diff --git a/apps/webapp/src/i18n/en-US.json b/apps/webapp/src/i18n/en-US.json index a434345d77c..54df42aa667 100644 --- a/apps/webapp/src/i18n/en-US.json +++ b/apps/webapp/src/i18n/en-US.json @@ -1728,12 +1728,6 @@ "preferencesOptionsEmojiReplaceDetail": ":-) → [icon]", "preferencesOptionsEnableAgcCheckbox": "Automatic gain control (AGC)", "preferencesOptionsEnableAgcDetails": "Enable to allow your microphone volume to be adjusted automatically to ensure all participants in a call are heard with similar and comfortable loudness.", - "preferencesOptionsEnableHardwareAcceleration": "Hardware acceleration", - "preferencesOptionsEnableHardwareAccelerationDetails": "This improves stability and video performance while reducing CPU usage. If you change the setting, you need to restart the app.", - "preferencesOptionsEnableHardwareAccelerationModalCancel": "Cancel", - "preferencesOptionsEnableHardwareAccelerationModalMessage": "To update the hardware acceleration setting, you need to restart the app.", - "preferencesOptionsEnableHardwareAccelerationModalOk": "Restart App", - "preferencesOptionsEnableHardwareAccelerationModalTitle": "Restart app", "preferencesOptionsEnablePressSpaceToUnmute": "Unmute with space bar", "preferencesOptionsEnablePressSpaceToUnmuteDetails": "Enable to unmute your microphone by pressing and holding the space bar as long as you want to speak. You can use this option in full view.", "preferencesOptionsEnableSoundlessIncomingCalls": "Silence other calls", diff --git a/apps/webapp/src/script/Config.ts b/apps/webapp/src/script/Config.ts index 505bf080663..ed795f59b73 100644 --- a/apps/webapp/src/script/Config.ts +++ b/apps/webapp/src/script/Config.ts @@ -24,6 +24,7 @@ import {Runtime} from '@wireapp/commons'; import {createUuid} from 'Util/uuid'; import packageJson from '../../package.json'; + const env = window.wire.env; export const ACCENT_ID = { @@ -121,13 +122,6 @@ const Config = { return window.desktopAppConfig; }, - getDesktopSettings: () => { - if (!Runtime.isDesktopApp()) { - return undefined; - } - - return window.desktopAppSettings; - }, }; export {Config}; diff --git a/apps/webapp/src/script/page/MainContent/panels/preferences/avPreferences/CallOptions.tsx b/apps/webapp/src/script/page/MainContent/panels/preferences/avPreferences/CallOptions.tsx index 917db86847c..a1836c50a57 100644 --- a/apps/webapp/src/script/page/MainContent/panels/preferences/avPreferences/CallOptions.tsx +++ b/apps/webapp/src/script/page/MainContent/panels/preferences/avPreferences/CallOptions.tsx @@ -22,11 +22,9 @@ import {ChangeEvent, useCallback, useEffect, useRef, useState} from 'react'; import type {WebappProperties} from '@wireapp/api-client/lib/user/data/'; import {amplify} from 'amplify'; -import {Runtime} from '@wireapp/commons'; import {Checkbox, CheckboxLabel} from '@wireapp/react-ui-kit'; import {WebAppEvents} from '@wireapp/webapp-events'; -import {PrimaryModal} from 'Components/Modals/PrimaryModal'; import type {MediaConstraintsHandler} from 'Repositories/media/MediaConstraintsHandler'; import type {PropertiesRepository} from 'Repositories/properties/propertiesRepository'; import {PROPERTIES_TYPE} from 'Repositories/properties/propertiesType'; @@ -56,20 +54,6 @@ const CallOptions = ({constraintsHandler, propertiesRepository}: CallOptionsProp !!propertiesRepository.properties.settings.call.enable_press_space_to_unmute, ); - const hardwareAccelerationDescriptionId = 'status-preference-hardware-acceleration-description'; - - const desktopSettings = Config.getDesktopSettings(); - - const isHardwareAccelerationChangeable = Runtime.isDesktopApp() && !!desktopSettings; - - const [isHardwareAccelerationEnabled, setIsHardwareAccelerationEnabled] = useState(() => { - if (!isHardwareAccelerationChangeable) { - return true; // default in browser (but not changeable) - } - - return desktopSettings.isHardwareAccelerationEnabled(); - }); - useEffect(() => { const updateProperties = ({settings}: WebappProperties) => { setVbrEncoding(!isCbrEncodingEnforced && settings.call.enable_vbr_encoding); @@ -118,33 +102,6 @@ const CallOptions = ({constraintsHandler, propertiesRepository}: CallOptionsProp [propertiesRepository], ); - const showHardwareAccelerationRestartModal = () => { - PrimaryModal.show(PrimaryModal.type.CONFIRM, { - size: 'large', - primaryAction: { - action: confirmHardwareAccelerationChange, - text: t('preferencesOptionsEnableHardwareAccelerationModalOk'), - }, - text: { - message: t('preferencesOptionsEnableHardwareAccelerationModalMessage'), - title: t('preferencesOptionsEnableHardwareAccelerationModalTitle'), - }, - }); - }; - - const confirmHardwareAccelerationChange = () => { - if (!desktopSettings) { - return; - } - - const currentHwValue = desktopSettings.isHardwareAccelerationEnabled(); - - desktopSettings.setHardwareAccelerationEnabled(!currentHwValue); - setIsHardwareAccelerationEnabled(!currentHwValue); - - amplify.publish(WebAppEvents.LIFECYCLE.RESTART); - }; - return (
@@ -196,25 +153,6 @@ const CallOptions = ({constraintsHandler, propertiesRepository}: CallOptionsProp

)} - - {isHardwareAccelerationChangeable && ( -
- - - {t('preferencesOptionsEnableHardwareAcceleration')} - - -

- {t('preferencesOptionsEnableHardwareAccelerationDetails')} -

-
- )}
); }; diff --git a/apps/webapp/src/script/page/MainContent/panels/preferences/avPreferences/callOptions.test.tsx b/apps/webapp/src/script/page/MainContent/panels/preferences/avPreferences/callOptions.test.tsx deleted file mode 100644 index 85da15ceba6..00000000000 --- a/apps/webapp/src/script/page/MainContent/panels/preferences/avPreferences/callOptions.test.tsx +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Wire - * Copyright (C) 2026 Wire Swiss GmbH - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - * - */ - -import {act, fireEvent, render} from '@testing-library/react'; -import {amplify} from 'amplify'; - -import {Runtime} from '@wireapp/commons'; -import {WebAppEvents} from '@wireapp/webapp-events'; - -import {PrimaryModal} from 'Components/Modals/PrimaryModal'; -import type {MediaConstraintsHandler} from 'Repositories/media/MediaConstraintsHandler'; -import type {PropertiesRepository} from 'Repositories/properties/propertiesRepository'; -import {withTheme} from 'src/script/auth/util/test/TestUtil'; - -import {CallOptions} from './CallOptions'; - -import {Config} from '../../../../../Config'; - -jest.mock('Util/localizerUtil', () => ({ - t: (key: string) => key, -})); - -type DesktopSettingsMock = { - isHardwareAccelerationEnabled: jest.Mock; - setHardwareAccelerationEnabled: jest.Mock; -}; - -type PrimaryModalOptions = Parameters[1]; - -const mockDesktopSettings = (hwEnabled: boolean): DesktopSettingsMock => ({ - isHardwareAccelerationEnabled: jest.fn().mockReturnValue(hwEnabled), - setHardwareAccelerationEnabled: jest.fn(), -}); - -const getDefaultProps = () => { - const constraintsHandler = { - getAgcPreference: jest.fn().mockReturnValue(false), - setAgcPreference: jest.fn(), - } as unknown as MediaConstraintsHandler; - - const propertiesRepository = { - properties: { - settings: { - call: { - enable_vbr_encoding: false, - enable_soundless_incoming_calls: false, - enable_press_space_to_unmute: false, - }, - }, - } as PropertiesRepository['properties'], - savePreference: jest.fn(), - } as unknown as PropertiesRepository; - - return { - constraintsHandler, - propertiesRepository, - }; -}; - -const setupDesktop = (hwEnabled: boolean): DesktopSettingsMock => { - const desktopSettings = mockDesktopSettings(hwEnabled); - jest.spyOn(Runtime, 'isDesktopApp').mockReturnValue(true); - jest - .spyOn(Config, 'getDesktopSettings') - .mockReturnValue(desktopSettings as ReturnType); - return desktopSettings; -}; - -beforeEach(() => { - jest.restoreAllMocks(); - - jest.spyOn(Config, 'getConfig').mockReturnValue({ - FEATURE: { - ENFORCE_CONSTANT_BITRATE: false, - ENABLE_PRESS_SPACE_TO_UNMUTE: false, - }, - } as ReturnType); -}); - -describe('CallOptions — hardware acceleration checkbox', () => { - it('is not shown in a browser (non-desktop)', () => { - jest.spyOn(Runtime, 'isDesktopApp').mockReturnValue(false); - jest.spyOn(Config, 'getDesktopSettings').mockReturnValue(undefined); - - const {queryByTestId} = render(withTheme()); - - expect(queryByTestId('status-preference-hardware-acceleration')).toBeNull(); - }); - - it('is not shown when desktopSettings is null even on desktop', () => { - jest.spyOn(Runtime, 'isDesktopApp').mockReturnValue(true); - jest.spyOn(Config, 'getDesktopSettings').mockReturnValue(undefined); - - const {queryByTestId} = render(withTheme()); - - expect(queryByTestId('status-preference-hardware-acceleration')).toBeNull(); - }); - - it('is shown and checked when hardware acceleration is enabled', () => { - setupDesktop(true); - - const {getByTestId} = render(withTheme()); - const checkbox = getByTestId('status-preference-hardware-acceleration') as HTMLInputElement; - - expect(checkbox.checked).toBe(true); - }); - - it('is shown and unchecked when hardware acceleration is disabled', () => { - setupDesktop(false); - - const {getByTestId} = render(withTheme()); - const checkbox = getByTestId('status-preference-hardware-acceleration') as HTMLInputElement; - - expect(checkbox.checked).toBe(false); - }); - - it('opens a confirmation modal when the checkbox is clicked without immediately applying the change', () => { - const desktopSettings = setupDesktop(true); - const showModalSpy = jest.spyOn(PrimaryModal, 'show').mockImplementation(() => {}); - - const {getByTestId} = render(withTheme()); - fireEvent.click(getByTestId('status-preference-hardware-acceleration')); - - expect(showModalSpy).toHaveBeenCalledTimes(1); - expect(showModalSpy).toHaveBeenCalledWith( - PrimaryModal.type.CONFIRM, - expect.objectContaining({ - primaryAction: expect.objectContaining({action: expect.any(Function)}), - }), - ); - expect(desktopSettings.setHardwareAccelerationEnabled).not.toHaveBeenCalled(); - }); - - it('does not publish a restart event when the modal is merely opened', () => { - setupDesktop(true); - jest.spyOn(PrimaryModal, 'show').mockImplementation(() => {}); - const publishSpy = jest.spyOn(amplify, 'publish'); - - const {getByTestId} = render(withTheme()); - fireEvent.click(getByTestId('status-preference-hardware-acceleration')); - - expect(publishSpy).not.toHaveBeenCalledWith(WebAppEvents.LIFECYCLE.RESTART); - }); - - it('disables hardware acceleration and triggers restart when confirmed', () => { - const desktopSettings = setupDesktop(true); - let capturedAction: (() => void) | undefined; - - jest.spyOn(PrimaryModal, 'show').mockImplementation((_type, options: PrimaryModalOptions) => { - const primaryAction = options?.primaryAction; - if (primaryAction && 'action' in primaryAction && typeof primaryAction.action === 'function') { - capturedAction = primaryAction.action as () => void; - } - }); - - const publishSpy = jest.spyOn(amplify, 'publish'); - - const {getByTestId} = render(withTheme()); - fireEvent.click(getByTestId('status-preference-hardware-acceleration')); - - expect(capturedAction).toBeDefined(); - act(() => capturedAction?.()); - - expect(desktopSettings.setHardwareAccelerationEnabled).toHaveBeenCalledWith(false); - expect(publishSpy).toHaveBeenCalledWith(WebAppEvents.LIFECYCLE.RESTART); - - const checkbox = getByTestId('status-preference-hardware-acceleration') as HTMLInputElement; - expect(checkbox.checked).toBe(false); - }); - - it('enables hardware acceleration and triggers restart when confirmed', () => { - const desktopSettings = setupDesktop(false); - let capturedAction: (() => void) | undefined; - - jest.spyOn(PrimaryModal, 'show').mockImplementation((_type, options: PrimaryModalOptions) => { - const primaryAction = options?.primaryAction; - if (primaryAction && 'action' in primaryAction && typeof primaryAction.action === 'function') { - capturedAction = primaryAction.action as () => void; - } - }); - - const publishSpy = jest.spyOn(amplify, 'publish'); - - const {getByTestId} = render(withTheme()); - fireEvent.click(getByTestId('status-preference-hardware-acceleration')); - - expect(capturedAction).toBeDefined(); - act(() => capturedAction?.()); - - expect(desktopSettings.setHardwareAccelerationEnabled).toHaveBeenCalledWith(true); - expect(publishSpy).toHaveBeenCalledWith(WebAppEvents.LIFECYCLE.RESTART); - - const checkbox = getByTestId('status-preference-hardware-acceleration') as HTMLInputElement; - expect(checkbox.checked).toBe(true); - }); - - it('makes no changes when the confirmation modal is dismissed', () => { - const desktopSettings = setupDesktop(true); - jest.spyOn(PrimaryModal, 'show').mockImplementation(() => {}); - const publishSpy = jest.spyOn(amplify, 'publish'); - - const {getByTestId} = render(withTheme()); - fireEvent.click(getByTestId('status-preference-hardware-acceleration')); - - expect(desktopSettings.setHardwareAccelerationEnabled).not.toHaveBeenCalled(); - expect(publishSpy).not.toHaveBeenCalledWith(WebAppEvents.LIFECYCLE.RESTART); - - const checkbox = getByTestId('status-preference-hardware-acceleration') as HTMLInputElement; - expect(checkbox.checked).toBe(true); - }); -}); diff --git a/apps/webapp/src/script/repositories/conversation/linkPreviews/index.ts b/apps/webapp/src/script/repositories/conversation/linkPreviews/index.ts index 132f4cbe2e3..6a1491f9bf2 100644 --- a/apps/webapp/src/script/repositories/conversation/linkPreviews/index.ts +++ b/apps/webapp/src/script/repositories/conversation/linkPreviews/index.ts @@ -52,10 +52,6 @@ declare global { interface Window { openGraphAsync?: (url: string) => Promise; desktopAppConfig?: {version: string; supportsCallingPopoutWindow?: boolean}; - desktopAppSettings?: { - setHardwareAccelerationEnabled: (enabled: boolean) => void; - isHardwareAccelerationEnabled: () => boolean; - }; } } const logger = getLogger('LinkPreviewRepository'); diff --git a/apps/webapp/src/types/i18n.d.ts b/apps/webapp/src/types/i18n.d.ts index 4f45efda108..ae4ac474e39 100644 --- a/apps/webapp/src/types/i18n.d.ts +++ b/apps/webapp/src/types/i18n.d.ts @@ -1732,12 +1732,6 @@ declare module 'I18n/en-US.json' { 'preferencesOptionsEmojiReplaceDetail': `:-) → [icon]`; 'preferencesOptionsEnableAgcCheckbox': `Automatic gain control (AGC)`; 'preferencesOptionsEnableAgcDetails': `Enable to allow your microphone volume to be adjusted automatically to ensure all participants in a call are heard with similar and comfortable loudness.`; - 'preferencesOptionsEnableHardwareAcceleration': `Hardware acceleration`; - 'preferencesOptionsEnableHardwareAccelerationDetails': `This improves stability and video performance while reducing CPU usage. If you change the setting, you need to restart the app.`; - 'preferencesOptionsEnableHardwareAccelerationModalCancel': `Cancel`; - 'preferencesOptionsEnableHardwareAccelerationModalMessage': `To update the hardware acceleration setting, you need to restart the app.`; - 'preferencesOptionsEnableHardwareAccelerationModalOk': `Restart App`; - 'preferencesOptionsEnableHardwareAccelerationModalTitle': `Restart app`; 'preferencesOptionsEnablePressSpaceToUnmute': `Unmute with space bar`; 'preferencesOptionsEnablePressSpaceToUnmuteDetails': `Enable to unmute your microphone by pressing and holding the space bar as long as you want to speak. You can use this option in full view.`; 'preferencesOptionsEnableSoundlessIncomingCalls': `Silence other calls`;