2024-07-15 15:50:56 +02:00

181 lines
5.4 KiB
TypeScript

import type { FC } from '../../../lib/teact/teact';
import React, {
memo, useEffect, useState,
} from '../../../lib/teact/teact';
import { getActions } from '../../../global';
import type {
ApiAvailableReaction,
ApiReaction,
} from '../../../api/types';
import type { IAnchorPosition } from '../../../types';
import buildClassName from '../../../util/buildClassName';
import { IS_TOUCH_ENV } from '../../../util/windowEnvironment';
import useEffectWithPrevDeps from '../../../hooks/useEffectWithPrevDeps';
import useFlag from '../../../hooks/useFlag';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useMouseInside from '../../../hooks/useMouseInside';
import useOldLang from '../../../hooks/useOldLang';
import Menu from '../../ui/Menu';
import MenuItem from '../../ui/MenuItem';
import ReactionSelector from '../message/reactions/ReactionSelector';
import './CustomSendMenu.scss';
export type OwnProps = {
isOpen: boolean;
isOpenToBottom?: boolean;
isSavedMessages?: boolean;
canSchedule?: boolean;
canScheduleUntilOnline?: boolean;
onSendSilent?: NoneToVoidFunction;
onSendSchedule?: NoneToVoidFunction;
onSendWhenOnline?: NoneToVoidFunction;
onRemoveEffect?: NoneToVoidFunction;
onClose: NoneToVoidFunction;
onCloseAnimationEnd?: NoneToVoidFunction;
chatId?: string;
withEffects?: boolean;
hasCurrentEffect?: boolean;
effectReactions?: ApiReaction[];
allAvailableReactions?: ApiAvailableReaction[];
onToggleReaction?: (reaction: ApiReaction) => void;
canBuyPremium?: boolean;
isCurrentUserPremium?: boolean;
isInSavedMessages?: boolean;
isInStoryViewer?: boolean;
canPlayAnimatedEmojis?: boolean;
};
const ANIMATION_DURATION = 200;
const CustomSendMenu: FC<OwnProps> = ({
isOpen,
isOpenToBottom = false,
isSavedMessages,
canSchedule,
canScheduleUntilOnline,
onSendSilent,
onSendSchedule,
onSendWhenOnline,
onRemoveEffect,
onClose,
onCloseAnimationEnd,
chatId,
withEffects,
hasCurrentEffect,
effectReactions,
allAvailableReactions,
onToggleReaction,
canBuyPremium,
isCurrentUserPremium,
isInSavedMessages,
isInStoryViewer,
canPlayAnimatedEmojis,
}) => {
const {
openEffectPicker,
} = getActions();
const [handleMouseEnter, handleMouseLeave] = useMouseInside(isOpen, onClose);
const [displayScheduleUntilOnline, setDisplayScheduleUntilOnline] = useState(false);
const oldLang = useOldLang();
const lang = useLang();
const [areItemsHidden, hideItems, showItems] = useFlag();
useEffectWithPrevDeps(([prevIsOpen]) => {
// Avoid context menu item shuffling when opened
if (isOpen && !prevIsOpen) {
showItems();
setDisplayScheduleUntilOnline(Boolean(canScheduleUntilOnline));
}
}, [isOpen, canScheduleUntilOnline]);
const [isReady, markIsReady, unmarkIsReady] = useFlag();
const handleOpenMessageEffectsPicker = useLastCallback((position: IAnchorPosition) => {
hideItems();
if (chatId) openEffectPicker({ chatId, position });
});
useEffect(() => {
if (!isOpen) {
unmarkIsReady();
return;
}
setTimeout(() => {
markIsReady();
}, ANIMATION_DURATION);
}, [isOpen, markIsReady, unmarkIsReady]);
return (
<Menu
isOpen={isOpen}
autoClose
positionX="right"
positionY={isOpenToBottom ? 'top' : 'bottom'}
className={buildClassName(
'CustomSendMenu', 'fluid', 'with-menu-transitions', withEffects && 'with-effects',
)}
onClose={onClose}
onCloseAnimationEnd={onCloseAnimationEnd}
onMouseEnter={!IS_TOUCH_ENV ? handleMouseEnter : undefined}
onMouseLeave={!IS_TOUCH_ENV ? handleMouseLeave : undefined}
noCloseOnBackdrop={!IS_TOUCH_ENV}
>
{withEffects && !isInStoryViewer && (
<ReactionSelector
allAvailableReactions={allAvailableReactions}
effectReactions={effectReactions}
currentReactions={undefined}
onToggleReaction={onToggleReaction!}
isPrivate
isReady={isReady}
canBuyPremium={canBuyPremium}
isCurrentUserPremium={isCurrentUserPremium}
isInSavedMessages={isInSavedMessages}
isForEffects
canPlayAnimatedEmojis={canPlayAnimatedEmojis}
onShowMore={handleOpenMessageEffectsPicker}
onClose={onClose}
className={buildClassName(areItemsHidden && 'ReactionSelector-hidden')}
/>
)}
<div
className={buildClassName(
'CustomSendMenu_items',
areItemsHidden && 'CustomSendMenu_items-hidden',
)}
dir={oldLang.isRtl ? 'rtl' : undefined}
>
{onSendSilent && <MenuItem icon="mute" onClick={onSendSilent}>{oldLang('SendWithoutSound')}</MenuItem>}
{canSchedule && onSendSchedule && (
<MenuItem icon="schedule" onClick={onSendSchedule}>
{oldLang(isSavedMessages ? 'SetReminder' : 'ScheduleMessage')}
</MenuItem>
)}
{canSchedule && onSendSchedule && displayScheduleUntilOnline && (
<MenuItem icon="user-online" onClick={onSendWhenOnline}>
{oldLang('SendWhenOnline')}
</MenuItem>
)}
{withEffects && hasCurrentEffect && (
<MenuItem icon="delete" onClick={onRemoveEffect}>
{lang('RemoveEffect')}
</MenuItem>
)}
</div>
</Menu>
);
};
export default memo(CustomSendMenu);