import * as React from 'react'; import classNames from 'classnames'; import { noop } from 'lodash'; import { Manager, Popper, Reference } from 'react-popper'; import { createPortal } from 'react-dom'; import { StickerPicker } from './StickerPicker'; import { countStickers } from './lib'; import { StickerPackType, StickerType } from '../../state/ducks/stickers'; import { LocalizerType } from '../../types/Util'; export type OwnProps = { readonly i18n: LocalizerType; readonly receivedPacks: ReadonlyArray; readonly installedPacks: ReadonlyArray; readonly blessedPacks: ReadonlyArray; readonly knownPacks: ReadonlyArray; readonly installedPack?: StickerPackType | null; readonly recentStickers: ReadonlyArray; readonly clearInstalledStickerPack: () => unknown; readonly onClickAddPack: () => unknown; readonly onPickSticker: (packId: string, stickerId: number) => unknown; readonly showIntroduction?: boolean; readonly clearShowIntroduction: () => unknown; readonly showPickerHint: boolean; readonly clearShowPickerHint: () => unknown; }; export type Props = OwnProps; export const StickerButton = React.memo( // tslint:disable-next-line max-func-body-length ({ i18n, clearInstalledStickerPack, onClickAddPack, onPickSticker, recentStickers, receivedPacks, installedPack, installedPacks, blessedPacks, knownPacks, showIntroduction, clearShowIntroduction, showPickerHint, clearShowPickerHint, }: Props) => { const [open, setOpen] = React.useState(false); const [popperRoot, setPopperRoot] = React.useState( null ); const handleClickButton = React.useCallback( () => { // Clear tooltip state clearInstalledStickerPack(); clearShowIntroduction(); // Handle button click if (installedPacks.length === 0) { onClickAddPack(); } else if (popperRoot) { setOpen(false); } else { setOpen(true); } }, [ clearInstalledStickerPack, onClickAddPack, installedPacks, popperRoot, setOpen, ] ); const handlePickSticker = React.useCallback( (packId: string, stickerId: number) => { setOpen(false); onPickSticker(packId, stickerId); }, [setOpen, onPickSticker] ); const handleClose = React.useCallback( () => { setOpen(false); }, [setOpen] ); const handleClickAddPack = React.useCallback( () => { setOpen(false); if (showPickerHint) { clearShowPickerHint(); } onClickAddPack(); }, [onClickAddPack, showPickerHint, clearShowPickerHint] ); const handleClearIntroduction = React.useCallback( () => { clearInstalledStickerPack(); clearShowIntroduction(); }, [clearInstalledStickerPack, clearShowIntroduction] ); // Create popper root and handle outside clicks React.useEffect( () => { if (open) { const root = document.createElement('div'); setPopperRoot(root); document.body.appendChild(root); const handleOutsideClick = ({ target }: MouseEvent) => { if (!root.contains(target as Node)) { setOpen(false); } }; document.addEventListener('click', handleOutsideClick); return () => { document.body.removeChild(root); document.removeEventListener('click', handleOutsideClick); setPopperRoot(null); }; } return noop; }, [open, setOpen, setPopperRoot] ); // Clear the installed pack after one minute React.useEffect( () => { if (installedPack) { // tslint:disable-next-line:no-string-based-set-timeout const timerId = setTimeout(clearInstalledStickerPack, 60 * 1000); return () => { clearTimeout(timerId); }; } return noop; }, [installedPack, clearInstalledStickerPack] ); if ( countStickers({ knownPacks, blessedPacks, installedPacks, receivedPacks, }) === 0 ) { return null; } return ( {({ ref }) => (