mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-03-23 17:56:31 +00:00
feat(tv): add long-press mark as watched action using alert dialog
This commit is contained in:
82
hooks/useTVItemActionModal.ts
Normal file
82
hooks/useTVItemActionModal.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { useCallback } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Alert } from "react-native";
|
||||
import { usePlaybackManager } from "@/hooks/usePlaybackManager";
|
||||
import { useInvalidatePlaybackProgressCache } from "@/hooks/useRevalidatePlaybackProgressCache";
|
||||
|
||||
export const useTVItemActionModal = () => {
|
||||
const { t } = useTranslation();
|
||||
const queryClient = useQueryClient();
|
||||
const { markItemPlayed, markItemUnplayed } = usePlaybackManager();
|
||||
const invalidatePlaybackProgressCache = useInvalidatePlaybackProgressCache();
|
||||
|
||||
const showItemActions = useCallback(
|
||||
(item: BaseItemDto) => {
|
||||
const isPlayed = item.UserData?.Played ?? false;
|
||||
const itemTitle =
|
||||
item.Type === "Episode"
|
||||
? `${item.SeriesName} - ${item.Name}`
|
||||
: (item.Name ?? "");
|
||||
|
||||
const actionLabel = isPlayed
|
||||
? t("item_card.mark_unplayed")
|
||||
: t("item_card.mark_played");
|
||||
|
||||
Alert.alert(itemTitle, undefined, [
|
||||
{ text: t("common.cancel"), style: "cancel" },
|
||||
{
|
||||
text: actionLabel,
|
||||
onPress: async () => {
|
||||
if (!item.Id) return;
|
||||
|
||||
// Optimistic update
|
||||
queryClient.setQueriesData<BaseItemDto | null | undefined>(
|
||||
{ queryKey: ["item", item.Id] },
|
||||
(old) => {
|
||||
if (!old) return old;
|
||||
return {
|
||||
...old,
|
||||
UserData: {
|
||||
...old.UserData,
|
||||
Played: !isPlayed,
|
||||
PlaybackPositionTicks: 0,
|
||||
PlayedPercentage: 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
try {
|
||||
if (!isPlayed) {
|
||||
await markItemPlayed(item.Id);
|
||||
} else {
|
||||
await markItemUnplayed(item.Id);
|
||||
}
|
||||
} catch {
|
||||
// Revert on failure
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["item", item.Id],
|
||||
});
|
||||
} finally {
|
||||
await invalidatePlaybackProgressCache();
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["item", item.Id],
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
]);
|
||||
},
|
||||
[
|
||||
t,
|
||||
queryClient,
|
||||
markItemPlayed,
|
||||
markItemUnplayed,
|
||||
invalidatePlaybackProgressCache,
|
||||
],
|
||||
);
|
||||
|
||||
return { showItemActions };
|
||||
};
|
||||
Reference in New Issue
Block a user