Reaction Picker: Fix stuck state (#4946)

This commit is contained in:
zubiden 2024-09-06 15:43:39 +02:00 committed by Alexander Zinchuk
parent b9041b8fc3
commit 2c91ca86aa
4 changed files with 62 additions and 30 deletions

View File

@ -22,7 +22,7 @@ import useShowTransitionDeprecated from '../../../hooks/useShowTransitionDepreca
import CustomEmojiPicker from '../../common/CustomEmojiPicker';
import Button from '../../ui/Button';
import { UnfreezableMenu } from '../../ui/Menu';
import Menu from '../../ui/Menu';
import Portal from '../../ui/Portal';
import Transition from '../../ui/Transition';
import EmojiPicker from './EmojiPicker';
@ -316,7 +316,7 @@ const SymbolMenu: FC<OwnProps & StateProps> = ({
}
return (
<UnfreezableMenu
<Menu
isOpen={isOpen}
onClose={onClose}
withPortal={isAttachmentModal}
@ -333,7 +333,7 @@ const SymbolMenu: FC<OwnProps & StateProps> = ({
})}
>
{content}
</UnfreezableMenu>
</Menu>
);
};

View File

@ -6,7 +6,6 @@ import type { MenuPositionOptions } from '../../hooks/useMenuPosition';
import buildClassName from '../../util/buildClassName';
import captureEscKeyListener from '../../util/captureEscKeyListener';
import freezeWhenClosed from '../../util/hoc/freezeWhenClosed';
import { IS_BACKDROP_BLUR_SUPPORTED } from '../../util/windowEnvironment';
import { preventMessageInputBlurWithBubbling } from '../middle/helpers/preventMessageInputBlur';
@ -173,6 +172,4 @@ const Menu: FC<OwnProps> = ({
return menu;
};
export const UnfreezableMenu = memo(Menu);
export default memo(freezeWhenClosed(Menu));
export default memo(Menu);

View File

@ -1,8 +1,8 @@
import useShowTransition from './useShowTransition';
import useShowTransition, { type HookParams } from './useShowTransition';
export default function useMediaTransition<RefType extends HTMLElement = HTMLDivElement>(
mediaData?: unknown,
options?: Partial<Parameters<typeof useShowTransition<RefType>>[0]>,
options?: Partial<HookParams<RefType>>,
) {
const isMediaReady = Boolean(mediaData);

View File

@ -2,6 +2,8 @@ import type { RefObject } from 'react';
import { useLayoutEffect, useRef, useSignal } from '../lib/teact/teact';
import { addExtraClass, toggleExtraClass } from '../lib/teact/teact-dom';
import type { Signal } from '../util/signals';
import { requestMeasure } from '../lib/fasterdom/fasterdom';
import useDerivedSignal from './useDerivedSignal';
import useDerivedState from './useDerivedState';
@ -11,24 +13,7 @@ import useSyncEffectWithPrevDeps from './useSyncEffectWithPrevDeps';
const CLOSE_DURATION = 350;
type State =
'closed'
| 'scheduled-open'
| 'open'
| 'closing';
export default function useShowTransition<RefType extends HTMLElement = HTMLDivElement>({
isOpen,
ref,
noMountTransition = false,
noOpenTransition = false,
noCloseTransition = false,
closeDuration = CLOSE_DURATION,
className = 'fast',
prefix = '',
onCloseAnimationEnd,
withShouldRender,
}: {
type BaseHookParams<RefType extends HTMLElement> = {
isOpen: boolean | undefined;
ref?: RefObject<RefType>;
noMountTransition?: boolean;
@ -37,9 +22,55 @@ export default function useShowTransition<RefType extends HTMLElement = HTMLDivE
closeDuration?: number;
className?: string | false;
prefix?: string;
withShouldRender?: boolean;
onCloseAnimationEnd?: NoneToVoidFunction;
}) {
};
export type HookParams<RefType extends HTMLElement> = BaseHookParams<RefType> & {
withShouldRender?: never;
};
type HookParamsWithShouldRender<RefType extends HTMLElement> = BaseHookParams<RefType> & {
withShouldRender: true;
};
type HookResult<RefType extends HTMLElement> = {
ref: RefObject<RefType>;
getIsClosing: Signal<boolean>;
};
type HookResultWithShouldRender<RefType extends HTMLElement> = HookResult<RefType> & {
shouldRender: boolean;
};
type State =
'closed'
| 'scheduled-open'
| 'open'
| 'closing';
export default function useShowTransition<RefType extends HTMLElement = HTMLDivElement>(
params: HookParams<RefType>
): HookResult<RefType>;
export default function useShowTransition<RefType extends HTMLElement = HTMLDivElement>(
params: HookParamsWithShouldRender<RefType>
): HookResultWithShouldRender<RefType>;
export default function useShowTransition<RefType extends HTMLElement = HTMLDivElement>(
params: HookParams<RefType> | HookParamsWithShouldRender<RefType>,
): HookResult<RefType> | HookResultWithShouldRender<RefType> {
const {
isOpen,
noMountTransition = false,
noOpenTransition = false,
noCloseTransition = false,
closeDuration = CLOSE_DURATION,
className = 'fast',
prefix = '',
onCloseAnimationEnd,
} = params;
let ref = params.ref;
const withShouldRender = 'withShouldRender' in params && params.withShouldRender;
// eslint-disable-next-line no-null/no-null
const localRef = useRef<RefType>(null);
ref ||= localRef;
@ -106,5 +137,9 @@ export default function useShowTransition<RefType extends HTMLElement = HTMLDivE
);
const getIsClosing = useDerivedSignal(() => getState() === 'closing', [getState]);
return { ref, shouldRender, getIsClosing };
if (withShouldRender) {
return { ref, shouldRender, getIsClosing };
}
return { ref, getIsClosing };
}