From 420356c2a0b39726224405c53a0875bf41386a2a Mon Sep 17 00:00:00 2001 From: Mohamed El Mahallawy Date: Sat, 27 May 2017 18:28:27 -0600 Subject: [PATCH] Reduce audio api calls --- src/components/Audioplayer/index.js | 125 ++++++++++++++++++++-------- src/containers/Surah/index.js | 68 ++++++++------- src/redux/actions/audioplayer.js | 2 +- 3 files changed, 127 insertions(+), 68 deletions(-) diff --git a/src/components/Audioplayer/index.js b/src/components/Audioplayer/index.js index 44620c0f4..6c91a66e3 100644 --- a/src/components/Audioplayer/index.js +++ b/src/components/Audioplayer/index.js @@ -28,8 +28,13 @@ const RepeatDropdown = Loadable({ }); export class Audioplayer extends Component { + state = { + loadingFile: false + }; + componentDidMount() { - const { currentFile } = this.props; // eslint-disable-line no-shadow, max-len + const { currentFile, currentVerse, audio, verses, load } = this.props; // eslint-disable-line no-shadow, max-len + const nextVerse = verses[this.getNext()]; debug('component:Audioplayer', 'componentDidMount'); @@ -37,7 +42,19 @@ export class Audioplayer extends Component { return this.handleAddFileListeners(currentFile); } - console.error('Audioplayer mounted but no file available'); + load({ + chapterId: currentVerse.chapterId, + verseId: currentVerse.id, + verseKey: currentVerse.verseKey, + audio + }); + + load({ + chapterId: nextVerse.chapterId, + verseId: nextVerse.id, + verseKey: nextVerse.verseKey, + audio + }); return false; } @@ -58,7 +75,7 @@ export class Audioplayer extends Component { } // Change verse - if (this.props.currentVerse !== nextProps.currentVerse) { + if (this.props.currentVerse.verseKey !== nextProps.currentVerse.verseKey) { if (this.props.currentFile) { this.handleRemoveFileListeners(this.props.currentFile); } @@ -66,11 +83,42 @@ export class Audioplayer extends Component { return this.handleAddFileListeners(nextProps.currentFile); } + if (this.props.audio !== nextProps.audio) { + Object.keys(this.props.files).forEach(key => + this.props.load({ + chapterId: this.props.verses[key].chapterId, + verseId: this.props.verses[key].id, + verseKey: this.props.verses[key].verseKey, + audio: nextProps.audio + }) + ); + } + return false; } - componentDidUpdate() { - const { currentFile, isPlaying } = this.props; + componentDidUpdate(previousProps) { + const { + currentFile, + isPlaying, + verses, + audio, + currentVerse, + load + } = this.props; + + if ( + currentVerse.verseKey !== previousProps.currentVerse.verseKey && + verses[this.getNext()] + ) { + const verse = verses[this.getNext()]; + load({ + chapterId: verse.chapterId, + verseId: verse.id, + verseKey: verse.verseKey, + audio + }); + } if (!currentFile) return false; @@ -95,30 +143,28 @@ export class Audioplayer extends Component { } getPrevious() { - const { currentVerse, files } = this.props; - const ayahIds = Object.keys(files); - const index = ayahIds.findIndex(id => id === currentVerse); + const { currentVerse, verseIds } = this.props; + const index = verseIds.findIndex(id => id === currentVerse.verseKey); - return ayahIds[index - 1]; + return verseIds[index - 1]; } getNext() { - const { currentVerse, chapter, files, onLoadAyahs } = this.props; - const ayahIds = Object.keys(files); - const ayahNum = currentVerse.split(':')[1]; - const index = ayahIds.findIndex(id => id === currentVerse); + const { currentVerse, chapter, onLoadAyahs, verseIds } = this.props; + const ayahNum = currentVerse.verseKey.split(':')[1]; + const index = verseIds.findIndex(id => id === currentVerse.verseKey); if (chapter.versesCount === ayahNum + 1) { // We are at the end of the chapter! return false; } - if (ayahIds.length - 3 <= index + 1) { + if (verseIds.length - 3 <= index + 1) { // Need to load the next set of ayahs! onLoadAyahs(); } - return ayahIds[index + 1]; + return verseIds[index + 1]; } handleAyahChange = (direction = 'next') => { @@ -130,7 +176,7 @@ export class Audioplayer extends Component { const nextVerse = this[camelize(`get_${direction}`)](); if (!nextVerse) return pause(); - this.props[direction](currentVerse); + this.props[direction](currentVerse.verseKey); this.handleScrollTo(nextVerse); @@ -141,7 +187,7 @@ export class Audioplayer extends Component { return false; }; - scrollToVerse = (ayahNum = this.props.currentVerse) => { + scrollToVerse = (ayahNum = this.props.currentVerse.verseKey) => { scroller.scrollTo(`verse:${ayahNum}`, -45); }; @@ -163,7 +209,7 @@ export class Audioplayer extends Component { preloadNext() { const { currentVerse, files } = this.props; const ayahIds = Object.keys(files); - const index = ayahIds.findIndex(id => id === currentVerse) + 1; + const index = ayahIds.findIndex(id => id === currentVerse.verseKey) + 1; for (let id = index; id <= index + 2; id += 1) { if (ayahIds[id]) { @@ -183,7 +229,7 @@ export class Audioplayer extends Component { setRepeat, // eslint-disable-line no-shadow setAyah // eslint-disable-line no-shadow } = this.props; - const [chapter, ayah] = currentVerse + const [chapter, ayah] = currentVerse.verseKey .split(':') .map(val => parseInt(val, 10)); @@ -244,7 +290,7 @@ export class Audioplayer extends Component { if (!shouldScroll) { // we use the inverse (!) here because we're toggling, so false is true - this.scrollToVerse(currentVerse); + this.scrollToVerse(currentVerse.verseKey); } this.props.toggleScroll(); @@ -254,7 +300,7 @@ export class Audioplayer extends Component { // NOTE: if no file, just wait. if (!file) return false; - const { update, currentTime } = this.props; // eslint-disable-line no-shadow + const { update } = this.props; // eslint-disable-line no-shadow debug('component:Audioplayer', `Attaching listeners to ${file.src}`); // Preload file @@ -262,8 +308,8 @@ export class Audioplayer extends Component { const onLoadeddata = () => { // Default current time to zero. This will change - file.currentTime = // eslint-disable-line no-param-reassign - file.currentTime || currentTime || 0; + file.currentTime = 0; // eslint-disable-line + // file.currentTime || currentTime || 0; return update({ duration: file.duration, @@ -345,7 +391,9 @@ export class Audioplayer extends Component { renderPreviousButton() { const { currentVerse, files } = this.props; if (!files) return false; - const index = Object.keys(files).findIndex(id => id === currentVerse); + const index = Object.keys(files).findIndex( + id => id === currentVerse.verseKey + ); return ( } {segments && - segments[currentVerse] && + segments[currentVerse.verseKey] && } @@ -432,7 +480,7 @@ export class Audioplayer extends Component { /> : {' '} - {currentVerse.split(':')[1]} + {currentVerse.verseKey.split(':')[1]}
  • {this.renderPreviousButton()} @@ -447,7 +495,7 @@ export class Audioplayer extends Component {
  • @@ -464,22 +512,22 @@ export class Audioplayer extends Component { } const mapStateToProps = (state, ownProps) => { - const currentVerse = - state.audioplayer.currentVerse || ownProps.startVerse.verseKey; const files = state.audioplayer.files[ownProps.chapter.id]; + const verseIds = Object.keys(ownProps.verses); return { files, - currentVerse, + verseIds, segments: state.audioplayer.segments[ownProps.chapter.id], - currentFile: files[currentVerse], + currentFile: files[ownProps.currentVerse.verseKey], chapterId: ownProps.chapter.id, isPlaying: state.audioplayer.isPlaying, isLoading: state.audioplayer.isLoading, repeat: state.audioplayer.repeat, shouldScroll: state.audioplayer.shouldScroll, duration: state.audioplayer.duration, - currentTime: state.audioplayer.currentTime + currentTime: state.audioplayer.currentTime, + audio: state.options.audio }; }; @@ -490,7 +538,7 @@ Audioplayer.propTypes = { segments: customPropTypes.segments, // NOTE: should be PropTypes.instanceOf(Audio) but not on server. files: PropTypes.object, // eslint-disable-line - currentVerse: PropTypes.string, + currentVerse: PropTypes.verseType, isLoading: PropTypes.bool.isRequired, play: PropTypes.func.isRequired, pause: PropTypes.func.isRequired, @@ -505,9 +553,12 @@ Audioplayer.propTypes = { isPlaying: PropTypes.bool, currentTime: PropTypes.number, duration: PropTypes.number, + load: PropTypes.func.isRequired, // NOTE: should be PropTypes.instanceOf(Audio) but not on server. currentFile: PropTypes.any, // eslint-disable-line - startVerse: customPropTypes.verseType // eslint-disable-line + audio: PropTypes.number.isRequired, + verses: customPropTypes.verses, + verseIds: PropTypes.object // eslint-disable-line }; export default connect(mapStateToProps, AudioActions)(Audioplayer); diff --git a/src/containers/Surah/index.js b/src/containers/Surah/index.js index 94b5e031a..5198aed0b 100644 --- a/src/containers/Surah/index.js +++ b/src/containers/Surah/index.js @@ -79,34 +79,34 @@ class Surah extends Component { return false; } - componentDidMount() { - const { verses, options: { audio } } = this.props; - - Object.values(verses).forEach((verse) => { - this.props.actions.audio.load({ - chapterId: verse.chapterId, - verseId: verse.id, - verseKey: verse.verseKey, - audio - }); - }); - } - - // TODO: Should this belong here? - componentWillReceiveProps(nextProps) { - if (this.props.options.audio !== nextProps.options.audio) { - const { verses, options: { audio } } = nextProps; - - Object.values(verses).forEach((verse) => { - this.props.actions.audio.load({ - chapterId: verse.chapterId, - verseId: verse.id, - verseKey: verse.verseKey, - audio - }); - }); - } - } + // componentDidMount() { + // const { verses, options: { audio } } = this.props; + + // Object.values(verses).forEach((verse) => { + // this.props.actions.audio.load({ + // chapterId: verse.chapterId, + // verseId: verse.id, + // verseKey: verse.verseKey, + // audio + // }); + // }); + // } + + // // TODO: Should this belong here? + // componentWillReceiveProps(nextProps) { + // if (this.props.options.audio !== nextProps.options.audio) { + // const { verses, options: { audio } } = nextProps; + + // Object.values(verses).forEach((verse) => { + // this.props.actions.audio.load({ + // chapterId: verse.chapterId, + // verseId: verse.id, + // verseKey: verse.verseKey, + // audio + // }); + // }); + // } + // } shouldComponentUpdate(nextProps, nextState) { const conditions = [ @@ -360,7 +360,14 @@ class Surah extends Component { } render() { - const { chapter, verses, options, info, actions } = this.props; // eslint-disable-line no-shadow + const { + chapter, + verses, + options, + info, + actions, + currentVerse + } = this.props; // eslint-disable-line no-shadow debug('component:Surah', 'Render'); if (!this.hasVerses()) { @@ -430,7 +437,8 @@ class Surah extends Component { {__CLIENT__ && } diff --git a/src/redux/actions/audioplayer.js b/src/redux/actions/audioplayer.js index d140a9de0..65aeafc3b 100644 --- a/src/redux/actions/audioplayer.js +++ b/src/redux/actions/audioplayer.js @@ -116,5 +116,5 @@ export function load({ chapterId, verseId, verseKey, audio }) { } export function isLoaded(files, verse) { - return files[verse.chapterId][verse.verseKey]; + return files[verse.verseKey]; }