signal-desktop/ts/components/GlobalModalContainer.tsx

289 lines
8.1 KiB
TypeScript
Raw Normal View History

2021-05-28 16:15:17 +00:00
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
2021-11-12 01:17:29 +00:00
import type {
2023-02-27 22:34:43 +00:00
AuthorizeArtCreatorDataType,
2023-03-27 23:48:57 +00:00
ContactModalStateType,
DeleteMessagesPropsType,
2023-03-27 23:48:57 +00:00
EditHistoryMessagesType,
FormattingWarningDataType,
2023-03-20 22:23:53 +00:00
ForwardMessagesPropsType,
2023-03-27 23:48:57 +00:00
SafetyNumberChangedBlockingDataType,
UserNotFoundModalStateType,
2021-11-12 01:17:29 +00:00
} from '../state/ducks/globalModals';
import type { LocalizerType, ThemeType } from '../types/Util';
import type { ExplodePromiseResultType } from '../util/explodePromise';
import { missingCaseError } from '../util/missingCaseError';
2021-11-12 01:17:29 +00:00
import { ButtonVariant } from './Button';
import { ConfirmationDialog } from './ConfirmationDialog';
import { FormattingWarningModal } from './FormattingWarningModal';
import { SignalConnectionsModal } from './SignalConnectionsModal';
import { WhatsNewModal } from './WhatsNewModal';
2021-09-21 22:37:10 +00:00
2022-12-22 22:28:47 +00:00
// NOTE: All types should be required for this component so that the smart
// component gives you type errors when adding/removing props.
export type PropsType = {
i18n: LocalizerType;
theme: ThemeType;
2022-12-22 03:07:45 +00:00
// AddUserToAnotherGroupModal
2022-12-22 22:28:47 +00:00
addUserToAnotherGroupModalContactId: string | undefined;
2022-12-22 03:07:45 +00:00
renderAddUserToAnotherGroup: () => JSX.Element;
2021-09-21 22:37:10 +00:00
// ContactModal
2022-12-22 22:28:47 +00:00
contactModalState: ContactModalStateType | undefined;
2021-09-21 22:37:10 +00:00
renderContactModal: () => JSX.Element;
2023-03-27 23:48:57 +00:00
// EditHistoryMessagesModal
editHistoryMessages: EditHistoryMessagesType | undefined;
renderEditHistoryMessagesModal: () => JSX.Element;
2022-12-22 03:07:45 +00:00
// ErrorModal
2022-12-22 22:28:47 +00:00
errorModalProps: { description?: string; title?: string } | undefined;
2022-12-22 03:07:45 +00:00
renderErrorModal: (opts: {
description?: string;
title?: string;
}) => JSX.Element;
// DeleteMessageModal
deleteMessagesProps: DeleteMessagesPropsType | undefined;
renderDeleteMessagesModal: () => JSX.Element;
// FormattingWarningModal
showFormattingWarningModal: (
explodedPromise: ExplodePromiseResultType<boolean> | undefined
) => void;
formattingWarningData: FormattingWarningDataType | undefined;
2022-07-01 00:52:03 +00:00
// ForwardMessageModal
2023-03-20 22:23:53 +00:00
forwardMessagesProps: ForwardMessagesPropsType | undefined;
renderForwardMessagesModal: () => JSX.Element;
2021-07-19 19:26:06 +00:00
// ProfileEditor
isProfileEditorVisible: boolean;
renderProfileEditor: () => JSX.Element;
// SafetyNumberModal
2022-12-22 22:28:47 +00:00
safetyNumberModalContactId: string | undefined;
renderSafetyNumber: () => JSX.Element;
2022-12-22 03:07:45 +00:00
// ShortcutGuideModal
isShortcutGuideModalVisible: boolean;
renderShortcutGuideModal: () => JSX.Element;
// SignalConnectionsModal
isSignalConnectionsVisible: boolean;
toggleSignalConnectionsModal: () => unknown;
// StickerPackPreviewModal
2022-12-22 22:28:47 +00:00
stickerPackPreviewId: string | undefined;
renderStickerPreviewModal: () => JSX.Element | null;
// StoriesSettings
isStoriesSettingsVisible: boolean;
renderStoriesSettings: () => JSX.Element;
// SendAnywayDialog
hasSafetyNumberChangeModal: boolean;
2022-12-22 22:28:47 +00:00
safetyNumberChangedBlockingData:
| SafetyNumberChangedBlockingDataType
| undefined;
renderSendAnywayDialog: () => JSX.Element;
// UserNotFoundModal
hideUserNotFoundModal: () => unknown;
2022-12-22 22:28:47 +00:00
userNotFoundModalState: UserNotFoundModalStateType | undefined;
// WhatsNewModal
isWhatsNewVisible: boolean;
hideWhatsNewModal: () => unknown;
2023-02-27 22:34:43 +00:00
// AuthArtCreatorModal
authArtCreatorData?: AuthorizeArtCreatorDataType;
isAuthorizingArtCreator?: boolean;
cancelAuthorizeArtCreator: () => unknown;
confirmAuthorizeArtCreator: () => unknown;
2021-05-28 16:15:17 +00:00
};
2022-11-18 00:45:19 +00:00
export function GlobalModalContainer({
i18n,
2022-12-22 03:07:45 +00:00
// AddUserToAnotherGroupModal
addUserToAnotherGroupModalContactId,
renderAddUserToAnotherGroup,
2021-09-21 22:37:10 +00:00
// ContactModal
contactModalState,
renderContactModal,
2023-03-27 23:48:57 +00:00
// EditHistoryMessages
editHistoryMessages,
renderEditHistoryMessagesModal,
2022-12-22 03:07:45 +00:00
// ErrorModal
errorModalProps,
renderErrorModal,
// DeleteMessageModal
deleteMessagesProps,
renderDeleteMessagesModal,
// FormattingWarningModal
showFormattingWarningModal,
formattingWarningData,
2022-07-01 00:52:03 +00:00
// ForwardMessageModal
2023-03-20 22:23:53 +00:00
forwardMessagesProps,
renderForwardMessagesModal,
2021-07-19 19:26:06 +00:00
// ProfileEditor
isProfileEditorVisible,
renderProfileEditor,
// SafetyNumberModal
safetyNumberModalContactId,
renderSafetyNumber,
2022-12-22 03:07:45 +00:00
// ShortcutGuideModal
isShortcutGuideModalVisible,
renderShortcutGuideModal,
// SignalConnectionsModal
isSignalConnectionsVisible,
toggleSignalConnectionsModal,
// StickerPackPreviewModal
stickerPackPreviewId,
renderStickerPreviewModal,
// StoriesSettings
isStoriesSettingsVisible,
renderStoriesSettings,
// SendAnywayDialog
hasSafetyNumberChangeModal,
safetyNumberChangedBlockingData,
renderSendAnywayDialog,
// UserNotFoundModal
hideUserNotFoundModal,
userNotFoundModalState,
// WhatsNewModal
hideWhatsNewModal,
isWhatsNewVisible,
2023-02-27 22:34:43 +00:00
// AuthArtCreatorModal
authArtCreatorData,
isAuthorizingArtCreator,
cancelAuthorizeArtCreator,
confirmAuthorizeArtCreator,
2022-11-18 00:45:19 +00:00
}: PropsType): JSX.Element | null {
2022-12-22 03:07:45 +00:00
// We want the following dialogs to show in this order:
// 1. Errors
// 2. Safety Number Changes
// 3. The Rest (in no particular order, but they're ordered alphabetically)
// Errors
if (errorModalProps) {
return renderErrorModal(errorModalProps);
}
// Safety Number
if (hasSafetyNumberChangeModal || safetyNumberChangedBlockingData) {
return renderSendAnywayDialog();
}
2022-12-22 03:07:45 +00:00
// The Rest
if (addUserToAnotherGroupModalContactId) {
return renderAddUserToAnotherGroup();
}
if (contactModalState) {
return renderContactModal();
}
2023-03-27 23:48:57 +00:00
if (editHistoryMessages) {
return renderEditHistoryMessagesModal();
}
if (deleteMessagesProps) {
return renderDeleteMessagesModal();
}
if (formattingWarningData) {
const { resolve } = formattingWarningData.explodedPromise;
return (
<FormattingWarningModal
i18n={i18n}
onSendAnyway={() => {
showFormattingWarningModal(undefined);
resolve(true);
}}
onCancel={() => {
showFormattingWarningModal(undefined);
resolve(false);
}}
/>
);
}
2023-03-20 22:23:53 +00:00
if (forwardMessagesProps) {
return renderForwardMessagesModal();
2022-12-22 03:07:45 +00:00
}
if (isProfileEditorVisible) {
return renderProfileEditor();
}
if (isShortcutGuideModalVisible) {
return renderShortcutGuideModal();
}
if (isSignalConnectionsVisible) {
return (
<SignalConnectionsModal
i18n={i18n}
onClose={toggleSignalConnectionsModal}
/>
);
}
if (isStoriesSettingsVisible) {
return renderStoriesSettings();
}
if (isWhatsNewVisible) {
return <WhatsNewModal hideWhatsNewModal={hideWhatsNewModal} i18n={i18n} />;
}
if (safetyNumberModalContactId) {
return renderSafetyNumber();
}
2022-12-22 03:07:45 +00:00
if (stickerPackPreviewId) {
return renderStickerPreviewModal();
}
if (userNotFoundModalState) {
let content: string;
if (userNotFoundModalState.type === 'phoneNumber') {
2023-03-30 00:03:25 +00:00
content = i18n('icu:startConversation--phone-number-not-found', {
phoneNumber: userNotFoundModalState.phoneNumber,
});
} else if (userNotFoundModalState.type === 'username') {
2023-03-30 00:03:25 +00:00
content = i18n('icu:startConversation--username-not-found', {
2023-02-09 19:18:57 +00:00
atUsername: userNotFoundModalState.username,
});
} else {
throw missingCaseError(userNotFoundModalState);
}
2021-11-12 01:17:29 +00:00
return (
<ConfirmationDialog
2022-09-27 20:24:21 +00:00
dialogName="GlobalModalContainer.userNotFound"
2023-03-30 00:03:25 +00:00
cancelText={i18n('icu:ok')}
2021-11-12 01:17:29 +00:00
cancelButtonVariant={ButtonVariant.Secondary}
i18n={i18n}
onClose={hideUserNotFoundModal}
2021-11-12 01:17:29 +00:00
>
{content}
2021-11-12 01:17:29 +00:00
</ConfirmationDialog>
);
}
2023-02-27 22:34:43 +00:00
if (authArtCreatorData) {
return (
<ConfirmationDialog
dialogName="GlobalModalContainer.authArtCreator"
cancelText={i18n('icu:AuthArtCreator--dialog--dismiss')}
cancelButtonVariant={ButtonVariant.Secondary}
i18n={i18n}
isSpinning={isAuthorizingArtCreator}
onClose={cancelAuthorizeArtCreator}
actions={[
{
text: i18n('icu:AuthArtCreator--dialog--confirm'),
style: 'affirmative',
action: confirmAuthorizeArtCreator,
autoClose: false,
},
]}
>
{i18n('icu:AuthArtCreator--dialog--message')}
</ConfirmationDialog>
);
}
2021-05-28 16:15:17 +00:00
return null;
2022-11-18 00:45:19 +00:00
}