// Copyright 2024 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React, { useState, useCallback } from 'react'; import type { LocalizerType } from '../../types/Util'; import type { UpdatesStateType } from '../../state/ducks/updates'; import { InstallScreenStep, InstallScreenBackupStep, InstallScreenBackupError, } from '../../types/InstallScreen'; import { formatFileSize } from '../../util/formatFileSize'; import { TitlebarDragArea } from '../TitlebarDragArea'; import { ProgressBar } from '../ProgressBar'; import { ConfirmationDialog } from '../ConfirmationDialog'; import { InstallScreenSignalLogo } from './InstallScreenSignalLogo'; import { roundFractionForProgressBar } from '../../util/numbers'; import { missingCaseError } from '../../util/missingCaseError'; import { SYNCING_MESSAGES_SECURITY_URL } from '../../types/support'; import { I18n } from '../I18n'; import { InstallScreenUpdateDialog } from './InstallScreenUpdateDialog'; // We can't always use destructuring assignment because of the complexity of this props // type. export type PropsType = Readonly< { i18n: LocalizerType; error?: InstallScreenBackupError; onCancel: () => void; onRetry: () => void; onRestartLink: () => void; // Updater UI updates: UpdatesStateType; currentVersion: string; OS: string; startUpdate: () => void; forceUpdate: () => void; } & ( | { backupStep: InstallScreenBackupStep.WaitForBackup; } | { backupStep: | InstallScreenBackupStep.Download | InstallScreenBackupStep.Process; currentBytes: number; totalBytes: number; } ) >; export function InstallScreenBackupImportStep(props: PropsType): JSX.Element { const { i18n, backupStep, error, onCancel, onRetry, onRestartLink, updates, currentVersion, OS, startUpdate, forceUpdate, } = props; const [isConfirmingCancel, setIsConfirmingCancel] = useState(false); const [isConfirmingSkip, setIsConfirmingSkip] = useState(false); const confirmCancel = useCallback(() => { setIsConfirmingCancel(true); }, []); const abortCancel = useCallback(() => { setIsConfirmingCancel(false); }, []); const onCancelWrap = useCallback(() => { onCancel(); setIsConfirmingCancel(false); }, [onCancel]); const confirmSkip = useCallback(() => { setIsConfirmingSkip(true); }, []); const abortSkip = useCallback(() => { setIsConfirmingSkip(false); }, []); const onSkipWrap = useCallback(() => { onCancel(); setIsConfirmingSkip(false); }, [onCancel]); const onRetryWrap = useCallback(() => { onRetry(); setIsConfirmingSkip(false); }, [onRetry]); const learnMoreLink = (parts: Array) => ( {parts} ); let errorElem: JSX.Element | undefined; if (error == null) { // no-op } else if (error === InstallScreenBackupError.UnsupportedVersion) { errorElem = ( ); } else if (error === InstallScreenBackupError.Retriable) { if (!isConfirmingSkip) { errorElem = ( {i18n('icu:BackupImportScreen__error__body')} ); } } else if (error === InstallScreenBackupError.Fatal) { errorElem = ( null} noMouseClose noDefaultCancelButton noEscapeClose > {i18n('icu:BackupImportScreen__error-fatal__body')} ); } else { throw missingCaseError(error); } return (

{i18n('icu:BackupImportScreen__title')}

{i18n('icu:BackupImportScreen__description')}
{backupStep === InstallScreenBackupStep.Download && ( )}
{isConfirmingCancel && ( {i18n('icu:BackupImportScreen__cancel-confirmation__body')} )} {isConfirmingSkip && ( {i18n('icu:BackupImportScreen__skip-confirmation__body')} )} {errorElem}
); } type ProgressBarPropsType = Readonly< { i18n: LocalizerType; } & ( | { backupStep: InstallScreenBackupStep.WaitForBackup; } | { backupStep: | InstallScreenBackupStep.Download | InstallScreenBackupStep.Process; currentBytes: number; totalBytes: number; } ) >; function ProgressBarAndDescription(props: ProgressBarPropsType): JSX.Element { const { backupStep, i18n } = props; if (backupStep === InstallScreenBackupStep.WaitForBackup) { return ( <>
{i18n('icu:BackupImportScreen__progressbar-hint--preparing')}
); } const { currentBytes, totalBytes } = props; const fractionComplete = roundFractionForProgressBar( currentBytes / totalBytes ); if (backupStep === InstallScreenBackupStep.Download) { return ( <>
{i18n('icu:BackupImportScreen__progressbar-hint', { currentSize: formatFileSize(currentBytes), totalSize: formatFileSize(totalBytes), fractionComplete, })}
); // eslint-disable-next-line no-else-return } else if (backupStep === InstallScreenBackupStep.Process) { return ( <>
{i18n('icu:BackupImportScreen__progressbar-hint--processing')}
); } else { throw missingCaseError(backupStep); } }