signal-desktop/ts/state/ducks/globalModals.ts

1274 lines
34 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
2022-07-01 00:52:03 +00:00
import type { ThunkAction } from 'redux-thunk';
import type { ReadonlyDeep } from 'type-fest';
import type { ExplodePromiseResultType } from '../../util/explodePromise';
2023-03-27 23:48:57 +00:00
import type {
GroupV2PendingMemberType,
MessageAttributesType,
} from '../../model-types.d';
import type {
MessageChangedActionType,
MessageDeletedActionType,
MessageExpiredActionType,
} from './conversations';
import type { MessagePropsType } from '../selectors/message';
2022-12-08 06:41:37 +00:00
import type { RecipientsByConversation } from './stories';
import type { SafetyNumberChangeSource } from '../../components/SafetyNumberChangeDialog';
import type { EditState as ProfileEditorEditState } from '../../components/ProfileEditor';
import type { StateType as RootStateType } from '../reducer';
import * as SingleServePromise from '../../services/singleServePromise';
import * as Stickers from '../../types/Stickers';
import { UsernameOnboardingState } from '../../types/globalModals';
2023-03-27 23:48:57 +00:00
import * as log from '../../logging/log';
2022-07-01 00:52:03 +00:00
import { getMessagePropsSelector } from '../selectors/message';
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
2022-12-08 06:41:37 +00:00
import { longRunningTaskWrapper } from '../../util/longRunningTaskWrapper';
2022-07-01 00:52:03 +00:00
import { useBoundActions } from '../../hooks/useBoundActions';
2022-12-08 06:41:37 +00:00
import { isGroupV1 } from '../../util/whatTypeOfConversation';
import { getGroupMigrationMembers } from '../../groups';
2023-03-27 23:48:57 +00:00
import {
MESSAGE_CHANGED,
MESSAGE_DELETED,
MESSAGE_EXPIRED,
actions as conversationsActions,
2023-03-27 23:48:57 +00:00
} from './conversations';
import { isDownloaded } from '../../types/Attachment';
2024-02-22 21:19:50 +00:00
import type { ButtonVariant } from '../../components/Button';
2024-03-12 16:29:31 +00:00
import type { MessageRequestState } from '../../components/conversation/MessageRequestActionsConfirmation';
2024-05-22 16:24:27 +00:00
import type { MessageForwardDraft } from '../../types/ForwardDraft';
import { hydrateRanges } from '../../types/BodyRange';
import {
getConversationSelector,
type GetConversationByIdType,
} from '../selectors/conversations';
import { missingCaseError } from '../../util/missingCaseError';
import { ForwardMessagesModalType } from '../../components/ForwardMessagesModal';
2024-06-10 15:23:43 +00:00
import type { CallLinkType } from '../../types/CallLink';
import type { LocalizerType } from '../../types/I18N';
import { linkCallRoute } from '../../util/signalRoutes';
2022-07-01 00:52:03 +00:00
2021-05-28 16:15:17 +00:00
// State
2023-03-27 23:48:57 +00:00
export type EditHistoryMessagesType = ReadonlyDeep<
Array<MessageAttributesType>
>;
2024-03-26 19:48:33 +00:00
export type EditNicknameAndNoteModalPropsType = ReadonlyDeep<{
conversationId: string;
}>;
export type DeleteMessagesPropsType = ReadonlyDeep<{
conversationId: string;
messageIds: ReadonlyArray<string>;
onDelete?: () => void;
}>;
2023-03-27 23:48:57 +00:00
export type ForwardMessagePropsType = ReadonlyDeep<MessagePropsType>;
2023-03-20 22:23:53 +00:00
export type ForwardMessagesPropsType = ReadonlyDeep<{
2024-05-22 16:24:27 +00:00
type: ForwardMessagesModalType;
messageDrafts: Array<MessageForwardDraft>;
2023-03-20 22:23:53 +00:00
onForward?: () => void;
}>;
2024-03-12 16:29:31 +00:00
export type MessageRequestActionsConfirmationPropsType = ReadonlyDeep<{
conversationId: string;
state: MessageRequestState;
}>;
2024-03-26 19:48:33 +00:00
export type NotePreviewModalPropsType = ReadonlyDeep<{
conversationId: string;
}>;
export type SafetyNumberChangedBlockingDataType = ReadonlyDeep<{
promiseUuid: SingleServePromise.SingleServePromiseIdString;
source?: SafetyNumberChangeSource;
}>;
type MigrateToGV2PropsType = ReadonlyDeep<{
2022-12-08 06:41:37 +00:00
areWeInvited: boolean;
conversationId: string;
droppedMemberIds: Array<string>;
2022-12-08 06:41:37 +00:00
hasMigrated: boolean;
invitedMemberIds: Array<string>;
}>;
2022-12-08 06:41:37 +00:00
export type GlobalModalsStateType = ReadonlyDeep<{
2022-12-08 06:41:37 +00:00
addUserToAnotherGroupModalContactId?: string;
2024-02-16 22:16:13 +00:00
aboutContactModalContactId?: string;
2024-06-10 15:23:43 +00:00
callLinkEditModalRoomId: string | null;
contactModalState?: ContactModalStateType;
deleteMessagesProps?: DeleteMessagesPropsType;
2023-03-27 23:48:57 +00:00
editHistoryMessages?: EditHistoryMessagesType;
2024-03-26 19:48:33 +00:00
editNicknameAndNoteModalProps: EditNicknameAndNoteModalPropsType | null;
2022-12-22 03:07:45 +00:00
errorModalProps?: {
2024-02-22 21:19:50 +00:00
buttonVariant?: ButtonVariant;
2022-12-22 03:07:45 +00:00
description?: string;
title?: string;
};
2023-03-20 22:23:53 +00:00
forwardMessagesProps?: ForwardMessagesPropsType;
2022-12-08 06:41:37 +00:00
gv2MigrationProps?: MigrateToGV2PropsType;
hasConfirmationModal: boolean;
isProfileEditorVisible: boolean;
2022-12-22 03:07:45 +00:00
isShortcutGuideModalVisible: boolean;
isSignalConnectionsVisible: boolean;
isStoriesSettingsVisible: boolean;
isWhatsNewVisible: boolean;
2024-03-12 16:29:31 +00:00
messageRequestActionsConfirmationProps: MessageRequestActionsConfirmationPropsType | null;
2024-03-26 19:48:33 +00:00
notePreviewModalProps: NotePreviewModalPropsType | null;
usernameOnboardingState: UsernameOnboardingState;
profileEditorHasError: boolean;
profileEditorInitialEditState: ProfileEditorEditState | undefined;
safetyNumberChangedBlockingData?: SafetyNumberChangedBlockingDataType;
safetyNumberModalContactId?: string;
stickerPackPreviewId?: string;
userNotFoundModalState?: UserNotFoundModalStateType;
}>;
2021-05-28 16:15:17 +00:00
// Actions
2021-09-21 22:37:10 +00:00
const HIDE_CONTACT_MODAL = 'globalModals/HIDE_CONTACT_MODAL';
const SHOW_CONTACT_MODAL = 'globalModals/SHOW_CONTACT_MODAL';
2022-07-01 00:52:03 +00:00
const HIDE_WHATS_NEW_MODAL = 'globalModals/HIDE_WHATS_NEW_MODAL_MODAL';
const SHOW_WHATS_NEW_MODAL = 'globalModals/SHOW_WHATS_NEW_MODAL_MODAL';
const HIDE_SERVICE_ID_NOT_FOUND_MODAL =
'globalModals/HIDE_SERVICE_ID_NOT_FOUND_MODAL';
const SHOW_SERVICE_ID_NOT_FOUND_MODAL =
'globalModals/SHOW_SERVICE_ID_NOT_FOUND_MODAL';
const SHOW_STORIES_SETTINGS = 'globalModals/SHOW_STORIES_SETTINGS';
const HIDE_STORIES_SETTINGS = 'globalModals/HIDE_STORIES_SETTINGS';
const TOGGLE_DELETE_MESSAGES_MODAL =
'globalModals/TOGGLE_DELETE_MESSAGES_MODAL';
2023-03-20 22:23:53 +00:00
const TOGGLE_FORWARD_MESSAGES_MODAL =
'globalModals/TOGGLE_FORWARD_MESSAGES_MODAL';
2024-03-26 19:48:33 +00:00
const TOGGLE_NOTE_PREVIEW_MODAL = 'globalModals/TOGGLE_NOTE_PREVIEW_MODAL';
2021-07-19 19:26:06 +00:00
const TOGGLE_PROFILE_EDITOR = 'globalModals/TOGGLE_PROFILE_EDITOR';
export const TOGGLE_PROFILE_EDITOR_ERROR =
'globalModals/TOGGLE_PROFILE_EDITOR_ERROR';
const TOGGLE_SAFETY_NUMBER_MODAL = 'globalModals/TOGGLE_SAFETY_NUMBER_MODAL';
const TOGGLE_ADD_USER_TO_ANOTHER_GROUP_MODAL =
'globalModals/TOGGLE_ADD_USER_TO_ANOTHER_GROUP_MODAL';
2024-06-10 15:23:43 +00:00
const TOGGLE_CALL_LINK_EDIT_MODAL = 'globalModals/TOGGLE_CALL_LINK_EDIT_MODAL';
const TOGGLE_ABOUT_MODAL = 'globalModals/TOGGLE_ABOUT_MODAL';
const TOGGLE_SIGNAL_CONNECTIONS_MODAL =
'globalModals/TOGGLE_SIGNAL_CONNECTIONS_MODAL';
export const SHOW_SEND_ANYWAY_DIALOG = 'globalModals/SHOW_SEND_ANYWAY_DIALOG';
const HIDE_SEND_ANYWAY_DIALOG = 'globalModals/HIDE_SEND_ANYWAY_DIALOG';
2022-12-08 06:41:37 +00:00
const SHOW_GV2_MIGRATION_DIALOG = 'globalModals/SHOW_GV2_MIGRATION_DIALOG';
const CLOSE_GV2_MIGRATION_DIALOG = 'globalModals/CLOSE_GV2_MIGRATION_DIALOG';
const SHOW_STICKER_PACK_PREVIEW = 'globalModals/SHOW_STICKER_PACK_PREVIEW';
const CLOSE_STICKER_PACK_PREVIEW = 'globalModals/CLOSE_STICKER_PACK_PREVIEW';
2022-12-22 03:07:45 +00:00
const CLOSE_ERROR_MODAL = 'globalModals/CLOSE_ERROR_MODAL';
export const SHOW_ERROR_MODAL = 'globalModals/SHOW_ERROR_MODAL';
2024-03-26 19:48:33 +00:00
const TOGGLE_EDIT_NICKNAME_AND_NOTE_MODAL =
'globalModals/TOGGLE_EDIT_NICKNAME_AND_NOTE_MODAL';
2024-03-12 16:29:31 +00:00
const TOGGLE_MESSAGE_REQUEST_ACTIONS_CONFIRMATION =
'globalModals/TOGGLE_MESSAGE_REQUEST_ACTIONS_CONFIRMATION';
2022-12-22 03:07:45 +00:00
const CLOSE_SHORTCUT_GUIDE_MODAL = 'globalModals/CLOSE_SHORTCUT_GUIDE_MODAL';
const SHOW_SHORTCUT_GUIDE_MODAL = 'globalModals/SHOW_SHORTCUT_GUIDE_MODAL';
const TOGGLE_CONFIRMATION_MODAL = 'globalModals/TOGGLE_CONFIRMATION_MODAL';
2023-03-27 23:48:57 +00:00
const SHOW_EDIT_HISTORY_MODAL = 'globalModals/SHOW_EDIT_HISTORY_MODAL';
const CLOSE_EDIT_HISTORY_MODAL = 'globalModals/CLOSE_EDIT_HISTORY_MODAL';
const TOGGLE_USERNAME_ONBOARDING = 'globalModals/TOGGLE_USERNAME_ONBOARDING';
2021-05-28 16:15:17 +00:00
export type ContactModalStateType = ReadonlyDeep<{
2021-09-21 22:37:10 +00:00
contactId: string;
conversationId?: string;
}>;
2021-09-21 22:37:10 +00:00
export type UserNotFoundModalStateType = ReadonlyDeep<
| {
type: 'phoneNumber';
phoneNumber: string;
}
| {
type: 'username';
username: string;
}
>;
2021-11-12 01:17:29 +00:00
type HideContactModalActionType = ReadonlyDeep<{
2021-09-21 22:37:10 +00:00
type: typeof HIDE_CONTACT_MODAL;
}>;
2021-09-21 22:37:10 +00:00
type ShowContactModalActionType = ReadonlyDeep<{
2021-09-21 22:37:10 +00:00
type: typeof SHOW_CONTACT_MODAL;
payload: ContactModalStateType;
}>;
2021-09-21 22:37:10 +00:00
type HideWhatsNewModalActionType = ReadonlyDeep<{
type: typeof HIDE_WHATS_NEW_MODAL;
}>;
type ShowWhatsNewModalActionType = ReadonlyDeep<{
type: typeof SHOW_WHATS_NEW_MODAL;
}>;
type HideUserNotFoundModalActionType = ReadonlyDeep<{
type: typeof HIDE_SERVICE_ID_NOT_FOUND_MODAL;
}>;
2021-11-12 01:17:29 +00:00
export type ShowUserNotFoundModalActionType = ReadonlyDeep<{
type: typeof SHOW_SERVICE_ID_NOT_FOUND_MODAL;
payload: UserNotFoundModalStateType;
}>;
2021-11-12 01:17:29 +00:00
type ToggleDeleteMessagesModalActionType = ReadonlyDeep<{
type: typeof TOGGLE_DELETE_MESSAGES_MODAL;
payload: DeleteMessagesPropsType | undefined;
}>;
2023-03-20 22:23:53 +00:00
type ToggleForwardMessagesModalActionType = ReadonlyDeep<{
type: typeof TOGGLE_FORWARD_MESSAGES_MODAL;
payload: ForwardMessagesPropsType | undefined;
}>;
2022-07-01 00:52:03 +00:00
2024-03-26 19:48:33 +00:00
type ToggleNotePreviewModalActionType = ReadonlyDeep<{
type: typeof TOGGLE_NOTE_PREVIEW_MODAL;
payload: NotePreviewModalPropsType | null;
}>;
type ToggleProfileEditorActionType = ReadonlyDeep<{
2021-07-19 19:26:06 +00:00
type: typeof TOGGLE_PROFILE_EDITOR;
payload: {
initialEditState?: ProfileEditorEditState;
};
}>;
2021-07-19 19:26:06 +00:00
export type ToggleProfileEditorErrorActionType = ReadonlyDeep<{
2021-07-19 19:26:06 +00:00
type: typeof TOGGLE_PROFILE_EDITOR_ERROR;
}>;
2021-07-19 19:26:06 +00:00
type ToggleSafetyNumberModalActionType = ReadonlyDeep<{
type: typeof TOGGLE_SAFETY_NUMBER_MODAL;
payload: string | undefined;
}>;
type ToggleAddUserToAnotherGroupModalActionType = ReadonlyDeep<{
type: typeof TOGGLE_ADD_USER_TO_ANOTHER_GROUP_MODAL;
payload: string | undefined;
}>;
2024-06-10 15:23:43 +00:00
type ToggleCallLinkEditModalActionType = ReadonlyDeep<{
type: typeof TOGGLE_CALL_LINK_EDIT_MODAL;
payload: string | null;
}>;
type ToggleAboutContactModalActionType = ReadonlyDeep<{
type: typeof TOGGLE_ABOUT_MODAL;
2024-02-16 22:16:13 +00:00
payload: string | undefined;
}>;
type ToggleSignalConnectionsModalActionType = ReadonlyDeep<{
type: typeof TOGGLE_SIGNAL_CONNECTIONS_MODAL;
}>;
type ToggleConfirmationModalActionType = ReadonlyDeep<{
type: typeof TOGGLE_CONFIRMATION_MODAL;
payload: boolean;
}>;
type ToggleUsernameOnboardingActionType = ReadonlyDeep<{
type: typeof TOGGLE_USERNAME_ONBOARDING;
}>;
type ShowStoriesSettingsActionType = ReadonlyDeep<{
type: typeof SHOW_STORIES_SETTINGS;
}>;
type HideStoriesSettingsActionType = ReadonlyDeep<{
type: typeof HIDE_STORIES_SETTINGS;
}>;
type StartMigrationToGV2ActionType = ReadonlyDeep<{
2022-12-08 06:41:37 +00:00
type: typeof SHOW_GV2_MIGRATION_DIALOG;
payload: MigrateToGV2PropsType;
}>;
2022-12-08 06:41:37 +00:00
type CloseGV2MigrationDialogActionType = ReadonlyDeep<{
2022-12-08 06:41:37 +00:00
type: typeof CLOSE_GV2_MIGRATION_DIALOG;
}>;
2022-12-08 06:41:37 +00:00
export type ShowSendAnywayDialogActionType = ReadonlyDeep<{
type: typeof SHOW_SEND_ANYWAY_DIALOG;
payload: SafetyNumberChangedBlockingDataType & {
untrustedByConversation: RecipientsByConversation;
};
}>;
type HideSendAnywayDialogActiontype = ReadonlyDeep<{
type: typeof HIDE_SEND_ANYWAY_DIALOG;
}>;
export type ShowStickerPackPreviewActionType = ReadonlyDeep<{
type: typeof SHOW_STICKER_PACK_PREVIEW;
payload: string;
}>;
type CloseStickerPackPreviewActionType = ReadonlyDeep<{
type: typeof CLOSE_STICKER_PACK_PREVIEW;
}>;
type CloseErrorModalActionType = ReadonlyDeep<{
2022-12-22 03:07:45 +00:00
type: typeof CLOSE_ERROR_MODAL;
}>;
2022-12-22 03:07:45 +00:00
export type ShowErrorModalActionType = ReadonlyDeep<{
2022-12-22 03:07:45 +00:00
type: typeof SHOW_ERROR_MODAL;
payload: {
2024-02-22 21:19:50 +00:00
buttonVariant?: ButtonVariant;
2022-12-22 03:07:45 +00:00
description?: string;
title?: string;
};
}>;
2022-12-22 03:07:45 +00:00
2024-03-26 19:48:33 +00:00
type ToggleEditNicknameAndNoteModalActionType = ReadonlyDeep<{
type: typeof TOGGLE_EDIT_NICKNAME_AND_NOTE_MODAL;
payload: EditNicknameAndNoteModalPropsType | null;
}>;
2024-03-12 16:29:31 +00:00
type ToggleMessageRequestActionsConfirmationActionType = ReadonlyDeep<{
type: typeof TOGGLE_MESSAGE_REQUEST_ACTIONS_CONFIRMATION;
payload: MessageRequestActionsConfirmationPropsType | null;
}>;
type CloseShortcutGuideModalActionType = ReadonlyDeep<{
2022-12-22 03:07:45 +00:00
type: typeof CLOSE_SHORTCUT_GUIDE_MODAL;
}>;
2022-12-22 03:07:45 +00:00
type ShowShortcutGuideModalActionType = ReadonlyDeep<{
2022-12-22 03:07:45 +00:00
type: typeof SHOW_SHORTCUT_GUIDE_MODAL;
}>;
2022-12-22 03:07:45 +00:00
2023-03-27 23:48:57 +00:00
type ShowEditHistoryModalActionType = ReadonlyDeep<{
type: typeof SHOW_EDIT_HISTORY_MODAL;
payload: {
messages: EditHistoryMessagesType;
};
}>;
type CloseEditHistoryModalActionType = ReadonlyDeep<{
type: typeof CLOSE_EDIT_HISTORY_MODAL;
}>;
export type GlobalModalsActionType = ReadonlyDeep<
2023-03-27 23:48:57 +00:00
| CloseEditHistoryModalActionType
| CloseErrorModalActionType
2022-12-08 06:41:37 +00:00
| CloseGV2MigrationDialogActionType
2023-03-27 23:48:57 +00:00
| CloseShortcutGuideModalActionType
| CloseStickerPackPreviewActionType
2021-09-21 22:37:10 +00:00
| HideContactModalActionType
| HideSendAnywayDialogActiontype
2023-03-27 23:48:57 +00:00
| HideStoriesSettingsActionType
| HideUserNotFoundModalActionType
| HideWhatsNewModalActionType
| MessageChangedActionType
| MessageDeletedActionType
| MessageExpiredActionType
| ShowContactModalActionType
| ShowEditHistoryModalActionType
2022-12-22 03:07:45 +00:00
| ShowErrorModalActionType
2024-03-26 19:48:33 +00:00
| ToggleEditNicknameAndNoteModalActionType
2024-03-12 16:29:31 +00:00
| ToggleMessageRequestActionsConfirmationActionType
2023-03-27 23:48:57 +00:00
| ShowSendAnywayDialogActionType
2022-12-22 03:07:45 +00:00
| ShowShortcutGuideModalActionType
2023-03-27 23:48:57 +00:00
| ShowStickerPackPreviewActionType
| ShowStoriesSettingsActionType
| ShowUserNotFoundModalActionType
| ShowWhatsNewModalActionType
| StartMigrationToGV2ActionType
| ToggleAboutContactModalActionType
2023-03-27 23:48:57 +00:00
| ToggleAddUserToAnotherGroupModalActionType
2024-06-10 15:23:43 +00:00
| ToggleCallLinkEditModalActionType
| ToggleConfirmationModalActionType
| ToggleDeleteMessagesModalActionType
2023-03-20 22:23:53 +00:00
| ToggleForwardMessagesModalActionType
2024-03-26 19:48:33 +00:00
| ToggleNotePreviewModalActionType
2021-07-19 19:26:06 +00:00
| ToggleProfileEditorActionType
| ToggleProfileEditorErrorActionType
| ToggleSafetyNumberModalActionType
| ToggleSignalConnectionsModalActionType
| ToggleUsernameOnboardingActionType
>;
2021-05-28 16:15:17 +00:00
// Action Creators
export const actions = {
2023-03-27 23:48:57 +00:00
closeEditHistoryModal,
closeErrorModal,
closeGV2MigrationDialog,
closeShortcutGuideModal,
closeStickerPackPreview,
hideBlockingSafetyNumberChangeDialog,
2021-09-21 22:37:10 +00:00
hideContactModal,
hideStoriesSettings,
2023-03-27 23:48:57 +00:00
hideUserNotFoundModal,
hideWhatsNewModal,
showBlockingSafetyNumberChangeDialog,
2023-03-27 23:48:57 +00:00
showContactModal,
showEditHistoryModal,
showErrorModal,
2024-03-26 19:48:33 +00:00
toggleEditNicknameAndNoteModal,
2024-03-12 16:29:31 +00:00
toggleMessageRequestActionsConfirmation,
2023-03-27 23:48:57 +00:00
showGV2MigrationDialog,
2024-06-10 15:23:43 +00:00
showShareCallLinkViaSignal,
2023-03-27 23:48:57 +00:00
showShortcutGuideModal,
showStickerPackPreview,
showStoriesSettings,
showUserNotFoundModal,
showWhatsNewModal,
toggleAboutContactModal,
2023-03-27 23:48:57 +00:00
toggleAddUserToAnotherGroupModal,
2024-06-10 15:23:43 +00:00
toggleCallLinkEditModal,
2023-03-27 23:48:57 +00:00
toggleConfirmationModal,
toggleDeleteMessagesModal,
2023-03-20 22:23:53 +00:00
toggleForwardMessagesModal,
2024-03-26 19:48:33 +00:00
toggleNotePreviewModal,
2021-07-19 19:26:06 +00:00
toggleProfileEditor,
toggleProfileEditorHasError,
toggleSafetyNumberModal,
toggleSignalConnectionsModal,
toggleUsernameOnboarding,
2021-05-28 16:15:17 +00:00
};
export const useGlobalModalActions = (): BoundActionCreatorsMapObject<
typeof actions
> => useBoundActions(actions);
2022-07-01 00:52:03 +00:00
2021-09-21 22:37:10 +00:00
function hideContactModal(): HideContactModalActionType {
return {
type: HIDE_CONTACT_MODAL,
};
}
function showContactModal(
contactId: string,
conversationId?: string
): ShowContactModalActionType {
return {
type: SHOW_CONTACT_MODAL,
payload: {
contactId,
conversationId,
},
};
}
function hideWhatsNewModal(): HideWhatsNewModalActionType {
return {
type: HIDE_WHATS_NEW_MODAL,
};
}
function showWhatsNewModal(): ShowWhatsNewModalActionType {
return {
type: SHOW_WHATS_NEW_MODAL,
};
}
function hideUserNotFoundModal(): HideUserNotFoundModalActionType {
2021-11-12 01:17:29 +00:00
return {
type: HIDE_SERVICE_ID_NOT_FOUND_MODAL,
2021-11-12 01:17:29 +00:00
};
}
function showUserNotFoundModal(
payload: UserNotFoundModalStateType
): ShowUserNotFoundModalActionType {
2021-11-12 01:17:29 +00:00
return {
type: SHOW_SERVICE_ID_NOT_FOUND_MODAL,
payload,
2021-11-12 01:17:29 +00:00
};
}
function hideStoriesSettings(): HideStoriesSettingsActionType {
return { type: HIDE_STORIES_SETTINGS };
}
function showStoriesSettings(): ShowStoriesSettingsActionType {
return { type: SHOW_STORIES_SETTINGS };
}
2022-12-08 06:41:37 +00:00
function showGV2MigrationDialog(
conversationId: string
): ThunkAction<void, RootStateType, unknown, StartMigrationToGV2ActionType> {
return async dispatch => {
const conversation = window.ConversationController.get(conversationId);
if (!conversation) {
throw new Error(
'showGV2MigrationDialog: Expected a conversation to be found. Doing nothing'
);
}
const idForLogging = conversation.idForLogging();
if (!isGroupV1(conversation.attributes)) {
throw new Error(
`showGV2MigrationDialog/${idForLogging}: Cannot start, not a GroupV1 group`
);
}
// Note: this call will throw if, after generating member lists, we are no longer a
// member or are in the pending member list.
const { droppedGV2MemberIds, pendingMembersV2 } =
await longRunningTaskWrapper({
idForLogging,
name: 'getGroupMigrationMembers',
task: () => getGroupMigrationMembers(conversation),
});
const invitedMemberIds = pendingMembersV2.map(
2023-08-16 20:54:39 +00:00
(item: GroupV2PendingMemberType) => item.serviceId
2022-12-08 06:41:37 +00:00
);
dispatch({
type: SHOW_GV2_MIGRATION_DIALOG,
payload: {
areWeInvited: false,
conversationId,
droppedMemberIds: droppedGV2MemberIds,
hasMigrated: false,
invitedMemberIds,
},
});
};
}
function closeGV2MigrationDialog(): CloseGV2MigrationDialogActionType {
return {
type: CLOSE_GV2_MIGRATION_DIALOG,
};
}
function toggleDeleteMessagesModal(
props: DeleteMessagesPropsType | undefined
): ToggleDeleteMessagesModalActionType {
return {
type: TOGGLE_DELETE_MESSAGES_MODAL,
payload: props,
};
}
2024-05-22 16:24:27 +00:00
function toMessageForwardDraft(
props: ForwardMessagePropsType,
getConversation: GetConversationByIdType
): MessageForwardDraft {
return {
attachments: props.attachments ?? [],
bodyRanges: hydrateRanges(props.bodyRanges, getConversation),
hasContact: Boolean(props.contact),
isSticker: Boolean(props.isSticker),
messageBody: props.text,
originalMessageId: props.id,
previews: props.previews ?? [],
};
}
export type ForwardMessagesPayload = ReadonlyDeep<
| {
type: ForwardMessagesModalType.Forward;
messageIds: ReadonlyArray<string>;
}
| {
type: ForwardMessagesModalType.ShareCallLink;
draft: MessageForwardDraft;
}
>;
2023-03-20 22:23:53 +00:00
function toggleForwardMessagesModal(
2024-05-22 16:24:27 +00:00
payload: ForwardMessagesPayload | null,
2023-03-20 22:23:53 +00:00
onForward?: () => void
2022-07-01 00:52:03 +00:00
): ThunkAction<
void,
RootStateType,
unknown,
2023-03-20 22:23:53 +00:00
ToggleForwardMessagesModalActionType
2022-07-01 00:52:03 +00:00
> {
return async (dispatch, getState) => {
2024-05-22 16:24:27 +00:00
if (payload == null) {
2022-07-01 00:52:03 +00:00
dispatch({
2023-03-20 22:23:53 +00:00
type: TOGGLE_FORWARD_MESSAGES_MODAL,
2022-07-01 00:52:03 +00:00
payload: undefined,
});
return;
}
2024-05-22 16:24:27 +00:00
let messageDrafts: ReadonlyArray<MessageForwardDraft>;
2024-05-22 16:24:27 +00:00
if (payload.type === ForwardMessagesModalType.Forward) {
messageDrafts = await Promise.all(
payload.messageIds.map(async messageId => {
const messageAttributes = await window.MessageCache.resolveAttributes(
'toggleForwardMessagesModal',
messageId
);
2024-05-22 16:24:27 +00:00
const { attachments = [] } = messageAttributes;
2022-07-01 00:52:03 +00:00
2024-05-22 16:24:27 +00:00
if (!attachments.every(isDownloaded)) {
dispatch(
conversationsActions.kickOffAttachmentDownload({ messageId })
);
}
const state = getState();
const messagePropsSelector = getMessagePropsSelector(state);
const conversationSelector = getConversationSelector(state);
const messageProps = messagePropsSelector(messageAttributes);
const messageDraft = toMessageForwardDraft(
messageProps,
conversationSelector
);
return messageDraft;
})
);
} else if (payload.type === ForwardMessagesModalType.ShareCallLink) {
messageDrafts = [payload.draft];
} else {
throw missingCaseError(payload);
}
2022-07-01 00:52:03 +00:00
dispatch({
2023-03-20 22:23:53 +00:00
type: TOGGLE_FORWARD_MESSAGES_MODAL,
2024-05-22 16:24:27 +00:00
payload: { type: payload.type, messageDrafts, onForward },
2022-07-01 00:52:03 +00:00
});
};
}
2024-06-10 15:23:43 +00:00
function showShareCallLinkViaSignal(
callLink: CallLinkType,
i18n: LocalizerType
): ThunkAction<
void,
RootStateType,
unknown,
ToggleForwardMessagesModalActionType
> {
return dispatch => {
const url = linkCallRoute
.toWebUrl({
key: callLink.rootKey,
})
.toString();
dispatch(
toggleForwardMessagesModal({
type: ForwardMessagesModalType.ShareCallLink,
draft: {
originalMessageId: null,
hasContact: false,
isSticker: false,
previews: [
{
title: callLink.name,
url,
isCallLink: true,
},
],
messageBody: i18n(
'icu:ShareCallLinkViaSignal__DraftMessageText',
{
url,
},
{ textIsBidiFreeSkipNormalization: true }
),
},
})
);
};
}
2024-03-26 19:48:33 +00:00
function toggleNotePreviewModal(
payload: NotePreviewModalPropsType | null
): ToggleNotePreviewModalActionType {
return {
type: TOGGLE_NOTE_PREVIEW_MODAL,
payload,
};
}
function toggleProfileEditor(
initialEditState?: ProfileEditorEditState
): ToggleProfileEditorActionType {
return { type: TOGGLE_PROFILE_EDITOR, payload: { initialEditState } };
2021-07-19 19:26:06 +00:00
}
function toggleProfileEditorHasError(): ToggleProfileEditorErrorActionType {
return { type: TOGGLE_PROFILE_EDITOR_ERROR };
}
function toggleSafetyNumberModal(
safetyNumberModalContactId?: string
): ToggleSafetyNumberModalActionType {
return {
type: TOGGLE_SAFETY_NUMBER_MODAL,
payload: safetyNumberModalContactId,
};
}
function toggleAddUserToAnotherGroupModal(
contactId?: string
): ToggleAddUserToAnotherGroupModalActionType {
return {
type: TOGGLE_ADD_USER_TO_ANOTHER_GROUP_MODAL,
payload: contactId,
};
}
2024-06-10 15:23:43 +00:00
function toggleCallLinkEditModal(
roomId: string | null
): ToggleCallLinkEditModalActionType {
return {
type: TOGGLE_CALL_LINK_EDIT_MODAL,
payload: roomId,
};
}
function toggleAboutContactModal(
contactId?: string
): ToggleAboutContactModalActionType {
return {
type: TOGGLE_ABOUT_MODAL,
2024-02-16 22:16:13 +00:00
payload: contactId,
};
}
function toggleSignalConnectionsModal(): ToggleSignalConnectionsModalActionType {
return {
type: TOGGLE_SIGNAL_CONNECTIONS_MODAL,
};
}
function toggleConfirmationModal(
isOpen: boolean
): ToggleConfirmationModalActionType {
return {
type: TOGGLE_CONFIRMATION_MODAL,
payload: isOpen,
};
}
function toggleUsernameOnboarding(): ToggleUsernameOnboardingActionType {
return { type: TOGGLE_USERNAME_ONBOARDING };
}
function showBlockingSafetyNumberChangeDialog(
untrustedByConversation: RecipientsByConversation,
explodedPromise: ExplodePromiseResultType<boolean>,
source?: SafetyNumberChangeSource
): ThunkAction<void, RootStateType, unknown, ShowSendAnywayDialogActionType> {
const promiseUuid = SingleServePromise.set<boolean>(explodedPromise);
return dispatch => {
dispatch({
type: SHOW_SEND_ANYWAY_DIALOG,
payload: {
untrustedByConversation,
promiseUuid,
source,
},
});
};
}
function hideBlockingSafetyNumberChangeDialog(): HideSendAnywayDialogActiontype {
return {
type: HIDE_SEND_ANYWAY_DIALOG,
};
}
function closeStickerPackPreview(): ThunkAction<
void,
RootStateType,
unknown,
CloseStickerPackPreviewActionType
> {
return async (dispatch, getState) => {
const packId = getState().globalModals.stickerPackPreviewId;
if (packId && Stickers.getStickerPack(packId) !== undefined) {
await Stickers.removeEphemeralPack(packId);
}
dispatch({
type: CLOSE_STICKER_PACK_PREVIEW,
});
};
}
2022-12-10 02:02:22 +00:00
export function showStickerPackPreview(
packId: string,
packKey: string
): ShowStickerPackPreviewActionType {
// Intentionally not awaiting this so that we can show the modal right away.
// The modal has a loading spinner on it.
void Stickers.downloadEphemeralPack(packId, packKey);
return {
type: SHOW_STICKER_PACK_PREVIEW,
payload: packId,
};
}
2022-12-22 03:07:45 +00:00
function closeErrorModal(): CloseErrorModalActionType {
return {
type: CLOSE_ERROR_MODAL,
};
}
function showErrorModal({
2024-02-22 21:19:50 +00:00
buttonVariant,
2022-12-22 03:07:45 +00:00
description,
title,
}: {
2024-02-22 21:19:50 +00:00
buttonVariant?: ButtonVariant;
2022-12-22 03:07:45 +00:00
description?: string;
2024-02-22 21:19:50 +00:00
title?: string;
2022-12-22 03:07:45 +00:00
}): ShowErrorModalActionType {
return {
type: SHOW_ERROR_MODAL,
payload: {
2024-02-22 21:19:50 +00:00
buttonVariant,
2022-12-22 03:07:45 +00:00
description,
title,
},
};
}
2024-03-26 19:48:33 +00:00
function toggleEditNicknameAndNoteModal(
payload: EditNicknameAndNoteModalPropsType | null
): ToggleEditNicknameAndNoteModalActionType {
return {
type: TOGGLE_EDIT_NICKNAME_AND_NOTE_MODAL,
payload,
};
}
2024-03-12 16:29:31 +00:00
function toggleMessageRequestActionsConfirmation(
payload: {
conversationId: string;
state: MessageRequestState;
} | null
): ToggleMessageRequestActionsConfirmationActionType {
return {
type: TOGGLE_MESSAGE_REQUEST_ACTIONS_CONFIRMATION,
payload,
};
}
2022-12-22 03:07:45 +00:00
function closeShortcutGuideModal(): CloseShortcutGuideModalActionType {
return {
type: CLOSE_SHORTCUT_GUIDE_MODAL,
};
}
function showShortcutGuideModal(): ShowShortcutGuideModalActionType {
return {
type: SHOW_SHORTCUT_GUIDE_MODAL,
};
}
2023-03-27 23:48:57 +00:00
function copyOverMessageAttributesIntoEditHistory(
messageAttributes: ReadonlyDeep<MessageAttributesType>
): EditHistoryMessagesType | undefined {
if (!messageAttributes.editHistory) {
return;
}
return messageAttributes.editHistory.map(editedMessageAttributes => ({
...messageAttributes,
// Always take attachments from the edited message (they might be absent)
attachments: undefined,
2023-07-05 22:38:37 +00:00
editMessageTimestamp: undefined,
quote: undefined,
preview: [],
2023-03-27 23:48:57 +00:00
...editedMessageAttributes,
// For timestamp uniqueness of messages
sent_at: editedMessageAttributes.timestamp,
}));
}
function showEditHistoryModal(
messageId: string
): ThunkAction<void, RootStateType, unknown, ShowEditHistoryModalActionType> {
return async dispatch => {
const messageAttributes = await window.MessageCache.resolveAttributes(
'showEditHistoryModal',
messageId
);
2023-03-27 23:48:57 +00:00
const nextEditHistoryMessages =
copyOverMessageAttributesIntoEditHistory(messageAttributes);
if (!nextEditHistoryMessages) {
log.warn('showEditHistoryModal: no edit history for message');
return;
}
dispatch({
type: SHOW_EDIT_HISTORY_MODAL,
payload: {
messages: nextEditHistoryMessages,
},
});
};
}
function closeEditHistoryModal(): CloseEditHistoryModalActionType {
return {
type: CLOSE_EDIT_HISTORY_MODAL,
};
}
function copyOverMessageAttributesIntoForwardMessages(
2024-05-22 16:24:27 +00:00
messageDrafts: ReadonlyArray<MessageForwardDraft>,
attributes: ReadonlyDeep<MessageAttributesType>
2024-05-22 16:24:27 +00:00
): ReadonlyArray<MessageForwardDraft> {
return messageDrafts.map(messageDraft => {
if (messageDraft.originalMessageId !== attributes.id) {
return messageDraft;
}
return {
2024-05-22 16:24:27 +00:00
...messageDraft,
attachments: attributes.attachments,
};
});
}
2021-05-28 16:15:17 +00:00
// Reducer
export function getEmptyState(): GlobalModalsStateType {
return {
hasConfirmationModal: false,
2024-06-10 15:23:43 +00:00
callLinkEditModalRoomId: null,
2024-03-26 19:48:33 +00:00
editNicknameAndNoteModalProps: null,
2021-07-19 19:26:06 +00:00
isProfileEditorVisible: false,
2022-12-22 03:07:45 +00:00
isShortcutGuideModalVisible: false,
isSignalConnectionsVisible: false,
isStoriesSettingsVisible: false,
isWhatsNewVisible: false,
usernameOnboardingState: UsernameOnboardingState.NeverShown,
profileEditorHasError: false,
profileEditorInitialEditState: undefined,
2024-03-12 16:29:31 +00:00
messageRequestActionsConfirmationProps: null,
2024-03-26 19:48:33 +00:00
notePreviewModalProps: null,
2021-05-28 16:15:17 +00:00
};
}
export function reducer(
state: Readonly<GlobalModalsStateType> = getEmptyState(),
action: Readonly<GlobalModalsActionType>
): GlobalModalsStateType {
if (action.type === TOGGLE_ABOUT_MODAL) {
return {
...state,
2024-02-16 22:16:13 +00:00
aboutContactModalContactId: action.payload,
};
}
2024-03-26 19:48:33 +00:00
if (action.type === TOGGLE_NOTE_PREVIEW_MODAL) {
return {
...state,
notePreviewModalProps: action.payload,
};
}
2021-07-19 19:26:06 +00:00
if (action.type === TOGGLE_PROFILE_EDITOR) {
return {
...state,
isProfileEditorVisible: !state.isProfileEditorVisible,
profileEditorInitialEditState: action.payload.initialEditState,
2021-07-19 19:26:06 +00:00
};
}
if (action.type === TOGGLE_PROFILE_EDITOR_ERROR) {
return {
...state,
profileEditorHasError: !state.profileEditorHasError,
};
}
if (action.type === SHOW_WHATS_NEW_MODAL) {
return {
...state,
isWhatsNewVisible: true,
};
}
if (action.type === HIDE_WHATS_NEW_MODAL) {
return {
...state,
isWhatsNewVisible: false,
};
}
if (action.type === HIDE_SERVICE_ID_NOT_FOUND_MODAL) {
2021-11-12 01:17:29 +00:00
return {
...state,
userNotFoundModalState: undefined,
2021-11-12 01:17:29 +00:00
};
}
if (action.type === SHOW_SERVICE_ID_NOT_FOUND_MODAL) {
2021-11-12 01:17:29 +00:00
return {
...state,
userNotFoundModalState: {
...action.payload,
2021-11-12 01:17:29 +00:00
},
};
}
2021-09-21 22:37:10 +00:00
if (action.type === SHOW_CONTACT_MODAL) {
2024-02-16 22:16:13 +00:00
const ourId = window.ConversationController.getOurConversationIdOrThrow();
if (action.payload.contactId === ourId) {
return {
...state,
aboutContactModalContactId: ourId,
};
}
2021-09-21 22:37:10 +00:00
return {
...state,
contactModalState: action.payload,
};
}
if (action.type === HIDE_CONTACT_MODAL) {
return {
...state,
contactModalState: undefined,
};
}
if (action.type === TOGGLE_SAFETY_NUMBER_MODAL) {
return {
...state,
safetyNumberModalContactId: action.payload,
};
}
if (action.type === TOGGLE_ADD_USER_TO_ANOTHER_GROUP_MODAL) {
return {
...state,
addUserToAnotherGroupModalContactId: action.payload,
};
}
2024-06-10 15:23:43 +00:00
if (action.type === TOGGLE_CALL_LINK_EDIT_MODAL) {
return {
...state,
callLinkEditModalRoomId: action.payload,
};
}
if (action.type === TOGGLE_DELETE_MESSAGES_MODAL) {
return {
...state,
deleteMessagesProps: action.payload,
};
}
2023-03-20 22:23:53 +00:00
if (action.type === TOGGLE_FORWARD_MESSAGES_MODAL) {
2022-07-01 00:52:03 +00:00
return {
...state,
2023-03-20 22:23:53 +00:00
forwardMessagesProps: action.payload,
2022-07-01 00:52:03 +00:00
};
}
if (action.type === HIDE_STORIES_SETTINGS) {
return {
...state,
isStoriesSettingsVisible: false,
};
}
if (action.type === SHOW_STORIES_SETTINGS) {
return {
...state,
isStoriesSettingsVisible: true,
};
}
if (action.type === TOGGLE_SIGNAL_CONNECTIONS_MODAL) {
return {
...state,
isSignalConnectionsVisible: !state.isSignalConnectionsVisible,
};
}
if (action.type === TOGGLE_CONFIRMATION_MODAL) {
return {
...state,
hasConfirmationModal: action.payload,
};
}
if (action.type === TOGGLE_USERNAME_ONBOARDING) {
return {
...state,
usernameOnboardingState:
state.usernameOnboardingState === UsernameOnboardingState.Open
? UsernameOnboardingState.Closed
: UsernameOnboardingState.Open,
};
}
if (action.type === SHOW_SEND_ANYWAY_DIALOG) {
const { promiseUuid, source } = action.payload;
return {
...state,
safetyNumberChangedBlockingData: {
promiseUuid,
source,
},
};
}
if (action.type === HIDE_SEND_ANYWAY_DIALOG) {
return {
...state,
safetyNumberChangedBlockingData: undefined,
};
}
if (action.type === CLOSE_STICKER_PACK_PREVIEW) {
return {
...state,
stickerPackPreviewId: undefined,
};
}
if (action.type === SHOW_STICKER_PACK_PREVIEW) {
return {
...state,
stickerPackPreviewId: action.payload,
};
}
2022-12-22 03:07:45 +00:00
if (action.type === CLOSE_ERROR_MODAL) {
return {
...state,
errorModalProps: undefined,
};
}
if (action.type === SHOW_ERROR_MODAL) {
return {
...state,
errorModalProps: action.payload,
};
2024-03-26 19:48:33 +00:00
}
if (action.type === TOGGLE_EDIT_NICKNAME_AND_NOTE_MODAL) {
return {
...state,
editNicknameAndNoteModalProps: action.payload,
};
2022-12-22 03:07:45 +00:00
}
2024-03-12 16:29:31 +00:00
if (action.type === TOGGLE_MESSAGE_REQUEST_ACTIONS_CONFIRMATION) {
return {
...state,
messageRequestActionsConfirmationProps: action.payload,
};
}
2022-12-22 03:07:45 +00:00
if (action.type === CLOSE_SHORTCUT_GUIDE_MODAL) {
return {
...state,
isShortcutGuideModalVisible: false,
};
}
if (action.type === SHOW_SHORTCUT_GUIDE_MODAL) {
return {
...state,
isShortcutGuideModalVisible: true,
};
}
2023-03-27 23:48:57 +00:00
if (action.type === SHOW_EDIT_HISTORY_MODAL) {
return {
...state,
editHistoryMessages: action.payload.messages,
};
}
if (action.type === CLOSE_EDIT_HISTORY_MODAL) {
return {
...state,
editHistoryMessages: undefined,
};
}
if (state.forwardMessagesProps != null) {
if (action.type === MESSAGE_CHANGED) {
if (
2024-05-22 16:24:27 +00:00
!state.forwardMessagesProps.messageDrafts.some(message => {
return message.originalMessageId === action.payload.id;
})
) {
2023-03-27 23:48:57 +00:00
return state;
}
return {
...state,
forwardMessagesProps: {
...state.forwardMessagesProps,
2024-05-22 16:24:27 +00:00
messageDrafts: copyOverMessageAttributesIntoForwardMessages(
state.forwardMessagesProps.messageDrafts,
action.payload.data
),
},
2023-03-27 23:48:57 +00:00
};
}
}
2023-03-27 23:48:57 +00:00
if (state.editHistoryMessages != null) {
if (
action.type === MESSAGE_CHANGED ||
action.type === MESSAGE_DELETED ||
action.type === MESSAGE_EXPIRED
) {
if (action.type === MESSAGE_DELETED || action.type === MESSAGE_EXPIRED) {
const hasMessageId = state.editHistoryMessages.some(
edit => edit.id === action.payload.id
);
if (!hasMessageId) {
return state;
}
return {
...state,
editHistoryMessages: undefined,
};
2023-03-27 23:48:57 +00:00
}
if (action.type === MESSAGE_CHANGED) {
if (!action.payload.data.editHistory) {
return state;
}
2023-03-27 23:48:57 +00:00
const hasMessageId = state.editHistoryMessages.some(
edit => edit.id === action.payload.id
);
2023-03-27 23:48:57 +00:00
if (!hasMessageId) {
return state;
}
2023-03-27 23:48:57 +00:00
const nextEditHistoryMessages =
copyOverMessageAttributesIntoEditHistory(action.payload.data);
2023-03-27 23:48:57 +00:00
if (!nextEditHistoryMessages) {
return state;
}
return {
...state,
editHistoryMessages: nextEditHistoryMessages,
};
}
2023-03-27 23:48:57 +00:00
}
}
2021-05-28 16:15:17 +00:00
return state;
}