diff options
Diffstat (limited to 'ext/js/pages')
-rw-r--r-- | ext/js/pages/settings/audio-controller.js | 180 |
1 files changed, 103 insertions, 77 deletions
diff --git a/ext/js/pages/settings/audio-controller.js b/ext/js/pages/settings/audio-controller.js index dcc5428e..2581893c 100644 --- a/ext/js/pages/settings/audio-controller.js +++ b/ext/js/pages/settings/audio-controller.js @@ -30,6 +30,14 @@ class AudioController { this._ttsVoiceTestTextInput = null; } + get settingsController() { + return this._settingsController; + } + + get modalController() { + return this._modalController; + } + async prepare() { this._audioSystem.prepare(); @@ -51,18 +59,41 @@ class AudioController { this._onOptionsChanged({options}); } + async removeSource(entry) { + const {index} = entry; + this._audioSourceEntries.splice(index, 1); + entry.cleanup(); + for (let i = index, ii = this._audioSourceEntries.length; i < ii; ++i) { + this._audioSourceEntries[i].index = i; + } + + await this._settingsController.modifyProfileSettings([{ + action: 'splice', + path: 'audio.sources', + start: index, + deleteCount: 1, + items: [] + }]); + } + // Private _onOptionsChanged({options}) { - for (let i = this._audioSourceEntries.length - 1; i >= 0; --i) { - this._cleanupAudioSourceEntry(i); + for (const entry of this._audioSourceEntries) { + entry.cleanup(); } + this._audioSourceEntries = []; - for (const audioSource of options.audio.sources) { - this._createAudioSourceEntry(audioSource); + const {sources} = options.audio; + for (let i = 0, ii = sources.length; i < ii; ++i) { + this._createAudioSourceEntry(i, sources[i]); } } + _onAddAudioSource() { + this._addAudioSource(); + } + _onTestTextToSpeech() { try { const text = this._ttsVoiceTestTextInput.value || ''; @@ -132,103 +163,93 @@ class AudioController { ); } - _getUnusedAudioSource() { - const audioSourcesAvailable = [ + _createAudioSourceEntry(index, type) { + const node = this._settingsController.instantiateTemplate('audio-source'); + const entry = new AudioSourceEntry(this, index, type, node); + this._audioSourceEntries.push(entry); + this._audioSourceContainer.appendChild(node); + entry.prepare(); + } + + _getUnusedAudioSourceType() { + const typesAvailable = [ 'jpod101', 'jpod101-alternate', 'jisho', 'custom' ]; - for (const source of audioSourcesAvailable) { - if (!this._audioSourceEntries.some((metadata) => metadata.value === source)) { - return source; + for (const type of typesAvailable) { + if (!this._audioSourceEntries.some((entry) => entry.type === type)) { + return type; } } - return audioSourcesAvailable[0]; - } - - _createAudioSourceEntry(value) { - const eventListeners = new EventListenerCollection(); - const container = this._settingsController.instantiateTemplate('audio-source'); - const select = container.querySelector('.audio-source-select'); - const removeButton = container.querySelector('.audio-source-remove'); - const menuButton = container.querySelector('.audio-source-menu-button'); - - select.value = value; - - const entry = { - container, - eventListeners, - value - }; - - eventListeners.addEventListener(select, 'change', this._onAudioSourceSelectChange.bind(this, entry), false); - if (removeButton !== null) { - eventListeners.addEventListener(removeButton, 'click', this._onAudioSourceRemoveClicked.bind(this, entry), false); - } - if (menuButton !== null) { - eventListeners.addEventListener(menuButton, 'menuOpen', this._onMenuOpen.bind(this, entry), false); - eventListeners.addEventListener(menuButton, 'menuClose', this._onMenuClose.bind(this, entry), false); - } - - this._audioSourceContainer.appendChild(container); - this._audioSourceEntries.push(entry); + return typesAvailable[0]; } - async _removeAudioSourceEntry(entry) { - const index = this._audioSourceEntries.indexOf(entry); - if (index < 0) { return; } - - this._cleanupAudioSourceEntry(index); + async _addAudioSource() { + const type = this._getUnusedAudioSourceType(); + const index = this._audioSourceEntries.length; + this._createAudioSourceEntry(index, type); await this._settingsController.modifyProfileSettings([{ action: 'splice', path: 'audio.sources', start: index, - deleteCount: 1, - items: [] + deleteCount: 0, + items: [type] }]); } +} - _cleanupAudioSourceEntry(index) { - const {container, eventListeners} = this._audioSourceEntries[index]; - if (container.parentNode !== null) { - container.parentNode.removeChild(container); - } - eventListeners.removeAllEventListeners(); - this._audioSourceEntries.splice(index, 1); +class AudioSourceEntry { + constructor(parent, index, type, node) { + this._parent = parent; + this._index = index; + this._type = type; + this._node = node; + this._eventListeners = new EventListenerCollection(); } - async _onAddAudioSource() { - const audioSource = this._getUnusedAudioSource(); - const index = this._audioSourceEntries.length; - this._createAudioSourceEntry(audioSource); - await this._settingsController.modifyProfileSettings([{ - action: 'splice', - path: 'audio.sources', - start: index, - deleteCount: 0, - items: [audioSource] - }]); + get index() { + return this._index; + } + + set index(value) { + this._index = value; } - async _onAudioSourceSelectChange(entry, event) { - const index = this._audioSourceEntries.indexOf(entry); - if (index < 0) { return; } + get type() { + return this._type; + } + + prepare() { + const select = this._node.querySelector('.audio-source-select'); + const menuButton = this._node.querySelector('.audio-source-menu-button'); + + select.value = this._type; - const value = event.currentTarget.value; - entry.value = value; - await this._settingsController.setProfileSetting(`audio.sources[${index}]`, value); + this._eventListeners.addEventListener(select, 'change', this._onAudioSourceSelectChange.bind(this), false); + this._eventListeners.addEventListener(menuButton, 'menuOpen', this._onMenuOpen.bind(this), false); + this._eventListeners.addEventListener(menuButton, 'menuClose', this._onMenuClose.bind(this), false); } - _onAudioSourceRemoveClicked(entry) { - this._removeAudioSourceEntry(entry); + cleanup() { + if (this._node.parentNode !== null) { + this._node.parentNode.removeChild(this._node); + } + this._eventListeners.removeAllEventListeners(); } - _onMenuOpen(entry, e) { + // Private + + _onAudioSourceSelectChange(event) { + this._setType(event.currentTarget.value); + } + + _onMenuOpen(e) { const {menu} = e.detail; let hasHelp = false; - switch (entry.value) { + switch (this._type) { case 'custom': case 'custom-json': hasHelp = true; @@ -238,17 +259,22 @@ class AudioController { menu.bodyNode.querySelector('.popup-menu-item[data-menu-action=help]').hidden = !hasHelp; } - _onMenuClose(entry, e) { + _onMenuClose(e) { switch (e.detail.action) { case 'help': - this._showHelp(entry.value); + this._showHelp(this._type); break; case 'remove': - this._removeAudioSourceEntry(entry); + this._parent.removeSource(this); break; } } + async _setType(value) { + this._type = value; + await this._parent.settingsController.setProfileSetting(`audio.sources[${this._index}]`, value); + } + _showHelp(type) { switch (type) { case 'custom': @@ -261,6 +287,6 @@ class AudioController { } _showModal(name) { - this._modalController.getModal(name).setVisible(true); + this._parent.modalController.getModal(name).setVisible(true); } } |