diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-10-10 12:11:33 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-10 12:11:33 -0400 | 
| commit | 3174f3c6578de7a525a629f1acd0d2f04d06da66 (patch) | |
| tree | 392695a6b514ab3c668220a7fab2efbf7c5813ae | |
| parent | 6799b87cc6bc9c456b65e37d72f3003f45c47737 (diff) | |
Update audio controller (#904)
* Remove redundant assignment of select value
* Update TTS preparation
* Don't hide options
* Improve voice sorting
* Update event handler
* Apply options to all selects targeting audio.textToSpeechVoice
* Update selector
* Use IDs
* Move test text to a hidden text input
| -rw-r--r-- | ext/bg/js/settings/audio-controller.js | 103 | ||||
| -rw-r--r-- | ext/bg/settings.html | 9 | 
2 files changed, 54 insertions, 58 deletions
| diff --git a/ext/bg/js/settings/audio-controller.js b/ext/bg/js/settings/audio-controller.js index 6ea11e15..ae0e234a 100644 --- a/ext/bg/js/settings/audio-controller.js +++ b/ext/bg/js/settings/audio-controller.js @@ -28,18 +28,25 @@ class AudioController {          this._audioSourceContainer = null;          this._audioSourceAddButton = null;          this._audioSourceEntries = []; +        this._ttsVoiceTestTextInput = null;      }      async prepare() {          this._audioSystem.prepare(); -        this._audioSourceContainer = document.querySelector('.audio-source-list'); -        this._audioSourceAddButton = document.querySelector('.audio-source-add'); +        this._ttsVoiceTestTextInput = document.querySelector('#text-to-speech-voice-test-text'); +        this._audioSourceContainer = document.querySelector('#audio-source-list'); +        this._audioSourceAddButton = document.querySelector('#audio-source-add');          this._audioSourceContainer.textContent = '';          this._audioSourceAddButton.addEventListener('click', this._onAddAudioSource.bind(this), false); -        this._prepareTextToSpeech(); +        if (typeof speechSynthesis !== 'undefined') { +            speechSynthesis.addEventListener('voiceschanged', this._updateTextToSpeechVoices.bind(this), false); +        } +        this._updateTextToSpeechVoices(); + +        document.querySelector('#text-to-speech-voice-test').addEventListener('click', this._onTestTextToSpeech.bind(this), false);          this._settingsController.on('optionsChanged', this._onOptionsChanged.bind(this)); @@ -59,57 +66,62 @@ class AudioController {          }      } -    _prepareTextToSpeech() { -        if (typeof speechSynthesis === 'undefined') { return; } - -        speechSynthesis.addEventListener('voiceschanged', this._updateTextToSpeechVoices.bind(this), false); -        this._updateTextToSpeechVoices(); +    _onTestTextToSpeech() { +        try { +            const text = this._ttsVoiceTestTextInput.value || ''; +            const voiceUri = document.querySelector('[data-setting="audio.textToSpeechVoice"]').value; -        document.querySelector('#text-to-speech-voice').addEventListener('change', this._onTextToSpeechVoiceChange.bind(this), false); -        document.querySelector('#text-to-speech-voice-test').addEventListener('click', this._testTextToSpeech.bind(this), false); +            const audio = this._audioSystem.createTextToSpeechAudio(text, voiceUri); +            audio.volume = 1.0; +            audio.play(); +        } catch (e) { +            // NOP +        }      }      _updateTextToSpeechVoices() { -        const voices = Array.prototype.map.call(speechSynthesis.getVoices(), (voice, index) => ({voice, index})); +        const voices = ( +            typeof speechSynthesis !== 'undefined' ? +            [...speechSynthesis.getVoices()].map((voice, index) => ({ +                voice, +                isJapanese: this._languageTagIsJapanese(voice.lang), +                index +            })) : +            [] +        );          voices.sort(this._textToSpeechVoiceCompare.bind(this)); -        document.querySelector('#text-to-speech-voice-container').hidden = (voices.length === 0); +        for (const select of document.querySelectorAll('[data-setting="audio.textToSpeechVoice"]')) { +            const fragment = document.createDocumentFragment(); -        const fragment = document.createDocumentFragment(); +            let option = document.createElement('option'); +            option.value = ''; +            option.textContent = 'None'; +            fragment.appendChild(option); -        let option = document.createElement('option'); -        option.value = ''; -        option.textContent = 'None'; -        fragment.appendChild(option); +            for (const {voice} of voices) { +                option = document.createElement('option'); +                option.value = voice.voiceURI; +                option.textContent = `${voice.name} (${voice.lang})`; +                fragment.appendChild(option); +            } -        for (const {voice} of voices) { -            option = document.createElement('option'); -            option.value = voice.voiceURI; -            option.textContent = `${voice.name} (${voice.lang})`; -            fragment.appendChild(option); +            select.textContent = ''; +            select.appendChild(fragment);          } - -        const select = document.querySelector('#text-to-speech-voice'); -        select.textContent = ''; -        select.appendChild(fragment); -        select.value = select.dataset.value;      }      _textToSpeechVoiceCompare(a, b) { -        const aIsJapanese = this._languageTagIsJapanese(a.voice.lang); -        const bIsJapanese = this._languageTagIsJapanese(b.voice.lang); -        if (aIsJapanese) { -            if (!bIsJapanese) { return -1; } +        if (a.isJapanese) { +            if (!b.isJapanese) { return -1; }          } else { -            if (bIsJapanese) { return 1; } +            if (b.isJapanese) { return 1; }          } -        const aIsDefault = a.voice.default; -        const bIsDefault = b.voice.default; -        if (aIsDefault) { -            if (!bIsDefault) { return -1; } +        if (a.voice.default) { +            if (!b.voice.default) { return -1; }          } else { -            if (bIsDefault) { return 1; } +            if (b.voice.default) { return 1; }          }          return a.index - b.index; @@ -123,19 +135,6 @@ class AudioController {          );      } -    _testTextToSpeech() { -        try { -            const text = document.querySelector('#text-to-speech-voice-test').dataset.speechText || ''; -            const voiceUri = document.querySelector('#text-to-speech-voice').value; - -            const audio = this._audioSystem.createTextToSpeechAudio(text, voiceUri); -            audio.volume = 1.0; -            audio.play(); -        } catch (e) { -            // NOP -        } -    } -      _getUnusedAudioSource() {          const audioSourcesAvailable = [              'jpod101', @@ -195,10 +194,6 @@ class AudioController {          this._audioSourceEntries.splice(index, 1);      } -    _onTextToSpeechVoiceChange(e) { -        e.currentTarget.dataset.value = e.currentTarget.value; -    } -      async _onAddAudioSource() {          const audioSource = this._getUnusedAudioSource();          const index = this._audioSourceEntries.length; diff --git a/ext/bg/settings.html b/ext/bg/settings.html index c318401f..795cdd54 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -346,14 +346,15 @@                      <input type="number" min="0" max="100" id="audio-playback-volume" class="form-control" data-setting="audio.volume">                  </div> -                <div class="form-group" id="text-to-speech-voice-container" hidden> +                <div class="form-group" id="text-to-speech-voice-container">                      <label for="text-to-speech-voice">Text-to-speech voice</label>                      <div class="input-group">                          <select class="form-control" id="text-to-speech-voice" data-setting="audio.textToSpeechVoice"></select>                          <div class="input-group-btn"> -                            <button class="btn btn-default" id="text-to-speech-voice-test" title="Test voice" data-speech-text="よみちゃん"><span class="glyphicon glyphicon-volume-up"></span></button> +                            <button class="btn btn-default" id="text-to-speech-voice-test" title="Test voice"><span class="glyphicon glyphicon-volume-up"></span></button>                          </div>                      </div> +                    <input type="text" value="よみちゃん" id="text-to-speech-voice-test-text" hidden>                  </div>                  <div class="form-group options-advanced"> @@ -363,9 +364,9 @@                  <div class="form-group ignore-form-changes">                      <label>Audio playback sources</label> -                    <div class="audio-source-list generic-input-list"></div> +                    <div class="audio-source-list generic-input-list" id="audio-source-list"></div>                      <div class="input-group audio-source-options"> -                        <button class="btn btn-default audio-source-add" title="Add audio playback source"><span class="glyphicon glyphicon-plus"></span></button> +                        <button class="btn btn-default audio-source-add" title="Add audio playback source" id="audio-source-add"><span class="glyphicon glyphicon-plus"></span></button>                      </div>                      <template id="audio-source-template"><div class="input-group audio-source"> |