diff --git a/front/packages/primitives/src/utils/touchonly.tsx b/front/packages/primitives/src/utils/touchonly.tsx
index 98cb6040..7972037c 100644
--- a/front/packages/primitives/src/utils/touchonly.tsx
+++ b/front/packages/primitives/src/utils/touchonly.tsx
@@ -18,6 +18,7 @@
* along with Kyoo. If not, see .
*/
+import { useEffect } from "react";
import { Platform, ViewProps } from "react-native";
export const TouchOnlyCss = () => {
@@ -39,3 +40,10 @@ export const touchOnly: ViewProps = {
export const noTouch: ViewProps = {
style: Platform.OS === "web" ? ({ $$css: true, noTouch: "noTouch" } as any) : { display: "none" },
};
+
+export const useIsTouch = () => {
+ if (Platform.OS !== "web") return true;
+ if (typeof window === "undefined") return false;
+ // TODO: Subscribe to the change.
+ return document.body.classList.contains("noHover");
+};
diff --git a/front/packages/ui/src/player/components/hover.tsx b/front/packages/ui/src/player/components/hover.tsx
index eb651579..54871a7e 100644
--- a/front/packages/ui/src/player/components/hover.tsx
+++ b/front/packages/ui/src/player/components/hover.tsx
@@ -33,12 +33,13 @@ import {
Tooltip,
tooltip,
ts,
+ useIsTouch,
} from "@kyoo/primitives";
import { Chapter, KyooImage, Subtitle, Audio } from "@kyoo/models";
import { useAtomValue, useSetAtom, useAtom } from "jotai";
import { ImageStyle, Platform, Pressable, View, ViewProps } from "react-native";
import { useTranslation } from "react-i18next";
-import { percent, rem, useYoshiki } from "yoshiki/native";
+import { percent, rem, useYoshiki, vh } from "yoshiki/native";
import { useRouter } from "solito/router";
import ArrowBack from "@material-symbols/svg-400/rounded/arrow_back-fill.svg";
import { LeftButtons, TouchControls } from "./left-buttons";
@@ -63,6 +64,7 @@ const hoverReasonAtom = atom({
export const hoverAtom = atom((get) =>
[!get(playAtom), ...Object.values(get(hoverReasonAtom))].includes(true),
);
+export const seekingAtom = atom(false);
export const Hover = ({
isLoading,
@@ -93,6 +95,10 @@ export const Hover = ({
}) => {
const show = useAtomValue(hoverAtom);
const setHover = useSetAtom(hoverReasonAtom);
+ const isSeeking = useAtomValue(seekingAtom);
+ const isTouch = useIsTouch();
+
+ const showBottomSeeker = isSeeking && isTouch;
return (
@@ -150,32 +156,37 @@ export const Hover = ({
maxWidth: percent(100),
})}
>
-
- {isLoading ? : name}
-
-
-
-
-
- setHover((x) => ({ ...x, menuOpened: true }))}
- onMenuClose={() => {
- // Disable hover since the menu overlay makes the mouseout unreliable.
- setHover((x) => ({ ...x, menuOpened: false, mouseHover: false }));
- }}
- />
-
+ {!showBottomSeeker && (
+
+ {isLoading ? : name}
+
+ )}
+
+ {showBottomSeeker ? (
+
+ ) : (
+
+
+ setHover((x) => ({ ...x, menuOpened: true }))}
+ onMenuClose={() => {
+ // Disable hover since the menu overlay makes the mouseout unreliable.
+ setHover((x) => ({ ...x, menuOpened: false, mouseHover: false }));
+ }}
+ />
+
+ )}
@@ -318,13 +329,20 @@ const ProgressBar = ({ url, chapters }: { url: string; chapters?: Chapter[] }) =
const setPlay = useSetAtom(playAtom);
const [hoverProgress, setHoverProgress] = useState(null);
const [layout, setLayout] = useState({ x: 0, y: 0, width: 0, height: 0 });
+ const setSeeking = useSetAtom(seekingAtom);
return (
<>
setPlay(false)}
- endSeek={() => setTimeout(() => setPlay(true), 10)}
+ startSeek={() => {
+ setPlay(false);
+ setSeeking(true);
+ }}
+ endSeek={() => {
+ setSeeking(false);
+ setTimeout(() => setPlay(true), 10);
+ }}
onHover={(progress, layout) => {
setHoverProgress(progress);
setLayout(layout);