Merge pull request #1349 from Stremio/fix/web-context-menu-fallback
Some checks failed
Build / build (push) Has been cancelled

Fix repeated context menu handling
This commit is contained in:
Timothy Z. 2026-07-22 15:56:25 +03:00 committed by GitHub
commit e4a412a2e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 37 additions and 15 deletions

View file

@ -75,15 +75,17 @@ const ContextMenu = ({ children, on, autoClose, lock }: Props) => {
return { top, left };
}, [position, containerSize, lock, triggerRect]);
const close = () => {
const close = useCallback(() => {
setActive(false);
};
}, []);
const stopPropagation = (event: React.MouseEvent | React.TouchEvent) => {
const stopPropagation = useCallback((event: React.MouseEvent | React.TouchEvent) => {
event.stopPropagation();
};
}, []);
const onContextMenu = useCallback((event: MouseEvent) => {
if (event.shiftKey) return;
event.preventDefault();
if (lock) {
@ -95,11 +97,24 @@ const ContextMenu = ({ children, on, autoClose, lock }: Props) => {
setActive(true);
}, [lock]);
const handleKeyDown = useCallback((event: KeyboardEvent) => event.key === 'Escape' && close(), []);
const containerOnMouseDown = useCallback((event: React.MouseEvent) => {
if (event.button !== 2 && !event.ctrlKey) close();
}, [close]);
const containerOnContextMenu = useCallback((event: React.MouseEvent) => {
if (event.shiftKey) return;
event.preventDefault();
if (!lock && event.target === event.currentTarget) {
setPosition([event.clientX, event.clientY]);
}
}, [lock]);
const handleKeyDown = useCallback((event: KeyboardEvent) => event.key === 'Escape' && close(), [close]);
const onClick = useCallback(() => {
autoClose && close();
}, [autoClose]);
}, [autoClose, close]);
useEffect(() => {
on.forEach((ref) => ref.current && ref.current.addEventListener('contextmenu', onContextMenu));
@ -115,7 +130,8 @@ const ContextMenu = ({ children, on, autoClose, lock }: Props) => {
<Transition when={active} name={'fade'}>
<div
className={styles['context-menu-container']}
onMouseDown={close}
onMouseDown={containerOnMouseDown}
onContextMenu={containerOnContextMenu}
onTouchStart={close}
>
<div

View file

@ -22,18 +22,18 @@ const Video = ({ className, id, title, thumbnail, season, episode, released, upc
const platform = usePlatform();
const { t } = useTranslation();
const [menuOpen, , closeMenu, toggleMenu] = useBinaryState(false);
const [menuOpen, openMenu, closeMenu, toggleMenu] = useBinaryState(false);
const popupLabelOnMouseUp = React.useCallback((event) => {
if (!event.nativeEvent.togglePopupPrevented) {
if (event.nativeEvent.ctrlKey || event.nativeEvent.button === 2) {
event.preventDefault();
toggleMenu();
openMenu();
}
}
}, []);
}, [openMenu]);
const popupLabelOnContextMenu = React.useCallback((event) => {
if (!event.nativeEvent.togglePopupPrevented && !event.nativeEvent.ctrlKey) {
if (!event.nativeEvent.togglePopupPrevented && !event.nativeEvent.ctrlKey && !event.nativeEvent.shiftKey) {
event.preventDefault();
}
}, [toggleMenu]);
@ -47,6 +47,9 @@ const Video = ({ className, id, title, thumbnail, season, episode, released, upc
}, []);
const popupMenuOnContextMenu = React.useCallback((event) => {
event.nativeEvent.togglePopupPrevented = true;
if (!event.nativeEvent.ctrlKey && !event.nativeEvent.shiftKey) {
event.preventDefault();
}
}, []);
const popupMenuOnClick = React.useCallback((event) => {
event.nativeEvent.togglePopupPrevented = true;

View file

@ -19,18 +19,18 @@ const Stream = ({ className, videoId, videoReleased, addonName, name, descriptio
const core = useCore();
const routeFocused = useRouteFocused();
const [menuOpen, , closeMenu, toggleMenu] = useBinaryState(false);
const [menuOpen, openMenu, closeMenu, toggleMenu] = useBinaryState(false);
const popupLabelOnMouseUp = React.useCallback((event) => {
if (!event.nativeEvent.togglePopupPrevented) {
if (event.nativeEvent.ctrlKey || event.nativeEvent.button === 2) {
event.preventDefault();
toggleMenu();
openMenu();
}
}
}, []);
}, [openMenu]);
const popupLabelOnContextMenu = React.useCallback((event) => {
if (!event.nativeEvent.togglePopupPrevented && !event.nativeEvent.ctrlKey) {
if (!event.nativeEvent.togglePopupPrevented && !event.nativeEvent.ctrlKey && !event.nativeEvent.shiftKey) {
event.preventDefault();
}
}, [toggleMenu]);
@ -44,6 +44,9 @@ const Stream = ({ className, videoId, videoReleased, addonName, name, descriptio
}, []);
const popupMenuOnContextMenu = React.useCallback((event) => {
event.nativeEvent.togglePopupPrevented = true;
if (!event.nativeEvent.ctrlKey && !event.nativeEvent.shiftKey) {
event.preventDefault();
}
}, []);
const popupMenuOnClick = React.useCallback((event) => {
event.nativeEvent.togglePopupPrevented = true;