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

Commit

Permalink
Feature/refactor redux (#414)
Browse files Browse the repository at this point in the history
* refactoring the redux structure to something more standard.

* ayahs actions/reducers

* SURAHS actions/reducers

* search action

* options and fontface actions

* lowercase the file names

* rename actions/actionTypes

* isLoaded is now a helper function, added audioplayer

* fix

* action unit tests
  • Loading branch information
thabti authored and mmahalwy committed Aug 6, 2016
1 parent 8f92662 commit 663d46c
Show file tree
Hide file tree
Showing 28 changed files with 495 additions and 332 deletions.
4 changes: 2 additions & 2 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import debug from './src/helpers/debug';

import Html from './src/helpers/Html';

import { setUserAgent } from './src/redux/modules/audioplayer';
import { setOption } from './src/redux/modules/options';
import { setUserAgent } from './src/redux/actions/audioplayer.js';
import { setOption } from './src/redux/actions/options.js';

// Use varnish for the static routes, which will cache too
server.use(raven.middleware.express.requestHandler(config.sentryServer));
Expand Down
2 changes: 1 addition & 1 deletion src/components/Audioplayer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import { camelize } from 'humps';

// Redux
import * as AudioActions from '../../redux/modules/audioplayer';
import * as AudioActions from '../../redux/actions/audioplayer';

// Components
import Track from './Track';
Expand Down
2 changes: 1 addition & 1 deletion src/components/FontStyles/index.js
Original file line number Diff line number Diff line change
@@ -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/modules/fontFaces';
import { load } from 'redux/actions/fontFace.js';

import debug from 'helpers/debug';
import selector from './selector';
Expand Down
2 changes: 1 addition & 1 deletion src/containers/Home/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { connect } from 'react-redux';

import debug from '../../helpers/debug';

import { isAllLoaded, loadAll } from '../../redux/modules/surahs';
import { isAllLoaded, loadAll } from '../../redux/actions/surahs.js';

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

Expand Down
2 changes: 1 addition & 1 deletion src/containers/Search/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Header from './Header';
import Ayah from '../../components/Ayah';
import CoreLoader from '../../components/Loader';

import { search } from '../../redux/modules/searchResults';
import { search } from '../../redux/actions/search.js';

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

Expand Down
16 changes: 12 additions & 4 deletions src/containers/Surah/connect.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { isAllLoaded, loadAll, setCurrent as setCurrentSurah } from '../../redux/modules/surahs';
import { clearCurrent, isLoaded, load as loadAyahs } from '../../redux/modules/ayahs';

import debug from 'helpers/debug';
import {
isAllLoaded,
loadAll,
setCurrent as setCurrentSurah
} from '../../redux/actions/surahs.js';

import {
clearCurrent,
load as loadAyahs
} from '../../redux/actions/ayahs.js';

import {debug, isLoaded} from 'helpers';

const ayahRangeSize = 30;

Expand Down
6 changes: 3 additions & 3 deletions src/containers/Surah/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ import descriptions from './descriptions';

import { surahsConnect, ayahsConnect } from './connect';

import * as AudioActions from '../../redux/modules/audioplayer';
import * as AyahActions from '../../redux/modules/ayahs';
import * as OptionsActions from '../../redux/modules/options';
import * as AudioActions from '../../redux/actions/audioplayer.js';
import * as AyahActions from '../../redux/actions/ayahs.js';
import * as OptionsActions from '../../redux/actions/options.js';

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

Expand Down
8 changes: 8 additions & 0 deletions src/helpers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function isLoaded(globalState, surahId, from, to) {
return (
globalState.ayahs.entities[surahId] &&
globalState.ayahs.entities[surahId][`${surahId}:${from}`] &&
globalState.ayahs.entities[surahId][`${surahId}:${to}`]
);
}
export { default as debug } from './debug';
94 changes: 94 additions & 0 deletions src/redux/actions/audioplayer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import {
SET_USER_AGENT,
SET_CURRENT_FILE,
SET_CURRENT_WORD,
PLAY,
PAUSE,
NEXT,
SET_AYAH,
PREVIOUS,
SET_REPEAT,
TOGGLE_SCROLL,
BUILD_ON_CLIENT,
UPDATE } from '../constants/audioplayer.js';

export function setUserAgent(userAgent) {
return {
type: SET_USER_AGENT,
userAgent
};
}

export function setCurrentFile(file) {
return {
type: SET_CURRENT_FILE,
file
};
}

export function setCurrentWord(word) {
return {
type: SET_CURRENT_WORD,
word
};
}

export function play() {
return {
type: PLAY
};
}

export function pause() {
return {
type: PAUSE
};
}

export function next(currentAyah) {
return {
type: NEXT,
currentAyah
};
}

export function setAyah(currentAyah) {
return {
type: SET_AYAH,
currentAyah
};
}

export function previous(currentAyah) {
return {
type: PREVIOUS,
currentAyah
};
}

export function setRepeat(repeat) {
return {
type: SET_REPEAT,
repeat
};
}

export function toggleScroll() {
return {
type: TOGGLE_SCROLL
};
}

export function buildOnClient(surahId) {
return {
type: BUILD_ON_CLIENT,
surahId
};
}

export function update(payload) {
return {
type: UPDATE,
payload
};
}
66 changes: 66 additions & 0 deletions src/redux/actions/ayahs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { ayahsSchema } from '../schemas';

import { arrayOf } from 'normalizr';

import {
LOAD,
LOAD_SUCCESS,
LOAD_FAIL,
CLEAR_CURRENT,
SET_CURRENT_AYAH,
SET_CURRENT_WORD,
CLEAR_CURRENT_WORD
} from '../constants/ayahs.js';

// For safe measure
const defaultOptions = {
audio: 8,
quran: 1,
content: [19]
};

export function load(id, from, to, options = defaultOptions) {
const { audio, quran, content } = options;

return {
types: [LOAD, LOAD_SUCCESS, LOAD_FAIL],
schema: arrayOf(ayahsSchema),
promise: (client) => client.get(`/v2/surahs/${id}/ayahs`, {
params: {
from,
to,
audio,
quran,
content
}
}),
surahId: id
};
}

export function clearCurrent(id) {
return {
type: CLEAR_CURRENT,
id
};
}

export function clearCurrentWord() {
return {
type: CLEAR_CURRENT_WORD
};
}

export function setCurrentAyah(id) {
return {
type: SET_CURRENT_AYAH,
id
};
}

export function setCurrentWord(id) {
return {
type: SET_CURRENT_WORD,
id
};
}
8 changes: 8 additions & 0 deletions src/redux/actions/fontFace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { LOAD } from '../constants/fontFace.js';

export function load(className) {
return {
type: LOAD,
className
};
}
23 changes: 23 additions & 0 deletions src/redux/actions/options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import cookie from 'react-cookie';
import { TOGGLE_READING_MODE, SET_OPTION } from '../constants/options.js';

export function isReadingMode(globalState) {
return globalState.options.isReadingMode;
}

export function setOption(payload) {
const options = cookie.load('options') || {}; // protect against first timers.
Object.keys(payload).forEach(option => { options[option] = payload[option]; });
cookie.save('options', JSON.stringify(options));

return {
type: SET_OPTION,
payload
};
}

export function toggleReadingMode() {
return {
type: TOGGLE_READING_MODE
};
}
21 changes: 21 additions & 0 deletions src/redux/actions/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ayahsSchema } from '../schemas';
import { arrayOf } from 'normalizr';

