From e5f83fd1397701d2f488e7ffbbd9e9d4aece88c5 Mon Sep 17 00:00:00 2001 From: Mohamed El Mahallawy Date: Fri, 23 Dec 2016 02:58:54 +0200 Subject: [PATCH 01/11] stylelint --- .eslintrc | 48 +- package.json | 56 +- src/client.js | 13 +- .../Audioplayer/RepeatDropdown/index.js | 50 +- .../Audioplayer/RepeatDropdown/spec.js | 20 +- .../Audioplayer/ScrollButton/index.js | 5 +- .../Audioplayer/ScrollButton/spec.js | 8 +- src/components/Audioplayer/Segments/spec.js | 19 +- src/components/Audioplayer/Track/index.js | 11 +- src/components/Audioplayer/Track/spec.js | 7 +- src/components/Audioplayer/index.js | 44 +- src/components/Audioplayer/spec.js | 64 +- src/components/Ayah/index.js | 8 +- src/components/FontStyles/index.js | 4 +- src/components/FontStyles/selector.js | 2 +- src/components/Footer/index.js | 40 +- src/components/Home/LastVisit/index.js | 9 +- src/components/Home/QuickSurahs/spec.js | 6 +- src/components/Home/SurahsList/index.js | 3 +- src/components/Home/SurahsList/spec.js | 6 +- src/components/IndexHeader/Nav/index.js | 2 +- src/components/IndexHeader/index.js | 6 +- src/components/InformationToggle/index.js | 3 +- src/components/LazyLoad/index.js | 2 +- src/components/Line/index.js | 12 +- src/components/NightModeToggle/index.js | 1 + src/components/NoScript/index.js | 14 +- src/components/PageBreak/index.js | 2 +- src/components/QuranNav/index.js | 6 +- src/components/ReciterDropdown/index.js | 2 +- src/components/SearchAutocomplete/index.js | 12 +- src/components/SearchInput/index.js | 2 +- src/components/Share/index.js | 21 +- src/components/Sidebar/index.js | 8 +- src/components/SmartBanner/index.js | 48 +- src/components/SurahInfo/index.js | 9 +- src/components/TooltipDropdown/index.js | 2 +- src/components/TopOptions/index.js | 6 +- src/config.js | 118 +- src/containers/About/index.js | 12 +- src/containers/App/connect.js | 2 +- src/containers/App/index.js | 30 +- src/containers/Contact/index.js | 32 +- src/containers/Donations/index.js | 3 +- src/containers/Home/index.js | 7 +- src/containers/MobileLanding/index.js | 6 +- src/containers/Search/Header/index.js | 2 +- src/containers/Search/index.js | 9 +- src/containers/Surah/Header/index.js | 11 +- src/containers/Surah/Title/index.js | 18 +- src/containers/Surah/connect.js | 2 +- src/containers/Surah/index.js | 30 +- src/helpers/ApiClient.js | 2 +- src/helpers/Html.js | 12 +- src/helpers/buildAudio.js | 7 +- src/helpers/buildFontFaces.js | 6 +- src/helpers/buildSegments.js | 4 +- src/helpers/makeHeadTags.js | 20 +- src/helpers/metrics.js | 3 +- src/redux/actions/auth.js | 4 +- src/redux/actions/ayahs.js | 2 +- src/redux/actions/bookmarks.js | 6 +- src/redux/actions/fontFace.js | 10 +- src/redux/actions/media.js | 18 +- src/redux/actions/options.js | 2 +- src/redux/actions/search.js | 4 +- src/redux/actions/surahs.js | 27 +- src/redux/create.js | 3 +- src/redux/middleware/clientMiddleware.js | 10 +- src/redux/modules/audioplayer.js | 39 +- src/redux/modules/ayahs.js | 22 +- src/redux/modules/bookmarks.js | 6 - src/redux/modules/fontFaces.js | 6 +- src/redux/modules/lines.js | 9 +- src/redux/modules/options.js | 6 +- src/redux/modules/surahs.js | 4 +- src/routes.js | 2 +- src/server.js | 108 +- src/server/config/express.js | 19 +- src/server/config/sitemap.js | 7 +- src/server/config/support.js | 2 +- src/styles/components/SmartBanner.scss | 16 - src/types/surahType.js | 20 + src/utils/bindTooltip.js | 8 +- src/utils/getOffset.js | 2 +- src/utils/scroller.js | 1 + yarn.lock | 1769 ++++++++--------- 87 files changed, 1492 insertions(+), 1557 deletions(-) create mode 100644 src/types/surahType.js diff --git a/.eslintrc b/.eslintrc index 2ee45a587..58b1abbaf 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,39 +1,24 @@ { - "parser": "babel-eslint", "extends": "airbnb", - "env": { - "browser": true, - "node": true, - "mocha": true, - "es6": true - }, + "parser": "babel-eslint", "rules": { - "react/no-multi-comp": 0, - "import/default": 0, - "import/no-duplicates": 0, - "import/named": 0, - "import/namespace": 0, + "comma-dangle": 0, + "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], + "import/no-extraneous-dependencies": 0, + "import/extensions": 0, "import/no-unresolved": 0, - "import/no-named-as-default": 2, - // Temporarirly disabled due to a possible bug in babel-eslint (todomvc example) - "block-scoped-var": 0, - // Temporarily disabled for test/* until babel/babel-eslint#33 is resolved - "padded-blocks": 0, - "comma-dangle": 0, // not sure why airbnb turned this on. gross! - "indent": [2, 2, {"SwitchCase": 1}], - "no-console": 0, - "no-alert": 0, - "object-curly-spacing": 0, - "no-case-declarations": 0 + "strict": 0 + }, + "ecmaFeatures": { + "classes": true, + "jsx": true }, "plugins": [ - "react", "import" + "react", + "mocha" ], "settings": { - "import/parser": "babel-eslint", - "import/resolve": { - moduleDirectory: ["node_modules", "src"] - } + "import/resolver": "webpack" }, "parserOptions":{ "ecmaFeatures": { @@ -53,6 +38,11 @@ mixpanel: true, "expect": true, "browser": true, - "FB": true + "FB": true, + sinon: true + }, + "env": { + "mocha": true, + "amd": true } } diff --git a/package.json b/package.json index 9c22ed569..e54161b1f 100644 --- a/package.json +++ b/package.json @@ -55,82 +55,84 @@ "clean-webpack-plugin": "0.1.10", "compression": "1.6.2", "cookie-parser": "1.4.3", - "copy-to-clipboard": "1.1.1", + "copy-to-clipboard": "3.0.5", "cors": "2.7.1", - "crypto-js": "3.1.6", "css-loader": "0.23.1", "debug": "2.2.0", - "dotenv": "1.2.0", + "dotenv": "2.0.0", "errorhandler": "1.4.3", "express": "4.14.0", "express-state": "1.4.0", - "express-useragent": "0.2.4", + "express-useragent": "1.0.4", "extract-text-webpack-plugin": "2.0.0-beta.3", "file-loader": "0.8.5", "fontfaceobserver": "1.7.3", + "history": "^3.0.0", "html-webpack-plugin": "1.7.0", "http-proxy": "1.14.0", - "humps": "1.1.0", + "humps": "2.0.0", "imports-loader": "0.6.5", - "jquery": "2.2.4", "json-loader": "0.5.4", "morgan": "1.7.0", - "node-sass": "3.8.0", + "node-sass": "4.1.1", "normalizr": "2.2.1", "pretty-error": "2.0.0", "promise": "7.1.1", "proxy-middleware": "0.14.0", "qs": "6.2.1", - "raven": "0.11.0", + "raven": "1.1.1", "raw-loader": "0.5.1", - "react": "0.14.8", + "react": "15.4.1", + "react-a11y": "0.3.3", + "react-addons-create-fragment": "15.4.1", "react-bootstrap": "0.29.5", - "react-cookie": "0.3.4", - "react-dom": "0.14.8", + "react-cookie": "1.0.4", + "react-dom": "15.4.1", "react-helmet": "3.1.0", + "react-inlinesvg": "0.5.4", "react-metrics": "1.2.1", - "react-paginate": "0.4.3", - "react-redux": "4.4.5", - "react-router": "2.6.1", + "react-paginate": "4.0.0", + "react-redux": "5.0.1", + "react-router": "3.0.0", "react-router-bootstrap": "0.20.1", - "react-router-redux": "4.0.5", + "react-router-redux": "4.0.7", "react-router-scroll": "0.2.1", "react-scroll": "1.2.0", "react-share": "1.11.0", "react-sidebar": "2.2.1", "redux": "3.5.2", - "redux-connect": "2.4.0", + "redux-connect": "5.0.0", "reselect": "2.5.3", "resolve-url": "0.2.1", - "sass-loader": "2.0.1", + "sass-loader": "4.1.1", "serialize-javascript": "1.3.0", "serve-favicon": "2.3.0", "sitemap": "1.8.1", "strip-loader": "0.1.2", "style-loader": "0.13.1", - "superagent": "1.8.4", + "superagent": "3.3.1", "url": "0.11.0", "url-loader": "0.5.7", "webpack": "2.1.0-beta.20", "webpack-isomorphic-tools": "2.5.7", "react-intl": "2.1.5", - "winston": "1.1.2", - "react-inlinesvg": "0.5.4" + "winston": "1.1.2" }, "devDependencies": { - "babel-eslint": "6.0.4", + "babel-eslint": "7.1.1", "babel-plugin-react-transform": "2.0.2", "babel-preset-react-hmre": "1.1.1", "chai": "3.0.0", "chromedriver": "2.22.2", "del": "2.0.2", "enzyme": "2.2.0", - "eslint": "2.13.0", - "eslint-config-airbnb": "9.0.1", + "eslint": "3.12.2", + "eslint-config-airbnb": "13.0.0", "eslint-loader": "1.3.0", - "eslint-plugin-import": "1.8.1", - "eslint-plugin-jsx-a11y": "1.5.3", - "eslint-plugin-react": "5.2.2", + "eslint-plugin-import": "2.2.0", + "eslint-plugin-jsx-a11y": "2.2.3", + "eslint-plugin-mocha": "4.8.0", + "eslint-plugin-react": "6.8.0", "jscs": "2.1.1", "karma": "1.2.0", "karma-chai": "0.1.0", @@ -151,7 +153,7 @@ "phantomjs-polyfill": "0.0.1", "piping": "0.3.0", "pre-commit": "1.1.3", - "react-addons-test-utils": "0.14.7", + "react-addons-test-utils": "15.4.1", "react-transform-catch-errors": "1.0.0", "react-transform-hmr": "1.0.1", "redbox-react": "1.1.1", diff --git a/src/client.js b/src/client.js index 92ccb4b3c..b8cbd3d78 100644 --- a/src/client.js +++ b/src/client.js @@ -20,7 +20,7 @@ import config from './config'; import ApiClient from './helpers/ApiClient'; import createStore from './redux/create'; import routes from './routes'; -import {getLocalMessages} from './helpers/setLocal'; +import { getLocalMessages } from './helpers/setLocal'; const client = new ApiClient(); const store = createStore(browserHistory, client, window.reduxData); @@ -29,7 +29,7 @@ const history = syncHistoryWithStore(browserHistory, store); try { Raven.config(config.sentryClient).install(); } catch (error) { - console.log(error); + debug('client', error); } window.quranDebug = debug; @@ -49,11 +49,10 @@ match({ history, routes: routes(store) }, (error, redirectLocation, renderProps) const component = ( ( + render={props => ( !item.deferred} render={applyRouterMiddleware(useScroll())} /> )} @@ -65,9 +64,9 @@ match({ history, routes: routes(store) }, (error, redirectLocation, renderProps) debug('client', 'React Rendering'); ReactDOM.render( - - - {component} + + + {component} , mountNode, () => { debug('client', 'React Rendered'); diff --git a/src/components/Audioplayer/RepeatDropdown/index.js b/src/components/Audioplayer/RepeatDropdown/index.js index ef90239ae..1f9c4ff7d 100644 --- a/src/components/Audioplayer/RepeatDropdown/index.js +++ b/src/components/Audioplayer/RepeatDropdown/index.js @@ -11,11 +11,13 @@ import { intlShape, injectIntl } from 'react-intl'; import SwitchToggle from 'components/SwitchToggle'; import LocaleFormattedMessage from 'components/LocaleFormattedMessage'; +import surahType from 'types/surahType'; + const style = require('../style.scss'); class RepeatButton extends Component { static propTypes = { - surah: PropTypes.object.isRequired, + surah: surahType, repeat: PropTypes.shape({ from: PropTypes.number, to: PropTypes.number, @@ -61,18 +63,18 @@ class RepeatButton extends Component { const array = Array(surah.ayat).join().split(','); return ( - -
    + +
    • {' '}:
      setRepeat({ + onChange={event => setRepeat({ ...repeat, from: parseInt(event.target.value, 10), to: parseInt(event.target.value, 10) + 3 @@ -90,14 +92,14 @@ class RepeatButton extends Component {
    • -
    • {' '}:
      setRepeat({ ...repeat, to: parseInt(event.target.value, 10)})} + onChange={event => setRepeat({ ...repeat, to: parseInt(event.target.value, 10) })} > { array.map((ayah, index) => ( @@ -118,15 +120,15 @@ class RepeatButton extends Component { const array = Array(surah.ayat).join().split(','); return ( - + {' '}:
      setRepeat({ + onChange={event => setRepeat({ ...repeat, from: parseInt(event.target.value, 10), to: parseInt(event.target.value, 10) @@ -157,14 +159,14 @@ class RepeatButton extends Component { > @@ -189,22 +191,22 @@ class RepeatButton extends Component { return ( - + :
      setRepeat({ + onChange={event => setRepeat({ ...repeat, times: parseInt(event.target.value, 10) })} > { @@ -231,8 +233,8 @@ class RepeatButton extends Component { {' '} { +const makeComponent = (repeat) => { setRepeat = sinon.stub(); component = mountWithIntl( @@ -21,24 +23,24 @@ makeComponent = (repeat) => { ); overlay = mountWithIntl(component.find('OverlayTrigger').first().props().overlay); -} +}; describe('', () => { it('should not be repeating', () => { - makeComponent({times: Infinity}); + makeComponent({ times: Infinity }); expect(component.find('i').first().props().className).not.to.contain('repeat_'); }); it('should indicate repeating', () => { - makeComponent({from: 1, to: 10, times: Infinity}); + makeComponent({ from: 1, to: 10, times: Infinity }); expect(component.find('i').first().props().className).to.contain('repeat'); }); describe('when single ayah', () => { beforeEach(() => { - makeComponent({from: 3, to: 3, times: Infinity}); + makeComponent({ from: 3, to: 3, times: Infinity }); }); it('should have a single ayah input', () => { @@ -52,7 +54,7 @@ describe('', () => { describe('when range', () => { beforeEach(() => { - makeComponent({from: 1, to: 3, times: Infinity}); + makeComponent({ from: 1, to: 3, times: Infinity }); }); it('should have a range ayah input', () => { @@ -67,13 +69,13 @@ describe('', () => { describe('times', () => { it('should have Infinity count', () => { - makeComponent({from: 1, to: 3, times: Infinity}); + makeComponent({ from: 1, to: 3, times: Infinity }); expect(overlay.find('FormControl').last().props().value).to.eql(Infinity); }); it('should have a count', () => { - makeComponent({from: 1, to: 3, times: 4}); + makeComponent({ from: 1, to: 3, times: 4 }); expect(overlay.find('FormControl').last().props().value).to.eql(4); }); diff --git a/src/components/Audioplayer/ScrollButton/index.js b/src/components/Audioplayer/ScrollButton/index.js index 314212625..eae95adc4 100644 --- a/src/components/Audioplayer/ScrollButton/index.js +++ b/src/components/Audioplayer/ScrollButton/index.js @@ -9,7 +9,7 @@ const ScrollButton = ({ shouldScroll, onScrollToggle }) => { const tooltip = ( @@ -24,10 +24,11 @@ const ScrollButton = ({ shouldScroll, onScrollToggle }) => { trigger={['hover', 'focus']} > diff --git a/src/components/Audioplayer/ScrollButton/spec.js b/src/components/Audioplayer/ScrollButton/spec.js index fac524805..60f711fb6 100644 --- a/src/components/Audioplayer/ScrollButton/spec.js +++ b/src/components/Audioplayer/ScrollButton/spec.js @@ -3,7 +3,9 @@ import { mount } from 'enzyme'; import ScrollButton from './index'; -let makeComponent, component, onScrollToggle; +let makeComponent; +let component; +let onScrollToggle; describe('', () => { beforeEach(() => { @@ -13,7 +15,7 @@ describe('', () => { component = mount( ); - } + }; }); it('should indicate that shouldScroll', () => { @@ -31,6 +33,6 @@ describe('', () => { it('should call onScrollToggle when clicked', () => { component.find('label').first().simulate('click'); - expect(onScrollToggle).to.have.been.called; + expect(onScrollToggle).to.have.been.called; // eslint-disable-line }); }); diff --git a/src/components/Audioplayer/Segments/spec.js b/src/components/Audioplayer/Segments/spec.js index 49a98ad19..be3b3fd5e 100644 --- a/src/components/Audioplayer/Segments/spec.js +++ b/src/components/Audioplayer/Segments/spec.js @@ -4,7 +4,7 @@ import Helmet from 'react-helmet'; import Segments from './index'; -let makeComponent, component; +let component; describe('', () => { describe('when are an empty object', () => { @@ -15,7 +15,7 @@ describe('', () => { }); it('should not have add any styles', () => { - expect(component.props()).to.eql({segments: {}}); + expect(component.props()).to.eql({ segments: {} }); }); it('should return noscript', () => { @@ -27,7 +27,7 @@ describe('', () => { beforeEach(() => { component = mount( @@ -51,7 +51,18 @@ describe('', () => { beforeEach(() => { component = mount( diff --git a/src/components/Audioplayer/Track/index.js b/src/components/Audioplayer/Track/index.js index 378cce1f0..619403bdd 100644 --- a/src/components/Audioplayer/Track/index.js +++ b/src/components/Audioplayer/Track/index.js @@ -1,3 +1,4 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ import React, { Component, PropTypes } from 'react'; const styles = require('./style.scss'); @@ -13,7 +14,7 @@ export default class Track extends Component { const fraction = ( event.nativeEvent.offsetX / - this.refs.container.getBoundingClientRect().width + this.container.getBoundingClientRect().width ); return onTrackChange(fraction); @@ -23,8 +24,12 @@ export default class Track extends Component { const { progress } = this.props; return ( -
      -
      +
      { this.container = container; }} + className={styles.container} + onClick={this.handleClick} + > +
      ); } diff --git a/src/components/Audioplayer/Track/spec.js b/src/components/Audioplayer/Track/spec.js index d4676bba1..a7395b23e 100644 --- a/src/components/Audioplayer/Track/spec.js +++ b/src/components/Audioplayer/Track/spec.js @@ -3,7 +3,8 @@ import { mount } from 'enzyme'; import Track from './index'; -let component, onTrackChange; +let component; +let onTrackChange; describe('', () => { beforeEach(() => { @@ -18,9 +19,9 @@ describe('', () => { }); it('should return click progress', () => { - component.simulate('click', {nativeEvent: {offsetX: 1}}); + component.simulate('click', { nativeEvent: { offsetX: 1 } }); - expect(onTrackChange).to.have.been.called; + expect(onTrackChange).to.have.been.called; // eslint-disable-line expect(onTrackChange).to.have.been.calledWith(Infinity); // because the bounding box is 0! }); }); diff --git a/src/components/Audioplayer/index.js b/src/components/Audioplayer/index.js index e5bc42620..26d628562 100644 --- a/src/components/Audioplayer/index.js +++ b/src/components/Audioplayer/index.js @@ -1,28 +1,31 @@ +/* global document */ // TODO: This file is too too large. import React, { Component, PropTypes } from 'react'; import { connect } from 'react-redux'; import { camelize } from 'humps'; +import LocaleFormattedMessage from 'components/LocaleFormattedMessage'; + +// Helpers +import debug from 'helpers/debug'; +import scroller from 'utils/scroller'; + +import surahType from 'types/surahType'; + // Redux import * as AudioActions from 'redux/actions/audioplayer'; -// Components import Track from './Track'; import Segments from './Segments'; import ScrollButton from './ScrollButton'; import RepeatDropdown from './RepeatDropdown'; -import LocaleFormattedMessage from 'components/LocaleFormattedMessage'; - -// Helpers -import debug from 'helpers/debug'; -import scroller from 'utils/scroller'; const style = require('./style.scss'); export class Audioplayer extends Component { static propTypes = { className: PropTypes.string, - surah: PropTypes.object.isRequired, + surah: surahType, onLoadAyahs: PropTypes.func.isRequired, segments: PropTypes.object, files: PropTypes.object, @@ -32,10 +35,14 @@ export class Audioplayer extends Component { isLoading: PropTypes.bool.isRequired, play: PropTypes.func.isRequired, pause: PropTypes.func.isRequired, - next: PropTypes.func.isRequired, - previous: PropTypes.func.isRequired, + next: PropTypes.func.isRequired, // eslint-disable-line + previous: PropTypes.func.isRequired, // eslint-disable-line update: PropTypes.func.isRequired, - repeat: PropTypes.object.isRequired, + repeat: PropTypes.shape({ + from: PropTypes.number, + to: PropTypes.number, + time: PropTypes.number, + }).isRequired, shouldScroll: PropTypes.bool.isRequired, setRepeat: PropTypes.func.isRequired, setAyah: PropTypes.func.isRequired, @@ -165,7 +172,7 @@ export class Audioplayer extends Component { const ayahIds = Object.keys(files); const index = ayahIds.findIndex(id => id === currentAyah) + 1; - for (let id = index; id <= index + 2; id++) { + for (let id = index; id <= index + 2; id += 1) { if (ayahIds[id]) { const ayahKey = ayahIds[id]; @@ -308,7 +315,7 @@ export class Audioplayer extends Component { return file; } - handleRemoveFileListeneres(file) { + handleRemoveFileListeneres = (file) => { file.pause(); file.currentTime = 0; // eslint-disable-line no-param-reassign file.onloadeddata = null; // eslint-disable-line no-param-reassign @@ -334,6 +341,7 @@ export class Audioplayer extends Component { return ( @@ -349,6 +357,7 @@ export class Audioplayer extends Component { return ( index && this.handleAyahChange('previous')} > @@ -364,6 +373,7 @@ export class Audioplayer extends Component { return ( !isEnd && this.handleAyahChange()} > @@ -395,8 +405,8 @@ export class Audioplayer extends Component {
    • @@ -408,7 +418,7 @@ export class Audioplayer extends Component {
      {isLoadedOnClient ? : null} { @@ -426,8 +436,8 @@ export class Audioplayer extends Component {
      • : {currentAyah.split(':')[1]}
      • diff --git a/src/components/Audioplayer/spec.js b/src/components/Audioplayer/spec.js index da297dfca..fff7dbe49 100644 --- a/src/components/Audioplayer/spec.js +++ b/src/components/Audioplayer/spec.js @@ -3,7 +3,11 @@ import { shallow } from 'enzyme'; import { Audioplayer } from './index'; -let makeComponent, component, setRepeat, setAyah, file; +let makeComponent; +let component; +let setRepeat; +let setAyah; +let file; describe('', () => { describe('#handleRepeat', () => { @@ -36,38 +40,38 @@ describe('', () => { makeComponent({}); component.instance().handleRepeat(file); - expect(component.instance().handleAyahChange).to.have.been.called; - expect(component.instance().play).not.to.have.been.called; - expect(setRepeat).not.to.have.been.called; - expect(setAyah).not.to.have.been.called; + expect(component.instance().handleAyahChange).to.have.been.called; // eslint-disable-line + expect(component.instance().play).not.to.have.been.called; // eslint-disable-line + expect(setRepeat).not.to.have.been.called; // eslint-disable-line + expect(setAyah).not.to.have.been.called; // eslint-disable-line }); it('should not do anything when out of range', () => { - makeComponent({from: 13, to: 13, times: 10}); + makeComponent({ from: 13, to: 13, times: 10 }); component.instance().handleRepeat(file); - expect(component.instance().handleAyahChange).to.have.been.called; - expect(setRepeat).not.to.have.been.called; + expect(component.instance().handleAyahChange).to.have.been.called; // eslint-disable-line + expect(setRepeat).not.to.have.been.called; // eslint-disable-line }); it('should repeat current ayah', () => { - makeComponent({from: 3, to: 3, times: 10}); + makeComponent({ from: 3, to: 3, times: 10 }); component.instance().handleRepeat(file); - expect(file.pause).to.have.been.called; - expect(setRepeat).to.have.been.called; - expect(setRepeat).to.have.been.calledWith({from: 3, to: 3, times: 9}); + expect(file.pause).to.have.been.called; // eslint-disable-line + expect(setRepeat).to.have.been.called; // eslint-disable-line + expect(setRepeat).to.have.been.calledWith({ from: 3, to: 3, times: 9 }); expect(file.currentTime).to.eql(0); - expect(file.play).to.have.been.called; + expect(file.play).to.have.been.called; // eslint-disable-line }); it('should not repeat when last time to repeat', () => { - makeComponent({from: 3, to: 3, times: 1}); + makeComponent({ from: 3, to: 3, times: 1 }); component.instance().handleRepeat(file); - expect(setRepeat).to.have.been.called; + expect(setRepeat).to.have.been.called; // eslint-disable-line expect(setRepeat).to.have.been.calledWith({}); - expect(component.instance().handleAyahChange).to.have.been.called; + expect(component.instance().handleAyahChange).to.have.been.called; // eslint-disable-line }); }); @@ -97,39 +101,39 @@ describe('', () => { }); it('should not do anything when out of range', () => { - makeComponent({from: 7, to: 13, times: 10}); + makeComponent({ from: 7, to: 13, times: 10 }); component.instance().handleRepeat(file); - expect(component.instance().handleAyahChange).to.have.been.called; - expect(setRepeat).not.to.have.been.called; + expect(component.instance().handleAyahChange).to.have.been.called; // eslint-disable-line + expect(setRepeat).not.to.have.been.called; // eslint-disable-line }); it('should play next ayah when within range', () => { - makeComponent({from: 2, to: 5, times: 10}); + makeComponent({ from: 2, to: 5, times: 10 }); component.instance().handleRepeat(file); - expect(file.pause).to.have.been.called; - expect(setRepeat).not.to.have.been.called; - expect(component.instance().handleAyahChange).to.have.been.called; + expect(file.pause).to.have.been.called; // eslint-disable-line + expect(setRepeat).not.to.have.been.called; // eslint-disable-line + expect(component.instance().handleAyahChange).to.have.been.called; // eslint-disable-line }); it('should start the range from the beginning when at the end', () => { - makeComponent({from: 1, to: 3, times: 10}); + makeComponent({ from: 1, to: 3, times: 10 }); component.instance().handleRepeat(file); - expect(file.pause).to.have.been.called; - expect(setRepeat).to.have.been.called; - expect(setRepeat).to.have.been.calledWith({from: 1, to: 3, times: 9}); + expect(file.pause).to.have.been.called; // eslint-disable-line + expect(setRepeat).to.have.been.called; // eslint-disable-line + expect(setRepeat).to.have.been.calledWith({ from: 1, to: 3, times: 9 }); expect(setAyah).to.have.been.calledWith('2:1'); }); it('should not repeat when last time to repeat when range ayah', () => { - makeComponent({from: 1, to: 3, times: 1}); + makeComponent({ from: 1, to: 3, times: 1 }); component.instance().handleRepeat(file); - expect(setRepeat).to.have.been.called; + expect(setRepeat).to.have.been.called; // eslint-disable-line expect(setRepeat).to.have.been.calledWith({}); - expect(component.instance().handleAyahChange).to.have.been.called; + expect(component.instance().handleAyahChange).to.have.been.called; // eslint-disable-line }); }); }); diff --git a/src/components/Ayah/index.js b/src/components/Ayah/index.js index 6a9d18fa2..41a00bdf3 100644 --- a/src/components/Ayah/index.js +++ b/src/components/Ayah/index.js @@ -33,7 +33,8 @@ export default class Ayah extends Component { tooltip: PropTypes.string, currentWord: PropTypes.any, // gets passed in an integer, null by default isCurrentAyah: PropTypes.bool, - audioActions: PropTypes.object.isRequired + audioActions: PropTypes.object.isRequired, + currentAyah: PropTypes.string }; static defaultProps = { @@ -64,10 +65,11 @@ export default class Ayah extends Component { handlePlay(ayah) { const { isPlaying, audioActions, currentAyah } = this.props; const { pause, setAyah, play } = audioActions; - const isPreviouslyPlaying = isPlaying; - if (isPlaying) + if (isPlaying) { pause(); + } + setAyah(ayah); play(); } diff --git a/src/components/FontStyles/index.js b/src/components/FontStyles/index.js index 79622e38b..18191c22b 100644 --- a/src/components/FontStyles/index.js +++ b/src/components/FontStyles/index.js @@ -1,7 +1,7 @@ import React, { Component, PropTypes } from 'react'; import { connect } from 'react-redux'; import { fontFaceStyle, fontFaceStyleLoaded } from 'helpers/buildFontFaces'; -import { load } from 'redux/actions/fontFace.js'; +import load from 'redux/actions/fontFace.js'; import debug from 'helpers/debug'; import selector from './selector'; @@ -29,7 +29,7 @@ export default class FontStyles extends Component { if (__CLIENT__) { const FontFaceObserver = require('fontfaceobserver'); // eslint-disable-line global-require - Object.keys(fontFaces).filter(className => !fontFaces[className]).forEach(className => { + Object.keys(fontFaces).filter(className => !fontFaces[className]).forEach((className) => { const font = new FontFaceObserver(className); font.load().then(() => load(className), () => load(className)); diff --git a/src/components/FontStyles/selector.js b/src/components/FontStyles/selector.js index 77ed63c5b..90be4a1c6 100644 --- a/src/components/FontStyles/selector.js +++ b/src/components/FontStyles/selector.js @@ -2,5 +2,5 @@ import { createSelector } from 'reselect'; export default createSelector( state => state.fontFaces, - (fontFaces) => fontFaces + fontFaces => fontFaces ); diff --git a/src/components/Footer/index.js b/src/components/Footer/index.js index eecfacf9c..55472601f 100644 --- a/src/components/Footer/index.js +++ b/src/components/Footer/index.js @@ -53,11 +53,43 @@ const Footer = () => ( />

          -
        • Sunnah.com
        • -
        • Salah.com
        • -
        • QuranicAudio.com
        • - + + Sunnah.com + +
        • +
        • + + Salah.com + +
        • +
        • + + QuranicAudio.com + +
        • +
        • + Corpus: Word by Word
        • diff --git a/src/components/Home/LastVisit/index.js b/src/components/Home/LastVisit/index.js index d66b57bcb..a4b528f20 100644 --- a/src/components/Home/LastVisit/index.js +++ b/src/components/Home/LastVisit/index.js @@ -1,19 +1,18 @@ import React, { PropTypes } from 'react'; import debug from 'helpers/debug'; +import Link from 'react-router/lib/Link'; + const styles = require('./style.scss'); const LastVisit = (props) => { - debug('component:Index', 'LastVisit'); - const {lastVisit, surahs} = props; + const { lastVisit, surahs } = props; if (lastVisit) { - const surah = surahs[lastVisit.surah - 1]; if (surah) { - const lastVisitedAyah = parseInt(lastVisit.ayah, 10); return ( @@ -48,6 +47,8 @@ const LastVisit = (props) => { ); } } + + return false; }; LastVisit.propTypes = { diff --git a/src/components/Home/QuickSurahs/spec.js b/src/components/Home/QuickSurahs/spec.js index 375c0fb0d..467c7d00a 100644 --- a/src/components/Home/QuickSurahs/spec.js +++ b/src/components/Home/QuickSurahs/spec.js @@ -1,11 +1,10 @@ import React from 'react'; import { mount } from 'enzyme'; -import Link from 'react-router/lib/Link'; import QuickSurahs from './index.js'; import { mountWithIntl } from '../../../../tests/helpers/intl-enzyme-test-helper.js'; -describe("", () => { +describe('', () => { const count = new Date().getDay() === 5 ? 5 : 4; it("Should render QuickSurahs component", () => { @@ -19,6 +18,5 @@ describe("", () => { let component = mountWithIntl(); expect(component).to.be.ok; expect(component.find('a').length).to.equal(count); - }) - + }); }); diff --git a/src/components/Home/SurahsList/index.js b/src/components/Home/SurahsList/index.js index 577f3a1c8..706313a9e 100644 --- a/src/components/Home/SurahsList/index.js +++ b/src/components/Home/SurahsList/index.js @@ -1,6 +1,7 @@ import React, { PropTypes } from 'react'; import debug from 'helpers/debug'; import Link from 'react-router/lib/Link'; + const styles = require('./style.scss'); const SurahsList = (props) => { @@ -8,7 +9,7 @@ const SurahsList = (props) => { return (
            - {props.surahs.map((surah) => ( + {props.surahs.map(surah => (
          • diff --git a/src/components/Home/SurahsList/spec.js b/src/components/Home/SurahsList/spec.js index a61199ef5..0e7eaf86f 100644 --- a/src/components/Home/SurahsList/spec.js +++ b/src/components/Home/SurahsList/spec.js @@ -5,11 +5,9 @@ import getSurahs from '../../../../tests/fixtures/getSurahs.js'; import SurahsList from './index.js'; describe('', () => { - - it("Should render SurahList component", () => { - let component = mount(); + it('Should render SurahList component', () => { + const component = mount(); expect(component).to.be.ok; expect(component.find('li').length).to.equal(4); }); - }); diff --git a/src/components/IndexHeader/Nav/index.js b/src/components/IndexHeader/Nav/index.js index 1d683a34d..46ae7141a 100644 --- a/src/components/IndexHeader/Nav/index.js +++ b/src/components/IndexHeader/Nav/index.js @@ -16,7 +16,7 @@ export class IndexHeaderNav extends Component { openNav(event) { event.preventDefault(); - this.setState({open: !this.state.open}); + this.setState({ open: !this.state.open }); } links() { diff --git a/src/components/IndexHeader/index.js b/src/components/IndexHeader/index.js index 7c317b97a..d58ffb1ce 100644 --- a/src/components/IndexHeader/index.js +++ b/src/components/IndexHeader/index.js @@ -2,10 +2,10 @@ import React, { Component, PropTypes } from 'react'; import Link from 'react-router/lib/Link'; import SearchInput from 'components/SearchInput'; -import Nav from './Nav'; - import debug from 'helpers/debug'; +import Nav from './Nav'; + const logo = require('../../../static/images/logo-lg-w.png'); export default class IndexHeader extends Component { @@ -27,7 +27,7 @@ export default class IndexHeader extends Component { debug('component:IndexHeader', 'Render'); return ( -
            +