diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2019-12-05 22:36:59 -0500 |
---|---|---|
committer | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2019-12-05 22:36:59 -0500 |
commit | b418760a521033dd0939194ab8cfef3dbeac29fc (patch) | |
tree | 59fb20d5f652b2ace839e07e44a50864b37b770c /ext/bg/js/settings/audio-ui.js | |
parent | 63f3e94bb18182afff694481899e5961cf505fdb (diff) |
Simplify audio settings UI
Diffstat (limited to 'ext/bg/js/settings/audio-ui.js')
-rw-r--r-- | ext/bg/js/settings/audio-ui.js | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/ext/bg/js/settings/audio-ui.js b/ext/bg/js/settings/audio-ui.js new file mode 100644 index 00000000..de3be083 --- /dev/null +++ b/ext/bg/js/settings/audio-ui.js @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2019 Alex Yatskov <alex@foosoft.net> + * Author: Alex Yatskov <alex@foosoft.net> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +class AudioSourceUI { + static instantiateTemplate(templateSelector) { + const template = document.querySelector(templateSelector); + const content = document.importNode(template.content, true); + return content.firstChild; + } +} + +AudioSourceUI.Container = class Container { + constructor(audioSources, container, addButton) { + this.audioSources = audioSources; + this.container = container; + this.addButton = addButton; + this.children = []; + + this.container.textContent = ''; + + for (const audioSource of toIterable(audioSources)) { + this.children.push(new AudioSourceUI.AudioSource(this, audioSource, this.children.length)); + } + + this._clickListener = () => this.onAddAudioSource(); + this.addButton.addEventListener('click', this._clickListener, false); + } + + cleanup() { + for (const child of this.children) { + child.cleanup(); + } + + this.addButton.removeEventListener('click', this._clickListener, false); + this.container.textContent = ''; + this._clickListener = null; + } + + save() { + // Override + } + + remove(child) { + const index = this.children.indexOf(child); + if (index < 0) { + return; + } + + child.cleanup(); + this.children.splice(index, 1); + this.audioSources.splice(index, 1); + + for (let i = index; i < this.children.length; ++i) { + this.children[i].index = i; + } + } + + onAddAudioSource() { + const audioSource = this.getUnusedAudioSource(); + this.audioSources.push(audioSource); + this.save(); + this.children.push(new AudioSourceUI.AudioSource(this, audioSource, this.children.length)); + } + + getUnusedAudioSource() { + const audioSourcesAvailable = [ + 'jpod101', + 'jpod101-alternate', + 'jisho', + 'custom' + ]; + for (const source of audioSourcesAvailable) { + if (this.audioSources.indexOf(source) < 0) { + return source; + } + } + return audioSourcesAvailable[0]; + } +}; + +AudioSourceUI.AudioSource = class AudioSource { + constructor(parent, audioSource, index) { + this.parent = parent; + this.audioSource = audioSource; + this.index = index; + + this.container = AudioSourceUI.instantiateTemplate('#audio-source-template'); + this.select = this.container.querySelector('.audio-source-select'); + this.removeButton = this.container.querySelector('.audio-source-remove'); + + this.select.value = audioSource; + + this._selectChangeListener = () => this.onSelectChanged(); + this._removeClickListener = () => this.onRemoveClicked(); + + this.select.addEventListener('change', this._selectChangeListener, false); + this.removeButton.addEventListener('click', this._removeClickListener, false); + + parent.container.appendChild(this.container); + } + + cleanup() { + this.select.removeEventListener('change', this._selectChangeListener, false); + this.removeButton.removeEventListener('click', this._removeClickListener, false); + + if (this.container.parentNode !== null) { + this.container.parentNode.removeChild(this.container); + } + } + + save() { + this.parent.save(); + } + + onSelectChanged() { + this.audioSource = this.select.value; + this.parent.audioSources[this.index] = this.audioSource; + this.save(); + } + + onRemoveClicked() { + this.parent.remove(this); + this.save(); + } +}; |