mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 12:14:46 -04:00
Enable the bottom scrubber only on touch
This commit is contained in:
parent
d026f9b418
commit
a56c06ca33
@ -18,6 +18,7 @@
|
|||||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { useEffect } from "react";
|
||||||
import { Platform, ViewProps } from "react-native";
|
import { Platform, ViewProps } from "react-native";
|
||||||
|
|
||||||
export const TouchOnlyCss = () => {
|
export const TouchOnlyCss = () => {
|
||||||
@ -39,3 +40,10 @@ export const touchOnly: ViewProps = {
|
|||||||
export const noTouch: ViewProps = {
|
export const noTouch: ViewProps = {
|
||||||
style: Platform.OS === "web" ? ({ $$css: true, noTouch: "noTouch" } as any) : { display: "none" },
|
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");
|
||||||
|
};
|
||||||
|
@ -33,12 +33,13 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
tooltip,
|
tooltip,
|
||||||
ts,
|
ts,
|
||||||
|
useIsTouch,
|
||||||
} from "@kyoo/primitives";
|
} from "@kyoo/primitives";
|
||||||
import { Chapter, KyooImage, Subtitle, Audio } from "@kyoo/models";
|
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 } from "yoshiki/native";
|
import { percent, rem, useYoshiki, vh } 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";
|
||||||
@ -63,6 +64,7 @@ const hoverReasonAtom = atom({
|
|||||||
export const hoverAtom = atom((get) =>
|
export const hoverAtom = atom((get) =>
|
||||||
[!get(playAtom), ...Object.values(get(hoverReasonAtom))].includes(true),
|
[!get(playAtom), ...Object.values(get(hoverReasonAtom))].includes(true),
|
||||||
);
|
);
|
||||||
|
export const seekingAtom = atom(false);
|
||||||
|
|
||||||
export const Hover = ({
|
export const Hover = ({
|
||||||
isLoading,
|
isLoading,
|
||||||
@ -93,6 +95,10 @@ export const Hover = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const show = useAtomValue(hoverAtom);
|
const show = useAtomValue(hoverAtom);
|
||||||
const setHover = useSetAtom(hoverReasonAtom);
|
const setHover = useSetAtom(hoverReasonAtom);
|
||||||
|
const isSeeking = useAtomValue(seekingAtom);
|
||||||
|
const isTouch = useIsTouch();
|
||||||
|
|
||||||
|
const showBottomSeeker = isSeeking && isTouch;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContrastArea mode="dark">
|
<ContrastArea mode="dark">
|
||||||
@ -150,32 +156,37 @@ export const Hover = ({
|
|||||||
maxWidth: percent(100),
|
maxWidth: percent(100),
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<H2 numberOfLines={1} {...css({ paddingBottom: ts(1) })}>
|
{!showBottomSeeker && (
|
||||||
{isLoading ? <Skeleton {...css({ width: rem(15), height: rem(2) })} /> : name}
|
<H2 numberOfLines={1} {...css({ paddingBottom: ts(1) })}>
|
||||||
</H2>
|
{isLoading ? <Skeleton {...css({ width: rem(15), height: rem(2) })} /> : name}
|
||||||
<ProgressBar url={url} chapters={chapters} />
|
</H2>
|
||||||
<BottomScrubber url={url} />
|
)}
|
||||||
<View
|
<ProgressBar chapters={chapters} url={url} />
|
||||||
{...css({
|
{showBottomSeeker ? (
|
||||||
flexDirection: "row",
|
<BottomScrubber url={url} />
|
||||||
flexGrow: 1,
|
) : (
|
||||||
justifyContent: "space-between",
|
<View
|
||||||
flexWrap: "wrap",
|
{...css({
|
||||||
})}
|
flexDirection: "row",
|
||||||
>
|
flexGrow: 1,
|
||||||
<LeftButtons previousSlug={previousSlug} nextSlug={nextSlug} />
|
justifyContent: "space-between",
|
||||||
<RightButtons
|
flexWrap: "wrap",
|
||||||
subtitles={subtitles}
|
})}
|
||||||
audios={audios}
|
>
|
||||||
fonts={fonts}
|
<LeftButtons previousSlug={previousSlug} nextSlug={nextSlug} />
|
||||||
qualitiesAvailables={qualitiesAvailables}
|
<RightButtons
|
||||||
onMenuOpen={() => setHover((x) => ({ ...x, menuOpened: true }))}
|
subtitles={subtitles}
|
||||||
onMenuClose={() => {
|
audios={audios}
|
||||||
// Disable hover since the menu overlay makes the mouseout unreliable.
|
fonts={fonts}
|
||||||
setHover((x) => ({ ...x, menuOpened: false, mouseHover: false }));
|
qualitiesAvailables={qualitiesAvailables}
|
||||||
}}
|
onMenuOpen={() => setHover((x) => ({ ...x, menuOpened: true }))}
|
||||||
/>
|
onMenuClose={() => {
|
||||||
</View>
|
// Disable hover since the menu overlay makes the mouseout unreliable.
|
||||||
|
setHover((x) => ({ ...x, menuOpened: false, mouseHover: false }));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@ -318,13 +329,20 @@ const ProgressBar = ({ url, chapters }: { url: string; chapters?: Chapter[] }) =
|
|||||||
const setPlay = useSetAtom(playAtom);
|
const setPlay = useSetAtom(playAtom);
|
||||||
const [hoverProgress, setHoverProgress] = useState<number | null>(null);
|
const [hoverProgress, setHoverProgress] = useState<number | null>(null);
|
||||||
const [layout, setLayout] = useState({ x: 0, y: 0, width: 0, height: 0 });
|
const [layout, setLayout] = useState({ x: 0, y: 0, width: 0, height: 0 });
|
||||||
|
const setSeeking = useSetAtom(seekingAtom);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Slider
|
<Slider
|
||||||
progress={progress}
|
progress={progress}
|
||||||
startSeek={() => setPlay(false)}
|
startSeek={() => {
|
||||||
endSeek={() => setTimeout(() => setPlay(true), 10)}
|
setPlay(false);
|
||||||
|
setSeeking(true);
|
||||||
|
}}
|
||||||
|
endSeek={() => {
|
||||||
|
setSeeking(false);
|
||||||
|
setTimeout(() => setPlay(true), 10);
|
||||||
|
}}
|
||||||
onHover={(progress, layout) => {
|
onHover={(progress, layout) => {
|
||||||
setHoverProgress(progress);
|
setHoverProgress(progress);
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user