import * as React from 'react';
import { createPortal } from 'react-dom';
import { isNumber, range } from 'lodash';
import classNames from 'classnames';
import { StickerPackInstallButton } from './StickerPackInstallButton';
import { ConfirmationDialog } from '../ConfirmationDialog';
import { LocalizerType } from '../../types/Util';
import { StickerPackType } from '../../state/ducks/stickers';
import { Spinner } from '../Spinner';
import { useRestoreFocus } from '../../util/hooks';
export type OwnProps = {
readonly onClose: () => unknown;
readonly downloadStickerPack: (
packId: string,
packKey: string,
options?: { finalStatus?: 'installed' | 'downloaded' }
) => unknown;
readonly installStickerPack: (packId: string, packKey: string) => unknown;
readonly uninstallStickerPack: (packId: string, packKey: string) => unknown;
readonly pack?: StickerPackType;
readonly i18n: LocalizerType;
};
export type Props = OwnProps;
function renderBody({ pack, i18n }: Props) {
if (pack && pack.status === 'error') {
return (
{i18n('stickers--StickerPreview--Error')}
);
}
if (!pack || pack.stickerCount === 0 || !isNumber(pack.stickerCount)) {
return ;
}
return (
{pack.stickers.map(({ id, url }) => (
))}
{range(pack.stickerCount - pack.stickers.length).map(i => (
))}
);
}
export const StickerPreviewModal = React.memo(
// tslint:disable-next-line max-func-body-length
(props: Props) => {
const {
onClose,
pack,
i18n,
downloadStickerPack,
installStickerPack,
uninstallStickerPack,
} = props;
const focusRef = React.useRef(null);
const [root, setRoot] = React.useState(null);
const [confirmingUninstall, setConfirmingUninstall] = React.useState(false);
// Restore focus on teardown
useRestoreFocus(focusRef, root);
React.useEffect(() => {
const div = document.createElement('div');
document.body.appendChild(div);
setRoot(div);
return () => {
document.body.removeChild(div);
};
}, []);
React.useEffect(() => {
if (pack && pack.status === 'known') {
downloadStickerPack(pack.id, pack.key);
}
if (
pack &&
pack.status === 'error' &&
(pack.attemptedStatus === 'downloaded' ||
pack.attemptedStatus === 'installed')
) {
downloadStickerPack(pack.id, pack.key, {
finalStatus: pack.attemptedStatus,
});
}
}, []);
const isInstalled = Boolean(pack && pack.status === 'installed');
const handleToggleInstall = React.useCallback(() => {
if (!pack) {
return;
}
if (isInstalled) {
setConfirmingUninstall(true);
} else if (pack.status === 'ephemeral') {
downloadStickerPack(pack.id, pack.key, { finalStatus: 'installed' });
onClose();
} else {
installStickerPack(pack.id, pack.key);
onClose();
}
}, [
isInstalled,
pack,
setConfirmingUninstall,
installStickerPack,
onClose,
]);
const handleUninstall = React.useCallback(() => {
if (!pack) {
return;
}
uninstallStickerPack(pack.id, pack.key);
setConfirmingUninstall(false);
// onClose is called by the confirmation modal
}, [uninstallStickerPack, setConfirmingUninstall, pack]);
React.useEffect(() => {
const handler = ({ key }: KeyboardEvent) => {
if (key === 'Escape') {
onClose();
}
};
document.addEventListener('keydown', handler);
return () => {
document.removeEventListener('keydown', handler);
};
}, [onClose]);
const handleClickToClose = React.useCallback(
(e: React.MouseEvent) => {
if (e.target === e.currentTarget) {
onClose();
}
},
[onClose]
);
return root
? createPortal(
{confirmingUninstall ? (
{i18n('stickers--StickerManager--UninstallWarning')}
) : (
{i18n('stickers--StickerPreview--Title')}
{renderBody(props)}
{pack && pack.status !== 'error' ? (
{pack.title}
{pack.isBlessed ? (
) : null}
{pack.author}
{pack.status === 'pending' ? (
) : (
)}
) : null}
)}
,
root
)
: null;
}
);