// Copyright 2025 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React, { type ReactNode } from 'react'; import { LocalExportErrors, LocalBackupExportSteps, } from '../types/LocalExport.std.js'; import { AxoDialog } from '../axo/AxoDialog.dom.js'; import { AxoAlertDialog } from '../axo/AxoAlertDialog.dom.js'; import type { LocalBackupExportWorkflowType } from '../types/LocalExport.std.js'; import type { LocalizerType } from '../types/I18N.std.js'; import { formatFileSize } from '../util/formatFileSize.std.js'; import { ProgressBar } from './ProgressBar.dom.js'; import { missingCaseError } from '../util/missingCaseError.std.js'; import { tw } from '../axo/tw.dom.js'; import { AxoSymbol } from '../axo/AxoSymbol.dom.js'; import type { AxoSymbolIconName } from '../axo/_internal/AxoSymbolDefs.generated.std.js'; export type PropsType = { cancelWorkflow: () => void; clearWorkflow: () => void; i18n: LocalizerType; openFileInFolder: (path: string) => void; osName: 'linux' | 'macos' | 'windows' | undefined; workflow: LocalBackupExportWorkflowType; }; export function LocalBackupExportWorkflow({ cancelWorkflow, clearWorkflow, i18n, openFileInFolder, osName, workflow, }: PropsType): React.JSX.Element { const { step } = workflow; if ( step === LocalBackupExportSteps.ExportingMessages || step === LocalBackupExportSteps.ExportingAttachments ) { const progress = step === LocalBackupExportSteps.ExportingAttachments ? workflow.progress : undefined; let progressElements; if (progress) { const fractionComplete = progress.totalBytes > 0 ? progress.currentBytes / progress.totalBytes : 0; progressElements = ( <>
{i18n('icu:PlaintextExport--ProgressDialog--Progress', { currentBytes: formatFileSize(progress.currentBytes), totalBytes: formatFileSize(progress.totalBytes), percentage: fractionComplete, })}
); } else { progressElements = (
); } return (
{i18n('icu:LocalBackupExport--ProgressDialog--Header')}
{progressElements}
{i18n('icu:PlaintextExport--ProgressDialog--TimeWarning')}
{i18n('icu:cancel')}
); } if (step === LocalBackupExportSteps.Complete) { let showInFolderText = i18n( 'icu:PlaintextExport--CompleteDialog--ShowFiles--Windows' ); if (osName === 'macos') { showInFolderText = i18n( 'icu:PlaintextExport--CompleteDialog--ShowFiles--Mac' ); } else if (osName === 'linux') { showInFolderText = i18n( 'icu:PlaintextExport--CompleteDialog--ShowFiles--Linux' ); } return (
{i18n('icu:LocalBackupExport--CompleteDialog--Header')}
{i18n( 'icu:LocalBackupExport--CompleteDialog--RestoreInstructionsHeader' )}
{ openFileInFolder(workflow.localBackupFolder); clearWorkflow(); }} > {showInFolderText} {i18n('icu:ok')}
); } if (step === LocalBackupExportSteps.Error) { const { type } = workflow.errorDetails; let title; let detail; if (type === LocalExportErrors.General) { title = i18n('icu:PlaintextExport--Error--General--Title'); detail = i18n('icu:PlaintextExport--Error--General--Description'); } else if (type === LocalExportErrors.NotEnoughStorage) { title = i18n('icu:PlaintextExport--Error--NotEnoughStorage--Title'); detail = i18n('icu:PlaintextExport--Error--NotEnoughStorage--Detail', { bytes: formatFileSize(workflow.errorDetails.bytesNeeded), }); } else if (type === LocalExportErrors.RanOutOfStorage) { title = i18n('icu:PlaintextExport--Error--RanOutOfStorage--Title'); detail = i18n('icu:PlaintextExport--Error--RanOutOfStorage--Detail', { bytes: formatFileSize(workflow.errorDetails.bytesNeeded), }); } else if (type === LocalExportErrors.StoragePermissions) { title = i18n('icu:PlaintextExport--Error--DiskPermssions--Title'); detail = i18n('icu:PlaintextExport--Error--DiskPermssions--Detail'); } else { throw missingCaseError(type); } return ( {title} {detail} {i18n('icu:ok')} ); } throw missingCaseError(step); } function ListItemWithIcon({ iconName, content, }: { iconName: AxoSymbolIconName; content: ReactNode; }): ReactNode { return (
  • {content}
  • ); }