diff --git a/extension/entrypoints/background/notifications.ts b/extension/entrypoints/background/notifications.ts index 8064ca22e..9bf141f85 100644 --- a/extension/entrypoints/background/notifications.ts +++ b/extension/entrypoints/background/notifications.ts @@ -189,6 +189,7 @@ export async function notifyUser(title: string, message: string, url?: string) { if (matchedVoice) ttsMessage.voice = matchedVoice; } + ttsMessage.rate = settings.notifications.ttsRate; window.speechSynthesis.speak(ttsMessage); } else { // Offscreen documents @@ -199,6 +200,7 @@ export async function notifyUser(title: string, message: string, url?: string) { text: text, volume: settings.notifications.volume / 100, voice: settings.notifications.ttsVoice, + rate: settings.notifications.ttsRate, } satisfies OffscreenMessage); } } diff --git a/extension/entrypoints/offscreen/offscreen.ts b/extension/entrypoints/offscreen/offscreen.ts index 41b464bba..831bf4b65 100644 --- a/extension/entrypoints/offscreen/offscreen.ts +++ b/extension/entrypoints/offscreen/offscreen.ts @@ -16,9 +16,10 @@ interface PlayTTSOptions { text: string; volume: number; voice: string; + rate: number; } -function playTTS({ text, volume, voice }: PlayTTSOptions) { +function playTTS({ text, volume, voice, rate }: PlayTTSOptions) { const ttsMessage = new SpeechSynthesisUtterance(text); ttsMessage.volume = volume; if (voice !== "default") { @@ -26,6 +27,8 @@ function playTTS({ text, volume, voice }: PlayTTSOptions) { if (matchedVoice) ttsMessage.voice = matchedVoice; } + ttsMessage.rate = rate; + window.speechSynthesis.speak(ttsMessage); } diff --git a/extension/entrypoints/options/index.html b/extension/entrypoints/options/index.html index e5c81fae3..32ace6415 100644 --- a/extension/entrypoints/options/index.html +++ b/extension/entrypoints/options/index.html @@ -737,6 +737,10 @@

+
+ + +
diff --git a/extension/entrypoints/options/settings.ts b/extension/entrypoints/options/settings.ts index 3580ccfc1..ce47127e8 100644 --- a/extension/entrypoints/options/settings.ts +++ b/extension/entrypoints/options/settings.ts @@ -744,6 +744,7 @@ async function setupPreferences(requireCleanup: boolean = false) { _preferences.querySelector("#notification-sound").value = settings.notifications.sound; _preferences.querySelector("#notification-tts").checked = settings.notifications.tts; + _preferences.querySelector("#notification-ttsRate").value = settings.notifications.ttsRate.toString(); _preferences.querySelector("#notification-link").checked = settings.notifications.link; _preferences.querySelector("#notification-requireInteraction").checked = settings.notifications.requireInteraction; _preferences.querySelector("#notification-volume").value = settings.notifications.volume.toString(); @@ -1202,6 +1203,7 @@ async function setupPreferences(requireCleanup: boolean = false) { settings.notifications.tts = _preferences.querySelector("#notification-tts").checked; settings.notifications.ttsVoice = _preferences.querySelector("#tts-voice").value; + settings.notifications.ttsRate = parseFloat(_preferences.querySelector("#notification-ttsRate").value); settings.notifications.link = _preferences.querySelector("#notification-link").checked; settings.notifications.requireInteraction = _preferences.querySelector("#notification-requireInteraction").checked; settings.notifications.volume = parseInt(_preferences.querySelector("#notification-volume").value); diff --git a/extension/utils/common/data/default-database.ts b/extension/utils/common/data/default-database.ts index 35796414b..08c5931a3 100644 --- a/extension/utils/common/data/default-database.ts +++ b/extension/utils/common/data/default-database.ts @@ -71,6 +71,7 @@ export const DEFAULT_STORAGE = { soundCustom: new DefaultSetting("string", ""), tts: new DefaultSetting("boolean", false), ttsVoice: new DefaultSetting("string", "default"), + ttsRate: new DefaultSetting("number", 1), link: new DefaultSetting("boolean", true), volume: new DefaultSetting("number", 100), requireInteraction: new DefaultSetting("boolean", false), diff --git a/public/changelog.json b/public/changelog.json index 97d9a63c0..3b637428a 100644 --- a/public/changelog.json +++ b/public/changelog.json @@ -8,7 +8,8 @@ { "message": "'FF Scouter' score filter for ranked wars.", "contributor": "DeKleineKobini" }, { "message": "Labels for stakeouts.", "contributor": "DeKleineKobini" }, { "message": "Added bazaarOpen filter on abroad people page", "contributor": "mystify-321" }, - { "message": "More special filters to the 'Userlist Filter': has bounties and bazaar open", "contributor": "DeKleineKobini" } + { "message": "More special filters to the 'Userlist Filter': has bounties and bazaar open", "contributor": "DeKleineKobini" }, + { "message": "Modify TTS speaking rate for notifications.", "contributor": "DeKleineKobini" } ], "fixes": [ { "message": "Filtering on profit in the 'Stocks Filter' gave errors for stocks you don't own.", "contributor": "DeKleineKobini" },