Skip to content
This repository was archived by the owner on Jun 28, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 3 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
28 changes: 16 additions & 12 deletions src/components/SurahInfo/index.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import React, { PropTypes } from 'react';

import { surahType } from 'types';
import { surahType, infoType } from 'types';
import Loader from 'quran-components/lib/Loader';

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

const SurahInfo = ({ chapter, isShowingSurahInfo, onClose }) => {
const SurahInfo = ({ chapter, info, isShowingSurahInfo, onClose }) => {
// So we don't need to load images and files unless needed
if (!isShowingSurahInfo) return <noscript />;
if (!chapter.info) {
if (!info) {
return <Loader isActive />;
}

return (
<div className={`col-xs-12 ${style.container} chapter-info ${style.show}`}>
<button
tabIndex="-1"
className={`${style.close} ss-delete`}
onClick={() => onClose({ isShowingSurahInfo: !isShowingSurahInfo })}
/>
{
onClose &&
<button
tabIndex="-1"
className={`${style.close} ss-delete`}
onClick={() => onClose({ isShowingSurahInfo: !isShowingSurahInfo })}
/>
}
<div className={`${style.row} row`}>
<div
className={`col-md-3 col-xs-6 ${style.bg} ${style[chapter.revelationPlace]}`}
Expand All @@ -31,12 +34,12 @@ const SurahInfo = ({ chapter, isShowingSurahInfo, onClose }) => {
<dd className="text-uppercase">{chapter.pages.join('-')}</dd>
</dl>
</div>
<div className={`${style.info} ${chapter.info.languageName} times-new col-md-8`}>
<div dangerouslySetInnerHTML={{ __html: chapter.info.text }} />
<div className={`${style.info} ${info.languageName} times-new col-md-8`}>
<div dangerouslySetInnerHTML={{ __html: info.text }} />
<div>
<p>
<em>
Source: {chapter.info.source}
Source: {info.source}
</em>
</p>
</div>
Expand All @@ -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;
84 changes: 84 additions & 0 deletions src/containers/ChapterInfo/index.js
Original file line number Diff line number Diff line change
@@ -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 }) => (
<div className="row" style={{ marginTop: 20 }}>
<Helmet
{...makeHeadTags({
title: `Surah ${chapter.nameSimple} [${chapter.chapterNumber}]`,
description: `${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
})}
script={[{
type: 'application/ld+json',
innerHTML: `{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [{
"@type": "ListItem",
"position": 1,
"item": {
"@id": "https://quran.com/",
"name": "Quran"
}
},{
"@type": "ListItem",
"position": 2,
"item": {
"@id": "https://quran.com/${chapter.chapterNumber}",
"name": "${chapter.nameSimple}"
}
}]
}`
}]}
/>
<SurahInfo
chapter={chapter}
info={info}
isShowingSurahInfo
/>
<div className="text-center">
<Button href={`/${chapter.id}`}>
<LocaleFormattedMessage id="surah.read" defaultMessage="Read full Surah" />
</Button>
</div>
</div>
);

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);
26 changes: 13 additions & 13 deletions src/containers/Surah/connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import {
isAllLoaded,
loadAll,
loadInfo,
setCurrent as setCurrentSurah
setCurrent as setCurrentSurah,
isInfoLoaded
} from 'redux/actions/chapters.js';

import {
Expand Down Expand Up @@ -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 }) => {
Expand Down
11 changes: 7 additions & 4 deletions src/containers/Surah/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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('-')) {
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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 <div className={style.container} style={{ margin: '50px auto' }}>{this.renderNoAyah()}</div>;
Expand Down Expand Up @@ -395,6 +396,7 @@ class Surah extends Component {
<div className="row">
<SurahInfo
chapter={chapter}
info={info}
loadInfo={actions.loadInfo}
isShowingSurahInfo={options.isShowingSurahInfo}
onClose={this.handleSurahInfoToggle}
Expand Down Expand Up @@ -440,6 +442,7 @@ function mapStateToProps(state, ownProps) {
verses,
verseIds,
isSingleAyah,
info: state.chapters.infos[ownProps.params.chapterId],
isStarted: state.audioplayer.isStarted,
isPlaying: state.audioplayer.isPlaying,
currentVerse: state.audioplayer.currentVerse,
Expand Down
2 changes: 1 addition & 1 deletion src/helpers/ApiClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default class {

params = params || {}; // eslint-disable-line no-param-reassign

params.language = contentLanguage(); // eslint-disable-line no-param-reassign
params.language = params.language || contentLanguage(); // eslint-disable-line

request.query(qs.stringify(decamelizeKeys(params), {
arrayFormat: arrayFormat || 'brackets'
Expand Down
1 change: 1 addition & 0 deletions src/locale/ar.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export default {
'surah.index.continue': 'استءنف',
'surah.index.quickLinks': 'روابط سريعة',
'surah.goToBeginning': 'ابتداء من سورة',
'surah.read': 'قراءة سورة كاملة',

'player.currentVerse': 'آية',
'player.nextAyah': 'آية القادمة',
Expand Down
1 change: 1 addition & 0 deletions src/locale/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default {
'surah.index.continue': 'Continue',
'surah.index.quickLinks': 'Quick links',
'surah.goToBeginning': 'Beginning of Surah',
'surah.read': 'Read full Surah',

'player.currentVerse': 'Ayah',
'player.nextAyah': 'Next Ayah',
Expand Down
2 changes: 1 addition & 1 deletion src/locale/fr.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default {
'surah.index.continue': 'Continuer',
'surah.index.quickLinks': 'Liens rapides',
'surah.goToBeginning': 'Début de la Sourate',
'surah.read': 'Lire la sourate complète',

'player.currentVerse': 'Verset',
'player.nextAyah': 'Prochain Verset',
Expand Down Expand Up @@ -80,4 +81,3 @@ export default {
'login.message': 'Identifiez-vous sur Quran.com pour enregistrer tous vos favoris, notes et activités. '
}
};

1 change: 1 addition & 0 deletions src/locale/id.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default {
'surah.index.continue': 'Lanjutkan',
'surah.index.quickLinks': 'Tautan cepat',
'surah.goToBeginning': 'Awal Surat',
'surah.read': 'Baca lengkap Surah',

'player.currentVerse': 'Ayat',
'player.nextAyah': 'Ayat Berikutnya',
Expand Down
1 change: 1 addition & 0 deletions src/locale/tr.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default {
'surah.index.continue': 'Devam',
'surah.index.quickLinks': 'Hızlı bağlantılar',
'surah.goToBeginning': 'Sure Başlangıcı',
'surah.read': 'Tam suratı oku',

'player.currentAyah': 'Ayet',
'player.nextAyah': 'Sonraki Ayet',
Expand Down
1 change: 1 addition & 0 deletions src/locale/ur.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default {
'surah.index.continue': 'جاری رہے',
'surah.index.quickLinks': 'فوری لنک',
'surah.goToBeginning': 'سورہ کے شروع میں جائیں',
'surah.read': 'مکمل سورت پڑھیں',

'player.currentVerse': 'آیت',
'player.nextAyah': 'اگلی آیت',
Expand Down
14 changes: 11 additions & 3 deletions src/redux/actions/chapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ export function load(id) {
};
}

export const loadInfo = id => ({
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 => ({
Expand All @@ -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];
}
10 changes: 4 additions & 6 deletions src/redux/modules/chapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const initialState = {
loading: false,
infoLoading: false,
current: null,
entities: {}
entities: {},
infos: {}
};

export default function reducer(state = initialState, action = {}) {
Expand Down Expand Up @@ -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:
Expand Down
7 changes: 7 additions & 0 deletions src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ export default (store) => {
<Route path="/profile" getComponent={(nextState, cb) => import('./containers/Profile').then(module => cb(null, module.default)).catch(err => console.trace(err))} />
</Route>

<Route
path="/:chapterId/info(/:language)"
getComponents={
(nextState, cb) => import('./containers/ChapterInfo').then(module => cb(null, module.default)).catch(err => console.trace(err))
}
/>

<Redirect from="/:chapterId:(:range)" to="/:chapterId(/:range)" />

<Route
Expand Down
6 changes: 6 additions & 0 deletions src/server/config/sitemap.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ export default (server) => {
changefreq: 'weekly',
priority: 1
});

urls.push({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we've surah info in four languages, ['ur', 'en', 'ml', 'ta'] ill suggest to loop over these language /1/info/ur

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah cool! Didn't even know!

url: `/${chapter.chapterNumber}/info`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keys conversion isn't happening here, not sure why. Switch to chapter.chapter_number or chapter.id

changefreq: 'weekly',
priority: 1
});
});


Expand Down
Loading