From 2451eaccbd6fee8b58cba022a5c2d11114b8882b Mon Sep 17 00:00:00 2001 From: yash-signal Date: Wed, 21 Jan 2026 15:52:26 -0600 Subject: [PATCH] Update CQS logic: remove duration thresholds and add test mode --- ts/components/Preferences.dom.stories.tsx | 6 ++---- ts/components/Preferences.dom.tsx | 16 ++++++---------- ts/components/PreferencesInternal.dom.tsx | 14 +++++++------- ts/services/calling.preload.ts | 5 ++--- ts/state/smart/Preferences.preload.tsx | 13 +++++-------- ts/types/Storage.d.ts | 3 ++- ts/util/callQualitySurvey.dom.ts | 19 +++++++------------ 7 files changed, 31 insertions(+), 45 deletions(-) diff --git a/ts/components/Preferences.dom.stories.tsx b/ts/components/Preferences.dom.stories.tsx index 06270bdd9d..e71f5b2491 100644 --- a/ts/components/Preferences.dom.stories.tsx +++ b/ts/components/Preferences.dom.stories.tsx @@ -627,10 +627,8 @@ export default { __dangerouslyRunAbitraryReadOnlySqlQuery: async () => { return Promise.resolve([]); }, - callQualitySurveyCooldownDisabled: false, - setCallQualitySurveyCooldownDisabled: action( - 'setCallQualitySurveyCooldownDisabled' - ), + cqsTestMode: false, + setCqsTestMode: action('setCqsTestMode'), } satisfies PropsType, } satisfies Meta; diff --git a/ts/components/Preferences.dom.tsx b/ts/components/Preferences.dom.tsx index e430979ade..f89dcfce91 100644 --- a/ts/components/Preferences.dom.tsx +++ b/ts/components/Preferences.dom.tsx @@ -331,8 +331,8 @@ type PropsFunctionType = { __dangerouslyRunAbitraryReadOnlySqlQuery: ( readonlySqlQuery: string ) => Promise>>; - callQualitySurveyCooldownDisabled: boolean; - setCallQualitySurveyCooldownDisabled: (value: boolean) => void; + cqsTestMode: boolean; + setCqsTestMode: (value: boolean) => void; // Localization i18n: LocalizerType; @@ -543,8 +543,8 @@ export function Preferences({ generateDonationReceiptBlob, internalDeleteAllMegaphones, __dangerouslyRunAbitraryReadOnlySqlQuery, - callQualitySurveyCooldownDisabled, - setCallQualitySurveyCooldownDisabled, + cqsTestMode, + setCqsTestMode, }: PropsType): React.JSX.Element { const storiesId = useId(); const themeSelectId = useId(); @@ -2297,12 +2297,8 @@ export function Preferences({ __dangerouslyRunAbitraryReadOnlySqlQuery={ __dangerouslyRunAbitraryReadOnlySqlQuery } - callQualitySurveyCooldownDisabled={ - callQualitySurveyCooldownDisabled - } - setCallQualitySurveyCooldownDisabled={ - setCallQualitySurveyCooldownDisabled - } + cqsTestMode={cqsTestMode} + setCqsTestMode={setCqsTestMode} /> } contentsRef={settingsPaneRef} diff --git a/ts/components/PreferencesInternal.dom.tsx b/ts/components/PreferencesInternal.dom.tsx index 30f99f4863..062ddf8a02 100644 --- a/ts/components/PreferencesInternal.dom.tsx +++ b/ts/components/PreferencesInternal.dom.tsx @@ -35,8 +35,8 @@ export function PreferencesInternal({ generateDonationReceiptBlob, internalDeleteAllMegaphones, __dangerouslyRunAbitraryReadOnlySqlQuery, - callQualitySurveyCooldownDisabled, - setCallQualitySurveyCooldownDisabled, + cqsTestMode, + setCqsTestMode, }: { i18n: LocalizerType; validateBackup: () => Promise; @@ -59,8 +59,8 @@ export function PreferencesInternal({ __dangerouslyRunAbitraryReadOnlySqlQuery: ( readonlySqlQuery: string ) => Promise>>; - callQualitySurveyCooldownDisabled: boolean; - setCallQualitySurveyCooldownDisabled: (value: boolean) => void; + cqsTestMode: boolean; + setCqsTestMode: (value: boolean) => void; }): React.JSX.Element { const [messageCountBySchemaVersion, setMessageCountBySchemaVersion] = useState(); @@ -441,12 +441,12 @@ export function PreferencesInternal({
- Disable 24h cooldown + CQS testing: disable cooldown and always show for calls under 30s
diff --git a/ts/services/calling.preload.ts b/ts/services/calling.preload.ts index 3e24625a62..904bc7edf4 100644 --- a/ts/services/calling.preload.ts +++ b/ts/services/calling.preload.ts @@ -337,8 +337,7 @@ function maybeShowCallQualitySurvey( const lastSurveyTime = itemStorage.get('lastCallQualitySurveyTime') ?? null; const lastFailureSurveyTime = itemStorage.get('lastCallQualityFailureSurveyTime') ?? null; - const bypassCooldown = - itemStorage.get('callQualitySurveyCooldownDisabled') ?? false; + const cqsTestMode = itemStorage.get('cqsTestMode') ?? false; const ourE164 = itemStorage.user.getNumber(); if ( @@ -347,7 +346,7 @@ function maybeShowCallQualitySurvey( lastSurveyTime, lastFailureSurveyTime, e164: ourE164, - bypassCooldown, + cqsTestMode, }) ) { return; diff --git a/ts/state/smart/Preferences.preload.tsx b/ts/state/smart/Preferences.preload.tsx index bebe658e8f..c5d89646eb 100644 --- a/ts/state/smart/Preferences.preload.tsx +++ b/ts/state/smart/Preferences.preload.tsx @@ -758,11 +758,10 @@ export function SmartPreferences(): React.JSX.Element | null { [] ); - const callQualitySurveyCooldownDisabled = - items.callQualitySurveyCooldownDisabled ?? false; + const cqsTestMode = items.cqsTestMode ?? false; - const setCallQualitySurveyCooldownDisabled = useCallback((value: boolean) => { - drop(itemStorage.put('callQualitySurveyCooldownDisabled', value)); + const setCqsTestMode = useCallback((value: boolean) => { + drop(itemStorage.put('cqsTestMode', value)); }, []); if (currentLocation.tab !== NavTab.Settings) { @@ -970,10 +969,8 @@ export function SmartPreferences(): React.JSX.Element | null { __dangerouslyRunAbitraryReadOnlySqlQuery={ __dangerouslyRunAbitraryReadOnlySqlQuery } - callQualitySurveyCooldownDisabled={callQualitySurveyCooldownDisabled} - setCallQualitySurveyCooldownDisabled={ - setCallQualitySurveyCooldownDisabled - } + cqsTestMode={cqsTestMode} + setCqsTestMode={setCqsTestMode} /> diff --git a/ts/types/Storage.d.ts b/ts/types/Storage.d.ts index c2c8328f4e..ec32d30a31 100644 --- a/ts/types/Storage.d.ts +++ b/ts/types/Storage.d.ts @@ -69,7 +69,7 @@ export type StorageAccessType = { 'call-system-notification': boolean; lastCallQualitySurveyTime: number; lastCallQualityFailureSurveyTime: number; - callQualitySurveyCooldownDisabled: boolean; + cqsTestMode: boolean; 'hide-menu-bar': boolean; 'incoming-call-notification': boolean; 'notification-draw-attention': boolean; @@ -294,6 +294,7 @@ export type StorageAccessType = { versionedExpirationTimer: never; primarySendsSms: never; backupMediaDownloadIdle: never; + callQualitySurveyCooldownDisabled: never; }; export type StorageInterface = { diff --git a/ts/util/callQualitySurvey.dom.ts b/ts/util/callQualitySurvey.dom.ts index 41ef97380f..a214b0cba3 100644 --- a/ts/util/callQualitySurvey.dom.ts +++ b/ts/util/callQualitySurvey.dom.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: AGPL-3.0-only import type { CallSummary } from '@signalapp/ringrtc'; -import { DAY, MINUTE } from './durations/index.std.js'; +import { DAY, SECOND } from './durations/index.std.js'; import { isFeaturedEnabledNoRedux } from './isFeatureEnabled.dom.js'; import { isMockEnvironment } from '../environment.std.js'; import { @@ -23,8 +23,7 @@ const FAILURE_END_REASONS: ReadonlySet = new Set([ ]); const SURVEY_COOLDOWN = DAY; -const SHORT_CALL_THRESHOLD = MINUTE; -const LONG_CALL_THRESHOLD = 25 * MINUTE; +const TEST_SHORT_CALL_THRESHOLD = 30 * SECOND; const DEFAULT_PPM = 10000; // 1% default export function isCallFailure(callEndReasonText: string): boolean { @@ -43,13 +42,13 @@ export function shouldShowCallQualitySurvey({ lastSurveyTime, lastFailureSurveyTime, e164, - bypassCooldown, + cqsTestMode, }: { callSummary: CallSummary; lastSurveyTime: number | null; lastFailureSurveyTime: number | null; e164: string | undefined; - bypassCooldown?: boolean; + cqsTestMode?: boolean; }): boolean { if ( isMockEnvironment() || @@ -63,7 +62,7 @@ export function shouldShowCallQualitySurvey({ const isFailure = isCallFailure(callSummary.callEndReasonText); const canShowFailureSurvey = - bypassCooldown || + cqsTestMode || lastFailureSurveyTime == null || now - lastFailureSurveyTime > SURVEY_COOLDOWN; if (isFailure && canShowFailureSurvey) { @@ -71,7 +70,7 @@ export function shouldShowCallQualitySurvey({ } const canShowGeneralSurvey = - bypassCooldown || + cqsTestMode || lastSurveyTime == null || now - lastSurveyTime > SURVEY_COOLDOWN; if (!canShowGeneralSurvey) { @@ -80,11 +79,7 @@ export function shouldShowCallQualitySurvey({ const callDuration = callSummary.endTime - callSummary.startTime; - if (callDuration < SHORT_CALL_THRESHOLD) { - return true; - } - - if (callDuration > LONG_CALL_THRESHOLD) { + if (cqsTestMode && callDuration < TEST_SHORT_CALL_THRESHOLD) { return true; }