mirror of
https://github.com/sussy-code/smov.git
synced 2025-01-04 16:47:40 +01:00
181 lines
4.4 KiB
TypeScript
181 lines
4.4 KiB
TypeScript
import { create } from "zustand";
|
|
import { persist } from "zustand/middleware";
|
|
import { immer } from "zustand/middleware/immer";
|
|
|
|
import { PlayerMeta } from "@/stores/player/slices/source";
|
|
|
|
export interface ProgressItem {
|
|
watched: number;
|
|
duration: number;
|
|
}
|
|
|
|
export interface ProgressSeasonItem {
|
|
title: string;
|
|
number: number;
|
|
id: string;
|
|
}
|
|
|
|
export interface ProgressEpisodeItem {
|
|
title: string;
|
|
number: number;
|
|
id: string;
|
|
seasonId: string;
|
|
updatedAt: number;
|
|
progress: ProgressItem;
|
|
}
|
|
|
|
export interface ProgressMediaItem {
|
|
title: string;
|
|
year?: number;
|
|
poster?: string;
|
|
type: "show" | "movie";
|
|
progress?: ProgressItem;
|
|
updatedAt: number;
|
|
seasons: Record<string, ProgressSeasonItem>;
|
|
episodes: Record<string, ProgressEpisodeItem>;
|
|
}
|
|
|
|
export interface ProgressUpdateItem {
|
|
title?: string;
|
|
year?: number;
|
|
poster?: string;
|
|
type?: "show" | "movie";
|
|
progress?: ProgressItem;
|
|
tmdbId: string;
|
|
id: string;
|
|
episodeId?: string;
|
|
seasonId?: string;
|
|
episodeNumber?: number;
|
|
seasonNumber?: number;
|
|
action: "upsert" | "delete";
|
|
}
|
|
|
|
export interface UpdateItemOptions {
|
|
meta: PlayerMeta;
|
|
progress: ProgressItem;
|
|
}
|
|
|
|
export interface ProgressStore {
|
|
items: Record<string, ProgressMediaItem>;
|
|
updateQueue: ProgressUpdateItem[];
|
|
updateItem(ops: UpdateItemOptions): void;
|
|
removeItem(id: string): void;
|
|
replaceItems(items: Record<string, ProgressMediaItem>): void;
|
|
clear(): void;
|
|
clearUpdateQueue(): void;
|
|
removeUpdateItem(id: string): void;
|
|
}
|
|
|
|
let updateId = 0;
|
|
|
|
export const useProgressStore = create(
|
|
persist(
|
|
immer<ProgressStore>((set) => ({
|
|
items: {},
|
|
updateQueue: [],
|
|
removeItem(id) {
|
|
set((s) => {
|
|
updateId += 1;
|
|
s.updateQueue.push({
|
|
id: updateId.toString(),
|
|
action: "delete",
|
|
tmdbId: id,
|
|
});
|
|
|
|
delete s.items[id];
|
|
});
|
|
},
|
|
replaceItems(items: Record<string, ProgressMediaItem>) {
|
|
set((s) => {
|
|
s.items = items;
|
|
});
|
|
},
|
|
updateItem({ meta, progress }) {
|
|
set((s) => {
|
|
// add to updateQueue
|
|
updateId += 1;
|
|
s.updateQueue.push({
|
|
tmdbId: meta.tmdbId,
|
|
title: meta.title,
|
|
year: meta.releaseYear,
|
|
poster: meta.poster,
|
|
type: meta.type,
|
|
progress: { ...progress },
|
|
id: updateId.toString(),
|
|
episodeId: meta.episode?.tmdbId,
|
|
seasonId: meta.season?.tmdbId,
|
|
seasonNumber: meta.season?.number,
|
|
episodeNumber: meta.episode?.number,
|
|
action: "upsert",
|
|
});
|
|
|
|
// add to progress store
|
|
if (!s.items[meta.tmdbId])
|
|
s.items[meta.tmdbId] = {
|
|
type: meta.type,
|
|
episodes: {},
|
|
seasons: {},
|
|
updatedAt: 0,
|
|
title: meta.title,
|
|
year: meta.releaseYear,
|
|
poster: meta.poster,
|
|
};
|
|
const item = s.items[meta.tmdbId];
|
|
item.updatedAt = Date.now();
|
|
|
|
if (meta.type === "movie") {
|
|
if (!item.progress)
|
|
item.progress = {
|
|
duration: 0,
|
|
watched: 0,
|
|
};
|
|
item.progress = { ...progress };
|
|
return;
|
|
}
|
|
|
|
if (!meta.episode || !meta.season) return;
|
|
|
|
if (!item.seasons[meta.season.tmdbId])
|
|
item.seasons[meta.season.tmdbId] = {
|
|
id: meta.season.tmdbId,
|
|
number: meta.season.number,
|
|
title: meta.season.title,
|
|
};
|
|
|
|
if (!item.episodes[meta.episode.tmdbId])
|
|
item.episodes[meta.episode.tmdbId] = {
|
|
id: meta.episode.tmdbId,
|
|
number: meta.episode.number,
|
|
title: meta.episode.title,
|
|
seasonId: meta.season.tmdbId,
|
|
updatedAt: Date.now(),
|
|
progress: {
|
|
duration: 0,
|
|
watched: 0,
|
|
},
|
|
};
|
|
|
|
item.episodes[meta.episode.tmdbId].progress = { ...progress };
|
|
});
|
|
},
|
|
clear() {
|
|
set((s) => {
|
|
s.items = {};
|
|
});
|
|
},
|
|
clearUpdateQueue() {
|
|
set((s) => {
|
|
s.updateQueue = [];
|
|
});
|
|
},
|
|
removeUpdateItem(id: string) {
|
|
set((s) => {
|
|
s.updateQueue = [...s.updateQueue.filter((v) => v.id !== id)];
|
|
});
|
|
},
|
|
})),
|
|
{
|
|
name: "__MW::progress",
|
|
},
|
|
),
|
|
);
|