mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-01 11:38:26 +01:00
refactor: Feature/offline mode rework (#859)
Co-authored-by: lostb1t <coding-mosses0z@icloud.com> Co-authored-by: Fredrik Burmester <fredrik.burmester@gmail.com> Co-authored-by: Gauvain <68083474+Gauvino@users.noreply.github.com> Co-authored-by: Gauvino <uruknarb20@gmail.com> Co-authored-by: storm1er <le.storm1er@gmail.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Chris <182387676+whoopsi-daisy@users.noreply.github.com> Co-authored-by: arch-fan <55891793+arch-fan@users.noreply.github.com> Co-authored-by: Alex Kim <alexkim@Alexs-MacBook-Pro.local>
This commit is contained in:
@@ -1,102 +1,25 @@
|
||||
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { useAtom } from "jotai";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { markAsNotPlayed } from "@/utils/jellyfin/playstate/markAsNotPlayed";
|
||||
import { markAsPlayed } from "@/utils/jellyfin/playstate/markAsPlayed";
|
||||
import { useHaptic } from "./useHaptic";
|
||||
import { usePlaybackManager } from "./usePlaybackManager";
|
||||
import { useInvalidatePlaybackProgressCache } from "./useRevalidatePlaybackProgressCache";
|
||||
|
||||
export const useMarkAsPlayed = (items: BaseItemDto[]) => {
|
||||
const [api] = useAtom(apiAtom);
|
||||
const [user] = useAtom(userAtom);
|
||||
const queryClient = useQueryClient();
|
||||
const lightHapticFeedback = useHaptic("light");
|
||||
const { markItemPlayed, markItemUnplayed } = usePlaybackManager();
|
||||
const invalidatePlaybackProgressCache = useInvalidatePlaybackProgressCache();
|
||||
|
||||
const invalidateQueries = () => {
|
||||
const queriesToInvalidate = [
|
||||
["resumeItems"],
|
||||
["continueWatching"],
|
||||
["nextUp-all"],
|
||||
["nextUp"],
|
||||
["episodes"],
|
||||
["seasons"],
|
||||
["home"],
|
||||
];
|
||||
|
||||
items.forEach((item) => {
|
||||
if (!item.Id) return;
|
||||
queriesToInvalidate.push(["item", item.Id]);
|
||||
});
|
||||
|
||||
queriesToInvalidate.forEach((queryKey) => {
|
||||
queryClient.invalidateQueries({ queryKey });
|
||||
});
|
||||
};
|
||||
|
||||
const markAsPlayedStatus = async (played: boolean) => {
|
||||
const toggle = async (played: boolean) => {
|
||||
lightHapticFeedback();
|
||||
// Process all items
|
||||
await Promise.all(
|
||||
items.map((item) => {
|
||||
if (!item.Id) return Promise.resolve();
|
||||
return played ? markItemPlayed(item.Id) : markItemUnplayed(item.Id);
|
||||
}),
|
||||
);
|
||||
|
||||
items.forEach((item) => {
|
||||
// Optimistic update
|
||||
queryClient.setQueryData(
|
||||
["item", item.Id],
|
||||
(oldData: BaseItemDto | undefined) => {
|
||||
if (oldData) {
|
||||
return {
|
||||
...oldData,
|
||||
UserData: {
|
||||
...oldData.UserData,
|
||||
Played: played,
|
||||
},
|
||||
};
|
||||
}
|
||||
return oldData;
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
try {
|
||||
// Process all items
|
||||
await Promise.all(
|
||||
items.map((item) =>
|
||||
played
|
||||
? markAsPlayed({ api, item, userId: user?.Id })
|
||||
: markAsNotPlayed({ api, itemId: item?.Id, userId: user?.Id }),
|
||||
),
|
||||
);
|
||||
|
||||
// Bulk invalidate
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [
|
||||
"resumeItems",
|
||||
"continueWatching",
|
||||
"nextUp-all",
|
||||
"nextUp",
|
||||
"episodes",
|
||||
"seasons",
|
||||
"home",
|
||||
...items.map((item) => ["item", item.Id]),
|
||||
].flat(),
|
||||
});
|
||||
} catch (error) {
|
||||
// Revert all optimistic updates on any failure
|
||||
items.forEach((item) => {
|
||||
queryClient.setQueryData(
|
||||
["item", item.Id],
|
||||
(oldData: BaseItemDto | undefined) =>
|
||||
oldData
|
||||
? {
|
||||
...oldData,
|
||||
UserData: { ...oldData.UserData, Played: played },
|
||||
}
|
||||
: oldData,
|
||||
);
|
||||
});
|
||||
console.error("Error updating played status:", error);
|
||||
}
|
||||
|
||||
invalidateQueries();
|
||||
await invalidatePlaybackProgressCache();
|
||||
};
|
||||
|
||||
return markAsPlayedStatus;
|
||||
return toggle;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user