) : null}
+ {shouldShowMediaProgress && backupMediaDownloadStatus ? (
+
+
+
+ ) : null}
) : null}
>
diff --git a/ts/components/conversation/ChatSessionRefreshedNotification.tsx b/ts/components/conversation/ChatSessionRefreshedNotification.tsx
index d0f91e5f68..4c4733d661 100644
--- a/ts/components/conversation/ChatSessionRefreshedNotification.tsx
+++ b/ts/components/conversation/ChatSessionRefreshedNotification.tsx
@@ -10,7 +10,6 @@ import { Button, ButtonSize, ButtonVariant } from '../Button';
import { SystemMessage } from './SystemMessage';
import { ChatSessionRefreshedDialog } from './ChatSessionRefreshedDialog';
import { openLinkInWebBrowser } from '../../util/openLinkInWebBrowser';
-import { getLocalizedUrl } from '../../util/getLocalizedUrl';
type PropsHousekeepingType = {
i18n: LocalizerType;
@@ -34,9 +33,8 @@ export function ChatSessionRefreshedNotification(
const wrappedContactSupport = useCallback(() => {
setIsDialogOpen(false);
- const url = getLocalizedUrl(
- 'https://support.signal.org/hc/LOCALE/requests/new?desktop&chat_refreshed'
- );
+ const url =
+ 'https://support.signal.org/hc/requests/new?desktop&chat_refreshed';
openLinkInWebBrowser(url);
}, [setIsDialogOpen]);
diff --git a/ts/components/conversation/conversation-details/ConversationDetails.tsx b/ts/components/conversation/conversation-details/ConversationDetails.tsx
index fafc24b12c..d5614a2924 100644
--- a/ts/components/conversation/conversation-details/ConversationDetails.tsx
+++ b/ts/components/conversation/conversation-details/ConversationDetails.tsx
@@ -15,7 +15,6 @@ import type { SmartChooseGroupMembersModalPropsType } from '../../../state/smart
import type { SmartConfirmAdditionsModalPropsType } from '../../../state/smart/ConfirmAdditionsModal';
import { assertDev } from '../../../util/assert';
import { getMutedUntilText } from '../../../util/getMutedUntilText';
-import { getLocalizedUrl } from '../../../util/getLocalizedUrl';
import type { LocalizerType, ThemeType } from '../../../types/Util';
import type { BadgeType } from '../../../badges/types';
@@ -521,9 +520,7 @@ export function ConversationDetails({
}
label={i18n('icu:ConversationDetails--support-center')}
onClick={() => {
- openLinkInWebBrowser(
- getLocalizedUrl('https://support.signal.org/hc/LOCALE')
- );
+ openLinkInWebBrowser('https://support.signal.org');
}}
/>
{
openLinkInWebBrowser(
- getLocalizedUrl(
- 'https://support.signal.org/hc/LOCALE/requests/new?desktop'
- )
+ 'https://support.signal.org/hc/requests/new?desktop'
);
}}
/>
diff --git a/ts/state/smart/Preferences.tsx b/ts/state/smart/Preferences.tsx
index a9820765b3..b5652c14ae 100644
--- a/ts/state/smart/Preferences.tsx
+++ b/ts/state/smart/Preferences.tsx
@@ -79,6 +79,11 @@ import type { WidthBreakpoint } from '../../components/_util';
import { DialogType } from '../../types/Dialogs';
import { promptOSAuth } from '../../util/promptOSAuth';
import type { StateType } from '../reducer';
+import {
+ pauseBackupMediaDownload,
+ resumeBackupMediaDownload,
+ cancelBackupMediaDownload,
+} from '../../util/backupMediaDownload';
const DEFAULT_NOTIFICATION_SETTING = 'message';
@@ -490,8 +495,15 @@ export function SmartPreferences(): JSX.Element | null {
// Simple, one-way items
- const { backupSubscriptionStatus, cloudBackupStatus, localBackupFolder } =
- items;
+ const {
+ backupSubscriptionStatus,
+ cloudBackupStatus,
+ localBackupFolder,
+ backupMediaDownloadCompletedBytes,
+ backupMediaDownloadTotalBytes,
+ attachmentDownloadManagerIdled,
+ backupMediaDownloadPaused,
+ } = items;
const defaultConversationColor =
items.defaultConversationColor || DEFAULT_CONVERSATION_COLOR;
const hasLinkPreviews = items.linkPreviews ?? false;
@@ -712,6 +724,12 @@ export function SmartPreferences(): JSX.Element | null {
backupFeatureEnabled={backupFeatureEnabled}
backupKeyViewed={backupKeyViewed}
backupSubscriptionStatus={backupSubscriptionStatus ?? { status: 'off' }}
+ backupMediaDownloadStatus={{
+ completedBytes: backupMediaDownloadCompletedBytes ?? 0,
+ totalBytes: backupMediaDownloadTotalBytes ?? 0,
+ isPaused: Boolean(backupMediaDownloadPaused),
+ isIdle: Boolean(attachmentDownloadManagerIdled),
+ }}
backupLocalBackupsEnabled={backupLocalBackupsEnabled}
badge={badge}
blockedCount={blockedCount}
@@ -837,6 +855,9 @@ export function SmartPreferences(): JSX.Element | null {
resetDefaultChatColor={resetDefaultChatColor}
resolvedLocale={resolvedLocale}
savePreferredLeftPaneWidth={savePreferredLeftPaneWidth}
+ resumeBackupMediaDownload={resumeBackupMediaDownload}
+ pauseBackupMediaDownload={pauseBackupMediaDownload}
+ cancelBackupMediaDownload={cancelBackupMediaDownload}
selectedCamera={selectedCamera}
selectedMicrophone={selectedMicrophone}
selectedSpeaker={selectedSpeaker}
diff --git a/ts/types/backups.ts b/ts/types/backups.ts
index 3bf80b64cb..898a78cb0f 100644
--- a/ts/types/backups.ts
+++ b/ts/types/backups.ts
@@ -40,6 +40,13 @@ export type BackupStatusType = {
protoSize?: number;
};
+export type BackupMediaDownloadStatusType = {
+ totalBytes: number;
+ completedBytes: number;
+ isPaused: boolean;
+ isIdle: boolean;
+};
+
export type BackupsSubscriptionType =
| {
status: 'off' | 'not-found' | 'expired';
diff --git a/ts/util/getLocalizedUrl.ts b/ts/util/getLocalizedUrl.ts
deleted file mode 100644
index 6c2c6771fa..0000000000
--- a/ts/util/getLocalizedUrl.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2025 Signal Messenger, LLC
-// SPDX-License-Identifier: AGPL-3.0-only
-
-import { mapToSupportLocale } from './mapToSupportLocale';
-
-/**
- * Ensures the provided string contains "LOCALE".
- * If not, produces a readable TypeScript error.
- */
-type RequiresLocale = T extends `${string}LOCALE${string}`
- ? T
- : `Error: The URL must contain "LOCALE" but got "${T}"`;
-
-/**
- * Replaces "LOCALE" in a URL with the appropriate localized support locale.
- *
- * @param url The URL string containing "LOCALE" to be replaced
- * @returns The URL with "LOCALE" replaced with the appropriate locale
- */
-export function getLocalizedUrl(
- url: RequiresLocale
-): string {
- const locale = window.SignalContext.getResolvedMessagesLocale();
- const supportLocale = mapToSupportLocale(locale);
- return url.replace('LOCALE', supportLocale);
-}
diff --git a/ts/util/mapToSupportLocale.ts b/ts/util/mapToSupportLocale.ts
deleted file mode 100644
index b3cf41032b..0000000000
--- a/ts/util/mapToSupportLocale.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2021 Signal Messenger, LLC
-// SPDX-License-Identifier: AGPL-3.0-only
-
-export type SupportLocaleType =
- | 'ar'
- | 'de'
- | 'en-us'
- | 'es'
- | 'fr'
- | 'it'
- | 'ja'
- | 'pl'
- | 'pt-br'
- | 'ru'
- | 'sq'
- | 'zh-tw';
-
-// See https://source.chromium.org/chromium/chromium/src/+/main:ui/base/l10n/l10n_util.cc
-export type ElectronLocaleType =
- | 'af'
- | 'ar'
- | 'bg'
- | 'bn'
- | 'ca'
- | 'cs'
- | 'cy'
- | 'da'
- | 'de'
- | 'de-AT'
- | 'de-CH'
- | 'de-DE'
- | 'de-LI'
- | 'el'
- | 'en'
- | 'en-AU'
- | 'en-CA'
- | 'en-GB'
- | 'en-GB-oxendict'
- | 'en-IN'
- | 'en-NZ'
- | 'en-US'
- | 'eo'
- | 'es'
- | 'es-419'
- | 'et'
- | 'eu'
- | 'fa'
- | 'fi'
- | 'fr'
- | 'fr-CA'
- | 'fr-CH'
- | 'fr-FR'
- | 'he'
- | 'hi'
- | 'hr'
- | 'hu'
- | 'id'
- | 'it'
- | 'it-CH'
- | 'it-IT'
- | 'ja'
- | 'km'
- | 'kn'
- | 'ko'
- | 'lt'
- | 'mk'
- | 'mr'
- | 'ms'
- | 'nb'
- | 'nl'
- | 'nn'
- | 'no'
- | 'pl'
- | 'pt-BR'
- | 'pt-PT'
- | 'ro'
- | 'ru'
- | 'sk'
- | 'sl'
- | 'sq'
- | 'sr'
- | 'sv'
- | 'sw'
- | 'ta'
- | 'te'
- | 'th'
- | 'tr'
- | 'uk'
- | 'ur'
- | 'vi'
- | 'zh-CN'
- | 'zh-HK'
- | 'zh-TW';
-
-export function mapToSupportLocale(ourLocale: string): SupportLocaleType {
- if (ourLocale === 'ar') {
- return ourLocale;
- }
- if (ourLocale === 'de') {
- return ourLocale;
- }
- if (ourLocale === 'es') {
- return ourLocale;
- }
- if (ourLocale === 'fr') {
- return ourLocale;
- }
- if (ourLocale === 'it') {
- return ourLocale;
- }
- if (ourLocale === 'ja') {
- return ourLocale;
- }
- if (ourLocale === 'pl') {
- return ourLocale;
- }
- if (ourLocale === 'pt-BR') {
- return 'pt-br';
- }
- if (ourLocale === 'ru') {
- return ourLocale;
- }
- if (ourLocale === 'sq') {
- return ourLocale;
- }
- if (ourLocale === 'zh-TW') {
- return 'zh-tw';
- }
-
- return 'en-us';
-}