Show a warning dialog when sending first edited message
This commit is contained in:
parent
23b058fe10
commit
4d354c8005
8 changed files with 175 additions and 23 deletions
|
@ -5742,6 +5742,14 @@
|
||||||
"messageformat": "Chat marked unread",
|
"messageformat": "Chat marked unread",
|
||||||
"description": "A toast that shows up when user marks a conversation as unread"
|
"description": "A toast that shows up when user marks a conversation as unread"
|
||||||
},
|
},
|
||||||
|
"icu:SendEdit--dialog--title": {
|
||||||
|
"messageformat": "Signal beta only",
|
||||||
|
"description": "Title of the modal shown before sending your first edit message"
|
||||||
|
},
|
||||||
|
"icu:SendEdit--dialog--body": {
|
||||||
|
"messageformat": "Editing messages is available to Signal beta users only. If you edit a message, it will only be visible to people who are on the latest version of Signal beta.",
|
||||||
|
"description": "Body text of the modal shown before sending your first edit message"
|
||||||
|
},
|
||||||
"icu:SendFormatting--dialog--title": {
|
"icu:SendFormatting--dialog--title": {
|
||||||
"messageformat": "Sending formatted text",
|
"messageformat": "Sending formatted text",
|
||||||
"description": "Title of the modal shown before sending your first formatting message"
|
"description": "Title of the modal shown before sending your first formatting message"
|
||||||
|
|
|
@ -10,6 +10,7 @@ import type {
|
||||||
FormattingWarningDataType,
|
FormattingWarningDataType,
|
||||||
ForwardMessagesPropsType,
|
ForwardMessagesPropsType,
|
||||||
SafetyNumberChangedBlockingDataType,
|
SafetyNumberChangedBlockingDataType,
|
||||||
|
SendEditWarningDataType,
|
||||||
UserNotFoundModalStateType,
|
UserNotFoundModalStateType,
|
||||||
} from '../state/ducks/globalModals';
|
} from '../state/ducks/globalModals';
|
||||||
import type { LocalizerType, ThemeType } from '../types/Util';
|
import type { LocalizerType, ThemeType } from '../types/Util';
|
||||||
|
@ -19,6 +20,7 @@ import { missingCaseError } from '../util/missingCaseError';
|
||||||
import { ButtonVariant } from './Button';
|
import { ButtonVariant } from './Button';
|
||||||
import { ConfirmationDialog } from './ConfirmationDialog';
|
import { ConfirmationDialog } from './ConfirmationDialog';
|
||||||
import { FormattingWarningModal } from './FormattingWarningModal';
|
import { FormattingWarningModal } from './FormattingWarningModal';
|
||||||
|
import { SendEditWarningModal } from './SendEditWarningModal';
|
||||||
import { SignalConnectionsModal } from './SignalConnectionsModal';
|
import { SignalConnectionsModal } from './SignalConnectionsModal';
|
||||||
import { WhatsNewModal } from './WhatsNewModal';
|
import { WhatsNewModal } from './WhatsNewModal';
|
||||||
|
|
||||||
|
@ -59,6 +61,11 @@ export type PropsType = {
|
||||||
// SafetyNumberModal
|
// SafetyNumberModal
|
||||||
safetyNumberModalContactId: string | undefined;
|
safetyNumberModalContactId: string | undefined;
|
||||||
renderSafetyNumber: () => JSX.Element;
|
renderSafetyNumber: () => JSX.Element;
|
||||||
|
// SendEditWarningModal
|
||||||
|
showSendEditWarningModal: (
|
||||||
|
explodedPromise: ExplodePromiseResultType<boolean> | undefined
|
||||||
|
) => void;
|
||||||
|
sendEditWarningData: SendEditWarningDataType | undefined;
|
||||||
// ShortcutGuideModal
|
// ShortcutGuideModal
|
||||||
isShortcutGuideModalVisible: boolean;
|
isShortcutGuideModalVisible: boolean;
|
||||||
renderShortcutGuideModal: () => JSX.Element;
|
renderShortcutGuideModal: () => JSX.Element;
|
||||||
|
@ -119,6 +126,9 @@ export function GlobalModalContainer({
|
||||||
// SafetyNumberModal
|
// SafetyNumberModal
|
||||||
safetyNumberModalContactId,
|
safetyNumberModalContactId,
|
||||||
renderSafetyNumber,
|
renderSafetyNumber,
|
||||||
|
// SendEditWarningDataType
|
||||||
|
showSendEditWarningModal,
|
||||||
|
sendEditWarningData,
|
||||||
// ShortcutGuideModal
|
// ShortcutGuideModal
|
||||||
isShortcutGuideModalVisible,
|
isShortcutGuideModalVisible,
|
||||||
renderShortcutGuideModal,
|
renderShortcutGuideModal,
|
||||||
|
@ -205,6 +215,23 @@ export function GlobalModalContainer({
|
||||||
return renderProfileEditor();
|
return renderProfileEditor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sendEditWarningData) {
|
||||||
|
const { resolve } = sendEditWarningData.explodedPromise;
|
||||||
|
return (
|
||||||
|
<SendEditWarningModal
|
||||||
|
i18n={i18n}
|
||||||
|
onSendAnyway={() => {
|
||||||
|
showSendEditWarningModal(undefined);
|
||||||
|
resolve(true);
|
||||||
|
}}
|
||||||
|
onCancel={() => {
|
||||||
|
showSendEditWarningModal(undefined);
|
||||||
|
resolve(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (isShortcutGuideModalVisible) {
|
if (isShortcutGuideModalVisible) {
|
||||||
return renderShortcutGuideModal();
|
return renderShortcutGuideModal();
|
||||||
}
|
}
|
||||||
|
|
38
ts/components/SendEditWarningModal.tsx
Normal file
38
ts/components/SendEditWarningModal.tsx
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import type { LocalizerType } from '../types/Util';
|
||||||
|
import { ConfirmationDialog } from './ConfirmationDialog';
|
||||||
|
|
||||||
|
type PropsType = {
|
||||||
|
i18n: LocalizerType;
|
||||||
|
onSendAnyway: () => void;
|
||||||
|
onCancel: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function SendEditWarningModal({
|
||||||
|
i18n,
|
||||||
|
onSendAnyway,
|
||||||
|
onCancel,
|
||||||
|
}: PropsType): JSX.Element | null {
|
||||||
|
return (
|
||||||
|
<ConfirmationDialog
|
||||||
|
actions={[
|
||||||
|
{
|
||||||
|
action: onSendAnyway,
|
||||||
|
autoClose: true,
|
||||||
|
style: 'affirmative',
|
||||||
|
text: i18n('icu:sendAnyway'),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
dialogName="SendEditWarningModal"
|
||||||
|
i18n={i18n}
|
||||||
|
onCancel={onCancel}
|
||||||
|
onClose={onCancel}
|
||||||
|
title={i18n('icu:SendEdit--dialog--title')}
|
||||||
|
>
|
||||||
|
{i18n('icu:SendEdit--dialog--body')}
|
||||||
|
</ConfirmationDialog>
|
||||||
|
);
|
||||||
|
}
|
|
@ -90,6 +90,7 @@ import { strictAssert } from '../../util/assert';
|
||||||
import { makeQuote } from '../../util/makeQuote';
|
import { makeQuote } from '../../util/makeQuote';
|
||||||
import { sendEditedMessage as doSendEditedMessage } from '../../util/sendEditedMessage';
|
import { sendEditedMessage as doSendEditedMessage } from '../../util/sendEditedMessage';
|
||||||
import { maybeBlockSendForFormattingModal } from '../../util/maybeBlockSendForFormattingModal';
|
import { maybeBlockSendForFormattingModal } from '../../util/maybeBlockSendForFormattingModal';
|
||||||
|
import { maybeBlockSendForEditWarningModal } from '../../util/maybeBlockSendForEditWarningModal';
|
||||||
import { Sound, SoundType } from '../../util/Sound';
|
import { Sound, SoundType } from '../../util/Sound';
|
||||||
|
|
||||||
// State
|
// State
|
||||||
|
@ -386,6 +387,7 @@ export function handleLeaveConversation(
|
||||||
type WithPreSendChecksOptions = Readonly<{
|
type WithPreSendChecksOptions = Readonly<{
|
||||||
bodyRanges?: DraftBodyRanges;
|
bodyRanges?: DraftBodyRanges;
|
||||||
message?: string;
|
message?: string;
|
||||||
|
isEditedMessage?: boolean;
|
||||||
voiceNoteAttachment?: InMemoryAttachmentDraftType;
|
voiceNoteAttachment?: InMemoryAttachmentDraftType;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
@ -409,7 +411,7 @@ async function withPreSendChecks(
|
||||||
conversation.attributes,
|
conversation.attributes,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const { bodyRanges, message, voiceNoteAttachment } = options;
|
const { bodyRanges, isEditedMessage, message, voiceNoteAttachment } = options;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dispatch(setComposerDisabledState(conversationId, true));
|
dispatch(setComposerDisabledState(conversationId, true));
|
||||||
|
@ -449,6 +451,27 @@ async function withPreSendChecks(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
isEditedMessage &&
|
||||||
|
!window.storage.get('sendEditWarningShown') &&
|
||||||
|
!window.SignalCI
|
||||||
|
) {
|
||||||
|
const sendAnyway = await maybeBlockSendForEditWarningModal();
|
||||||
|
if (!sendAnyway) {
|
||||||
|
dispatch(setComposerDisabledState(conversationId, false));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
drop(window.storage.put('sendEditWarningShown', true));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
log.error(
|
||||||
|
'withPreSendChecks block for send edit warning modal:',
|
||||||
|
Errors.toLogFormat(error)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const toast = shouldShowInvalidMessageToast(conversation.attributes);
|
const toast = shouldShowInvalidMessageToast(conversation.attributes);
|
||||||
if (toast != null) {
|
if (toast != null) {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -506,28 +529,33 @@ function sendEditedMessage(
|
||||||
targetMessageId,
|
targetMessageId,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
await withPreSendChecks(conversationId, options, dispatch, async () => {
|
await withPreSendChecks(
|
||||||
try {
|
conversationId,
|
||||||
await doSendEditedMessage(conversationId, {
|
{ ...options, isEditedMessage: true },
|
||||||
body: message,
|
dispatch,
|
||||||
bodyRanges,
|
async () => {
|
||||||
preview: getLinkPreviewForSend(message),
|
try {
|
||||||
quoteAuthorUuid,
|
await doSendEditedMessage(conversationId, {
|
||||||
quoteSentAt,
|
body: message,
|
||||||
targetMessageId,
|
bodyRanges,
|
||||||
});
|
preview: getLinkPreviewForSend(message),
|
||||||
} catch (error) {
|
quoteAuthorUuid,
|
||||||
log.error('sendEditedMessage', Errors.toLogFormat(error));
|
quoteSentAt,
|
||||||
if (error.toastType) {
|
targetMessageId,
|
||||||
dispatch({
|
|
||||||
type: SHOW_TOAST,
|
|
||||||
payload: {
|
|
||||||
toastType: error.toastType,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
log.error('sendEditedMessage', Errors.toLogFormat(error));
|
||||||
|
if (error.toastType) {
|
||||||
|
dispatch({
|
||||||
|
type: SHOW_TOAST,
|
||||||
|
payload: {
|
||||||
|
toastType: error.toastType,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,9 @@ export type SafetyNumberChangedBlockingDataType = ReadonlyDeep<{
|
||||||
export type FormattingWarningDataType = ReadonlyDeep<{
|
export type FormattingWarningDataType = ReadonlyDeep<{
|
||||||
explodedPromise: ExplodePromiseResultType<boolean>;
|
explodedPromise: ExplodePromiseResultType<boolean>;
|
||||||
}>;
|
}>;
|
||||||
|
export type SendEditWarningDataType = ReadonlyDeep<{
|
||||||
|
explodedPromise: ExplodePromiseResultType<boolean>;
|
||||||
|
}>;
|
||||||
export type AuthorizeArtCreatorDataType =
|
export type AuthorizeArtCreatorDataType =
|
||||||
ReadonlyDeep<AuthorizeArtCreatorOptionsType>;
|
ReadonlyDeep<AuthorizeArtCreatorOptionsType>;
|
||||||
|
|
||||||
|
@ -96,6 +99,7 @@ export type GlobalModalsStateType = ReadonlyDeep<{
|
||||||
profileEditorHasError: boolean;
|
profileEditorHasError: boolean;
|
||||||
safetyNumberChangedBlockingData?: SafetyNumberChangedBlockingDataType;
|
safetyNumberChangedBlockingData?: SafetyNumberChangedBlockingDataType;
|
||||||
safetyNumberModalContactId?: string;
|
safetyNumberModalContactId?: string;
|
||||||
|
sendEditWarningData?: SendEditWarningDataType;
|
||||||
stickerPackPreviewId?: string;
|
stickerPackPreviewId?: string;
|
||||||
userNotFoundModalState?: UserNotFoundModalStateType;
|
userNotFoundModalState?: UserNotFoundModalStateType;
|
||||||
}>;
|
}>;
|
||||||
|
@ -132,6 +136,8 @@ const CLOSE_ERROR_MODAL = 'globalModals/CLOSE_ERROR_MODAL';
|
||||||
const SHOW_ERROR_MODAL = 'globalModals/SHOW_ERROR_MODAL';
|
const SHOW_ERROR_MODAL = 'globalModals/SHOW_ERROR_MODAL';
|
||||||
const SHOW_FORMATTING_WARNING_MODAL =
|
const SHOW_FORMATTING_WARNING_MODAL =
|
||||||
'globalModals/SHOW_FORMATTING_WARNING_MODAL';
|
'globalModals/SHOW_FORMATTING_WARNING_MODAL';
|
||||||
|
const SHOW_SEND_EDIT_WARNING_MODAL =
|
||||||
|
'globalModals/SHOW_SEND_EDIT_WARNING_MODAL';
|
||||||
const CLOSE_SHORTCUT_GUIDE_MODAL = 'globalModals/CLOSE_SHORTCUT_GUIDE_MODAL';
|
const CLOSE_SHORTCUT_GUIDE_MODAL = 'globalModals/CLOSE_SHORTCUT_GUIDE_MODAL';
|
||||||
const SHOW_SHORTCUT_GUIDE_MODAL = 'globalModals/SHOW_SHORTCUT_GUIDE_MODAL';
|
const SHOW_SHORTCUT_GUIDE_MODAL = 'globalModals/SHOW_SHORTCUT_GUIDE_MODAL';
|
||||||
const SHOW_AUTH_ART_CREATOR = 'globalModals/SHOW_AUTH_ART_CREATOR';
|
const SHOW_AUTH_ART_CREATOR = 'globalModals/SHOW_AUTH_ART_CREATOR';
|
||||||
|
@ -234,6 +240,13 @@ type ShowFormattingWarningModalActionType = ReadonlyDeep<{
|
||||||
};
|
};
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
type ShowSendEditWarningModalActionType = ReadonlyDeep<{
|
||||||
|
type: typeof SHOW_SEND_EDIT_WARNING_MODAL;
|
||||||
|
payload: {
|
||||||
|
explodedPromise: ExplodePromiseResultType<boolean> | undefined;
|
||||||
|
};
|
||||||
|
}>;
|
||||||
|
|
||||||
type HideStoriesSettingsActionType = ReadonlyDeep<{
|
type HideStoriesSettingsActionType = ReadonlyDeep<{
|
||||||
type: typeof HIDE_STORIES_SETTINGS;
|
type: typeof HIDE_STORIES_SETTINGS;
|
||||||
}>;
|
}>;
|
||||||
|
@ -338,6 +351,7 @@ export type GlobalModalsActionType = ReadonlyDeep<
|
||||||
| ShowErrorModalActionType
|
| ShowErrorModalActionType
|
||||||
| ShowFormattingWarningModalActionType
|
| ShowFormattingWarningModalActionType
|
||||||
| ShowSendAnywayDialogActionType
|
| ShowSendAnywayDialogActionType
|
||||||
|
| ShowSendEditWarningModalActionType
|
||||||
| ShowShortcutGuideModalActionType
|
| ShowShortcutGuideModalActionType
|
||||||
| ShowStickerPackPreviewActionType
|
| ShowStickerPackPreviewActionType
|
||||||
| ShowStoriesSettingsActionType
|
| ShowStoriesSettingsActionType
|
||||||
|
@ -375,6 +389,7 @@ export const actions = {
|
||||||
showEditHistoryModal,
|
showEditHistoryModal,
|
||||||
showErrorModal,
|
showErrorModal,
|
||||||
showFormattingWarningModal,
|
showFormattingWarningModal,
|
||||||
|
showSendEditWarningModal,
|
||||||
showGV2MigrationDialog,
|
showGV2MigrationDialog,
|
||||||
showShortcutGuideModal,
|
showShortcutGuideModal,
|
||||||
showStickerPackPreview,
|
showStickerPackPreview,
|
||||||
|
@ -455,6 +470,12 @@ function showFormattingWarningModal(
|
||||||
return { type: SHOW_FORMATTING_WARNING_MODAL, payload: { explodedPromise } };
|
return { type: SHOW_FORMATTING_WARNING_MODAL, payload: { explodedPromise } };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showSendEditWarningModal(
|
||||||
|
explodedPromise: ExplodePromiseResultType<boolean> | undefined
|
||||||
|
): ShowSendEditWarningModalActionType {
|
||||||
|
return { type: SHOW_SEND_EDIT_WARNING_MODAL, payload: { explodedPromise } };
|
||||||
|
}
|
||||||
|
|
||||||
function showGV2MigrationDialog(
|
function showGV2MigrationDialog(
|
||||||
conversationId: string
|
conversationId: string
|
||||||
): ThunkAction<void, RootStateType, unknown, StartMigrationToGV2ActionType> {
|
): ThunkAction<void, RootStateType, unknown, StartMigrationToGV2ActionType> {
|
||||||
|
@ -984,6 +1005,21 @@ export function reducer(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action.type === SHOW_SEND_EDIT_WARNING_MODAL) {
|
||||||
|
const { explodedPromise } = action.payload;
|
||||||
|
if (!explodedPromise) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
sendEditWarningData: undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
sendEditWarningData: { explodedPromise },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (action.type === SHOW_STICKER_PACK_PREVIEW) {
|
if (action.type === SHOW_STICKER_PACK_PREVIEW) {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
|
|
@ -64,12 +64,14 @@ export function SmartGlobalModalContainer(): JSX.Element {
|
||||||
|
|
||||||
const {
|
const {
|
||||||
addUserToAnotherGroupModalContactId,
|
addUserToAnotherGroupModalContactId,
|
||||||
|
authArtCreatorData,
|
||||||
contactModalState,
|
contactModalState,
|
||||||
|
deleteMessagesProps,
|
||||||
editHistoryMessages,
|
editHistoryMessages,
|
||||||
errorModalProps,
|
errorModalProps,
|
||||||
deleteMessagesProps,
|
|
||||||
formattingWarningData,
|
formattingWarningData,
|
||||||
forwardMessagesProps,
|
forwardMessagesProps,
|
||||||
|
isAuthorizingArtCreator,
|
||||||
isProfileEditorVisible,
|
isProfileEditorVisible,
|
||||||
isShortcutGuideModalVisible,
|
isShortcutGuideModalVisible,
|
||||||
isSignalConnectionsVisible,
|
isSignalConnectionsVisible,
|
||||||
|
@ -77,10 +79,9 @@ export function SmartGlobalModalContainer(): JSX.Element {
|
||||||
isWhatsNewVisible,
|
isWhatsNewVisible,
|
||||||
safetyNumberChangedBlockingData,
|
safetyNumberChangedBlockingData,
|
||||||
safetyNumberModalContactId,
|
safetyNumberModalContactId,
|
||||||
|
sendEditWarningData,
|
||||||
stickerPackPreviewId,
|
stickerPackPreviewId,
|
||||||
userNotFoundModalState,
|
userNotFoundModalState,
|
||||||
isAuthorizingArtCreator,
|
|
||||||
authArtCreatorData,
|
|
||||||
} = useSelector<StateType, GlobalModalsStateType>(
|
} = useSelector<StateType, GlobalModalsStateType>(
|
||||||
state => state.globalModals
|
state => state.globalModals
|
||||||
);
|
);
|
||||||
|
@ -92,6 +93,7 @@ export function SmartGlobalModalContainer(): JSX.Element {
|
||||||
hideUserNotFoundModal,
|
hideUserNotFoundModal,
|
||||||
hideWhatsNewModal,
|
hideWhatsNewModal,
|
||||||
showFormattingWarningModal,
|
showFormattingWarningModal,
|
||||||
|
showSendEditWarningModal,
|
||||||
toggleSignalConnectionsModal,
|
toggleSignalConnectionsModal,
|
||||||
} = useGlobalModalActions();
|
} = useGlobalModalActions();
|
||||||
|
|
||||||
|
@ -162,7 +164,9 @@ export function SmartGlobalModalContainer(): JSX.Element {
|
||||||
renderStoriesSettings={renderStoriesSettings}
|
renderStoriesSettings={renderStoriesSettings}
|
||||||
safetyNumberChangedBlockingData={safetyNumberChangedBlockingData}
|
safetyNumberChangedBlockingData={safetyNumberChangedBlockingData}
|
||||||
safetyNumberModalContactId={safetyNumberModalContactId}
|
safetyNumberModalContactId={safetyNumberModalContactId}
|
||||||
|
sendEditWarningData={sendEditWarningData}
|
||||||
showFormattingWarningModal={showFormattingWarningModal}
|
showFormattingWarningModal={showFormattingWarningModal}
|
||||||
|
showSendEditWarningModal={showSendEditWarningModal}
|
||||||
stickerPackPreviewId={stickerPackPreviewId}
|
stickerPackPreviewId={stickerPackPreviewId}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
toggleSignalConnectionsModal={toggleSignalConnectionsModal}
|
toggleSignalConnectionsModal={toggleSignalConnectionsModal}
|
||||||
|
|
1
ts/types/Storage.d.ts
vendored
1
ts/types/Storage.d.ts
vendored
|
@ -88,6 +88,7 @@ export type StorageAccessType = {
|
||||||
regionCode: string;
|
regionCode: string;
|
||||||
registrationIdMap: Record<string, number>;
|
registrationIdMap: Record<string, number>;
|
||||||
remoteBuildExpiration: number;
|
remoteBuildExpiration: number;
|
||||||
|
sendEditWarningShown: boolean;
|
||||||
sessionResets: SessionResetsType;
|
sessionResets: SessionResetsType;
|
||||||
showStickerPickerHint: boolean;
|
showStickerPickerHint: boolean;
|
||||||
showStickersIntroduction: boolean;
|
showStickersIntroduction: boolean;
|
||||||
|
|
10
ts/util/maybeBlockSendForEditWarningModal.ts
Normal file
10
ts/util/maybeBlockSendForEditWarningModal.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
// Copyright 2023 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { explodePromise } from './explodePromise';
|
||||||
|
|
||||||
|
export async function maybeBlockSendForEditWarningModal(): Promise<boolean> {
|
||||||
|
const explodedPromise = explodePromise<boolean>();
|
||||||
|
window.reduxActions.globalModals.showSendEditWarningModal(explodedPromise);
|
||||||
|
return explodedPromise.promise;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue