From 0e73299429e98ea1620577738bc746e71b7995dd Mon Sep 17 00:00:00 2001 From: Fredrik Burmester Date: Sun, 5 Jan 2025 15:51:04 +0100 Subject: [PATCH] Revert "feat: haptic feedback settings and custom hook" --- app/(auth)/(tabs)/(home)/settings.tsx | 5 +- app/(auth)/player/direct-player.tsx | 8 ++- app/(auth)/player/music-player.tsx | 6 +-- app/(auth)/player/transcoding-player.tsx | 7 ++- components/Button.tsx | 6 +-- components/PlayButton.tsx | 5 +- components/RoundButton.tsx | 5 +- components/downloads/EpisodeCard.tsx | 5 +- components/downloads/MovieCard.tsx | 5 +- components/home/LargeMovieCarousel.tsx | 5 +- components/settings/OtherSettings.tsx | 9 ---- components/settings/QuickConnect.tsx | 10 ++-- components/settings/StorageSettings.tsx | 8 ++- components/video-player/controls/Controls.tsx | 18 +++---- hooks/useCreditSkipper.ts | 5 +- hooks/useHaptic.ts | 54 ------------------- hooks/useIntroSkipper.ts | 5 +- hooks/useMarkAsPlayed.ts | 5 +- providers/DownloadProvider.tsx | 8 +-- utils/atoms/settings.ts | 2 - 20 files changed, 47 insertions(+), 134 deletions(-) delete mode 100644 hooks/useHaptic.ts diff --git a/app/(auth)/(tabs)/(home)/settings.tsx b/app/(auth)/(tabs)/(home)/settings.tsx index 559611a8..8f6d102a 100644 --- a/app/(auth)/(tabs)/(home)/settings.tsx +++ b/app/(auth)/(tabs)/(home)/settings.tsx @@ -13,7 +13,7 @@ import { SubtitleToggles } from "@/components/settings/SubtitleToggles"; import { UserInfo } from "@/components/settings/UserInfo"; import { useJellyfin } from "@/providers/JellyfinProvider"; import { clearLogs } from "@/utils/log"; -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; import { useNavigation, useRouter } from "expo-router"; import { useEffect } from "react"; import { ScrollView, TouchableOpacity, View } from "react-native"; @@ -23,11 +23,10 @@ export default function settings() { const router = useRouter(); const insets = useSafeAreaInsets(); const { logout } = useJellyfin(); - const successHapticFeedback = useHaptic("success"); const onClearLogsClicked = async () => { clearLogs(); - successHapticFeedback(); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); }; const navigation = useNavigation(); diff --git a/app/(auth)/player/direct-player.tsx b/app/(auth)/player/direct-player.tsx index 44b0eb34..4d924938 100644 --- a/app/(auth)/player/direct-player.tsx +++ b/app/(auth)/player/direct-player.tsx @@ -27,7 +27,7 @@ import { getUserLibraryApi, } from "@jellyfin/sdk/lib/utils/api"; import { useQuery } from "@tanstack/react-query"; -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; import { useFocusEffect, useGlobalSearchParams } from "expo-router"; import { useAtomValue } from "jotai"; import React, { @@ -68,11 +68,9 @@ export default function page() { const { getDownloadedItem } = useDownload(); const revalidateProgressCache = useInvalidatePlaybackProgressCache(); - const lightHapticFeedback = useHaptic("light"); - const setShowControls = useCallback((show: boolean) => { _setShowControls(show); - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); }, []); const { @@ -177,7 +175,7 @@ export default function page() { const togglePlay = useCallback(async () => { if (!api) return; - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); if (isPlaying) { await videoRef.current?.pause(); diff --git a/app/(auth)/player/music-player.tsx b/app/(auth)/player/music-player.tsx index fc4b8863..eca16b4c 100644 --- a/app/(auth)/player/music-player.tsx +++ b/app/(auth)/player/music-player.tsx @@ -17,7 +17,7 @@ import { getUserLibraryApi, } from "@jellyfin/sdk/lib/utils/api"; import { useQuery } from "@tanstack/react-query"; -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; import { Image } from "expo-image"; import { useFocusEffect, useLocalSearchParams } from "expo-router"; import { useAtomValue } from "jotai"; @@ -45,8 +45,6 @@ export default function page() { const isSeeking = useSharedValue(false); const cacheProgress = useSharedValue(0); - const lightHapticFeedback = useHaptic("light"); - const { itemId, audioIndex: audioIndexStr, @@ -126,7 +124,7 @@ export default function page() { const togglePlay = useCallback( async (ticks: number) => { - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); if (isPlaying) { videoRef.current?.pause(); await getPlaystateApi(api!).onPlaybackProgress({ diff --git a/app/(auth)/player/transcoding-player.tsx b/app/(auth)/player/transcoding-player.tsx index 971410f4..bcb9a6e4 100644 --- a/app/(auth)/player/transcoding-player.tsx +++ b/app/(auth)/player/transcoding-player.tsx @@ -20,7 +20,7 @@ import { getUserLibraryApi, } from "@jellyfin/sdk/lib/utils/api"; import { useQuery } from "@tanstack/react-query"; -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; import { useFocusEffect, useLocalSearchParams } from "expo-router"; import { useAtomValue } from "jotai"; import React, { @@ -48,7 +48,6 @@ const Player = () => { const firstTime = useRef(true); const revalidateProgressCache = useInvalidatePlaybackProgressCache(); - const lightHapticFeedback = useHaptic("light"); const [isPlaybackStopped, setIsPlaybackStopped] = useState(false); const [showControls, _setShowControls] = useState(true); @@ -59,7 +58,7 @@ const Player = () => { const setShowControls = useCallback((show: boolean) => { _setShowControls(show); - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); }, []); const progress = useSharedValue(0); @@ -168,7 +167,7 @@ const Player = () => { const videoSource = useVideoSource(item, api, poster, stream?.url); const togglePlay = useCallback(async () => { - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); if (isPlaying) { videoRef.current?.pause(); await getPlaystateApi(api!).onPlaybackProgress({ diff --git a/components/Button.tsx b/components/Button.tsx index 2c41ad50..1a73ad01 100644 --- a/components/Button.tsx +++ b/components/Button.tsx @@ -1,4 +1,4 @@ -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; import React, { PropsWithChildren, ReactNode, useMemo } from "react"; import { Text, TouchableOpacity, View } from "react-native"; import { Loader } from "./Loader"; @@ -43,8 +43,6 @@ export const Button: React.FC> = ({ } }, [color]); - const lightHapticFeedback = useHaptic("light"); - return ( > = ({ onPress={() => { if (!loading && !disabled && onPress) { onPress(); - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); } }} disabled={disabled || loading} diff --git a/components/PlayButton.tsx b/components/PlayButton.tsx index e432f2a8..e5c5dd87 100644 --- a/components/PlayButton.tsx +++ b/components/PlayButton.tsx @@ -32,7 +32,7 @@ import Animated, { import { Button } from "./Button"; import { SelectedOptions } from "./ItemContent"; import { chromecastProfile } from "@/utils/profiles/chromecast"; -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; interface Props extends React.ComponentProps { item: BaseItemDto; @@ -64,7 +64,6 @@ export const PlayButton: React.FC = ({ const widthProgress = useSharedValue(0); const colorChangeProgress = useSharedValue(0); const [settings] = useSettings(); - const lightHapticFeedback = useHaptic("light"); const goToPlayer = useCallback( (q: string, bitrateValue: number | undefined) => { @@ -80,7 +79,7 @@ export const PlayButton: React.FC = ({ const onPress = useCallback(async () => { if (!item) return; - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); const queryParams = new URLSearchParams({ itemId: item.Id!, diff --git a/components/RoundButton.tsx b/components/RoundButton.tsx index 5d2faf73..049c5ed0 100644 --- a/components/RoundButton.tsx +++ b/components/RoundButton.tsx @@ -6,7 +6,7 @@ import { TouchableOpacity, TouchableOpacityProps, } from "react-native"; -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; interface Props extends TouchableOpacityProps { onPress?: () => void; @@ -29,11 +29,10 @@ export const RoundButton: React.FC> = ({ }) => { const buttonSize = size === "large" ? "h-10 w-10" : "h-9 w-9"; const fillColorClass = fillColor === "primary" ? "bg-purple-600" : ""; - const lightHapticFeedback = useHaptic("light"); const handlePress = () => { if (hapticFeedback) { - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); } onPress?.(); }; diff --git a/components/downloads/EpisodeCard.tsx b/components/downloads/EpisodeCard.tsx index 53b3ecec..e8387da5 100644 --- a/components/downloads/EpisodeCard.tsx +++ b/components/downloads/EpisodeCard.tsx @@ -1,5 +1,5 @@ import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; import React, { useCallback, useMemo } from "react"; import { TouchableOpacity, TouchableOpacityProps, View } from "react-native"; import { @@ -26,7 +26,6 @@ export const EpisodeCard: React.FC = ({ item, ...props }) => { const { deleteFile } = useDownload(); const { openFile } = useDownloadedFileOpener(); const { showActionSheetWithOptions } = useActionSheet(); - const successHapticFeedback = useHaptic("success"); const base64Image = useMemo(() => { return storage.getString(item.Id!); @@ -42,7 +41,7 @@ export const EpisodeCard: React.FC = ({ item, ...props }) => { const handleDeleteFile = useCallback(() => { if (item.Id) { deleteFile(item.Id); - successHapticFeedback(); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); } }, [deleteFile, item.Id]); diff --git a/components/downloads/MovieCard.tsx b/components/downloads/MovieCard.tsx index bb61f3c8..3073bd0a 100644 --- a/components/downloads/MovieCard.tsx +++ b/components/downloads/MovieCard.tsx @@ -3,7 +3,7 @@ import { useActionSheet, } from "@expo/react-native-action-sheet"; import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; import React, { useCallback, useMemo } from "react"; import { TouchableOpacity, View } from "react-native"; @@ -28,7 +28,6 @@ export const MovieCard: React.FC = ({ item }) => { const { deleteFile } = useDownload(); const { openFile } = useDownloadedFileOpener(); const { showActionSheetWithOptions } = useActionSheet(); - const successHapticFeedback = useHaptic("success"); const handleOpenFile = useCallback(() => { openFile(item); @@ -44,7 +43,7 @@ export const MovieCard: React.FC = ({ item }) => { const handleDeleteFile = useCallback(() => { if (item.Id) { deleteFile(item.Id); - successHapticFeedback(); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); } }, [deleteFile, item.Id]); diff --git a/components/home/LargeMovieCarousel.tsx b/components/home/LargeMovieCarousel.tsx index 00767621..a22c586f 100644 --- a/components/home/LargeMovieCarousel.tsx +++ b/components/home/LargeMovieCarousel.tsx @@ -22,7 +22,7 @@ import { itemRouter, TouchableItemRouter } from "../common/TouchableItemRouter"; import { Loader } from "../Loader"; import { Gesture, GestureDetector } from "react-native-gesture-handler"; import { useRouter, useSegments } from "expo-router"; -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; interface Props extends ViewProps {} @@ -128,7 +128,6 @@ const RenderItem: React.FC<{ item: BaseItemDto }> = ({ item }) => { const [api] = useAtom(apiAtom); const router = useRouter(); const screenWidth = Dimensions.get("screen").width; - const lightHapticFeedback = useHaptic("light"); const uri = useMemo(() => { if (!api) return null; @@ -154,7 +153,7 @@ const RenderItem: React.FC<{ item: BaseItemDto }> = ({ item }) => { const handleRoute = useCallback(() => { if (!from) return; const url = itemRouter(item, from); - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); // @ts-ignore if (url) router.push(url); }, [item, from]); diff --git a/components/settings/OtherSettings.tsx b/components/settings/OtherSettings.tsx index 66f73ef4..d280a167 100644 --- a/components/settings/OtherSettings.tsx +++ b/components/settings/OtherSettings.tsx @@ -178,15 +178,6 @@ export const OtherSettings: React.FC = () => { } /> - - - - updateSettings({ disableHapticFeedback: value }) - } - /> - ); }; diff --git a/components/settings/QuickConnect.tsx b/components/settings/QuickConnect.tsx index 85a8259f..9efbec43 100644 --- a/components/settings/QuickConnect.tsx +++ b/components/settings/QuickConnect.tsx @@ -7,7 +7,7 @@ import { BottomSheetView, } from "@gorhom/bottom-sheet"; import { getQuickConnectApi } from "@jellyfin/sdk/lib/utils/api"; -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; import { useAtom } from "jotai"; import React, { useCallback, useRef, useState } from "react"; import { Alert, View, ViewProps } from "react-native"; @@ -23,8 +23,6 @@ export const QuickConnect: React.FC = ({ ...props }) => { const [user] = useAtom(userAtom); const [quickConnectCode, setQuickConnectCode] = useState(); const bottomSheetModalRef = useRef(null); - const successHapticFeedback = useHaptic("success"); - const errorHapticFeedback = useHaptic("error"); const renderBackdrop = useCallback( (props: BottomSheetBackdropProps) => ( @@ -45,16 +43,16 @@ export const QuickConnect: React.FC = ({ ...props }) => { userId: user?.Id, }); if (res.status === 200) { - successHapticFeedback(); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); Alert.alert("Success", "Quick connect authorized"); setQuickConnectCode(undefined); bottomSheetModalRef?.current?.close(); } else { - errorHapticFeedback(); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error); Alert.alert("Error", "Invalid code"); } } catch (e) { - errorHapticFeedback(); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error); Alert.alert("Error", "Invalid code"); } } diff --git a/components/settings/StorageSettings.tsx b/components/settings/StorageSettings.tsx index 9064bc14..5b693acd 100644 --- a/components/settings/StorageSettings.tsx +++ b/components/settings/StorageSettings.tsx @@ -4,7 +4,7 @@ import { useDownload } from "@/providers/DownloadProvider"; import { clearLogs } from "@/utils/log"; import { useQuery } from "@tanstack/react-query"; import * as FileSystem from "expo-file-system"; -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; import { View } from "react-native"; import * as Progress from "react-native-progress"; import { toast } from "sonner-native"; @@ -13,8 +13,6 @@ import { ListItem } from "../list/ListItem"; export const StorageSettings = () => { const { deleteAllFiles, appSizeUsage } = useDownload(); - const successHapticFeedback = useHaptic("success"); - const errorHapticFeedback = useHaptic("error"); const { data: size, isLoading: appSizeLoading } = useQuery({ queryKey: ["appSize", appSizeUsage], @@ -31,9 +29,9 @@ export const StorageSettings = () => { const onDeleteClicked = async () => { try { await deleteAllFiles(); - successHapticFeedback(); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); } catch (e) { - errorHapticFeedback(); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error); toast.error("Error deleting files"); } }; diff --git a/components/video-player/controls/Controls.tsx b/components/video-player/controls/Controls.tsx index 620e112e..2fd1cba3 100644 --- a/components/video-player/controls/Controls.tsx +++ b/components/video-player/controls/Controls.tsx @@ -29,7 +29,7 @@ import { BaseItemDto, MediaSourceInfo, } from "@jellyfin/sdk/lib/generated-client"; -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; import { Image } from "expo-image"; import { useLocalSearchParams, useRouter } from "expo-router"; import { useAtom } from "jotai"; @@ -157,12 +157,10 @@ export const Controls: React.FC = ({ isVlc ); - const lightHapticFeedback = useHaptic("light"); - const goToPreviousItem = useCallback(() => { if (!previousItem || !settings) return; - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); const previousIndexes: previousIndexes = { subtitleIndex: subtitleIndex ? parseInt(subtitleIndex) : undefined, @@ -200,7 +198,7 @@ export const Controls: React.FC = ({ const goToNextItem = useCallback(() => { if (!nextItem || !settings) return; - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); const previousIndexes: previousIndexes = { subtitleIndex: subtitleIndex ? parseInt(subtitleIndex) : undefined, @@ -328,7 +326,7 @@ export const Controls: React.FC = ({ const handleSkipBackward = useCallback(async () => { if (!settings?.rewindSkipTime) return; wasPlayingRef.current = isPlaying; - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); try { const curr = progress.value; if (curr !== undefined) { @@ -346,7 +344,7 @@ export const Controls: React.FC = ({ const handleSkipForward = useCallback(async () => { if (!settings?.forwardSkipTime) return; wasPlayingRef.current = isPlaying; - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); try { const curr = progress.value; if (curr !== undefined) { @@ -363,7 +361,7 @@ export const Controls: React.FC = ({ const toggleIgnoreSafeAreas = useCallback(() => { setIgnoreSafeAreas((prev) => !prev); - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); }, []); const memoizedRenderBubble = useCallback(() => { @@ -442,7 +440,7 @@ export const Controls: React.FC = ({ const gotoItem = await getItemById(api, itemId); if (!settings || !gotoItem) return; - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); const previousIndexes: previousIndexes = { subtitleIndex: subtitleIndex ? parseInt(subtitleIndex) : undefined, @@ -586,7 +584,7 @@ export const Controls: React.FC = ({ )} { - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); router.back(); }} className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2" diff --git a/hooks/useCreditSkipper.ts b/hooks/useCreditSkipper.ts index 14a77161..1430e7c9 100644 --- a/hooks/useCreditSkipper.ts +++ b/hooks/useCreditSkipper.ts @@ -5,7 +5,7 @@ import { apiAtom } from "@/providers/JellyfinProvider"; import { getAuthHeaders } from "@/utils/jellyfin/jellyfin"; import { writeToLog } from "@/utils/log"; import { msToSeconds, secondsToMs } from "@/utils/time"; -import { useHaptic } from "./useHaptic"; +import * as Haptics from "expo-haptics"; interface CreditTimestamps { Introduction: { @@ -29,7 +29,6 @@ export const useCreditSkipper = ( ) => { const [api] = useAtom(apiAtom); const [showSkipCreditButton, setShowSkipCreditButton] = useState(false); - const lightHapticFeedback = useHaptic("light"); if (isVlc) { currentTime = msToSeconds(currentTime); @@ -80,7 +79,7 @@ export const useCreditSkipper = ( if (!creditTimestamps) return; console.log(`Skipping credits to ${creditTimestamps.Credits.End}`); try { - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); wrappedSeek(creditTimestamps.Credits.End); setTimeout(() => { play(); diff --git a/hooks/useHaptic.ts b/hooks/useHaptic.ts deleted file mode 100644 index c992def1..00000000 --- a/hooks/useHaptic.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { useCallback, useMemo } from "react"; -import { Platform } from "react-native"; -import * as Haptics from "expo-haptics"; -import { useSettings } from "@/utils/atoms/settings"; - -export type HapticFeedbackType = - | "light" - | "medium" - | "heavy" - | "selection" - | "success" - | "warning" - | "error"; - -export const useHaptic = (feedbackType: HapticFeedbackType = "selection") => { - const [settings] = useSettings(); - - const createHapticHandler = useCallback( - (type: Haptics.ImpactFeedbackStyle) => { - return Platform.OS === "web" ? () => {} : () => Haptics.impactAsync(type); - }, - [] - ); - const createNotificationFeedback = useCallback( - (type: Haptics.NotificationFeedbackType) => { - return Platform.OS === "web" - ? () => {} - : () => Haptics.notificationAsync(type); - }, - [] - ); - - const hapticHandlers = useMemo( - () => ({ - light: createHapticHandler(Haptics.ImpactFeedbackStyle.Light), - medium: createHapticHandler(Haptics.ImpactFeedbackStyle.Medium), - heavy: createHapticHandler(Haptics.ImpactFeedbackStyle.Heavy), - selection: Platform.OS === "web" ? () => {} : Haptics.selectionAsync, - success: createNotificationFeedback( - Haptics.NotificationFeedbackType.Success - ), - warning: createNotificationFeedback( - Haptics.NotificationFeedbackType.Warning - ), - error: createNotificationFeedback(Haptics.NotificationFeedbackType.Error), - }), - [createHapticHandler, createNotificationFeedback] - ); - - if (settings?.disableHapticFeedback) { - return () => {}; - } - return hapticHandlers[feedbackType]; -}; diff --git a/hooks/useIntroSkipper.ts b/hooks/useIntroSkipper.ts index b41872dc..15aaff05 100644 --- a/hooks/useIntroSkipper.ts +++ b/hooks/useIntroSkipper.ts @@ -5,7 +5,7 @@ import { apiAtom } from "@/providers/JellyfinProvider"; import { getAuthHeaders } from "@/utils/jellyfin/jellyfin"; import { writeToLog } from "@/utils/log"; import { msToSeconds, secondsToMs } from "@/utils/time"; -import { useHaptic } from "./useHaptic"; +import * as Haptics from "expo-haptics"; interface IntroTimestamps { EpisodeId: string; @@ -33,7 +33,6 @@ export const useIntroSkipper = ( if (isVlc) { currentTime = msToSeconds(currentTime); } - const lightHapticFeedback = useHaptic("light"); const wrappedSeek = (seconds: number) => { if (isVlc) { @@ -79,7 +78,7 @@ export const useIntroSkipper = ( const skipIntro = useCallback(() => { if (!introTimestamps) return; try { - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); wrappedSeek(introTimestamps.IntroEnd); setTimeout(() => { play(); diff --git a/hooks/useMarkAsPlayed.ts b/hooks/useMarkAsPlayed.ts index fb30bd14..ff039cc8 100644 --- a/hooks/useMarkAsPlayed.ts +++ b/hooks/useMarkAsPlayed.ts @@ -3,14 +3,13 @@ import { markAsNotPlayed } from "@/utils/jellyfin/playstate/markAsNotPlayed"; import { markAsPlayed } from "@/utils/jellyfin/playstate/markAsPlayed"; import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; import { useQueryClient } from "@tanstack/react-query"; -import { useHaptic } from "./useHaptic"; +import * as Haptics from "expo-haptics"; import { useAtom } from "jotai"; export const useMarkAsPlayed = (item: BaseItemDto) => { const [api] = useAtom(apiAtom); const [user] = useAtom(userAtom); const queryClient = useQueryClient(); - const lightHapticFeedback = useHaptic("light"); const invalidateQueries = () => { const queriesToInvalidate = [ @@ -30,7 +29,7 @@ export const useMarkAsPlayed = (item: BaseItemDto) => { }; const markAsPlayedStatus = async (played: boolean) => { - lightHapticFeedback(); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); // Optimistic update queryClient.setQueryData( diff --git a/providers/DownloadProvider.tsx b/providers/DownloadProvider.tsx index fb8b137f..78fbbe6f 100644 --- a/providers/DownloadProvider.tsx +++ b/providers/DownloadProvider.tsx @@ -48,7 +48,7 @@ import useImageStorage from "@/hooks/useImageStorage"; import { storage } from "@/utils/mmkv"; import useDownloadHelper from "@/utils/download"; import { FileInfo } from "expo-file-system"; -import { useHaptic } from "@/hooks/useHaptic"; +import * as Haptics from "expo-haptics"; import * as Application from "expo-application"; export type DownloadedItem = { @@ -78,8 +78,6 @@ function useDownloadProvider() { const [processes, setProcesses] = useAtom(processesAtom); - const successHapticFeedback = useHaptic("success"); - const authHeader = useMemo(() => { return api?.accessToken; }, [api]); @@ -534,7 +532,9 @@ function useDownloadProvider() { if (i.Id) return deleteFile(i.Id); return; }) - ).then(() => successHapticFeedback()); + ).then(() => + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success) + ); }; const cleanCacheDirectory = async () => { diff --git a/utils/atoms/settings.ts b/utils/atoms/settings.ts index c6e8a46a..c37dd4eb 100644 --- a/utils/atoms/settings.ts +++ b/utils/atoms/settings.ts @@ -84,7 +84,6 @@ export type Settings = { downloadMethod: "optimized" | "remux"; autoDownload: boolean; showCustomMenuLinks: boolean; - disableHapticFeedback: boolean; subtitleSize: number; remuxConcurrentLimit: 1 | 2 | 3 | 4; safeAreaInControlsEnabled: boolean; @@ -123,7 +122,6 @@ const loadSettings = (): Settings => { downloadMethod: "remux", autoDownload: false, showCustomMenuLinks: false, - disableHapticFeedback: false, subtitleSize: Platform.OS === "ios" ? 60 : 100, remuxConcurrentLimit: 1, safeAreaInControlsEnabled: true,