Moves showStickerPackPreview to globalModals

This commit is contained in:
Josh Perez 2022-12-09 14:01:46 -05:00 committed by GitHub
parent c0ebafe2bc
commit 7c68f9ef1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 104 additions and 124 deletions

View file

@ -37,6 +37,9 @@ export type PropsType = {
// SignalConnectionsModal
isSignalConnectionsVisible: boolean;
toggleSignalConnectionsModal: () => unknown;
// StickerPackPreviewModal
stickerPackPreviewId?: string;
renderStickerPreviewModal: () => JSX.Element | null;
// StoriesSettings
isStoriesSettingsVisible: boolean;
renderStoriesSettings: () => JSX.Element;
@ -72,6 +75,9 @@ export function GlobalModalContainer({
// SignalConnectionsModal
isSignalConnectionsVisible,
toggleSignalConnectionsModal,
// StickerPackPreviewModal
stickerPackPreviewId,
renderStickerPreviewModal,
// StoriesSettings
isStoriesSettingsVisible,
renderStoriesSettings,
@ -158,5 +164,9 @@ export function GlobalModalContainer({
return renderStoriesSettings();
}
if (stickerPackPreviewId) {
return renderStickerPreviewModal();
}
return null;
}

View file

@ -68,7 +68,7 @@ export const StickerManager = React.memo(function StickerManagerInner({
<StickerPreviewModal
i18n={i18n}
pack={packToPreview}
onClose={clearPackToPreview}
closeStickerPackPreview={clearPackToPreview}
downloadStickerPack={downloadStickerPack}
installStickerPack={installStickerPack}
uninstallStickerPack={uninstallStickerPack}

View file

@ -64,7 +64,7 @@ export function Full(): JSX.Element {
return (
<StickerPreviewModal
onClose={action('onClose')}
closeStickerPackPreview={action('closeStickerPackPreview')}
installStickerPack={action('installStickerPack')}
uninstallStickerPack={action('uninstallStickerPack')}
downloadStickerPack={action('downloadStickerPack')}
@ -93,7 +93,7 @@ export function JustFourStickers(): JSX.Element {
return (
<StickerPreviewModal
onClose={action('onClose')}
closeStickerPackPreview={action('closeStickerPackPreview')}
installStickerPack={action('installStickerPack')}
uninstallStickerPack={action('uninstallStickerPack')}
downloadStickerPack={action('downloadStickerPack')}
@ -110,7 +110,7 @@ JustFourStickers.story = {
export function InitialDownload(): JSX.Element {
return (
<StickerPreviewModal
onClose={action('onClose')}
closeStickerPackPreview={action('closeStickerPackPreview')}
installStickerPack={action('installStickerPack')}
uninstallStickerPack={action('uninstallStickerPack')}
downloadStickerPack={action('downloadStickerPack')}
@ -128,7 +128,7 @@ InitialDownload.story = {
export function PackDeleted(): JSX.Element {
return (
<StickerPreviewModal
onClose={action('onClose')}
closeStickerPackPreview={action('closeStickerPackPreview')}
installStickerPack={action('installStickerPack')}
uninstallStickerPack={action('uninstallStickerPack')}
downloadStickerPack={action('downloadStickerPack')}

View file

@ -13,7 +13,7 @@ import { Spinner } from '../Spinner';
import { useRestoreFocus } from '../../hooks/useRestoreFocus';
export type OwnProps = {
readonly onClose: () => unknown;
readonly closeStickerPackPreview: () => unknown;
readonly downloadStickerPack: (
packId: string,
packKey: string,
@ -76,7 +76,7 @@ export const StickerPreviewModal = React.memo(function StickerPreviewModalInner(
props: Props
) {
const {
onClose,
closeStickerPackPreview,
pack,
i18n,
downloadStickerPack,
@ -119,9 +119,9 @@ export const StickerPreviewModal = React.memo(function StickerPreviewModalInner(
React.useEffect(() => {
if (!pack) {
onClose();
closeStickerPackPreview();
}
}, [pack, onClose]);
}, [pack, closeStickerPackPreview]);
const isInstalled = Boolean(pack && pack.status === 'installed');
const handleToggleInstall = React.useCallback(() => {
@ -132,16 +132,16 @@ export const StickerPreviewModal = React.memo(function StickerPreviewModalInner(
setConfirmingUninstall(true);
} else if (pack.status === 'ephemeral') {
downloadStickerPack(pack.id, pack.key, { finalStatus: 'installed' });
onClose();
closeStickerPackPreview();
} else {
installStickerPack(pack.id, pack.key);
onClose();
closeStickerPackPreview();
}
}, [
downloadStickerPack,
installStickerPack,
isInstalled,
onClose,
closeStickerPackPreview,
pack,
setConfirmingUninstall,
]);
@ -152,13 +152,13 @@ export const StickerPreviewModal = React.memo(function StickerPreviewModalInner(
}
uninstallStickerPack(pack.id, pack.key);
setConfirmingUninstall(false);
// onClose is called by <ConfirmationDialog />
// closeStickerPackPreview is called by <ConfirmationDialog />'s onClose
}, [uninstallStickerPack, setConfirmingUninstall, pack]);
React.useEffect(() => {
const handler = ({ key }: KeyboardEvent) => {
if (key === 'Escape') {
onClose();
closeStickerPackPreview();
}
};
@ -167,15 +167,15 @@ export const StickerPreviewModal = React.memo(function StickerPreviewModalInner(
return () => {
document.removeEventListener('keydown', handler);
};
}, [onClose]);
}, [closeStickerPackPreview]);
const handleClickToClose = React.useCallback(
(e: React.MouseEvent) => {
if (e.target === e.currentTarget) {
onClose();
closeStickerPackPreview();
}
},
[onClose]
[closeStickerPackPreview]
);
return root
@ -192,7 +192,7 @@ export const StickerPreviewModal = React.memo(function StickerPreviewModalInner(
<ConfirmationDialog
dialogName="StickerPreviewModal.confirmUninstall"
i18n={i18n}
onClose={onClose}
onClose={closeStickerPackPreview}
actions={[
{
style: 'negative',
@ -211,7 +211,7 @@ export const StickerPreviewModal = React.memo(function StickerPreviewModalInner(
</h2>
<button
type="button"
onClick={onClose}
onClick={closeStickerPackPreview}
className="module-sticker-manager__preview-modal__container__header__close-button"
aria-label={i18n('close')}
/>

View file

@ -35,7 +35,6 @@ import { createGroupV2Permissions } from './state/roots/createGroupV2Permissions
import { createPendingInvites } from './state/roots/createPendingInvites';
import { createSafetyNumberViewer } from './state/roots/createSafetyNumberViewer';
import { createStickerManager } from './state/roots/createStickerManager';
import { createStickerPreviewModal } from './state/roots/createStickerPreviewModal';
import { createShortcutGuideModal } from './state/roots/createShortcutGuideModal';
import { createStore } from './state/createStore';
@ -417,7 +416,6 @@ export const setup = (options: {
createSafetyNumberViewer,
createShortcutGuideModal,
createStickerManager,
createStickerPreviewModal,
};
const Ducks = {

View file

@ -10,6 +10,7 @@ import type { SafetyNumberChangeSource } from '../../components/SafetyNumberChan
import type { StateType as RootStateType } from '../reducer';
import type { UUIDStringType } from '../../types/UUID';
import * as SingleServePromise from '../../services/singleServePromise';
import * as Stickers from '../../types/Stickers';
import { getMessageById } from '../../messages/getMessageById';
import { getMessagePropsSelector } from '../selectors/message';
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
@ -49,6 +50,7 @@ export type GlobalModalsStateType = Readonly<{
profileEditorHasError: boolean;
safetyNumberChangedBlockingData?: SafetyNumberChangedBlockingDataType;
safetyNumberModalContactId?: string;
stickerPackPreviewId?: string;
userNotFoundModalState?: UserNotFoundModalStateType;
}>;
@ -76,6 +78,8 @@ export const SHOW_SEND_ANYWAY_DIALOG = 'globalModals/SHOW_SEND_ANYWAY_DIALOG';
const HIDE_SEND_ANYWAY_DIALOG = 'globalModals/HIDE_SEND_ANYWAY_DIALOG';
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';
export type ContactModalStateType = {
contactId: string;
@ -173,6 +177,15 @@ type HideSendAnywayDialogActiontype = {
type: typeof HIDE_SEND_ANYWAY_DIALOG;
};
type ShowStickerPackPreviewActionType = {
type: typeof SHOW_STICKER_PACK_PREVIEW;
payload: string;
};
type CloseStickerPackPreviewActionType = {
type: typeof CLOSE_STICKER_PACK_PREVIEW;
};
export type GlobalModalsActionType =
| StartMigrationToGV2ActionType
| CloseGV2MigrationDialogActionType
@ -186,6 +199,8 @@ export type GlobalModalsActionType =
| ShowStoriesSettingsActionType
| HideSendAnywayDialogActiontype
| ShowSendAnywayDialogActionType
| CloseStickerPackPreviewActionType
| ShowStickerPackPreviewActionType
| ToggleForwardMessageModalActionType
| ToggleProfileEditorActionType
| ToggleProfileEditorErrorActionType
@ -214,6 +229,8 @@ export const actions = {
toggleSignalConnectionsModal,
showGV2MigrationDialog,
closeGV2MigrationDialog,
showStickerPackPreview,
closeStickerPackPreview,
};
export const useGlobalModalActions = (): BoundActionCreatorsMapObject<
@ -417,6 +434,40 @@ function hideBlockingSafetyNumberChangeDialog(): HideSendAnywayDialogActiontype
};
}
function closeStickerPackPreview(): ThunkAction<
void,
RootStateType,
unknown,
CloseStickerPackPreviewActionType
> {
return async (dispatch, getState) => {
const packId = getState().globalModals.stickerPackPreviewId;
if (!packId) {
return;
}
await Stickers.removeEphemeralPack(packId);
dispatch({
type: CLOSE_STICKER_PACK_PREVIEW,
});
};
}
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.
Stickers.downloadEphemeralPack(packId, packKey);
return {
type: SHOW_STICKER_PACK_PREVIEW,
payload: packId,
};
}
// Reducer
export function getEmptyState(): GlobalModalsStateType {
@ -552,5 +603,19 @@ export function reducer(
};
}
if (action.type === CLOSE_STICKER_PACK_PREVIEW) {
return {
...state,
stickerPackPreviewId: undefined,
};
}
if (action.type === SHOW_STICKER_PACK_PREVIEW) {
return {
...state,
stickerPackPreviewId: action.payload,
};
}
return state;
}

View file

@ -1,19 +0,0 @@
// Copyright 2019-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { Provider } from 'react-redux';
import type { Store } from 'redux';
import type { ExternalProps } from '../smart/StickerPreviewModal';
import { SmartStickerPreviewModal } from '../smart/StickerPreviewModal';
export const createStickerPreviewModal = (
store: Store,
props: ExternalProps
): React.ReactElement => (
<Provider store={store}>
<SmartStickerPreviewModal {...props} />
</Provider>
);

View file

@ -16,6 +16,7 @@ import { mapDispatchToProps } from '../actions';
import { getIntl, getTheme } from '../selectors/user';
import { SmartAddUserToAnotherGroupModal } from './AddUserToAnotherGroupModal';
import { SmartStickerPreviewModal } from './StickerPreviewModal';
function renderProfileEditor(): JSX.Element {
return <SmartProfileEditorModal />;
@ -40,6 +41,8 @@ function renderSendAnywayDialog(): JSX.Element {
const mapStateToProps = (state: StateType) => {
const i18n = getIntl(state);
const { stickerPackPreviewId } = state.globalModals;
return {
...state.globalModals,
hasSafetyNumberChangeModal: getConversationsStoppingSend(state).length > 0,
@ -49,6 +52,10 @@ const mapStateToProps = (state: StateType) => {
renderForwardMessageModal,
renderProfileEditor,
renderStoriesSettings,
renderStickerPreviewModal: () =>
stickerPackPreviewId ? (
<SmartStickerPreviewModal packId={stickerPackPreviewId} />
) : null,
renderSafetyNumber: () => (
<SmartSafetyNumberModal
contactID={String(state.globalModals.safetyNumberModalContactId)}

View file

@ -15,7 +15,6 @@ import {
export type ExternalProps = {
packId: string;
readonly onClose: () => unknown;
};
const mapStateToProps = (state: StateType, props: ExternalProps) => {

View file

@ -441,50 +441,7 @@ export function createIPCEvents(
log.warn('showStickerPack: Not registered, returning early');
return;
}
if (window.isShowingModal) {
log.warn('showStickerPack: Already showing modal, returning early');
return;
}
try {
window.isShowingModal = true;
// Kick off the download
Stickers.downloadEphemeralPack(packId, key);
const props = {
packId,
onClose: async () => {
window.isShowingModal = false;
stickerPreviewModalView.remove();
await Stickers.removeEphemeralPack(packId);
},
};
const stickerPreviewModalView = new ReactWrapperView({
className: 'sticker-preview-modal-wrapper',
JSX: window.Signal.State.Roots.createStickerPreviewModal(
window.reduxStore,
props
),
});
} catch (error) {
window.isShowingModal = false;
log.error(
'showStickerPack: Ran into an error!',
Errors.toLogFormat(error)
);
const errorView = new ReactWrapperView({
className: 'error-modal-wrapper',
JSX: (
<ErrorModal
i18n={window.i18n}
onClose={() => {
errorView.remove();
}}
/>
),
});
}
window.reduxActions.globalModals.showStickerPackPreview(packId, key);
},
showGroupViaLink: async hash => {
// We can get these events even if the user has never linked this instance.
@ -492,10 +449,6 @@ export function createIPCEvents(
log.warn('showGroupViaLink: Not registered, returning early');
return;
}
if (window.isShowingModal) {
log.warn('showGroupViaLink: Already showing modal, returning early');
return;
}
try {
await window.Signal.Groups.joinViaLink(hash);
} catch (error) {
@ -517,7 +470,6 @@ export function createIPCEvents(
),
});
}
window.isShowingModal = false;
},
async showConversationViaSignalDotMe(hash: string) {
if (!window.Signal.Util.Registration.everDone()) {
@ -559,13 +511,7 @@ export function createIPCEvents(
}
log.info('showConversationViaSignalDotMe: invalid E164');
if (window.isShowingModal) {
log.info(
'showConversationViaSignalDotMe: a modal is already showing. Doing nothing'
);
} else {
showUnknownSgnlLinkModal();
}
showUnknownSgnlLinkModal();
},
unknownSignalLink: () => {

View file

@ -11,7 +11,6 @@ import { render } from 'mustache';
import type { AttachmentType } from '../types/Attachment';
import { isGIF } from '../types/Attachment';
import * as Stickers from '../types/Stickers';
import type { MIMEType } from '../types/MIME';
import type { ConversationModel } from '../models/conversations';
import type { MessageAttributesType } from '../model-types.d';
@ -1108,29 +1107,6 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
});
}
showStickerPackPreview(packId: string, packKey: string): void {
Stickers.downloadEphemeralPack(packId, packKey);
const props = {
packId,
onClose: async () => {
if (this.stickerPreviewModalView) {
this.stickerPreviewModalView.remove();
this.stickerPreviewModalView = undefined;
}
await Stickers.removeEphemeralPack(packId);
},
};
this.stickerPreviewModalView = new ReactWrapperView({
className: 'sticker-preview-modal-wrapper',
JSX: window.Signal.State.Roots.createStickerPreviewModal(
window.reduxStore,
props
),
});
}
showLightboxForMedia(
selectedMediaItem: MediaItemType,
media: Array<MediaItemType> = []
@ -1195,7 +1171,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
const sticker = message.get('sticker');
if (sticker) {
const { packId, packKey } = sticker;
this.showStickerPackPreview(packId, packKey);
window.reduxActions.globalModals.showStickerPackPreview(packId, packKey);
return;
}

2
ts/window.d.ts vendored
View file

@ -48,7 +48,6 @@ import type { createPendingInvites } from './state/roots/createPendingInvites';
import type { createSafetyNumberViewer } from './state/roots/createSafetyNumberViewer';
import type { createShortcutGuideModal } from './state/roots/createShortcutGuideModal';
import type { createStickerManager } from './state/roots/createStickerManager';
import type { createStickerPreviewModal } from './state/roots/createStickerPreviewModal';
import type * as appDuck from './state/ducks/app';
import type * as callingDuck from './state/ducks/calling';
import type * as conversationsDuck from './state/ducks/conversations';
@ -179,7 +178,6 @@ export type SignalCoreType = {
createSafetyNumberViewer: typeof createSafetyNumberViewer;
createShortcutGuideModal: typeof createShortcutGuideModal;
createStickerManager: typeof createStickerManager;
createStickerPreviewModal: typeof createStickerPreviewModal;
};
Ducks: {
app: typeof appDuck;