From 5bf6ddc28123acbfe7493097a3e87ba5108af270 Mon Sep 17 00:00:00 2001 From: End Date: Mon, 27 Jul 2026 03:03:07 -0700 Subject: [PATCH] feat: add call voice processing toggle Expose RingRTC's setVoiceProcessingEnabled (AEC/NS/AGC) as a Preferences > Calls checkbox, applied at startup and live on toggle. --- _locales/en/messages.json | 8 ++++++++ ts/components/Preferences.dom.stories.tsx | 2 ++ ts/components/Preferences.dom.tsx | 12 ++++++++++++ ts/services/calling.preload.ts | 10 ++++++++++ ts/state/smart/Preferences.preload.tsx | 9 +++++++++ ts/types/StorageKeys.std.ts | 2 ++ 6 files changed, 43 insertions(+) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 8188301f8..c21587bc3 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -2865,6 +2865,14 @@ "messageformat": "Relay all calls through the Signal server to avoid revealing your IP address to your contact. Enabling will reduce call quality.", "description": "Details describing the always relay calls setting" }, + "icu:voiceProcessingDescription": { + "messageformat": "Voice processing", + "description": "Description of the call voice processing setting" + }, + "icu:voiceProcessingDetail": { + "messageformat": "Reduces echo and background noise during calls. Turn off if you're using specialized microphones or audio equipment.", + "description": "Details describing the call voice processing setting" + }, "icu:permissions": { "messageformat": "Permissions", "description": "Header for permissions section of settings" diff --git a/ts/components/Preferences.dom.stories.tsx b/ts/components/Preferences.dom.stories.tsx index 803a980c0..96c455ed6 100644 --- a/ts/components/Preferences.dom.stories.tsx +++ b/ts/components/Preferences.dom.stories.tsx @@ -484,6 +484,7 @@ export default { hasPreferContactAvatars: true, hasReadReceipts: true, hasRelayCalls: false, + hasVoiceProcessing: true, hasSealedSenderIndicators: true, hasSpellCheck: true, hasStoriesDisabled: false, @@ -623,6 +624,7 @@ export default { onPreferContactAvatarsChange: action('onPreferContactAvatarsChange'), onReadReceiptsChange: action('onReadReceiptsChange'), onRelayCallsChange: action('onRelayCallsChange'), + onVoiceProcessingChange: action('onVoiceProcessingChange'), onSealedSenderIndicatorsChange: action('onSealedSenderIndicatorsChange'), onSelectedCameraChange: action('onSelectedCameraChange'), onSelectedMicrophoneChange: action('onSelectedMicrophoneChange'), diff --git a/ts/components/Preferences.dom.tsx b/ts/components/Preferences.dom.tsx index 700633403..e1b200caf 100644 --- a/ts/components/Preferences.dom.tsx +++ b/ts/components/Preferences.dom.tsx @@ -157,6 +157,7 @@ export type PropsDataType = { hasPreferContactAvatars: boolean; hasReadReceipts: boolean; hasRelayCalls?: boolean; + hasVoiceProcessing?: boolean; hasSpellCheck: boolean | undefined; hasStoriesDisabled: boolean; hasTextFormatting: boolean; @@ -343,6 +344,7 @@ type PropsFunctionType = { onPreferContactAvatarsChange: CheckboxChangeHandlerType; onReadReceiptsChange: CheckboxChangeHandlerType; onRelayCallsChange: CheckboxChangeHandlerType; + onVoiceProcessingChange: CheckboxChangeHandlerType; onSealedSenderIndicatorsChange: CheckboxChangeHandlerType; onSelectedCameraChange: SelectChangeHandlerType; onSelectedMicrophoneChange: SelectChangeHandlerType; @@ -466,6 +468,7 @@ export function Preferences({ hasPreferContactAvatars, hasReadReceipts, hasRelayCalls, + hasVoiceProcessing, hasSealedSenderIndicators, hasSpellCheck, hasStoriesDisabled, @@ -523,6 +526,7 @@ export function Preferences({ onPreferContactAvatarsChange, onReadReceiptsChange, onRelayCallsChange, + onVoiceProcessingChange, onSealedSenderIndicatorsChange, onSelectedCameraChange, onSelectedMicrophoneChange, @@ -1515,6 +1519,14 @@ export function Preferences({ /> + { + calling.setVoiceProcessingEnabled(value); + } + ); const [hasStoriesDisabled, onHasStoriesDisabledChanged] = createItemsAccess( 'hasStoriesDisabled', false, @@ -956,6 +963,7 @@ export function SmartPreferences(): JSX.Element | null { hasPreferContactAvatars={hasPreferContactAvatars} hasReadReceipts={hasReadReceipts} hasRelayCalls={hasRelayCalls} + hasVoiceProcessing={hasVoiceProcessing} hasSealedSenderIndicators={hasSealedSenderIndicators} hasSpellCheck={hasSpellCheck} hasStoriesDisabled={hasStoriesDisabled} @@ -1020,6 +1028,7 @@ export function SmartPreferences(): JSX.Element | null { onPreferContactAvatarsChange={onPreferContactAvatarsChange} onReadReceiptsChange={onReadReceiptsChange} onRelayCallsChange={onRelayCallsChange} + onVoiceProcessingChange={onVoiceProcessingChange} onSealedSenderIndicatorsChange={onSealedSenderIndicatorsChange} onSelectedCameraChange={onSelectedCameraChange} onSelectedMicrophoneChange={onSelectedMicrophoneChange} diff --git a/ts/types/StorageKeys.std.ts b/ts/types/StorageKeys.std.ts index 8a1647886..b535fa1dd 100644 --- a/ts/types/StorageKeys.std.ts +++ b/ts/types/StorageKeys.std.ts @@ -59,6 +59,7 @@ export type IdentityKeyMap = Record< export type StorageAccessType = { 'always-relay-calls': boolean; + 'call-voice-processing-enabled': boolean; 'audio-notification': boolean; 'auto-download-update': boolean; 'auto-download-attachment': AutoDownloadAttachmentType; @@ -341,6 +342,7 @@ export const STORAGE_KEYS_TO_PRESERVE_AFTER_UNLINK = [ 'autoConvertEmoji', 'badge-count-muted-conversations', 'call-ringtone-notification', + 'call-voice-processing-enabled', 'call-system-notification', 'customColors', 'defaultConversationColor', -- 2.53.0