feat: gesture control toggle impl

This commit is contained in:
Adrian Castro
2024-03-21 12:33:47 +01:00
parent 30bf4c3d7a
commit 13143a2664
3 changed files with 57 additions and 4 deletions

View File

@@ -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>

View File

@@ -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) {

View File

@@ -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);
};