Fix touch controls triggering when showing them

This commit is contained in:
Zoe Roux 2024-01-31 11:53:43 +01:00
parent 2db6255fae
commit a0c1fdbd74
4 changed files with 32 additions and 39 deletions

View File

@ -39,7 +39,7 @@ import { Chapter, KyooImage, Subtitle, Audio } from "@kyoo/models";
import { useAtomValue, useSetAtom, useAtom } from "jotai"; import { useAtomValue, useSetAtom, useAtom } from "jotai";
import { ImageStyle, Platform, Pressable, View, ViewProps } from "react-native"; import { ImageStyle, Platform, Pressable, View, ViewProps } from "react-native";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { percent, rem, useYoshiki, vh } from "yoshiki/native"; import { percent, rem, useYoshiki } from "yoshiki/native";
import { useRouter } from "solito/router"; import { useRouter } from "solito/router";
import ArrowBack from "@material-symbols/svg-400/rounded/arrow_back-fill.svg"; import ArrowBack from "@material-symbols/svg-400/rounded/arrow_back-fill.svg";
import { LeftButtons, TouchControls } from "./left-buttons"; import { LeftButtons, TouchControls } from "./left-buttons";
@ -200,6 +200,7 @@ export const HoverTouch = ({ children, ...props }: { children: ReactNode }) => {
const mouseCallback = useRef<NodeJS.Timeout | null>(null); const mouseCallback = useRef<NodeJS.Timeout | null>(null);
const touch = useRef<{ count: number; timeout?: NodeJS.Timeout }>({ count: 0 }); const touch = useRef<{ count: number; timeout?: NodeJS.Timeout }>({ count: 0 });
const playerWidth = useRef<number | null>(null); const playerWidth = useRef<number | null>(null);
const isTouch = useIsTouch();
const show = useCallback(() => { const show = useCallback(() => {
setHover((x) => ({ ...x, mouseMoved: true })); setHover((x) => ({ ...x, mouseMoved: true }));
@ -283,18 +284,9 @@ export const HoverTouch = ({ children, ...props }: { children: ReactNode }) => {
onPointerLeave={(e) => { onPointerLeave={(e) => {
if (e.nativeEvent.pointerType === "mouse") setHover((x) => ({ ...x, mouseMoved: false })); if (e.nativeEvent.pointerType === "mouse") setHover((x) => ({ ...x, mouseMoved: false }));
}} }}
onPointerDown={(e) => {
// Theorically, this is available everywhere but android never calls this pointerDown so
// touch are handled in the onPress and we early return here if it is every called to prevent
// the click action to run twice.
if (Platform.OS !== "web") return;
e.preventDefault();
onAnyPress(e.nativeEvent);
}}
onPress={(e) => { onPress={(e) => {
if (Platform.OS === "web") return;
e.preventDefault(); e.preventDefault();
onAnyPress({ pointerType: "touch", x: e.nativeEvent.locationX }); onAnyPress({ pointerType: isTouch ? "touch" : "mouse", x: e.nativeEvent.locationX });
}} }}
onLayout={(e) => { onLayout={(e) => {
playerWidth.current = e.nativeEvent.layout.width; playerWidth.current = e.nativeEvent.layout.width;

View File

@ -101,9 +101,6 @@ export const TouchControls = ({
backgroundColor: (theme) => theme.darkOverlay, backgroundColor: (theme) => theme.darkOverlay,
marginHorizontal: ts(3), marginHorizontal: ts(3),
}, },
!hover && {
display: "none",
},
], ],
touchOnly, touchOnly,
); );
@ -124,28 +121,34 @@ export const TouchControls = ({
props, props,
)} )}
> >
<IconButton {hover && (
icon={SkipPrevious} <>
as={Link} <IconButton
href={previousSlug!} icon={SkipPrevious}
replace as={Link}
size={ts(4)} href={previousSlug!}
{...css([!previousSlug && { opacity: 0, pointerEvents: "none" }], common)} replace
/> size={ts(4)}
<IconButton {...css([!previousSlug && { opacity: 0, pointerEvents: "none" }], common)}
icon={isPlaying ? Pause : PlayArrow} />
onPress={() => setPlay(!isPlaying)} <IconButton
size={ts(8)} icon={isPlaying ? Pause : PlayArrow}
{...common} onPress={() => {
/> console.log("play pressed")
<IconButton setPlay(!isPlaying)}}
icon={SkipNext} size={ts(8)}
as={Link} {...common}
href={nextSlug!} />
replace <IconButton
size={ts(4)} icon={SkipNext}
{...css([!nextSlug && { opacity: 0, pointerEvents: "none" }], common)} as={Link}
/> href={nextSlug!}
replace
size={ts(4)}
{...css([!nextSlug && { opacity: 0, pointerEvents: "none" }], common)}
/>
</>
)}
</HoverTouch> </HoverTouch>
); );
}; };

View File

@ -64,7 +64,7 @@ const videoAtom = atom(0);
const clientId = uuid.v4() as string; const clientId = uuid.v4() as string;
const Video = forwardRef<VideoRef, VideoProps>(function Video( const Video = forwardRef<VideoRef, VideoProps>(function Video(
{ onLoad, onBuffer, source, onPointerDown, subtitles, ...props }, { onLoad, onBuffer, source, subtitles, ...props },
ref, ref,
) { ) {
const { css } = useYoshiki(); const { css } = useYoshiki();

View File

@ -118,7 +118,6 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
onPlayPause, onPlayPause,
onMediaUnsupported, onMediaUnsupported,
fonts, fonts,
onPointerDown,
}, },
forwaredRef, forwaredRef,
) { ) {
@ -241,7 +240,6 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
// onPlay={() => onPlayPause?.call(null, true)} // onPlay={() => onPlayPause?.call(null, true)}
// onPause={() => onPlayPause?.call(null, false)} // onPause={() => onPlayPause?.call(null, false)}
onEnded={onEnd} onEnded={onEnd}
onPointerDown={(e) => onPointerDown?.(e as any)}
{...css({ width: "100%", height: "100%", objectFit: "contain" })} {...css({ width: "100%", height: "100%", objectFit: "contain" })}
/> />
); );