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

Commit

Permalink
Fixes #657 Recitations dropdown from API call (#664)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmahalwy authored Mar 3, 2017
1 parent 4bcea72 commit b92e92e
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 196 deletions.
223 changes: 30 additions & 193 deletions src/components/ReciterDropdown/index.js
Original file line number Diff line number Diff line change
@@ -1,229 +1,66 @@
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import ButtonToolbar from 'react-bootstrap/lib/ButtonToolbar';
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
import MenuItem from 'react-bootstrap/lib/MenuItem';

const style = require('./style.scss');
import Loader from 'components/Loader';
import LocaleFormattedMessage from 'components/LocaleFormattedMessage';

// To save API calls.
export const slugs = [
{
reciter: {
slug: 'abdulbaset',
id: 1
},
name: {
english: 'AbdulBaset AbdulSamad (Mujawwad)',
arabic: 'عبد الباسط عبد الصمد (مجود)'
},
style: {
slug: 'mujawwad',
id: 1
},
id: 1
},
{
reciter: {
slug: 'abdulbaset',
id: 1
},
name: {
english: 'AbdulBaset AbdulSamad (Murattal)',
arabic: 'عبد الباسط عبد الصمد (مرتل)'
},
style: {
slug: 'murattal',
id: 2
},
id: 2
},
{
reciter: {
slug: 'sudais',
id: 2
},
name: {
english: 'Abdur-Rahman as-Sudais',
arabic: 'عبدالرحمن السديس'
},
style: {
slug: null,
id: null
},
id: 3
},
{
reciter: {
slug: 'shatri',
id: 3
},
name: {
english: 'Abu Bakr al-Shatri',
arabic: 'أبو بكر الشاطرى'
},
style: {
slug: null,
id: null
},
id: 4
},
{
reciter: {
slug: 'rifai',
id: 4
},
name: {
english: 'Hani ar-Rifai',
arabic: 'هاني الرفاعي'
},
style: {
slug: null,
id: null
},
id: 5
},
{
reciter: {
slug: 'alafasy',
id: 6
},
name: {
english: 'Mishari Rashid al-`Afasy',
arabic: 'مشاري راشد العفاسي'
},
style: {
slug: null,
id: null
},
id: 8
},
{
reciter: {
slug: 'minshawi',
id: 7
},
name: {
english: 'Mohamed Siddiq al-Minshawi (Mujawwad)',
arabic: 'محمد صديق المنشاوي (مجود)'
},
style: {
slug: 'mujawwad',
id: 1
},
id: 9
},
{
reciter: {
slug: 'minshawi',
id: 7
},
name: {
english: 'Mohamed Siddiq al-Minshawi (Murattal)',
arabic: 'محمد صديق المنشاوي (مرتل)'
},
style: {
slug: 'murattal',
id: 2
},
id: 10
},
{
reciter: {
slug: 'altablawi',
id: 9
},
name: {
english: 'Mohamed al-Tablawi',
arabic: 'محمد الطبلاوي'
},
style: {
slug: null,
id: null
},
id: 12
},
{
reciter: {
slug: 'alhusary',
id: 5
},
name: {
english: 'Mahmoud Khalil Al-Husary',
arabic: 'محمود خليل الحصري'
},
style: {
slug: null,
id: null
},
id: 7
},
{
reciter: {
slug: 'muallim', // i'm just making up values for slug, i dont think we need this at all
id: 5
},
name: {
english: 'Mahmoud Khalil Al-Husary (Muallim)',
arabic: 'محمود خليل الحصري'
},
style: {
slug: 'muallim',
id: 3
},
id: 13
},
{
reciter: {
slug: 'shuraym',
id: 8
},
name: {
english: 'Sa`ud ash-Shuraym',
arabic: 'سعود الشريم'
},
style: {
slug: null,
id: null
},
id: 11
}
];
import { loadRecitations } from 'redux/actions/options';
import { recitationType } from 'types';

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

