mirror of
https://github.com/movie-web/native-app.git
synced 2025-09-13 14:33:26 +00:00
feat: gesture control toggle impl
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import type { SelectProps } from "tamagui";
|
import type { SelectProps } from "tamagui";
|
||||||
import React from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { FontAwesome, MaterialIcons } from "@expo/vector-icons";
|
import { FontAwesome, MaterialIcons } from "@expo/vector-icons";
|
||||||
import {
|
import {
|
||||||
Adapt,
|
Adapt,
|
||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
|
|
||||||
import type { ThemeStoreOption } from "~/stores/theme";
|
import type { ThemeStoreOption } from "~/stores/theme";
|
||||||
import ScreenLayout from "~/components/layout/ScreenLayout";
|
import ScreenLayout from "~/components/layout/ScreenLayout";
|
||||||
|
import { getGestureControls, saveGestureControls } from "~/settings";
|
||||||
import { useThemeStore } from "~/stores/theme";
|
import { useThemeStore } from "~/stores/theme";
|
||||||
|
|
||||||
const themeOptions: ThemeStoreOption[] = [
|
const themeOptions: ThemeStoreOption[] = [
|
||||||
@@ -28,6 +29,19 @@ const themeOptions: ThemeStoreOption[] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export default function SettingsScreen() {
|
export default function SettingsScreen() {
|
||||||
|
const [gestureControlsEnabled, setGestureControlsEnabled] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
void getGestureControls().then((enabled) => {
|
||||||
|
setGestureControlsEnabled(enabled);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleGestureControlsToggle = async (isEnabled: boolean) => {
|
||||||
|
setGestureControlsEnabled(isEnabled);
|
||||||
|
await saveGestureControls(isEnabled);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScreenLayout title="Settings">
|
<ScreenLayout title="Settings">
|
||||||
<View padding={4}>
|
<View padding={4}>
|
||||||
@@ -38,7 +52,12 @@ export default function SettingsScreen() {
|
|||||||
<XStack width={200} alignItems="center" gap="$4">
|
<XStack width={200} alignItems="center" gap="$4">
|
||||||
<Label minWidth={110}>Gesture controls</Label>
|
<Label minWidth={110}>Gesture controls</Label>
|
||||||
<Separator minHeight={20} vertical />
|
<Separator minHeight={20} vertical />
|
||||||
<Switch size="$4" native>
|
<Switch
|
||||||
|
size="$4"
|
||||||
|
native
|
||||||
|
checked={gestureControlsEnabled}
|
||||||
|
onCheckedChange={handleGestureControlsToggle}
|
||||||
|
>
|
||||||
<Switch.Thumb animation="quicker" />
|
<Switch.Thumb animation="quicker" />
|
||||||
</Switch>
|
</Switch>
|
||||||
</XStack>
|
</XStack>
|
||||||
|
@@ -17,6 +17,7 @@ import { useBrightness } from "~/hooks/player/useBrightness";
|
|||||||
import { usePlaybackSpeed } from "~/hooks/player/usePlaybackSpeed";
|
import { usePlaybackSpeed } from "~/hooks/player/usePlaybackSpeed";
|
||||||
import { usePlayer } from "~/hooks/player/usePlayer";
|
import { usePlayer } from "~/hooks/player/usePlayer";
|
||||||
import { useVolume } from "~/hooks/player/useVolume";
|
import { useVolume } from "~/hooks/player/useVolume";
|
||||||
|
import { getGestureControls } from "~/settings";
|
||||||
import { useAudioTrackStore } from "~/stores/audio";
|
import { useAudioTrackStore } from "~/stores/audio";
|
||||||
import { usePlayerStore } from "~/stores/player/store";
|
import { usePlayerStore } from "~/stores/player/store";
|
||||||
import { CaptionRenderer } from "./CaptionRenderer";
|
import { CaptionRenderer } from "./CaptionRenderer";
|
||||||
@@ -61,6 +62,14 @@ export const VideoPlayer = () => {
|
|||||||
const playAudio = usePlayerStore((state) => state.playAudio);
|
const playAudio = usePlayerStore((state) => state.playAudio);
|
||||||
const pauseAudio = usePlayerStore((state) => state.pauseAudio);
|
const pauseAudio = usePlayerStore((state) => state.pauseAudio);
|
||||||
|
|
||||||
|
const [gestureControlsEnabled, setGestureControlsEnabled] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
void getGestureControls().then((enabled) => {
|
||||||
|
setGestureControlsEnabled(enabled);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const checkGestureInSliderVicinity = (x: number, y: number) => {
|
const checkGestureInSliderVicinity = (x: number, y: number) => {
|
||||||
isGestureInSliderVicinity.value = isPointInSliderVicinity(x, y);
|
isGestureInSliderVicinity.value = isPointInSliderVicinity(x, y);
|
||||||
};
|
};
|
||||||
@@ -89,6 +98,7 @@ export const VideoPlayer = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const doubleTapGesture = Gesture.Tap()
|
const doubleTapGesture = Gesture.Tap()
|
||||||
|
.enabled(gestureControlsEnabled)
|
||||||
.numberOfTaps(2)
|
.numberOfTaps(2)
|
||||||
.onEnd(() => {
|
.onEnd(() => {
|
||||||
runOnJS(togglePlayback)();
|
runOnJS(togglePlayback)();
|
||||||
@@ -97,6 +107,7 @@ export const VideoPlayer = () => {
|
|||||||
const screenHalfWidth = Dimensions.get("window").width / 2;
|
const screenHalfWidth = Dimensions.get("window").width / 2;
|
||||||
|
|
||||||
const panGesture = Gesture.Pan()
|
const panGesture = Gesture.Pan()
|
||||||
|
.enabled(gestureControlsEnabled)
|
||||||
.onStart((event) => {
|
.onStart((event) => {
|
||||||
runOnJS(checkGestureInSliderVicinity)(event.x, event.y);
|
runOnJS(checkGestureInSliderVicinity)(event.x, event.y);
|
||||||
if (isGestureInSliderVicinity.value) {
|
if (isGestureInSliderVicinity.value) {
|
||||||
|
@@ -7,14 +7,21 @@ interface ThemeSettings {
|
|||||||
theme: ThemeStoreOption;
|
theme: ThemeStoreOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface PlayerSettings {
|
||||||
|
gestureControls: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
interface Settings {
|
interface Settings {
|
||||||
themes: ThemeSettings;
|
themes: ThemeSettings;
|
||||||
|
player: PlayerSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingsKey = "settings";
|
const settingsKey = "settings";
|
||||||
|
|
||||||
const saveSettings = async (settings: Settings) => {
|
const saveSettings = async (newSettings: Partial<Settings>) => {
|
||||||
await AsyncStorage.setItem(settingsKey, JSON.stringify(settings));
|
const settings = await loadSettings();
|
||||||
|
const mergedSettings = { ...settings, ...newSettings };
|
||||||
|
await AsyncStorage.setItem(settingsKey, JSON.stringify(mergedSettings));
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadSettings = async (): Promise<Settings | null> => {
|
const loadSettings = async (): Promise<Settings | null> => {
|
||||||
@@ -55,3 +62,19 @@ export const loadDownloadHistory = async (): Promise<DownloadItem[]> => {
|
|||||||
: { downloads: [] };
|
: { downloads: [] };
|
||||||
return settings.downloads;
|
return settings.downloads;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getGestureControls = async (): Promise<boolean> => {
|
||||||
|
const settings = await loadSettings();
|
||||||
|
return settings?.player?.gestureControls ?? true;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const saveGestureControls = async (gestureControls: boolean) => {
|
||||||
|
const settings = (await loadSettings()) ?? ({} as Settings);
|
||||||
|
|
||||||
|
if (!settings.player) {
|
||||||
|
settings.player = { gestureControls: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.player.gestureControls = gestureControls;
|
||||||
|
await saveSettings(settings);
|
||||||
|
};
|
||||||
|
Reference in New Issue
Block a user