Skip to content
This repository has been archived by the owner on Jun 28, 2021. It is now read-only.

#568 UI improvements #583

Merged
merged 24 commits into from
Jan 18, 2017
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
"scripts": {
"test": "npm run test:dev:unit",
"test:ci:unit": "karma start --browsers PhantomJS --single-run",
"posttest:ci:unit": "npm run test:ci:lint",
"pretest:ci:unit": "npm run test:ci:lint",
"test:ci:functional": "BROWSER=phantomjs ./tests/functional/test.sh start-ci",
"posttest:ci:functional": "./tests/functional/test.sh stop",
"test:dev:unit": "karma start",
"test:ci:lint": "./node_modules/eslint/bin/eslint.js ./src/**/*.js",
"test:ci:lint": "./node_modules/eslint/bin/eslint.js ./src",
"test:dev:functional": "BROWSER=chrome ./tests/functional/test.sh start",
"posttest:dev:functional": "./tests/functional/test.sh stop",
"test:dev:lint": "eslint ./src/scripts/**/*.js",
"test:dev:lint": "./node_modules/eslint/bin/eslint.js ./src",
"test:stylelint": "stylelint './src/**/*.scss' --config ./webpack/.stylelintrc",
"dev": "env NODE_PATH='./src' PORT=8000 UV_THREADPOOL_SIZE=100 node ./webpack/webpack-dev-server.js & env NODE_PATH='./src' PORT=8000 node ./bin/server.js",
"start": "NODE_PATH='src' node ./start",
Expand Down
42 changes: 18 additions & 24 deletions src/components/Ayah/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import Word from 'components/Word';

import debug from 'helpers/debug';

import bindTooltip from 'utils/bindTooltip';

const styles = require('./style.scss');

export default class Ayah extends Component {
Expand Down Expand Up @@ -48,10 +46,6 @@ export default class Ayah extends Component {
isSearched: false
};

componentDidMount() {
bindTooltip();
}

shouldComponentUpdate(nextProps) {
const conditions = [
this.props.ayah !== nextProps.ayah,
Expand Down Expand Up @@ -99,7 +93,7 @@ export default class Ayah extends Component {
<h4 className="montserrat">{content.name || content.resource.name}</h4>
<h2 className={`${isArabic ? 'text-right' : 'text-left'} text-translation times-new`}>
<small
dangerouslySetInnerHTML={{__html: content.text}}
dangerouslySetInnerHTML={{ __html: content.text }}
className={`${lang || 'times-new'}`}
/>
</h2>
Expand Down Expand Up @@ -148,20 +142,19 @@ export default class Ayah extends Component {
}

renderText() {
const { ayah, tooltip, currentAyah, isPlaying, audioActions, isSearched} = this.props;

const text = ayah.words.map(word => {
return(
<Word
word={word}
currentAyah={currentAyah}
tooltip={tooltip}
isPlaying={isPlaying}
audioActions={audioActions}
isSearched={isSearched}
/>
)
});
const { ayah, tooltip, currentAyah, isPlaying, audioActions, isSearched } = this.props;

const text = ayah.words.map(word => (
<Word
word={word}
key={`${word.position}-${word.code}-${word.lineNum}`}
currentAyah={currentAyah}
tooltip={tooltip}
isPlaying={isPlaying}
audioActions={audioActions}
isSearched={isSearched}
/>
));

return (
<h1 className={`${styles.font} text-right text-arabic`}>
Expand All @@ -187,7 +180,7 @@ export default class Ayah extends Component {
onClick={() => this.handlePlay(ayah.ayahKey)}
className="text-muted"
>
<i className={`ss-icon ${playing ? 'ss-pause' : 'ss-play'}`} />
<i className={`ss-icon ${playing ? 'ss-pause' : 'ss-play'} vertical-align-middle`} />{' '}
<LocaleFormattedMessage
id={playing ? 'actions.pause' : 'actions.play'}
defaultMessage={playing ? 'Pause' : 'Play'}
Expand Down Expand Up @@ -223,7 +216,8 @@ export default class Ayah extends Component {
onClick={() => bookmarkActions.removeBookmark(ayah.ayahKey)}
className="text-muted"
>
<strong><i className="ss-icon ss-bookmark" />
<strong>
<i className="ss-icon ss-bookmark vertical-align-middle" />{' '}
<LocaleFormattedMessage
id="ayah.bookmarked"
defaultMessage="Bookmarked"
Expand All @@ -239,7 +233,7 @@ export default class Ayah extends Component {
onClick={() => bookmarkActions.addBookmark(ayah.ayahKey)}
className="text-muted"
>
<i className="ss-icon ss-bookmark" />
<i className="ss-icon ss-bookmark vertical-align-middle" />{' '}
<LocaleFormattedMessage
id="ayah.bookmark"
defaultMessage="Bookmark"
Expand Down
63 changes: 30 additions & 33 deletions src/components/ContentDropdown/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { Component, PropTypes } from 'react';

import ButtonToolbar from 'react-bootstrap/lib/ButtonToolbar';
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
import MenuItem from 'react-bootstrap/lib/MenuItem';
import LocaleFormattedMessage from 'components/LocaleFormattedMessage';
import { optionsType } from 'types';

const style = require('./style.scss');

Expand Down Expand Up @@ -450,26 +450,18 @@ export const slugs = [
export default class ContentDropdown extends Component {
static propTypes = {
onOptionChange: PropTypes.func.isRequired,
options: optionsType.isRequired,
content: PropTypes.arrayOf(PropTypes.number).isRequired,
className: PropTypes.string
};

static defaultProps = {
className: 'col-md-3'
}

shouldComponentUpdate(nextProps) {
return this.props.options !== nextProps.options;
}

handleRemoveContent = () => {
const { onOptionChange } = this.props;

onOptionChange({ content: [] });
}

handleOptionSelected(id) {
const { onOptionChange, options: { content } } = this.props;
const { onOptionChange, content } = this.props;

if (content.find(option => option === id)) {
onOptionChange({ content: content.filter(option => option !== id) });
Expand All @@ -479,7 +471,7 @@ export default class ContentDropdown extends Component {
}

renderItems(items) {
const { options: { content } } = this.props;
const { content } = this.props;

return items.map((slug) => {
const checked = content.find(option => option === slug.id);
Expand Down Expand Up @@ -515,29 +507,34 @@ export default class ContentDropdown extends Component {
}

render() {
const { className, options: { content } } = this.props;
const { className, content } = this.props;
const title = slugs.filter(slug => content.includes(slug.id)).map(slug => slug.name).join(', ');

return (
<DropdownButton
className={`dropdown ${className} ${style.dropdown}`}
title={<LocaleFormattedMessage id="setting.translations.title" defaultMessage="Translations" />}
>
{
content.length &&
<MenuItem onClick={this.handleRemoveContent}>
<LocaleFormattedMessage id="setting.translations.removeAll" defaultMessage="Remove all" />
</MenuItem>
}
<MenuItem header>
<LocaleFormattedMessage id="setting.translations.english" defaultMessage="English" />
</MenuItem>
{this.renderEnglishList()}
<MenuItem divider />
<MenuItem header>
<LocaleFormattedMessage id="setting.translations.other" defaultMessage="Other Languages" />
</MenuItem>
{this.renderLanguagesList()}
</DropdownButton>
<ButtonToolbar>
<DropdownButton
block
id="content-dropdown"
className={`dropdown ${className} ${style.dropdown}`}
title={title}
>
{
content.length &&
<MenuItem onClick={this.handleRemoveContent}>
<LocaleFormattedMessage id="setting.translations.removeAll" defaultMessage="Remove all" />
</MenuItem>
}
<MenuItem header>
<LocaleFormattedMessage id="setting.translations.english" defaultMessage="English" />
</MenuItem>
{this.renderEnglishList()}
<MenuItem divider />
<MenuItem header>
<LocaleFormattedMessage id="setting.translations.other" defaultMessage="Other Languages" />
</MenuItem>
{this.renderLanguagesList()}
</DropdownButton>
</ButtonToolbar>
);
}
}
2 changes: 1 addition & 1 deletion src/components/ContentDropdown/spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('<ContentDropdown />', () => {
onOptionChange = sinon.stub();
wrapper = mountWithIntl(
<ContentDropdown
options={{ content: [defaultOption] }}
content={[defaultOption]}
onOptionChange={onOptionChange}
/>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/Copy/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default class Copy extends Component {
className={!isCopied && 'text-muted'}
data-metrics-event-name="Ayah:Copy"
>
<i className="ss-icon ss-attach" />
<i className="ss-icon ss-attach vertical-align-middle" />{' '}
<LocaleFormattedMessage
id={isCopied ? 'actions.copied' : 'actions.copy'}
defaultMessage={isCopied ? 'Copied!' : 'Copy'}
Expand Down
29 changes: 16 additions & 13 deletions src/components/FontSizeDropdown/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ import Col from 'react-bootstrap/lib/Col';

import LocaleFormattedMessage from 'components/LocaleFormattedMessage';

import { optionsType } from 'types';

const style = require('./style.scss');

export default class FontSizeDropdown extends Component {
static propTypes = {
onOptionChange: PropTypes.func,
options: optionsType
fontSize: PropTypes.shape({
arabic: PropTypes.number,
translation: PropTypes.number
}).isRequired
}

handleOptionSelected = (type, direction) => {
const { onOptionChange, options: { fontSize } } = this.props;
const { onOptionChange, fontSize } = this.props;
const changeFactor = {
translation: 0.5,
arabic: 0.5
Expand Down Expand Up @@ -94,15 +95,17 @@ export default class FontSizeDropdown extends Component {

render() {
return (
<OverlayTrigger trigger="click" placement="bottom" overlay={this.renderPopup()} rootClose>
<a
tabIndex="-1"
className="text-color"
data-metrics-event-name="FontSizeDropdown"
>
<LocaleFormattedMessage id="setting.fontSize" defaultMessage="Font size" />
</a>
</OverlayTrigger>
<li className={style.link}>
<OverlayTrigger trigger="click" placement="bottom" overlay={this.renderPopup()} rootClose>
<a
tabIndex="-1"
data-metrics-event-name="FontSizeDropdown"
>
<i className="ss-icon ss-font vertical-align-middle" />
{' '}<LocaleFormattedMessage id="setting.fontSize" defaultMessage="Font Size" className="visible-xs-inline-block" />
</a>
</OverlayTrigger>
</li>
);
}
}
8 changes: 7 additions & 1 deletion src/components/FontSizeDropdown/style.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@import '../../styles/variables.scss';

:local .popover{
.popover{
:global(.popover-title){
font-family: $font-montserrat;
text-transform: uppercase;
Expand All @@ -16,3 +16,9 @@
}
}
}

.link{
position: relative;
display: block;
cursor: pointer;
}
2 changes: 0 additions & 2 deletions src/components/Footer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import Grid from 'react-bootstrap/lib/Grid';
import Col from 'react-bootstrap/lib/Col';

import LocaleFormattedMessage from 'components/LocaleFormattedMessage';
import LocaleSwitcher from 'components/LocaleSwitcher';

const styles = require('./style.scss');

Expand Down Expand Up @@ -144,7 +143,6 @@ const Footer = () => (
</p>

<div className={styles.list}>
<LocaleSwitcher />
<p className="monserrat">
<LocaleFormattedMessage
id="nav.aboutQuranProject"
Expand Down
80 changes: 80 additions & 0 deletions src/components/GlobalNav/Surah/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import NavDropdown from 'react-bootstrap/lib/NavDropdown';

import { surahType, optionsType } from 'types';
import * as OptionsActions from 'redux/actions/options.js';

import SurahsDropdown from 'components/SurahsDropdown';
import ReadingModeToggle from 'components/ReadingModeToggle';
import NightModeToggle from 'components/NightModeToggle';
import FontSizeDropdown from 'components/FontSizeDropdown';
import LocaleFormattedMessage from 'components/LocaleFormattedMessage';
// TODO: import VersesDropdown from 'components/VersesDropdown';
import InformationToggle from 'components/InformationToggle';
import GlobalNav from '../index';

const styles = require('../style.scss');

const GlobalNavSurah = ({ surah, surahs, setOption, options, ...props }) => (
<GlobalNav
{...props}
leftControls={[
<SurahsDropdown title={surah.name.simple} surahs={surahs} />,
<NavDropdown
id="hidden-dropdown"
className={`visible-xs-inline-block ${styles.optionsDropdown}`}
title={<LocaleFormattedMessage id="settings.options" defaultMessage="Options" />}
>
<FontSizeDropdown
fontSize={options.fontSize}
onOptionChange={setOption}
/>
<InformationToggle
onToggle={setOption}
isToggled={options.isShowingSurahInfo}
/>
<ReadingModeToggle
isToggled={options.isReadingMode}
onToggle={setOption}
/>
<NightModeToggle />
</NavDropdown>
]}
rightControls={[
<FontSizeDropdown
fontSize={options.fontSize}
onOptionChange={setOption}
/>,
<InformationToggle
onToggle={setOption}
isToggled={options.isShowingSurahInfo}
/>,
<ReadingModeToggle
isToggled={options.isReadingMode}
onToggle={setOption}
/>,
<NightModeToggle />
]}
/>
);

GlobalNavSurah.propTypes = {
surah: surahType.isRequired,
surahs: PropTypes.objectOf(surahType).isRequired,
options: optionsType.isRequired,
setOption: PropTypes.func.isRequired,
};

function mapStateToProps(state, ownProps) {
const surahId = parseInt(ownProps.params.surahId, 10);
const surah: Object = state.surahs.entities[surahId];

return {
surah,
surahs: state.surahs.entities,
options: state.options
};
}

export default connect(mapStateToProps, OptionsActions)(GlobalNavSurah);
Loading