export default class ReciterDropdown extends Component {
class ReciterDropdown extends Component {
static propTypes = {
onOptionChange: PropTypes.func,
audio: PropTypes.number,
className: PropTypes.string
className: PropTypes.string,
loadRecitations: PropTypes.func.isRequired,
recitations: PropTypes.arrayOf(recitationType)
};

componentDidMount() {
return this.props.loadRecitations();
}

renderMenu() {
const { audio, onOptionChange } = this.props;
const { audio, onOptionChange, recitations } = this.props;

return slugs.map(slug => (
return recitations.map(slug => (
<MenuItem
key={slug.name.english}
key={slug.id}
active={slug.id === audio}
onClick={() => onOptionChange({ audio: slug.id })}
>
{slug.name.english}
{slug.reciterNameEng} {slug.style ? `(${slug.style})` : ''}
</MenuItem>
));
}

render() {
const { className, audio } = this.props;
const { className, audio, recitations } = this.props;
const title = recitations.length ?
recitations.find(slug => slug.id === audio).reciterNameEng :
<LocaleFormattedMessage id="setting.reciters.title" default="Reciters" />;

return (
<ButtonToolbar>
<DropdownButton
block
id="reciter-dropdown"
className={`${className} ${style.dropdown}`}
title={slugs.find(slug => slug.id === audio).name.english}
title={title}
>
{this.renderMenu()}
{recitations.length ? this.renderMenu() : <Loader />}
</DropdownButton>
</ButtonToolbar>
);
}
}

export default connect(state => ({
recitations: state.options.options.recitations,
loadingRecitations: state.options.loadingRecitations
}), { loadRecitations })(ReciterDropdown);
13 changes: 12 additions & 1 deletion src/redux/actions/options.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import cookie from 'react-cookie';
import { SET_OPTION } from 'redux/constants/options.js';
import {
SET_OPTION,
LOAD_RECITERS,
LOAD_RECITERS_SUCCESS,
LOAD_RECITERS_FAIL
} from 'redux/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));

Expand All @@ -15,3 +21,8 @@ export function setOption(payload) {
payload
};
}

export const loadRecitations = () => ({
types: [LOAD_RECITERS, LOAD_RECITERS_SUCCESS, LOAD_RECITERS_FAIL],
promise: client => client.get('/api/v3/options/recitations')
});
4 changes: 4 additions & 0 deletions src/redux/constants/options.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
export const SET_OPTION = '@@quran/options/SET_OPTION';
export const TOGGLE_NIGHT_MODE = '@@quran/options/TOGGLE_NIGHT_MODE';

export const LOAD_RECITERS = '@@quran/verses/LOAD_RECITERS';
export const LOAD_RECITERS_SUCCESS = '@@quran/verses/LOAD_RECITERS_SUCCESS';
export const LOAD_RECITERS_FAIL = '@@quran/verses/LOAD_RECITERS_FAIL';
27 changes: 25 additions & 2 deletions src/redux/modules/options.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@

import { SET_OPTION } from 'redux/constants/options.js';
import {
SET_OPTION,
LOAD_RECITERS,
LOAD_RECITERS_SUCCESS
} from 'redux/constants/options.js';

const initialState = {
isReadingMode: false,
isShowingSurahInfo: false,
loadingRecitations: false,
audio: 8,
quran: 1,
content: [19],
tooltip: 'translation',
options: {
recitations: []
},
fontSize: {
arabic: 3.5,
translation: 2
Expand All @@ -23,6 +30,22 @@ export default function reducer(state = initialState, action = {}) {
...payload
};
}
case LOAD_RECITERS: {
return {
...state,
loadingRecitations: true
};
}
case LOAD_RECITERS_SUCCESS: {
return {
...state,
loadingRecitations: false,
options: {
...state.options,
recitations: action.result.recitations
}
};
}
default:
return state;
}
Expand Down
1 change: 1 addition & 0 deletions src/types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export { default as bookmarkType } from './bookmarkType';
export { default as segmentType } from './segmentType';
export { default as wordType } from './wordType';
export { default as matchType } from './matchType';
export { default as recitationType } from './recitationType';
7 changes: 7 additions & 0 deletions src/types/recitationType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { PropTypes } from 'react';

export default PropTypes.shape({
id: PropTypes.number,
style: PropTypes.string,
reciter_name_eng: PropTypes.string
});

0 comments on commit b92e92e

Please sign in to comment.