From 5ab84b869960d2d5670dcd36e032f087f1b3a066 Mon Sep 17 00:00:00 2001 From: ryanjavram <56175885+ryanjavram@users.noreply.github.com> Date: Mon, 8 Dec 2025 18:09:23 -0500 Subject: [PATCH 01/18] Add check for receive-only channels before transmission --- client/ui/js/script.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/ui/js/script.js b/client/ui/js/script.js index 4aaeddb..e80a19d 100644 --- a/client/ui/js/script.js +++ b/client/ui/js/script.js @@ -409,6 +409,12 @@ window.addEventListener('message', async function (event) { return; } + if (currentCodeplug.zones[currentZoneIndex].channels[currentChannelIndex].receiveOnly === true) { + console.debug("Cannot tx, rx only"); + bonk(); + return; + } + if (isReceiving) { console.debug("Receiving, not txing"); bonk(); From 4b64f4b7f341a7dcedf32534b525163159e8bb60 Mon Sep 17 00:00:00 2001 From: ryanjavram <56175885+ryanjavram@users.noreply.github.com> Date: Mon, 8 Dec 2025 18:11:33 -0500 Subject: [PATCH 02/18] Update voice announcements to use name_announce --- client/ui/js/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ui/js/script.js b/client/ui/js/script.js index e80a19d..1be609f 100644 --- a/client/ui/js/script.js +++ b/client/ui/js/script.js @@ -956,8 +956,8 @@ function changeZone(direction) { const currentZone = currentCodeplug.zones[currentZoneIndex]; const currentChannel = currentZone.channels[currentChannelIndex]; - // responsiveVoice.speak(`${currentZone.name}`, `US English Female`, {rate: .8}); - // responsiveVoice.speak(`${currentChannel.name}`, `US English Female`, {rate: .8}); + responsiveVoice.speak(`${currentZone.name_announce}`, `US English Female`, {rate: .8}); + responsiveVoice.speak(`${currentChannel.name_announce}`, `US English Female`, {rate: .8}); SendGroupAffiliationRemoval(currentTg); updateDisplay(); From 49c7310672630f6c17cf93164ff3afc7b939c7f5 Mon Sep 17 00:00:00 2001 From: ryanjavram <56175885+ryanjavram@users.noreply.github.com> Date: Mon, 8 Dec 2025 18:19:25 -0500 Subject: [PATCH 03/18] Add name_announce value for zones and channels; add isReceiveOnly value for channels (prevents radios using this codeplug to transmit on that channel) --- codeplugs/codeplug.example.yml | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/codeplugs/codeplug.example.yml b/codeplugs/codeplug.example.yml index e4923ad..fde0957 100644 --- a/codeplugs/codeplug.example.yml +++ b/codeplugs/codeplug.example.yml @@ -22,30 +22,44 @@ qcList: b: 500.9 zones: - - name: "Zone 1" + - name: "Z1" # Displayed on the radio UI + name_announce: "Zone 1" # Announced when switching to this zone channels: - - name: "Channel 1" + - name: "Ch 1" # Displayed on the radio UI + name_announce: "Channel 1" # Announced when switching to this channel system: "System 1" tgid: "2001" scanList: List 1 - - name: "Channel 2" + isReceiveOnly: false + - name: "Ch 2" # Displayed on the radio UI + name_announce: "Channel 2" # Announced when switching to this channel system: "System 1" tgid: "15002" - - name: "Channel 3" + isReceiveOnly: false + - name: "Ch 3" # Displayed on the radio UI + name_announce: "Channel 3" # Announced when switching to this channel system: "System 1" tgid: "15003" + isReceiveOnly: false - - name: "Zone 2" + - name: "Z2" # Displayed on the radio UI + name_announce: "Zone 2" # Announced when switching to this zone channels: - - name: "Channel A" + - name: "Ch A" # Displayed on the radio UI + name_announce: "Channel A" # Announced when switching to this channel system: "System 1" tgid: "16001" - - name: "Channel B" + isReceiveOnly: false + - name: "Ch B" # Displayed on the radio UI + name_announce: "Channel B" # Announced when switching to this channel system: "System 1" tgid: "16002" - - name: "Channel C" + isReceiveOnly: false + - name: "Ch C" # Displayed on the radio UI + name_announce: "Channel C" # Announced when switching to this channel system: "System 1" tgid: "16002" + isReceiveOnly: false scanLists: - name: List 1 From 8bf455bd95f638166f475ab024b212a324680f5b Mon Sep 17 00:00:00 2001 From: ryanjavram <56175885+ryanjavram@users.noreply.github.com> Date: Mon, 8 Dec 2025 18:20:27 -0500 Subject: [PATCH 04/18] Rename receiveOnly property to isReceiveOnly --- client/ui/js/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ui/js/script.js b/client/ui/js/script.js index 1be609f..bb71795 100644 --- a/client/ui/js/script.js +++ b/client/ui/js/script.js @@ -409,7 +409,7 @@ window.addEventListener('message', async function (event) { return; } - if (currentCodeplug.zones[currentZoneIndex].channels[currentChannelIndex].receiveOnly === true) { + if (currentCodeplug.zones[currentZoneIndex].channels[currentChannelIndex].isReceiveOnly === true) { console.debug("Cannot tx, rx only"); bonk(); return; From 46506e84acf9db89b5a7c2e5b5462c282e9d739b Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Mon, 8 Dec 2025 18:36:40 -0500 Subject: [PATCH 05/18] Forgot to update voice announce for changeChannel --- client/ui/js/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ui/js/script.js b/client/ui/js/script.js index bb71795..43a0b31 100644 --- a/client/ui/js/script.js +++ b/client/ui/js/script.js @@ -919,7 +919,7 @@ function changeChannel(direction) { const currentChannel = currentZone.channels[currentChannelIndex]; - // responsiveVoice.speak(`${currentChannel.name}`, `US English Female`, {rate: .8}); + responsiveVoice.speak(`${currentChannel.name_announce}`, `US English Female`, {rate: .8}); SendGroupAffiliationRemoval(currentTg); From 7891323919ecaf087033a832da5c46397d680213 Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Mon, 8 Dec 2025 21:52:33 -0500 Subject: [PATCH 06/18] Forgot to update zone/channel announce for scannerMode --- client/ui/js/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ui/js/script.js b/client/ui/js/script.js index 43a0b31..df802d8 100644 --- a/client/ui/js/script.js +++ b/client/ui/js/script.js @@ -659,8 +659,8 @@ async function powerOn(reReg) { } if (!isScannerModel()) { - // responsiveVoice.speak(`${currentZone.name}`, `US English Female`, {rate: .8}); - // responsiveVoice.speak(`${currentChannel.name}`, `US English Female`, {rate: .8}); + responsiveVoice.speak(`${currentZone.name_announce}`, `US English Female`, {rate: .8}); + responsiveVoice.speak(`${currentChannel.name_announce}`, `US English Female`, {rate: .8}); } updateDisplay(); From 6b987793317e4e2e11d5b015138bba4751e7ce74 Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Thu, 11 Dec 2025 13:48:43 -0500 Subject: [PATCH 07/18] Enable responsive voice script in index.html --- client/ui/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ui/index.html b/client/ui/index.html index 6e85112..59b82fb 100644 --- a/client/ui/index.html +++ b/client/ui/index.html @@ -107,6 +107,6 @@ - + From a29a868657ca50f16931846e74b2647fc5efdb01 Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Thu, 11 Dec 2025 21:30:24 -0500 Subject: [PATCH 08/18] Add new configuration options to config.yml --- configs/config.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configs/config.yml b/configs/config.yml index df9795c..2ad6a5d 100644 --- a/configs/config.yml +++ b/configs/config.yml @@ -1,4 +1,6 @@ siteBlips: true disableAnimations: false # Beep volume reduction factor. 0.0 is full volume, 1.0 is silent -beepVolumeReduction: 0.6 \ No newline at end of file +beepVolumeReduction: 0.6 +announceZoneChannelChanges: false +responsveVoiceApiKey: "add your api key here" From 9a9efc9768dab772c1f15bc6191ccc03b6eb63c0 Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Thu, 11 Dec 2025 21:31:06 -0500 Subject: [PATCH 09/18] Remove announceZoneChannelChanges from config Remove the announceZoneChannelChanges configuration option. --- configs/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/config.yml b/configs/config.yml index 2ad6a5d..079723f 100644 --- a/configs/config.yml +++ b/configs/config.yml @@ -2,5 +2,4 @@ siteBlips: true disableAnimations: false # Beep volume reduction factor. 0.0 is full volume, 1.0 is silent beepVolumeReduction: 0.6 -announceZoneChannelChanges: false responsveVoiceApiKey: "add your api key here" From e0f0ee167b6c865c48da07225598e7729a1fdd21 Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Thu, 11 Dec 2025 21:32:07 -0500 Subject: [PATCH 10/18] Add announceZoneChannelChanges to codeplug example Added 'announceZoneChannelChanges' field to configuration. --- codeplugs/codeplug.example.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/codeplugs/codeplug.example.yml b/codeplugs/codeplug.example.yml index fde0957..9152e6c 100644 --- a/codeplugs/codeplug.example.yml +++ b/codeplugs/codeplug.example.yml @@ -5,6 +5,7 @@ radioWide: serialNumber: "123ABC1234" model: "APX6000" inCarMode: "APX4500" + announceZoneChannelChanges: false # Make sure you add your own API key in the main config file before enabling this systems: - name: "System 1" From 63d9cca0f66e9d20da342c64a5f69ccaf5441774 Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Thu, 11 Dec 2025 21:48:24 -0500 Subject: [PATCH 11/18] Remove comment on announceZoneChannelChanges Removed comment about enabling announceZoneChannelChanges. --- codeplugs/codeplug.example.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/codeplugs/codeplug.example.yml b/codeplugs/codeplug.example.yml index 9152e6c..fde0957 100644 --- a/codeplugs/codeplug.example.yml +++ b/codeplugs/codeplug.example.yml @@ -5,7 +5,6 @@ radioWide: serialNumber: "123ABC1234" model: "APX6000" inCarMode: "APX4500" - announceZoneChannelChanges: false # Make sure you add your own API key in the main config file before enabling this systems: - name: "System 1" From 0cb302fd7684f8edc45edf968d6102a43c2a83df Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Thu, 11 Dec 2025 21:48:37 -0500 Subject: [PATCH 12/18] Remove responsiveVoiceApiKey from config.yml Removed responsiveVoiceApiKey placeholder from config. --- configs/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/config.yml b/configs/config.yml index 079723f..17b43d2 100644 --- a/configs/config.yml +++ b/configs/config.yml @@ -2,4 +2,3 @@ siteBlips: true disableAnimations: false # Beep volume reduction factor. 0.0 is full volume, 1.0 is silent beepVolumeReduction: 0.6 -responsveVoiceApiKey: "add your api key here" From e862b614cdcdc62be5c282bfb9b995db3c54b8d2 Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:22:26 -0500 Subject: [PATCH 13/18] Add responsiveVoiceApiKey to config --- configs/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/config.yml b/configs/config.yml index 17b43d2..c160075 100644 --- a/configs/config.yml +++ b/configs/config.yml @@ -2,3 +2,4 @@ siteBlips: true disableAnimations: false # Beep volume reduction factor. 0.0 is full volume, 1.0 is silent beepVolumeReduction: 0.6 +responsiveVoiceApiKey: "add your api key" From fa59a473b1dba489ad5a9f317a8267a99237a086 Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:24:06 -0500 Subject: [PATCH 14/18] Add isAnnonceZoneChannelChanges field to example config --- codeplugs/codeplug.example.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/codeplugs/codeplug.example.yml b/codeplugs/codeplug.example.yml index fde0957..58df94a 100644 --- a/codeplugs/codeplug.example.yml +++ b/codeplugs/codeplug.example.yml @@ -5,6 +5,7 @@ radioWide: serialNumber: "123ABC1234" model: "APX6000" inCarMode: "APX4500" + isAnnonceZoneChannelChanges: false systems: - name: "System 1" From 6293ff47a6581b5ac9ec0121bab15283b7accc68 Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Fri, 12 Dec 2025 11:54:03 -0500 Subject: [PATCH 15/18] Add API key check for voice announcements Fetch and check responsiveVoiceApiKey from config.yml before announcing zone and channel. --- client/ui/js/script.js | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/client/ui/js/script.js b/client/ui/js/script.js index df802d8..426d130 100644 --- a/client/ui/js/script.js +++ b/client/ui/js/script.js @@ -658,9 +658,27 @@ async function powerOn(reReg) { await displayBootScreen(bootScreenMessages); } - if (!isScannerModel()) { - responsiveVoice.speak(`${currentZone.name_announce}`, `US English Female`, {rate: .8}); - responsiveVoice.speak(`${currentChannel.name_announce}`, `US English Female`, {rate: .8}); + if (!isScannerModel() && currentCodeplug.isAnnounceZoneChannelTalkgroups === true) { + fetch('/configs/config.yml') + .then(response => response.text()) + .then(yamlText => { + const lines = yamlText.split('\n'); + for (const line of lines) { + const matchApiKey = line.match(/^\s*responsiveVoiceApiKey\s*:\s+\S*$/i); + const apiKey = matchApiKey.replace("responsiveVoiceApiKey: ", "") + if (apiKey !== null && apiKey !== "") { + responsiveVoice.speak(`${currentZone.name_announce}`, `US English Female`, {rate: .8}); + responsiveVoice.speak(`${currentChannel.name_announce}`, `US English Female`, {rate: .8}); + return; + } else { + console.error('responsiveVoiceApiKey not set in config.yml); + return; + } + } + }) + .catch(err => { + console.warn('Could not load config.yml, defaulting to disabled zone/channel announcements:', err); + }); } updateDisplay(); From 2427a743323f24046fdf65348f6baa4f3dbaf227 Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Sat, 13 Dec 2025 21:12:48 -0500 Subject: [PATCH 16/18] Implement responsive voice API key handling Added logic to fetch and check responsiveVoiceApiKey from config.yml, enabling/disabling responsive voice based on its presence. --- client/ui/js/script.js | 46 +++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/client/ui/js/script.js b/client/ui/js/script.js index 426d130..3421d37 100644 --- a/client/ui/js/script.js +++ b/client/ui/js/script.js @@ -130,6 +130,28 @@ fetch('/configs/config.yml') console.warn('Could not load config.yml, using default config values:', err); }); +let isResponsiveVoiceApiKeySet = false; // default value +fetch('/configs/config.yml') + .then(response => response.text()) + .then(yamlText => { + const lines = yamlText.split('\n'); + for (const line of lines) { + const matchApiKeyValue = line.match(/^\s*responsiveVoiceApiKey\s*:\s+\S*$/i); + const apiKey = matchApiKeyValue.replace("responsiveVoiceApiKey: ", ""); + if (apiKey !== null && apiKey !== "") { + isResponsiveVoiceApiKeySet = true + console.log('Responsive voice enabled); + } else { + console.log('Responsive voice API key not set, disabled); + } + } + } + }) + .catch(err => { + console.warn('Could not load config.yml, defaulting to disbaled responsive voice:', err); + }); + + reconnectInterval = setInterval(() => { if (isInSiteTrunking && radioOn) { connectWebSocket(); @@ -658,27 +680,9 @@ async function powerOn(reReg) { await displayBootScreen(bootScreenMessages); } - if (!isScannerModel() && currentCodeplug.isAnnounceZoneChannelTalkgroups === true) { - fetch('/configs/config.yml') - .then(response => response.text()) - .then(yamlText => { - const lines = yamlText.split('\n'); - for (const line of lines) { - const matchApiKey = line.match(/^\s*responsiveVoiceApiKey\s*:\s+\S*$/i); - const apiKey = matchApiKey.replace("responsiveVoiceApiKey: ", "") - if (apiKey !== null && apiKey !== "") { - responsiveVoice.speak(`${currentZone.name_announce}`, `US English Female`, {rate: .8}); - responsiveVoice.speak(`${currentChannel.name_announce}`, `US English Female`, {rate: .8}); - return; - } else { - console.error('responsiveVoiceApiKey not set in config.yml); - return; - } - } - }) - .catch(err => { - console.warn('Could not load config.yml, defaulting to disabled zone/channel announcements:', err); - }); + if (!isScannerModel() && currentCodeplug.isAnnounceZoneChannelTalkgroups === true && isResponsiveVoiceApiKeySet === true) { + responsiveVoice.speak(`${currentZone.name_announce}`, `US English Female`, {rate: .8}); + responsiveVoice.speak(`${currentChannel.name_announce}`, `US English Female`, {rate: .8}); } updateDisplay(); From 2cf37fa48de610debbe137f4bb1b0f5cf1338dbb Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Sun, 14 Dec 2025 12:17:52 -0500 Subject: [PATCH 17/18] Refactor config loading and API key handling --- client/ui/js/script.js | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/client/ui/js/script.js b/client/ui/js/script.js index 3421d37..fb30340 100644 --- a/client/ui/js/script.js +++ b/client/ui/js/script.js @@ -102,19 +102,20 @@ function socketOpen() { } let beepVolumeReduction = 0.6; // default value +let isResponsiveVoiceApiKeySet = false; // default value fetch('/configs/config.yml') .then(response => response.text()) .then(yamlText => { const lines = yamlText.split('\n'); for (const line of lines) { const matchBeepVolume = line.match(/^\s*beepVolumeReduction\s*:\s*([0-9.]+)\s*$/i); + const matchApiKeyValue = line.match(/^\s*responsiveVoiceApiKey\s*:\s+\S*$/i); if (matchBeepVolume) { let parsed = parseFloat(matchBeepVolume[1]); if (isNaN(parsed)) { console.error('beepVolumeReduction in config.yml is not a number. Using default value.'); return; - } - if (parsed < 0.0) { + } if (parsed < 0.0) { console.error('beepVolumeReduction in config.yml is less than 0. Clamping to 0.'); beepVolumeReduction = 0.0; } else if (parsed > 1.0) { @@ -124,31 +125,19 @@ fetch('/configs/config.yml') beepVolumeReduction = parsed; } } - } - }) - .catch(err => { - console.warn('Could not load config.yml, using default config values:', err); - }); - -let isResponsiveVoiceApiKeySet = false; // default value -fetch('/configs/config.yml') - .then(response => response.text()) - .then(yamlText => { - const lines = yamlText.split('\n'); - for (const line of lines) { - const matchApiKeyValue = line.match(/^\s*responsiveVoiceApiKey\s*:\s+\S*$/i); - const apiKey = matchApiKeyValue.replace("responsiveVoiceApiKey: ", ""); - if (apiKey !== null && apiKey !== "") { - isResponsiveVoiceApiKeySet = true - console.log('Responsive voice enabled); + if (matchApiKeyValue) { + let apiKey = matchApiKeyValue.replace("responsiveVoiceApiKey: ", ""); + if (apiKey !== null && apiKey !== "") { + isResponsiveVoiceApiKeySet = true + console.log('Responsive voice enabled') } else { - console.log('Responsive voice API key not set, disabled); + console.log('Responsive voice API key not set, disabled') } } } }) .catch(err => { - console.warn('Could not load config.yml, defaulting to disbaled responsive voice:', err); + console.warn('Could not load config.yml, using default config values:', err); }); @@ -671,9 +660,9 @@ async function powerOn(reReg) { bootImage.style.display = 'none'; } else { const bootScreenMessages = [ - {text: "", duration: 0, line: "line1"}, - {text: "", duration: 0, line: "line3"}, - {text: HOST_VERSION, duration: 1500, line: "line2"}, + {text: "", duration: 0, : "line1"}, + {text: "", duration: 0, : "line3"}, + {text: HOST_VERSION, duration: 1500, : "line2"}, {text: radioModel, duration: 1500, line: "line2"} ]; From bf2db2e49dde608a8bcacf7db5b6152cfd85faca Mon Sep 17 00:00:00 2001 From: crazyghost-12 <56175885+crazyghost-12@users.noreply.github.com> Date: Mon, 15 Dec 2025 15:22:40 -0500 Subject: [PATCH 18/18] Add conditional checks for voice announcements --- client/ui/js/script.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/client/ui/js/script.js b/client/ui/js/script.js index fb30340..60c8fc6 100644 --- a/client/ui/js/script.js +++ b/client/ui/js/script.js @@ -928,9 +928,10 @@ function changeChannel(direction) { setLine2("Fail 01/82"); } - const currentChannel = currentZone.channels[currentChannelIndex]; - - responsiveVoice.speak(`${currentChannel.name_announce}`, `US English Female`, {rate: .8}); + if (currentCodeplug.isAnnounceZoneChannelTalkgroups === true && isResponsiveVoiceApiKeySet === true) { + const currentChannel = currentZone.channels[currentChannelIndex]; + responsiveVoice.speak(`${currentChannel.name_announce}`, `US English Female`, {rate: .8}); + } SendGroupAffiliationRemoval(currentTg); @@ -964,11 +965,14 @@ function changeZone(direction) { } currentChannelIndex = 0; - const currentZone = currentCodeplug.zones[currentZoneIndex]; - const currentChannel = currentZone.channels[currentChannelIndex]; - responsiveVoice.speak(`${currentZone.name_announce}`, `US English Female`, {rate: .8}); - responsiveVoice.speak(`${currentChannel.name_announce}`, `US English Female`, {rate: .8}); + if (currentCodeplug.isAnnounceZoneChannelTalkgroups === true && isResponsiveVoiceApiKeySet === true) { + const currentZone = currentCodeplug.zones[currentZoneIndex]; + const currentChannel = currentZone.channels[currentChannelIndex]; + responsiveVoice.speak(`${currentZone.name_announce}`, `US English Female`, {rate: .8}); + responsiveVoice.speak(`${currentChannel.name_announce}`, `US English Female`, {rate: .8}); + } + SendGroupAffiliationRemoval(currentTg); updateDisplay();