Merge branch 'master' into feat/i18n

This commit is contained in:
Simon Caron
2025-01-05 15:06:44 -05:00
27 changed files with 142 additions and 56 deletions

View File

@@ -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 * as Haptics from "expo-haptics";
import { useHaptic } from "./useHaptic";
interface CreditTimestamps {
Introduction: {
@@ -29,6 +29,7 @@ export const useCreditSkipper = (
) => {
const [api] = useAtom(apiAtom);
const [showSkipCreditButton, setShowSkipCreditButton] = useState(false);
const lightHapticFeedback = useHaptic("light");
if (isVlc) {
currentTime = msToSeconds(currentTime);
@@ -79,7 +80,7 @@ export const useCreditSkipper = (
if (!creditTimestamps) return;
console.log(`Skipping credits to ${creditTimestamps.Credits.End}`);
try {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
lightHapticFeedback();
wrappedSeek(creditTimestamps.Credits.End);
setTimeout(() => {
play();

View File

@@ -6,7 +6,7 @@ import {
} from "@jellyfin/sdk/lib/generated-client";
import { useMemo } from "react";
// Used only for intial play settings.
// Used only for initial play settings.
const useDefaultPlaySettings = (
item: BaseItemDto,
settings: Settings | null

54
hooks/useHaptic.ts Normal file
View File

@@ -0,0 +1,54 @@
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];
};

View File

@@ -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 * as Haptics from "expo-haptics";
import { useHaptic } from "./useHaptic";
interface IntroTimestamps {
EpisodeId: string;
@@ -33,6 +33,7 @@ export const useIntroSkipper = (
if (isVlc) {
currentTime = msToSeconds(currentTime);
}
const lightHapticFeedback = useHaptic("light");
const wrappedSeek = (seconds: number) => {
if (isVlc) {
@@ -78,7 +79,7 @@ export const useIntroSkipper = (
const skipIntro = useCallback(() => {
if (!introTimestamps) return;
try {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
lightHapticFeedback();
wrappedSeek(introTimestamps.IntroEnd);
setTimeout(() => {
play();

View File

@@ -3,13 +3,14 @@ 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 * as Haptics from "expo-haptics";
import { useHaptic } from "./useHaptic";
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 = [
@@ -29,7 +30,7 @@ export const useMarkAsPlayed = (item: BaseItemDto) => {
};
const markAsPlayedStatus = async (played: boolean) => {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
lightHapticFeedback();
// Optimistic update
queryClient.setQueryData(