diff --git a/front/packages/ui/src/player/components/hover.tsx b/front/packages/ui/src/player/components/hover.tsx index 97589486..91ced460 100644 --- a/front/packages/ui/src/player/components/hover.tsx +++ b/front/packages/ui/src/player/components/hover.tsx @@ -35,7 +35,7 @@ import { } from "@kyoo/primitives"; import { Chapter, Font, Track, WatchItem } from "@kyoo/models"; import { useAtomValue, useSetAtom, useAtom } from "jotai"; -import { Platform, View, ViewProps } from "react-native"; +import { Platform, Pressable, View, ViewProps } from "react-native"; import { useTranslation } from "react-i18next"; import { percent, rem, useYoshiki } from "yoshiki/native"; import { useRouter } from "solito/router"; @@ -59,6 +59,7 @@ export const Hover = ({ onMenuOpen, onMenuClose, show, + onPointerDown, ...props }: { isLoading: boolean; @@ -83,7 +84,10 @@ export const Hover = ({ {({ css }) => ( <> - onPointerDown?.({} as any): undefined} {...css( [ { @@ -128,7 +132,7 @@ export const Hover = ({ /> - + )} diff --git a/front/packages/ui/src/player/index.tsx b/front/packages/ui/src/player/index.tsx index 5417ed62..d894fd01 100644 --- a/front/packages/ui/src/player/index.tsx +++ b/front/packages/ui/src/player/index.tsx @@ -21,7 +21,7 @@ import { QueryIdentifier, QueryPage, WatchItem, WatchItemP, useFetch } from "@kyoo/models"; import { Head } from "@kyoo/primitives"; import { useState, useEffect, ComponentProps } from "react"; -import { Platform, Pressable, PressableProps, StyleSheet, View } from "react-native"; +import { Platform, Pressable, PressableProps, StyleSheet, View, PointerEvent as NativePointerEvent } from "react-native"; import { useTranslation } from "react-i18next"; import { useRouter } from "solito/router"; import { useAtom } from "jotai"; @@ -127,6 +127,24 @@ export const Player: QueryPage<{ slug: string }> = ({ slug }) => { }; }, [setFullscreen]); + const onPointerDown = (e: NativePointerEvent) => { + if (Platform.OS === "web") e.preventDefault(); + if (Platform.OS !== "web" || e.nativeEvent.pointerType !== "mouse") { + displayControls ? setMouseMoved(false) : show(); + return; + } + touchCount++; + if (touchCount == 2) { + touchCount = 0; + setFullscreen(!isFullscreen); + clearTimeout(touchTimeout); + } else + touchTimeout = setTimeout(() => { + touchCount = 0; + }, 400); + setPlay(!isPlaying); + }; + if (error || playbackError) return ( <> @@ -159,29 +177,7 @@ export const Player: QueryPage<{ slug: string }> = ({ slug }) => { next={next} previous={previous} /> - { - e.preventDefault(); - displayControls ? setMouseMoved(false) : show(); - }} - onPointerDown={(e) => { - e.preventDefault(); - if (e.nativeEvent.pointerType !== "mouse") { - displayControls ? setMouseMoved(false) : show(); - return; - } - touchCount++; - if (touchCount == 2) { - touchCount = 0; - setFullscreen(!isFullscreen); - clearTimeout(touchTimeout); - } else - touchTimeout = setTimeout(() => { - touchCount = 0; - }, 400); - setPlay(!isPlaying); - }} + { if (e.nativeEvent.pointerType === "mouse") setMouseMoved(false); }} @@ -198,6 +194,7 @@ export const Player: QueryPage<{ slug: string }> = ({ slug }) => { subtitles={data?.subtitles} setError={setPlaybackError} fonts={data?.fonts} + onPointerDown={(e) => onPointerDown(e)} onEnd={() => { if (!data) return; if (data.isMovie) @@ -217,15 +214,14 @@ export const Player: QueryPage<{ slug: string }> = ({ slug }) => { { - if (e.nativeEvent.pointerType === "mouse") setHover(true); + if (Platform.OS !== "web" || e.nativeEvent.pointerType === "mouse") setHover(true); }} onPointerLeave={(e) => { if (e.nativeEvent.pointerType === "mouse") setHover(false); }} onPointerDown={(e) => { - // Prevent clicks on the hover to play/pause. - e.preventDefault(); - e.stopPropagation(); + if (!displayControls) onPointerDown(e); + if (Platform.OS === "web") e.preventDefault(); }} onMenuOpen={() => setMenuOpen(true)} onMenuClose={() => { @@ -235,7 +231,7 @@ export const Player: QueryPage<{ slug: string }> = ({ slug }) => { }} show={displayControls} /> - + ); }; diff --git a/front/packages/ui/src/player/video.tsx b/front/packages/ui/src/player/video.tsx index 9513f572..a70e0e1d 100644 --- a/front/packages/ui/src/player/video.tsx +++ b/front/packages/ui/src/player/video.tsx @@ -39,6 +39,8 @@ import NativeVideo, { OnLoadData, VideoProps } from "react-native-video"; import { useTranslation } from "react-i18next"; import { PlayMode, playModeAtom } from "./state"; import uuid from "react-native-uuid"; +import { Pressable } from "react-native"; +import { useYoshiki } from "yoshiki/native"; const infoAtom = atom(null); const videoAtom = atom(0); @@ -47,9 +49,10 @@ const audioAtom = atom(0); const clientId = uuid.v4() as string; const Video = forwardRef(function _NativeVideo( - { onLoad, source, ...props }, + { onLoad, source, onPointerDown, ...props }, ref, ) { + const { css } = useYoshiki(); const token = useRef(null); const setInfo = useSetAtom(infoAtom); const video = useAtomValue(videoAtom); @@ -66,23 +69,28 @@ const Video = forwardRef(function _NativeVideo( }, [source]); return ( - { - setInfo(info); - onLoad?.(info); - }} - selectedVideoTrack={video === -1 ? { type: "auto" } : { type: "resolution", value: video }} - selectedAudioTrack={{ type: "index", value: audio }} - {...props} - /> + onPointerDown?.({ nativeEvent: { pointerType: "pointer" } } as any)} + {...css({ flexGrow: 1, flexShrink: 1 })} + > + { + setInfo(info); + onLoad?.(info); + }} + selectedVideoTrack={video === -1 ? { type: "auto" } : { type: "resolution", value: video }} + selectedAudioTrack={{ type: "index", value: audio }} + {...props} + /> ); }); diff --git a/front/packages/ui/src/player/video.web.tsx b/front/packages/ui/src/player/video.web.tsx index 2b1efcfe..02bdb82a 100644 --- a/front/packages/ui/src/player/video.web.tsx +++ b/front/packages/ui/src/player/video.web.tsx @@ -79,6 +79,7 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function onPlayPause, onMediaUnsupported, fonts, + onPointerDown, }, forwaredRef, ) { @@ -191,6 +192,7 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function // onPlay={() => onPlayPause?.call(null, true)} // onPause={() => onPlayPause?.call(null, false)} onEnded={onEnd} + onPointerDown={(e) => onPointerDown?.(e as any)} {...css({ width: "100%", height: "100%", objectFit: "contain" })} /> );