diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 5d0e5130dc..2840b419ad 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -10086,10 +10086,6 @@ "messageformat": "This helps us learn more about calls and what is working or not working. You can view your debug log before submitting.", "description": "Call Quality Survey Dialog > Help us improve > Page Description" }, - "icu:CallQualitySurvey__ConfirmSubmission__PageDescriptionWithDiagnosticLink": { - "messageformat": "Submitting will share your feedback along with diagnostic information about your call. You can optionally share a debug log to help us improve call quality.", - "description": "Call Quality Survey Dialog > Help us improve > Page Description with link to view diagnostic info" - }, "icu:CallQualitySurvey__ConfirmSubmission__ShareDebugLog__Label": { "messageformat": "Share debug log", "description": "Call Quality Survey Dialog > Help us improve > Share debug log > Label" @@ -10102,14 +10098,6 @@ "messageformat": "Debug logs contain low level app information and do not reveal any of your message contents.", "description": "Call Quality Survey Dialog > Help us improve > Share debug log > Help Text" }, - "icu:CallQualitySurvey__ConfirmSubmission__PrivacyNote": { - "messageformat": "Information shared with us contains low level app information and does not include the contents of your calls.", - "description": "Call Quality Survey Dialog > Help us improve > Privacy note about what information is shared" - }, - "icu:CallDiagnosticWindow__title": { - "messageformat": "Diagnostic information", - "description": "Title of the call diagnostic information window" - }, "icu:CallQualitySurvey__ConfirmSubmission__SubmitButton": { "messageformat": "Submit", "description": "Call Quality Survey Dialog > Help us improve > Submit Button" diff --git a/app/main.main.ts b/app/main.main.ts index 10ae8d8295..d3ccf9f504 100644 --- a/app/main.main.ts +++ b/app/main.main.ts @@ -1401,28 +1401,16 @@ async function openArtCreator() { } let debugLogWindow: BrowserWindow | undefined; -let debugLogCurrentMode: 'submit' | 'close' | undefined; type DebugLogWindowOptions = { mode?: 'submit' | 'close'; }; async function showDebugLogWindow(options: DebugLogWindowOptions = {}) { - const newMode = options.mode ?? 'submit'; - if (debugLogWindow) { - if (debugLogCurrentMode !== newMode) { - debugLogCurrentMode = newMode; - const url = pathToFileURL(join(__dirname, '../debug_log.html')); - url.searchParams.set('mode', newMode); - await safeLoadURL(debugLogWindow, url.href); - } - doShowDebugLogWindow(); return; } - debugLogCurrentMode = newMode; - function doShowDebugLogWindow() { if (debugLogWindow) { // Electron has [a macOS bug][0] that causes parent windows to become unresponsive @@ -1464,7 +1452,6 @@ async function showDebugLogWindow(options: DebugLogWindowOptions = {}) { debugLogWindow.on('closed', () => { debugLogWindow = undefined; - debugLogCurrentMode = undefined; }); debugLogWindow.once('ready-to-show', () => { @@ -1484,71 +1471,6 @@ async function showDebugLogWindow(options: DebugLogWindowOptions = {}) { await safeLoadURL(debugLogWindow, url.href); } -let callDiagnosticWindow: BrowserWindow | undefined; -let storedCallDiagnosticData: string | undefined; - -async function showCallDiagnosticWindow() { - if (callDiagnosticWindow) { - doShowCallDiagnosticWindow(); - return; - } - - function doShowCallDiagnosticWindow() { - if (callDiagnosticWindow) { - // Electron has [a macOS bug][0] that causes parent windows to become unresponsive - // if it's fullscreen and opens a fullscreen child window. Until that's fixed, we - // only set the parent on MacOS is if the mainWindow is not fullscreen - // [0]: https://github.com/electron/electron/issues/32374 - if (OS.isMacOS() && mainWindow?.isFullScreen()) { - callDiagnosticWindow.setParentWindow(null); - } else { - callDiagnosticWindow.setParentWindow(mainWindow ?? null); - } - callDiagnosticWindow.show(); - } - } - - const windowOptions: Electron.BrowserWindowConstructorOptions = { - width: 700, - height: 500, - resizable: false, - title: getResolvedMessagesLocale().i18n('icu:CallDiagnosticWindow__title'), - titleBarStyle: nonMainTitleBarStyle, - autoHideMenuBar: true, - backgroundColor: await getBackgroundColor(), - show: false, - webPreferences: { - ...defaultWebPrefs, - nodeIntegration: false, - nodeIntegrationInWorker: false, - sandbox: true, - contextIsolation: true, - preload: join(__dirname, '../bundles/calldiagnostic/preload.preload.js'), - }, - parent: mainWindow, - }; - - callDiagnosticWindow = new BrowserWindow(windowOptions); - - await handleCommonWindowEvents(callDiagnosticWindow); - - callDiagnosticWindow.on('closed', () => { - callDiagnosticWindow = undefined; - }); - - callDiagnosticWindow.once('ready-to-show', () => { - if (callDiagnosticWindow) { - doShowCallDiagnosticWindow(); - - // Electron sometimes puts the window in a strange spot until it's shown. - callDiagnosticWindow.center(); - } - }); - - const url = pathToFileURL(join(__dirname, '../call_diagnostic.html')); - await safeLoadURL(callDiagnosticWindow, url.href); -} - let permissionsPopupWindow: BrowserWindow | undefined; function showPermissionsPopupWindow(forCalling: boolean, forCamera: boolean) { // eslint-disable-next-line no-async-promise-executor @@ -2764,35 +2686,6 @@ ipc.on( } ); -// Call Diagnostic Window-related IPC calls - -ipc.on('show-call-diagnostic', () => { - void showCallDiagnosticWindow(); -}); - -ipc.handle('get-call-diagnostic-data', () => { - return storedCallDiagnosticData ?? ''; -}); - -ipc.on('close-call-diagnostic', () => { - storedCallDiagnosticData = undefined; - callDiagnosticWindow?.close(); -}); - -ipc.on('close-debug-log', () => { - if (debugLogCurrentMode === 'close') { - debugLogWindow?.close(); - } -}); - -ipc.on('update-call-diagnostic-data', (_event, diagnosticData: string) => { - storedCallDiagnosticData = diagnosticData; - - if (callDiagnosticWindow && !callDiagnosticWindow.isDestroyed()) { - callDiagnosticWindow.webContents.send('call-diagnostic-data-updated'); - } -}); - // Permissions Popup-related IPC calls ipc.handle( diff --git a/call_diagnostic.html b/call_diagnostic.html deleted file mode 100644 index fa9b2da47b..0000000000 --- a/call_diagnostic.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - -
- - - diff --git a/scripts/esbuild.js b/scripts/esbuild.js index 8b02581be4..4ed3b2ae9e 100644 --- a/scripts/esbuild.js +++ b/scripts/esbuild.js @@ -178,7 +178,6 @@ async function sandboxedEnv() { mainFields: ['browser', 'main'], entryPoints: [ path.join(ROOT_DIR, 'ts', 'windows', 'about', 'app.dom.tsx'), - path.join(ROOT_DIR, 'ts', 'windows', 'calldiagnostic', 'app.dom.tsx'), path.join(ROOT_DIR, 'ts', 'windows', 'debuglog', 'app.dom.tsx'), path.join(ROOT_DIR, 'ts', 'windows', 'loading', 'start.dom.ts'), path.join(ROOT_DIR, 'ts', 'windows', 'permissions', 'app.dom.tsx'), @@ -190,13 +189,6 @@ async function sandboxedEnv() { mainFields: ['browser', 'main'], entryPoints: [ path.join(ROOT_DIR, 'ts', 'windows', 'about', 'preload.preload.ts'), - path.join( - ROOT_DIR, - 'ts', - 'windows', - 'calldiagnostic', - 'preload.preload.ts' - ), path.join(ROOT_DIR, 'ts', 'windows', 'debuglog', 'preload.preload.ts'), path.join(ROOT_DIR, 'ts', 'windows', 'loading', 'preload.preload.ts'), path.join( diff --git a/ts/components/CallDiagnosticWindow.dom.tsx b/ts/components/CallDiagnosticWindow.dom.tsx deleted file mode 100644 index 33d75c069f..0000000000 --- a/ts/components/CallDiagnosticWindow.dom.tsx +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2026 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -import React, { useMemo } from 'react'; - -import type { LocalizerType } from '../types/Util.std.js'; -import { tw } from '../axo/tw.dom.js'; -import { AxoButton } from '../axo/AxoButton.dom.js'; -import { useEscapeHandling } from '../hooks/useEscapeHandling.dom.js'; - -export type PropsType = { - closeWindow: () => unknown; - i18n: LocalizerType; - diagnosticData: string; -}; - -export function CallDiagnosticWindow({ - closeWindow, - i18n, - diagnosticData, -}: PropsType): React.JSX.Element { - useEscapeHandling(closeWindow); - - const formattedData = useMemo(() => { - try { - const parsed = JSON.parse(diagnosticData); - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { rawStats, rawStatsText, ...rest } = parsed; - const pretty = { - ...rest, - rawStats: JSON.parse(rawStatsText), - }; - return JSON.stringify(pretty, null, 2); - } catch { - return diagnosticData; - } - }, [diagnosticData]); - - return ( -
-
-

- {i18n('icu:CallDiagnosticWindow__title')} -

-
-
-
-          {formattedData}
-        
-
-
- - {i18n('icu:close')} - -
-
- ); -} diff --git a/ts/components/CallQualitySurvey.dom.stories.tsx b/ts/components/CallQualitySurvey.dom.stories.tsx index 82a352a5e5..53ee5880c8 100644 --- a/ts/components/CallQualitySurvey.dom.stories.tsx +++ b/ts/components/CallQualitySurvey.dom.stories.tsx @@ -19,8 +19,6 @@ export function Default(): React.JSX.Element { open={open} onOpenChange={setOpen} onSubmit={action('onSubmit')} - onViewDebugLog={action('onViewDebugLog')} - onViewDiagnosticInfo={action('onViewDiagnosticInfo')} /> ); } diff --git a/ts/components/CallQualitySurveyDialog.dom.tsx b/ts/components/CallQualitySurveyDialog.dom.tsx index bc90713ef3..7a9c4dc743 100644 --- a/ts/components/CallQualitySurveyDialog.dom.tsx +++ b/ts/components/CallQualitySurveyDialog.dom.tsx @@ -11,28 +11,9 @@ import { missingCaseError } from '../util/missingCaseError.std.js'; import { AxoCheckbox } from '../axo/AxoCheckbox.dom.js'; import { strictAssert } from '../util/assert.std.js'; import { Tooltip, TooltipPlacement } from './Tooltip.dom.js'; -import { I18n } from './I18n.dom.js'; import Issue = CallQualitySurvey.Issue; -function DiagnosticInfoLink({ - parts, - onClick, -}: { - parts: Array; - onClick: () => void; -}): React.JSX.Element { - return ( - - ); -} - enum Page { HOW_WAS_YOUR_CALL, WHAT_ISSUES_DID_YOU_HAVE, @@ -44,16 +25,14 @@ export type CallQualitySurveyDialogProps = Readonly<{ open: boolean; onOpenChange: (open: boolean) => void; onSubmit: (form: CallQualitySurvey.Form) => void; - onViewDebugLog: () => void; - onViewDiagnosticInfo: () => void; + onViewDebugLog?: () => void; isSubmitting?: boolean; }>; export function CallQualitySurveyDialog( props: CallQualitySurveyDialogProps ): React.JSX.Element { - const { i18n, onSubmit, onViewDebugLog, onViewDiagnosticInfo, isSubmitting } = - props; + const { i18n, onSubmit, onViewDebugLog, isSubmitting } = props; const [page, setPage] = useState(Page.HOW_WAS_YOUR_CALL); const [userSatisfied, setUserSatisfied] = useState(null); @@ -100,20 +79,6 @@ export function CallQualitySurveyDialog( shareDebugLog, ]); - const renderDiagnosticInfoLink = useCallback( - (parts: Array) => ( - - ), - [onViewDiagnosticInfo] - ); - - const diagnosticInfoLinkComponents = useMemo( - () => ({ - diagnosticInfoLink: renderDiagnosticInfoLink, - }), - [renderDiagnosticInfoLink] - ); - return ( @@ -326,11 +291,9 @@ export function CallQualitySurveyDialog(

- + {i18n( + 'icu:CallQualitySurvey__ConfirmSubmission__PageDescription' + )}

@@ -351,7 +314,9 @@ export function CallQualitySurveyDialog( { + onViewDebugLog?.(); + }} > {i18n( 'icu:CallQualitySurvey__ConfirmSubmission__ShareDebugLog__ViewButton' @@ -359,7 +324,9 @@ export function CallQualitySurveyDialog(

- {i18n('icu:CallQualitySurvey__ConfirmSubmission__PrivacyNote')} + {i18n( + 'icu:CallQualitySurvey__ConfirmSubmission__ShareDebugLog__HelpText' + )}

diff --git a/ts/state/ducks/calling.preload.ts b/ts/state/ducks/calling.preload.ts index 7eb44cc586..93cc5cabef 100644 --- a/ts/state/ducks/calling.preload.ts +++ b/ts/state/ducks/calling.preload.ts @@ -103,10 +103,10 @@ import type { ToggleConfirmLeaveCallModalActionType, } from './globalModals.preload.js'; import { + HIDE_CALL_QUALITY_SURVEY, SHOW_CALL_QUALITY_SURVEY, SHOW_ERROR_MODAL, toggleConfirmLeaveCallModal, - hideCallQualitySurvey, } from './globalModals.preload.js'; import { CallQualitySurvey } from '../../types/CallQualitySurvey.std.js'; import { isCallFailure } from '../../util/callQualitySurvey.dom.js'; @@ -2935,9 +2935,6 @@ function showCallQualitySurvey( return dispatch => { dispatch({ type: RESET_CQS_SUBMISSION_STATE }); dispatch({ type: SHOW_CALL_QUALITY_SURVEY, payload }); - - const diagnosticData = JSON.stringify(payload.callSummary); - window.IPC.updateCallDiagnosticData(diagnosticData); }; } @@ -3034,7 +3031,7 @@ function submitCallQualitySurvey( }, }); } finally { - dispatch(hideCallQualitySurvey()); + dispatch({ type: HIDE_CALL_QUALITY_SURVEY }); } }; } diff --git a/ts/state/ducks/globalModals.preload.ts b/ts/state/ducks/globalModals.preload.ts index 14f1f66ea0..200cabdc70 100644 --- a/ts/state/ducks/globalModals.preload.ts +++ b/ts/state/ducks/globalModals.preload.ts @@ -657,16 +657,9 @@ function showCallQualitySurvey( }; } -export function hideCallQualitySurvey(): ThunkAction< - void, - RootStateType, - unknown, - HideCallQualitySurveyActionType -> { - return dispatch => { - window.IPC.closeDebugLog(); - window.IPC.closeCallDiagnostic(); - dispatch({ type: HIDE_CALL_QUALITY_SURVEY }); +function hideCallQualitySurvey(): HideCallQualitySurveyActionType { + return { + type: HIDE_CALL_QUALITY_SURVEY, }; } diff --git a/ts/state/smart/CallQualitySurveyDialog.preload.tsx b/ts/state/smart/CallQualitySurveyDialog.preload.tsx index fc3dcbf490..fe6e7418b0 100644 --- a/ts/state/smart/CallQualitySurveyDialog.preload.tsx +++ b/ts/state/smart/CallQualitySurveyDialog.preload.tsx @@ -52,10 +52,6 @@ export const SmartCallQualitySurveyDialog = memo( [submitCallQualitySurvey, callSummary, callType] ); - const handleViewDiagnosticInfo = useCallback(() => { - window.IPC.showCallDiagnostic(); - }, []); - return ( window.IPC.showDebugLog({ mode: 'close' })} - onViewDiagnosticInfo={handleViewDiagnosticInfo} isSubmitting={isSubmitting} /> ); diff --git a/ts/window.d.ts b/ts/window.d.ts index 1c1d00b0fc..bbd2ea4de7 100644 --- a/ts/window.d.ts +++ b/ts/window.d.ts @@ -55,10 +55,6 @@ export type IPCType = { setMediaCameraPermissions: (value: boolean) => Promise; setMenuBarVisibility: (value: boolean) => void; showDebugLog: (options?: { mode?: 'submit' | 'close' }) => void; - showCallDiagnostic: () => void; - closeCallDiagnostic: () => void; - closeDebugLog: () => void; - updateCallDiagnosticData: (data: string) => void; showPermissionsPopup: ( forCalling: boolean, forCamera: boolean @@ -95,11 +91,6 @@ type DebugLogWindowPropsType = { mode: 'submit' | 'close'; }; -type CallDiagnosticWindowPropsType = { - subscribe: (listener: () => void) => () => void; - getSnapshot: () => string | null; -}; - type PermissionsWindowPropsType = { forCamera: boolean; forCalling: boolean; @@ -122,7 +113,6 @@ type SettingsWindowPropsType = { export type SignalCoreType = { AboutWindowProps?: AboutWindowPropsType; - CallDiagnosticWindowProps?: CallDiagnosticWindowPropsType; DebugLogWindowProps?: DebugLogWindowPropsType; PermissionsWindowProps?: PermissionsWindowPropsType; ScreenShareWindowProps?: ScreenShareWindowPropsType; diff --git a/ts/windows/calldiagnostic/app.dom.tsx b/ts/windows/calldiagnostic/app.dom.tsx deleted file mode 100644 index d564b13dd2..0000000000 --- a/ts/windows/calldiagnostic/app.dom.tsx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2026 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -import React, { StrictMode, useSyncExternalStore } from 'react'; -import { createRoot } from 'react-dom/client'; -import '../sandboxedInit.dom.js'; -import { CallDiagnosticWindow } from '../../components/CallDiagnosticWindow.dom.js'; -import { FunDefaultEnglishEmojiLocalizationProvider } from '../../components/fun/FunEmojiLocalizationProvider.dom.js'; -import { strictAssert } from '../../util/assert.std.js'; -import { AxoProvider } from '../../axo/AxoProvider.dom.js'; - -const { CallDiagnosticWindowProps } = window.Signal; -strictAssert(CallDiagnosticWindowProps, 'window values not provided'); -const { subscribe, getSnapshot } = CallDiagnosticWindowProps; -const { i18n } = window.SignalContext; - -function App(): React.JSX.Element | null { - const diagnosticData = useSyncExternalStore(subscribe, getSnapshot); - - if (diagnosticData == null) { - return null; - } - - return ( - window.SignalContext.executeMenuRole('close')} - i18n={i18n} - diagnosticData={diagnosticData} - /> - ); -} - -const app = document.getElementById('app'); -strictAssert(app != null, 'No #app'); - -createRoot(app).render( - - - - - - - -); diff --git a/ts/windows/calldiagnostic/preload.preload.ts b/ts/windows/calldiagnostic/preload.preload.ts deleted file mode 100644 index d7c9bd8783..0000000000 --- a/ts/windows/calldiagnostic/preload.preload.ts +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2026 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -import { contextBridge, ipcRenderer } from 'electron'; -import { MinimalSignalContext } from '../minimalContext.preload.js'; - -// External store for useSyncExternalStore -let currentData: string | null = null; -const listeners = new Set<() => void>(); - -async function fetchData(): Promise { - currentData = await ipcRenderer.invoke('get-call-diagnostic-data'); - listeners.forEach(listener => listener()); -} - -ipcRenderer.on('call-diagnostic-data-updated', () => { - void fetchData(); -}); - -function subscribe(listener: () => void): () => void { - listeners.add(listener); - return () => listeners.delete(listener); -} - -function getSnapshot(): string | null { - return currentData; -} - -void fetchData(); - -const Signal = { - CallDiagnosticWindowProps: { - subscribe, - getSnapshot, - }, -}; -contextBridge.exposeInMainWorld('Signal', Signal); -contextBridge.exposeInMainWorld('SignalContext', MinimalSignalContext); diff --git a/ts/windows/main/phase1-ipc.preload.ts b/ts/windows/main/phase1-ipc.preload.ts index ab09211a97..2eed5c118f 100644 --- a/ts/windows/main/phase1-ipc.preload.ts +++ b/ts/windows/main/phase1-ipc.preload.ts @@ -133,19 +133,6 @@ const IPC: IPCType = { log.info('showDebugLog', options); ipc.send('show-debug-log', options); }, - showCallDiagnostic: () => { - log.info('showCallDiagnostic'); - ipc.send('show-call-diagnostic'); - }, - closeCallDiagnostic: () => { - ipc.send('close-call-diagnostic'); - }, - closeDebugLog: () => { - ipc.send('close-debug-log'); - }, - updateCallDiagnosticData: (data: string) => { - ipc.send('update-call-diagnostic-data', data); - }, showPermissionsPopup: (forCalling, forCamera) => ipc.invoke('show-permissions-popup', forCalling, forCamera), setMediaPermissions: (value: boolean) =>