+
- Source: {chapter.info.source}
+ Source: {info.source}
@@ -49,7 +52,8 @@ const SurahInfo = ({ chapter, isShowingSurahInfo, onClose }) => {
SurahInfo.propTypes = {
onClose: PropTypes.func,
isShowingSurahInfo: PropTypes.bool,
- chapter: surahType
+ chapter: surahType,
+ info: infoType
};
export default SurahInfo;
diff --git a/src/containers/ChapterInfo/index.js b/src/containers/ChapterInfo/index.js
new file mode 100644
index 000000000..914118eeb
--- /dev/null
+++ b/src/containers/ChapterInfo/index.js
@@ -0,0 +1,84 @@
+import React from 'react';
+
+import { connect } from 'react-redux';
+import { asyncConnect } from 'redux-connect';
+
+import Helmet from 'react-helmet';
+import Loadable from 'react-loadable';
+import Button from 'quran-components/lib/Button';
+import ComponentLoader from 'components/ComponentLoader';
+import LocaleFormattedMessage from 'components/LocaleFormattedMessage';
+import { surahType, infoType } from 'types';
+import makeHeadTags from 'helpers/makeHeadTags';
+
+import { chaptersConnect, chapterInfoConnect } from '../Surah/connect';
+
+const SurahInfo = Loadable({
+ loader: () => import('components/SurahInfo'),
+ LoadingComponent: ComponentLoader
+});
+
+const ChapterInfo = ({ chapter, info }) => (
+
+);
+
+ChapterInfo.propTypes = {
+ chapter: surahType,
+ info: infoType
+};
+
+const AsyncChapterInfo = asyncConnect([
+ { promise: chaptersConnect },
+ { promise: chapterInfoConnect }
+])(ChapterInfo);
+
+function mapStateToProps(state, ownProps) {
+ const chapterId = parseInt(ownProps.params.chapterId, 10);
+ const chapter: Object = state.chapters.entities[chapterId];
+
+ return {
+ chapter,
+ info: state.chapters.infos[chapterId]
+ };
+}
+
+export default connect(mapStateToProps)(AsyncChapterInfo);
diff --git a/src/containers/Surah/connect.js b/src/containers/Surah/connect.js
index c4e68be77..4754b0057 100644
--- a/src/containers/Surah/connect.js
+++ b/src/containers/Surah/connect.js
@@ -2,7 +2,8 @@ import {
isAllLoaded,
loadAll,
loadInfo,
- setCurrent as setCurrentSurah
+ setCurrent as setCurrentSurah,
+ isInfoLoaded
} from 'redux/actions/chapters.js';
import {
@@ -44,28 +45,27 @@ const determinePage = (range) => {
export const chaptersConnect = ({ store: { getState, dispatch } }) => {
debug('component:Surah:chaptersConnect', 'Init');
+ if (isAllLoaded(getState())) return false;
- if (!isAllLoaded(getState())) {
- debug('component:Surah:chaptersConnect', 'Surahs not loaded');
+ debug('component:Surah:chaptersConnect', 'Surahs not loaded');
- if (__CLIENT__) {
- dispatch(loadAll());
- return true;
- }
-
- return dispatch(loadAll());
+ if (__CLIENT__) {
+ dispatch(loadAll());
+ return true;
}
- return true;
+ return dispatch(loadAll());
};
-export const chapterInfoConnect = ({ store: { dispatch }, params }) => {
+export const chapterInfoConnect = ({ store: { dispatch, getState }, params }) => {
+ if (isInfoLoaded(getState(), params.chapterId)) return false;
+
if (__CLIENT__) {
- dispatch(loadInfo(params.chapterId));
+ dispatch(loadInfo(params));
return true;
}
- return dispatch(loadInfo(params.chapterId));
+ return dispatch(loadInfo(params));
};
export const versesConnect = ({ store: { dispatch, getState }, params }) => {
diff --git a/src/containers/Surah/index.js b/src/containers/Surah/index.js
index ba79e2b5d..2242ea965 100644
--- a/src/containers/Surah/index.js
+++ b/src/containers/Surah/index.js
@@ -25,7 +25,7 @@ import scroller from 'utils/scroller';
import makeHeadTags from 'helpers/makeHeadTags';
import debug from 'helpers/debug';
-import { surahType, verseType } from 'types';
+import { surahType, verseType, infoType } from 'types';
import * as AudioActions from 'redux/actions/audioplayer.js';
import * as AyahActions from 'redux/actions/verses.js';
@@ -66,6 +66,7 @@ class Surah extends Component {
isEndOfSurah: PropTypes.bool.isRequired,
verseIds: PropTypes.instanceOf(Set),
currentVerse: PropTypes.string,
+ info: infoType,
bookmarks: PropTypes.object.isRequired, // eslint-disable-line
isLoading: PropTypes.bool.isRequired,
isLoaded: PropTypes.bool.isRequired,
@@ -192,7 +193,7 @@ class Surah extends Component {
}
description() {
- const { params, verses, chapter } = this.props;
+ const { params, verses, chapter, info } = this.props;
if (params.range) {
if (params.range.includes('-')) {
@@ -222,7 +223,7 @@ class Surah extends Component {
return `Surat ${chapter.nameSimple} [verse ${params.range}]`;
}
- return `${chapter.info ? chapter.info.shortDescription : ''} This Surah has ${chapter.versesCount} verses and resides between pages ${chapter.pages[0]} to ${chapter.pages[1]} in the Quran.`; // eslint-disable-line max-len
+ return `${info ? info.shortText : ''} This Surah has ${chapter.versesCount} verses and resides between pages ${chapter.pages[0]} to ${chapter.pages[1]} in the Quran.`; // eslint-disable-line max-len
}
renderNoAyah() {
@@ -351,7 +352,7 @@ class Surah extends Component {
}
render() {
- const { chapter, verses, options, actions } = this.props; // eslint-disable-line no-shadow
+ const { chapter, verses, options, info, actions } = this.props; // eslint-disable-line no-shadow
debug('component:Surah', 'Render');
if (!this.hasAyahs()) return
{this.renderNoAyah()}
;
@@ -395,6 +396,7 @@ class Surah extends Component {
({
+export const loadInfo = params => ({
types: [LOAD_INFO, LOAD_INFO_SUCCESS, LOAD_INFO_FAIL],
- promise: client => client.get(`/api/v3/chapters/${id}/info`),
- id
+ promise: client => client.get(`/api/v3/chapters/${params.chapterId}/info`, {
+ params: {
+ language: params.language || 'en'
+ }
+ }),
+ id: params.chapterId
});
export const setCurrent = id => ({
@@ -43,3 +47,7 @@ export function isSingleLoaded(globalState, id) {
export function isAllLoaded(globalState) {
return Object.keys(globalState.chapters.entities).length === 114;
}
+
+export function isInfoLoaded(globalState, id) {
+ return globalState.chapters.entities[id] && globalState.chapters.infos[id];
+}
diff --git a/src/redux/modules/chapters.js b/src/redux/modules/chapters.js
index 17ae67e1e..cb54e459e 100644
--- a/src/redux/modules/chapters.js
+++ b/src/redux/modules/chapters.js
@@ -12,7 +12,8 @@ const initialState = {
loading: false,
infoLoading: false,
current: null,
- entities: {}
+ entities: {},
+ infos: {}
};
export default function reducer(state = initialState, action = {}) {
@@ -45,12 +46,9 @@ export default function reducer(state = initialState, action = {}) {
case LOAD_INFO_SUCCESS:
return {
...state,
- entities: {
+ infos: {
...state.entities,
- [action.id]: {
- ...state.entities[action.id],
- info: action.result.chapterInfo
- }
+ [action.id]: action.result.chapterInfo
}
};
default:
diff --git a/src/routes.js b/src/routes.js
index 1cad48f44..7789033d2 100644
--- a/src/routes.js
+++ b/src/routes.js
@@ -60,6 +60,13 @@ export default (store) => {
import('./containers/Profile').then(module => cb(null, module.default)).catch(err => console.trace(err))} />
+ import('./containers/ChapterInfo').then(module => cb(null, module.default)).catch(err => console.trace(err))
+ }
+ />
+
{
const ayahId = index + 1;
urls.push({
- url: `/${chapter.chapterNumber}/${ayahId}`,
+ url: `/${chapter.id}/${ayahId}`,
changefreq: 'weekly',
priority: 1
});
urls.push({
- url: `/${chapter.chapterNumber}/${ayahId}-${ayahId + 9}`,
+ url: `/${chapter.id}/${ayahId}-${ayahId + 9}`,
changefreq: 'weekly',
priority: 1
});
});
urls.push({
- url: `/${chapter.chapterNumber}`,
+ url: `/${chapter.id}`,
+ changefreq: 'weekly',
+ priority: 1
+ });
+
+ urls.push({
+ url: `/${chapter.id}/info`,
+ changefreq: 'weekly',
+ priority: 1
+ });
+
+ urls.push({
+ url: `/${chapter.id}/info/ur`,
+ changefreq: 'weekly',
+ priority: 1
+ });
+
+ urls.push({
+ url: `/${chapter.id}/info/ml`,
+ changefreq: 'weekly',
+ priority: 1
+ });
+
+ urls.push({
+ url: `/${chapter.id}/info/ta`,
+ changefreq: 'weekly',
+ priority: 1
+ });
+
+ urls.push({
+ url: `/${chapter.id}/info/en`,
changefreq: 'weekly',
priority: 1
});
diff --git a/src/types/index.js b/src/types/index.js
index 3fc185971..af5c89f1e 100644
--- a/src/types/index.js
+++ b/src/types/index.js
@@ -10,3 +10,4 @@ export { default as recitationType } from './recitationType';
export { default as translationType } from './translationType';
export { default as contentType } from './contentType';
export { default as footNoteType } from './footNoteType';
+export { default as infoType } from './infoType';
diff --git a/src/types/infoType.js b/src/types/infoType.js
new file mode 100644
index 000000000..bd284088d
--- /dev/null
+++ b/src/types/infoType.js
@@ -0,0 +1,9 @@
+import { PropTypes } from 'react';
+
+export default PropTypes.shape({
+ chapterId: PropTypes.number.isRequired,
+ text: PropTypes.string.isRequired,
+ source: PropTypes.string.isRequired,
+ shortText: PropTypes.string.isRequired,
+ languageName: PropTypes.string.isRequired
+});