fix(Player): handle touch events for context menu

This commit is contained in:
Botzy 2025-03-10 17:52:02 +02:00
parent 45307b680a
commit 1b70268b40
3 changed files with 34 additions and 9 deletions

View file

@ -41,6 +41,8 @@ const ControlBar = ({
onToggleOptionsMenu,
onToggleStatisticsMenu,
onContextMenu,
onTouchStart,
onTouchEnd,
...props
}) => {
const { chromecast } = useServices();
@ -104,7 +106,7 @@ const ControlBar = ({
};
}, []);
return (
<div {...props} className={classnames(className, styles['control-bar-container'])} onContextMenu={onContextMenu}>
<div {...props} className={classnames(className, styles['control-bar-container'])} onContextMenu={onContextMenu} onTouchStart={onTouchStart} onTouchEnd={onTouchEnd}>
<SeekBar
className={styles['seek-bar']}
time={time}
@ -208,6 +210,8 @@ ControlBar.propTypes = {
onToggleOptionsMenu: PropTypes.func,
onToggleStatisticsMenu: PropTypes.func,
onContextMenu: PropTypes.func,
onTouchStart: PropTypes.func,
onTouchEnd: PropTypes.func,
};
module.exports = ControlBar;

View file

@ -251,9 +251,7 @@ const Player = ({ urlParams, queryParams }) => {
toggleFullscreen();
}, [toggleFullscreen]);
const onContextMenu = React.useCallback((e) => {
e.preventDefault();
const { clientX, clientY } = e;
const handleContextMenuPosition = (clientX, clientY) => {
const safeAreaTop = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('env(safe-area-inset-top)')) || 0;
const safeAreaRight = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('env(safe-area-inset-right)')) || 0;
const safeAreaBottom = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('env(safe-area-inset-bottom)')) || 0;
@ -280,9 +278,24 @@ const Player = ({ urlParams, queryParams }) => {
x: adjustedX,
y: adjustedY,
});
};
const onContextMenu = React.useCallback((e) => {
e.preventDefault();
const { clientX, clientY } = e;
handleContextMenuPosition(clientX, clientY);
openContextMenu();
}, [contextMenuRef]);
const onTouchStart = (event) => {
const touch = event.touches[0];
handleContextMenuPosition(touch.clientX, touch.clientY);
};
const onTouchEnd = () => {
openContextMenu();
};
React.useEffect(() => {
if (!contextMenuOpen) {
const menuSize = contextMenuRef?.current?.getBoundingClientRect();
@ -689,7 +702,7 @@ const Player = ({ urlParams, queryParams }) => {
/>
{
!video.state.loaded ?
<div className={classnames(styles['layer'], styles['background-layer'])} onContextMenu={onContextMenu}>
<div className={classnames(styles['layer'], styles['background-layer'])} onContextMenu={onContextMenu} onTouchStart={onTouchStart} onTouchEnd={onTouchEnd}>
<img className={styles['image']} src={player?.metaItem?.content?.background} />
</div>
:
@ -697,7 +710,7 @@ const Player = ({ urlParams, queryParams }) => {
}
{
(video.state.buffering || !video.state.loaded) && !error ?
<BufferingLoader className={classnames(styles['layer'], styles['buffering-layer'])} logo={player?.metaItem?.content?.logo} onContextMenu={onContextMenu} />
<BufferingLoader className={classnames(styles['layer'], styles['buffering-layer'])} logo={player?.metaItem?.content?.logo} onContextMenu={onContextMenu} onTouchStart={onTouchStart} onTouchEnd={onTouchEnd} />
:
null
}
@ -755,6 +768,8 @@ const Player = ({ urlParams, queryParams }) => {
onMouseMove={onBarMouseMove}
onMouseOver={onBarMouseMove}
onContextMenu={onContextMenu}
onTouchStart={onTouchStart}
onTouchEnd={onTouchEnd}
/>
{
player.metaItem?.type === 'Ready' ?
@ -762,6 +777,8 @@ const Player = ({ urlParams, queryParams }) => {
className={classnames(styles['layer'], styles['side-drawer-button-layer'])}
onClick={toggleSideDrawer}
onContextMenu={onContextMenu}
onTouchStart={onTouchStart}
onTouchEnd={onTouchEnd}
/>
:
null
@ -797,6 +814,8 @@ const Player = ({ urlParams, queryParams }) => {
onMouseMove={onBarMouseMove}
onMouseOver={onBarMouseMove}
onContextMenu={onContextMenu}
onTouchStart={onTouchStart}
onTouchEnd={onTouchEnd}
/>
{
nextVideoPopupOpen ?

View file

@ -1,6 +1,6 @@
// Copyright (C) 2017-2024 Smart code 203358507
import React from 'react';
import React, { BaseSyntheticEvent } from 'react';
import classNames from 'classnames';
import Icon from '@stremio/stremio-icons/react';
import styles from './SideDrawerButton.less';
@ -9,11 +9,13 @@ type Props = {
className: string,
onClick: () => void,
onContextMenu: () => void,
onTouchStart: (event: BaseSyntheticEvent) => void,
onTouchEnd: () => void,
};
const SideDrawerButton = ({ className, onClick, onContextMenu }: Props) => {
const SideDrawerButton = ({ className, onClick, onContextMenu, onTouchStart, onTouchEnd }: Props) => {
return (
<div className={classNames(className, styles['side-drawer-button'])} onClick={onClick} onContextMenu={onContextMenu}>
<div className={classNames(className, styles['side-drawer-button'])} onClick={onClick} onContextMenu={onContextMenu} onTouchStart={onTouchStart} onTouchEnd={onTouchEnd}>
<Icon name={'chevron-back'} className={styles['icon']} />
</div>
);