import {
SEARCH,
SEARCH_SUCCESS,
SEARCH_FAIL
} from '../constants/search.js';

export function search(params) {
return {
types: [SEARCH, SEARCH_SUCCESS, SEARCH_FAIL],
schema: {results: arrayOf({ayah: ayahsSchema})},
promise: (client) => client.get('/v2/search', { params }),
params
};
}

export function isQueried() {
return false;
}
43 changes: 43 additions & 0 deletions src/redux/actions/spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as audioplayerActions from './audioplayer.js';
import * as ayahsActions from './ayahs.js';
import * as surahsActions from './surahs.js';
import * as audioplayerConstant from '../constants/audioplayer.js';
import * as ayahsConstants from '../constants/ayahs.js';
import * as surahsConstants from '../constants/surahs.js';


describe("action tests", () => {

it("audioplayer actions", () => {
expect(audioplayerActions.setUserAgent('abc').type).to.equal(audioplayerConstant.SET_USER_AGENT);
expect(audioplayerActions.setCurrentFile('fil').type).to.equal(audioplayerConstant.SET_CURRENT_FILE);
expect(audioplayerActions.setCurrentWord('word').type).to.equal(audioplayerConstant.SET_CURRENT_WORD);
expect(audioplayerActions.play().type).to.equal(audioplayerConstant.PLAY);
expect(audioplayerActions.pause().type).to.equal(audioplayerConstant.PAUSE);
expect(audioplayerActions.next('abc').type).to.equal(audioplayerConstant.NEXT);
expect(audioplayerActions.previous('abc').type).to.equal(audioplayerConstant.PREVIOUS);
expect(audioplayerActions.setRepeat('abc').type).to.equal(audioplayerConstant.SET_REPEAT);
expect(audioplayerActions.toggleScroll().type).to.equal(audioplayerConstant.TOGGLE_SCROLL);
expect(audioplayerActions.buildOnClient('abc').type).to.equal(audioplayerConstant.BUILD_ON_CLIENT);
expect(audioplayerActions.update('abc').type).to.equal(audioplayerConstant.UPDATE);
});

it("ayahs actions", () => {
expect(ayahsActions.load(1, 2, 4).types.length).to.equal(3);
expect(ayahsActions.clearCurrent().type).to.equal(ayahsConstants.CLEAR_CURRENT);
expect(ayahsActions.clearCurrentWord(1).type).to.equal(ayahsConstants.CLEAR_CURRENT_WORD);
expect(ayahsActions.setCurrentAyah(1).type).to.equal(ayahsConstants.SET_CURRENT_AYAH);
expect(ayahsActions.setCurrentWord(1).type).to.equal(ayahsConstants.SET_CURRENT_WORD);
});

it("surahs actions", () => {
expect(surahsActions.loadAll().types.length).to.equal(3);
expect(surahsActions.load(1).types.length).to.equal(3);
expect(surahsActions.loadInfo('url').types.length).to.equal(3);
expect(surahsActions.setCurrent(1).type).to.equal(surahsConstants.SET_CURRENT);
});




});
48 changes: 48 additions & 0 deletions src/redux/actions/surahs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { surahsSchema } from '../schemas';
import { arrayOf } from 'normalizr';
import {
LOAD,
LOAD_SUCCESS,
LOAD_FAIL,
LOAD_INFO,
LOAD_INFO_SUCCESS,
LOAD_INFO_FAIL,
SET_CURRENT } from '../constants/surahs.js';

export function loadAll() {
return {
types: [LOAD, LOAD_SUCCESS, LOAD_FAIL],
schema: arrayOf(surahsSchema),
promise: (client) => client.get('/v2/surahs')
};
}

export function load(id) {
return {
types: [LOAD, LOAD_SUCCESS, LOAD_FAIL],
schema: arrayOf(surahsSchema),
promise: (client) => client.get(`/v2/surahs/${id}`)
};
}

export function loadInfo(link) {
return {
types: [LOAD_INFO, LOAD_INFO_SUCCESS, LOAD_INFO_FAIL],
promise: (client) => client.get(`http://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&titles=${link}&redirects=true`) // eslint-disable-line max-len
};
}

export function setCurrent(id) {
return {
type: SET_CURRENT,
current: id
};
}

export function isSingleLoaded(globalState, id) {
return !!globalState.surahs.entities[id];
}

export function isAllLoaded(globalState) {
return Object.keys(globalState.surahs.entities).length === 114;
}
Loading

0 comments on commit 663d46c

Please sign in to comment.