From 57b053844052337164a9f9396711c5946d1551b0 Mon Sep 17 00:00:00 2001 From: Kuuuube <61125188+Kuuuube@users.noreply.github.com> Date: Mon, 24 Feb 2025 07:12:58 -0500 Subject: [PATCH] Add option to select type of fallback sound (#1839) * Add option to select type of fallback sound * Set to advanced only --- README.md | 2 +- .../audio/{button.mp3 => fallback-bloop.mp3} | Bin ext/data/audio/fallback-click.mp3 | Bin 0 -> 17735 bytes ext/data/schemas/options-schema.json | 9 +++--- ext/js/data/options-util.js | 12 ++++++++ ext/js/display/display-audio.js | 10 +++---- ext/js/media/audio-system.js | 26 ++++++++++++------ ext/settings.html | 24 ++++++++++------ test/options-util.test.js | 6 ++-- types/ext/settings.d.ts | 4 ++- 10 files changed, 63 insertions(+), 30 deletions(-) rename ext/data/audio/{button.mp3 => fallback-bloop.mp3} (100%) create mode 100644 ext/data/audio/fallback-click.mp3 diff --git a/README.md b/README.md index 4949308f15..3b29a2278c 100644 --- a/README.md +++ b/README.md @@ -128,4 +128,4 @@ Yomitan uses several third-party libraries to function. ## Attribution -`button.mp3` is provided by [UNIVERSFIELD](https://pixabay.com/sound-effects/error-8-206492/) and licensed under the [Pixabay Content License](https://pixabay.com/service/license-summary/). +`fallback-bloop.mp3` is provided by [UNIVERSFIELD](https://pixabay.com/sound-effects/error-8-206492/) and licensed under the [Pixabay Content License](https://pixabay.com/service/license-summary/). diff --git a/ext/data/audio/button.mp3 b/ext/data/audio/fallback-bloop.mp3 similarity index 100% rename from ext/data/audio/button.mp3 rename to ext/data/audio/fallback-bloop.mp3 diff --git a/ext/data/audio/fallback-click.mp3 b/ext/data/audio/fallback-click.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..7a9728d1c840d84555adbbf3b7097e253672b304 GIT binary patch literal 17735 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∓UR5ZC zp$O?I;KTknVbcjGnZC%bYVnI7!tX6(BhbYb_BA zc-fioMt-fi`BLM;(M?2JxnEqzw&%TxXYPi)d@W4J#37Zibl=&DbKBbZ$O|%gICrIU zZdaSe_SF4&vhC*i#`R0jZ=dxS$S9Zbojfc{du`rrAiu7wIqK0r?FY~C5BQK#x5$E< z8o+_Z)~Yl#oHU&Ru=Ztqmbd30%eP^e$g8!SJl)adh5Biyv;BDy*R#@+wbNg`fk4aT zpF>ww-QVcy#?ix+`jEQmM|-PH0!As0DT*ff)y(^qD29WUL|0(P6)rz^_fKE$Uk0iT znmM}IHgzW}E$XLy-NB?zRi8bqZM>irUR`ttKeBjy;1Riz95CTZ2VL07L?<69m&BgM zZ7sH5J<7WfHCrwsNs}ww8FXc{#03&BwOEl<6M(QZOU7k88iTtCbC5DM8ZiBMayeF^ zB=UBJmMFUNH1L|_WR61cL(E2+MMF1MQ5R`JlC zo?cI^R_se!v4FGWH^nB|C|p)@17>8agZr?lN9~naj{_04_-Z?| zUhjSO_DVcx*+kgzTSuqKgyQi`y&@*S4eOCrKRuew_2Mb(MTUZZ;EryMt@7_J@5>)| z&CN}-ZU>B^xtzp1r7VdJVDxchcj~SX<8nkDgjdPk;J~DhaXI7 zNQ|uDxYugU zmP#%KlKI&dj-DTl1&hmUFetEW7U%SR_UX(=QJ~JU9z^atp9mI$?8V89?q!4FI^gtk zAis=}dVGi1@|fCJwd_^CPVkz_{+O*y2ohlFwZg{0xAXwcg*-;Hr=6?VXco_{H zkUPR__p-0-h1}Ek_J?uGDMoXYECG_`opA9S_}MQ4m41%6a3=CF4zVhQVN*PBSL6OQ z;@EuZ$W#SmfANyd@+7KP3B|^8>=DKj?od8v_DAO0diK8C@6B)V^kQmJmB|Jc_x07K zY{?o(w46#)ckz@EG^(;VJSOF1Xcr4HHDN}uv1_84ZZNrqox2s(0bYZasOz1-%=5TI z*vp@xc6@o~c;4J->z2@(eX*2QY>KywsH9I6AexkpN=_Z*y*I~a1Xhz27Z*)tXe5rk zO$5emzBN%}R#{*KxmR-&9Y@KO>O~p6R0PwDsl>eGvAEl}B-f!#7yCxsgbWdTar`ce zK}eqBQthX2;P7;9=mtb``6qzYiO_H1==A9yY3)@w$!9xr6o1uqRN1( zFOV8emnmxzahyPDVsUp*v?Fp(Zfr&DF3D4Tn;7jVbAEL~XU3fkLLGBqpy-+|(&O@+Pg0 z^=1;+P$_fl2q?`Yy0c7>UcT%sc;sH>S0hVUTE0?KY@~}z7vb8QIU5d}gui=#(% zb@hr1SYDQz$kkY5E@o!_Zmw80GQ6T)enB3O(9yU5Hw*s1mis>dZmQDxUu7hA|BN_7 z|2yRk{onZa_*a4drUHKf_;339x2k`sz+V9VrBHv<{+kN?1>nEw>))#Wr2>Be_?JTc zP5W;u@E3sprmugi`j-m)1>j!_^*8OmslZlG*f literal 0 HcmV?d00001 diff --git a/ext/data/schemas/options-schema.json b/ext/data/schemas/options-schema.json index c47f7063fd..227bc945ec 100644 --- a/ext/data/schemas/options-schema.json +++ b/ext/data/schemas/options-schema.json @@ -391,7 +391,7 @@ "enabled", "volume", "autoPlay", - "playFallbackSound", + "fallbackSoundType", "sources" ], "properties": { @@ -409,9 +409,10 @@ "type": "boolean", "default": false }, - "playFallbackSound": { - "type": "boolean", - "default": true + "fallbackSoundType": { + "type": "string", + "enum": ["none", "click", "bloop"], + "default": "click" }, "sources": { "type": "array", diff --git a/ext/js/data/options-util.js b/ext/js/data/options-util.js index 6c2bb816cf..b4d6129940 100644 --- a/ext/js/data/options-util.js +++ b/ext/js/data/options-util.js @@ -571,6 +571,7 @@ export class OptionsUtil { this._updateVersion57, this._updateVersion58, this._updateVersion59, + this._updateVersion60, ]; /* eslint-enable @typescript-eslint/unbound-method */ if (typeof targetVersion === 'number' && targetVersion < result.length) { @@ -1594,6 +1595,17 @@ export class OptionsUtil { } } + /** + * - Replaced audio.playFallbackSound with audio.fallbackSoundType + * @type {import('options-util').UpdateFunction} + */ + async _updateVersion60(options) { + for (const profile of options.profiles) { + profile.options.audio.fallbackSoundType = profile.options.audio.playFallbackSound ? 'click' : 'none'; + delete profile.options.audio.playFallbackSound; + } + } + /** * @param {string} url * @returns {Promise} diff --git a/ext/js/display/display-audio.js b/ext/js/display/display-audio.js index ef035857ce..87f5691370 100644 --- a/ext/js/display/display-audio.js +++ b/ext/js/display/display-audio.js @@ -36,8 +36,8 @@ export class DisplayAudio { this._playbackVolume = 1; /** @type {boolean} */ this._autoPlay = false; - /** @type {boolean} */ - this._playFallbackSound = true; + /** @type {import('settings').FallbackSoundType} */ + this._fallbackSoundType = 'none'; /** @type {?import('core').Timeout} */ this._autoPlayAudioTimer = null; /** @type {number} */ @@ -170,10 +170,10 @@ export class DisplayAudio { _onOptionsUpdated({options}) { const { general: {language}, - audio: {enabled, autoPlay, playFallbackSound, volume, sources}, + audio: {enabled, autoPlay, fallbackSoundType, volume, sources}, } = options; this._autoPlay = enabled && autoPlay; - this._playFallbackSound = playFallbackSound; + this._fallbackSoundType = fallbackSoundType; this._playbackVolume = Number.isFinite(volume) ? Math.max(0, Math.min(1, volume / 100)) : 1; /** @type {Set} */ @@ -454,7 +454,7 @@ export class DisplayAudio { const sourceIndex = sources.indexOf(source); title = `From source ${1 + sourceIndex}: ${source.name}`; } else { - audio = this._audioSystem.getFallbackAudio(this._playFallbackSound); + audio = this._audioSystem.getFallbackAudio(this._fallbackSoundType); title = 'Could not find audio'; } diff --git a/ext/js/media/audio-system.js b/ext/js/media/audio-system.js index 7a7e40bebd..0dfa2d20f9 100644 --- a/ext/js/media/audio-system.js +++ b/ext/js/media/audio-system.js @@ -27,8 +27,8 @@ export class AudioSystem extends EventDispatcher { super(); /** @type {?HTMLAudioElement} */ this._fallbackAudio = null; - /** @type {?boolean} */ - this._playFallbackSound = null; + /** @type {?import('settings').FallbackSoundType} */ + this._fallbackSoundType = null; } /** @@ -45,14 +45,24 @@ export class AudioSystem extends EventDispatcher { } /** - * @param {boolean} playFallbackSound + * @param {import('settings').FallbackSoundType} fallbackSoundType * @returns {HTMLAudioElement} */ - getFallbackAudio(playFallbackSound) { - if (this._fallbackAudio === null || this._playFallbackSound !== playFallbackSound) { - // audio handler expects audio url to always be present, empty string must be used instead of `new Audio()` - this._fallbackAudio = playFallbackSound ? new Audio('/data/audio/button.mp3') : new Audio(''); - this._playFallbackSound = playFallbackSound; + getFallbackAudio(fallbackSoundType) { + if (this._fallbackAudio === null || this._fallbackSoundType !== fallbackSoundType) { + this._fallbackSoundType = fallbackSoundType; + switch (fallbackSoundType) { + case 'click': + this._fallbackAudio = new Audio('/data/audio/fallback-click.mp3'); + break; + case 'bloop': + this._fallbackAudio = new Audio('/data/audio/fallback-bloop.mp3'); + break; + case 'none': + // audio handler expects audio url to always be present, empty string must be used instead of `new Audio()` + this._fallbackAudio = new Audio(''); + break; + } } return this._fallbackAudio; } diff --git a/ext/settings.html b/ext/settings.html index 924c230fe5..b6b3101545 100644 --- a/ext/settings.html +++ b/ext/settings.html @@ -1461,15 +1461,23 @@

Yomitan Settings

-
-
-
Enable audio fallback sound
-
Play sound when Yomitan fails to fetch audio.
-
-
- +
+
+
+
Audio fallback sound
+
+ The sound to play when Yomitan fails to fetch audio. +
+
+
+ +
-
+
Audio volume
diff --git a/test/options-util.test.js b/test/options-util.test.js index bc41089571..8505a27204 100644 --- a/test/options-util.test.js +++ b/test/options-util.test.js @@ -76,7 +76,7 @@ function createProfileOptionsTestData1() { sources: ['jpod101', 'text-to-speech', 'custom', 'jpod101-alternate'], volume: 100, autoPlay: false, - playFallbackSound: true, + fallbackSoundType: 'click', customSourceUrl: 'http://localhost/audio.mp3?term={expression}&reading={reading}', textToSpeechVoice: 'example-voice', }, @@ -337,7 +337,7 @@ function createProfileOptionsUpdatedTestData1() { ], volume: 100, autoPlay: false, - playFallbackSound: true, + fallbackSoundType: 'click', }, scanning: { selectText: true, @@ -680,7 +680,7 @@ function createOptionsUpdatedTestData1() { }, ], profileCurrent: 0, - version: 59, + version: 60, global: { database: { prefixWildcardsSupported: false, diff --git a/types/ext/settings.d.ts b/types/ext/settings.d.ts index 5ca7e62c39..f5111e629b 100644 --- a/types/ext/settings.d.ts +++ b/types/ext/settings.d.ts @@ -167,10 +167,12 @@ export type AudioOptions = { enabled: boolean; volume: number; autoPlay: boolean; - playFallbackSound: boolean; + fallbackSoundType: FallbackSoundType; sources: AudioSourceOptions[]; }; +export type FallbackSoundType = 'none' | 'click' | 'bloop'; + export type AudioSourceOptions = { type: AudioSourceType; url: string;