diff options
Diffstat (limited to 'ext/mixed/js/display.js')
-rw-r--r-- | ext/mixed/js/display.js | 59 |
1 files changed, 41 insertions, 18 deletions
diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index 63687dc2..c2284ffe 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -45,7 +45,14 @@ class Display { this.index = 0; this.audioPlaying = null; this.audioFallback = null; - this.audioSystem = new AudioSystem({getAudioUri: this._getAudioUri.bind(this)}); + this.audioSystem = new AudioSystem({ + audioUriBuilder: { + getUri: async (definition, source, details) => { + return await apiAudioGetUri(definition, source, details); + } + }, + useCache: true + }); this.styleNode = null; this.eventListeners = new EventListenerCollection(); @@ -784,16 +791,14 @@ class Display { const expression = expressionIndex === -1 ? definition : definition.expressions[expressionIndex]; - if (this.audioPlaying !== null) { - this.audioPlaying.pause(); - this.audioPlaying = null; - } + this._stopPlayingAudio(); - const sources = this.options.audio.sources; - let audio, source, info; + let audio, info; try { - ({audio, source} = await this.audioSystem.getDefinitionAudio(expression, sources)); - info = `From source ${1 + sources.indexOf(source)}: ${source}`; + const {sources, textToSpeechVoice, customSourceUrl} = this.options.audio; + let index; + ({audio, index} = await this.audioSystem.getDefinitionAudio(expression, sources, {textToSpeechVoice, customSourceUrl})); + info = `From source ${1 + index}: ${sources[index]}`; } catch (e) { if (this.audioFallback === null) { this.audioFallback = new Audio('/mixed/mp3/button.mp3'); @@ -802,7 +807,7 @@ class Display { info = 'Could not find audio'; } - const button = this.audioButtonFindImage(entryIndex); + const button = this.audioButtonFindImage(entryIndex, expressionIndex); if (button !== null) { let titleDefault = button.dataset.titleDefault; if (!titleDefault) { @@ -812,10 +817,19 @@ class Display { button.title = `${titleDefault}\n${info}`; } + this._stopPlayingAudio(); + this.audioPlaying = audio; audio.currentTime = 0; audio.volume = this.options.audio.volume / 100.0; - audio.play(); + const playPromise = audio.play(); + if (typeof playPromise !== 'undefined') { + try { + await playPromise; + } catch (e2) { + // NOP + } + } } catch (e) { this.onError(e); } finally { @@ -823,6 +837,13 @@ class Display { } } + _stopPlayingAudio() { + if (this.audioPlaying !== null) { + this.audioPlaying.pause(); + this.audioPlaying = null; + } + } + noteUsesScreenshot(mode) { const optionsAnki = this.options.anki; const fields = (mode === 'kanji' ? optionsAnki.kanji : optionsAnki.terms).fields; @@ -901,9 +922,16 @@ class Display { viewerButton.dataset.noteId = noteId; } - audioButtonFindImage(index) { + audioButtonFindImage(index, expressionIndex) { const entry = this.getEntry(index); - return entry !== null ? entry.querySelector('.action-play-audio>img') : null; + if (entry === null) { return null; } + + const container = ( + expressionIndex >= 0 ? + entry.querySelector(`.term-expression:nth-of-type(${expressionIndex + 1})`) : + entry + ); + return container !== null ? container.querySelector('.action-play-audio>img') : null; } async getDefinitionsAddable(definitions, modes) { @@ -947,9 +975,4 @@ class Display { } }; } - - async _getAudioUri(definition, source) { - const optionsContext = this.getOptionsContext(); - return await apiAudioGetUri(definition, source, optionsContext); - } } |