// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { JSX, ReactNode } from 'react';
import { DialogType } from '../../types/Dialogs.std.ts';
import { InstallScreenStep } from '../../types/InstallScreen.std.ts';
import type { LocalizerType } from '../../types/Util.std.ts';
import {
PRODUCTION_DOWNLOAD_URL,
BETA_DOWNLOAD_URL,
UNSUPPORTED_OS_URL,
} from '../../types/support.std.ts';
import type { UpdatesStateType } from '../../state/ducks/updates.preload.ts';
import { isBeta } from '../../util/version.std.ts';
import { missingCaseError } from '../../util/missingCaseError.std.ts';
import { roundFractionForProgressBar } from '../../util/numbers.std.ts';
import { I18n } from '../I18n.dom.tsx';
import { formatFileSize } from '../../util/formatFileSize.std.ts';
import { AxoConfirmDialog } from '../../axo/AxoConfirmDialog.dom.tsx';
import { AxoDialog } from '../../axo/AxoDialog.dom.tsx';
import { tw } from '../../axo/tw.dom.tsx';
export type PropsType = UpdatesStateType &
Readonly<{
i18n: LocalizerType;
step: InstallScreenStep;
forceUpdate: () => void;
startUpdate: () => void;
currentVersion: string;
OS: string;
onClose?: () => void;
}>;
export function InstallScreenUpdateDialog({
i18n,
step,
dialogType,
isCheckingForUpdates,
downloadSize,
downloadedSize,
forceUpdate,
startUpdate,
currentVersion,
OS,
onClose = () => null,
}: PropsType): JSX.Element | null {
if (dialogType === DialogType.None) {
if (step === InstallScreenStep.BackupImport) {
if (isCheckingForUpdates) {
return ;
}
return (
);
}
return null;
}
if (dialogType === DialogType.UnsupportedOS) {
return ;
}
if (dialogType === DialogType.DownloadedUpdate) {
return (
);
}
if (
dialogType === DialogType.AutoUpdate ||
// Manual update with an action button
dialogType === DialogType.DownloadReady ||
dialogType === DialogType.FullDownloadReady
) {
return (
);
}
if (dialogType === DialogType.Downloading) {
const fractionComplete = roundFractionForProgressBar(
(downloadedSize || 0) / (downloadSize || 1)
);
return (
);
}
if (
dialogType === DialogType.Cannot_Update ||
dialogType === DialogType.Cannot_Update_Require_Manual
) {
return (
);
}
if (dialogType === DialogType.MacOS_Read_Only) {
return ;
}
throw missingCaseError(dialogType);
}
/** @testexport */
export function UpdateRequiredModal(props: {
i18n: LocalizerType;
onClose: () => void;
onForceUpdate: () => void;
}): ReactNode {
const { i18n } = props;
return (
{i18n('icu:InstallScreenUpdateDialog--update-required__action-update')}
);
}
/** @testexport */
export function UpdateAvailableModal(props: {
i18n: LocalizerType;
onClose: () => void;
onStartUpdate: () => void;
downloadSize?: number;
downloadReady: boolean;
}): ReactNode {
const { i18n, onStartUpdate } = props;
return (
{
event.preventDefault();
onStartUpdate();
}}
>
{props.downloadReady ? (
({formatFileSize(props.downloadSize ?? 0)})
),
}}
/>
) : (
i18n('icu:autoUpdateRestartButtonLabel')
)}
);
}
/** @testexport */
export function UpdateDownloadingModal(props: {
i18n: LocalizerType;
progress: number;
}): ReactNode {
const { i18n } = props;
return (
{i18n('icu:DialogUpdate__downloading')}
);
}
/** @testexport */
export function UpdateDownloadedModal(props: {
i18n: LocalizerType;
onClose: () => void;
onStartUpdate: () => void;
}): ReactNode {
const { i18n, onStartUpdate } = props;
return (
{
event.preventDefault();
onStartUpdate();
}}
>
{i18n('icu:autoUpdateRestartButtonLabel')}
);
}
const learnMoreLink = (parts: Array) => (
{parts}
);
/** @testexport */
export function UnsupportedOSModal(props: {
i18n: LocalizerType;
OS: string;
onClose: () => void;
}): ReactNode {
const { i18n } = props;
return (
}
/>
);
}
/** @testexport */
export function CannotUpdateModal(props: {
i18n: LocalizerType;
onClose: () => void;
currentVersion: string;
needsManualUpdate: boolean;
onStartUpdate: () => void;
}): ReactNode {
const { i18n, onStartUpdate } = props;
const url = isBeta(props.currentVersion)
? BETA_DOWNLOAD_URL
: PRODUCTION_DOWNLOAD_URL;
return (
{url}
),
}}
/>
}
>
{!props.needsManualUpdate && (
{
event.preventDefault();
onStartUpdate();
}}
>
{i18n('icu:autoUpdateRetry')}
)}
);
}
/** @testexport */
export function CannotUpdateMacOsReadOnlyModal(props: {
i18n: LocalizerType;
onClose: () => void;
}): ReactNode {
const { i18n } = props;
return (
Signal.app,
folder: /Applications,
}}
i18n={i18n}
id="icu:readOnlyVolume"
/>
}
/>
);
}