diff --git a/src/components/media/MediaCard.tsx b/src/components/media/MediaCard.tsx
index 7b63bf7e..e51db836 100644
--- a/src/components/media/MediaCard.tsx
+++ b/src/components/media/MediaCard.tsx
@@ -8,8 +8,6 @@ export interface MediaCardProps {
linkable?: boolean;
}
-// TODO add progress back
-
function MediaCardContent({ media, linkable }: MediaCardProps) {
return (
diff --git a/src/state/bookmark/context.tsx b/src/state/bookmark/context.tsx
index 977b4596..b4593be2 100644
--- a/src/state/bookmark/context.tsx
+++ b/src/state/bookmark/context.tsx
@@ -63,15 +63,7 @@ export function BookmarkContextProvider(props: { children: ReactNode }) {
if (bookmarked) {
const itemIndex = getBookmarkIndexFromMedia(data.bookmarks, media);
if (itemIndex === -1) {
- const item = {
- id: media.id,
- type: media.type,
- // providerId: media.providerId,
- title: media.title,
- year: media.year,
- // episodeId: media.episodeId,
- // seasonId: media.seasonId,
- };
+ const item: MWMediaMeta = { ...media };
data.bookmarks.push(item);
}
} else {
diff --git a/src/state/bookmark/store.ts b/src/state/bookmark/store.ts
index 06456b78..089a6693 100644
--- a/src/state/bookmark/store.ts
+++ b/src/state/bookmark/store.ts
@@ -9,7 +9,6 @@ export const BookmarkStore = versionedStoreBuilder()
version: 1,
migrate() {
return {
- // TODO actually migrate
bookmarks: [],
};
},
diff --git a/src/state/watched/context.tsx b/src/state/watched/context.tsx
index c434801e..cefec243 100644
--- a/src/state/watched/context.tsx
+++ b/src/state/watched/context.tsx
@@ -1,5 +1,6 @@
-import { MWMediaMeta, MWMediaType } from "@/backend/metadata/types";
-import React, {
+import { DetailedMeta } from "@/backend/metadata/getmeta";
+import { MWMediaMeta } from "@/backend/metadata/types";
+import {
createContext,
ReactNode,
useCallback,
@@ -9,7 +10,16 @@ import React, {
} from "react";
import { VideoProgressStore } from "./store";
-interface WatchedStoreItem extends MWMediaMeta {
+interface MediaItem {
+ meta: MWMediaMeta;
+ series?: {
+ episode: number;
+ season: number;
+ };
+}
+
+interface WatchedStoreItem {
+ item: MediaItem;
progress: number;
percentage: number;
}
@@ -19,18 +29,11 @@ export interface WatchedStoreData {
}
interface WatchedStoreDataWrapper {
- updateProgress(media: MWMediaMeta, progress: number, total: number): void;
+ updateProgress(media: MediaItem, progress: number, total: number): void;
getFilteredWatched(): WatchedStoreItem[];
watched: WatchedStoreData;
}
-export function getWatchedFromPortable(
- items: WatchedStoreItem[],
- media: MWMediaMeta
-): WatchedStoreItem | undefined {
- return undefined;
-}
-
const WatchedContext = createContext
({
updateProgress: () => {},
getFilteredWatched: () => [],
@@ -62,49 +65,39 @@ export function WatchedContextProvider(props: { children: ReactNode }) {
const contextValue = useMemo(
() => ({
- updateProgress(
- media: MWMediaMeta,
- progress: number,
- total: number
- ): void {
- // setWatched((data: WatchedStoreData) => {
- // let item = getWatchedFromPortable(data.items, media);
- // if (!item) {
- // item = {
- // mediaId: media.mediaId,
- // mediaType: media.mediaType,
- // providerId: media.providerId,
- // title: media.title,
- // year: media.year,
- // percentage: 0,
- // progress: 0,
- // episodeId: media.episodeId,
- // seasonId: media.seasonId,
- // };
- // data.items.push(item);
- // }
- // // update actual item
- // item.progress = progress;
- // item.percentage = Math.round((progress / total) * 100);
- // return data;
- // });
+ updateProgress(media: MediaItem, progress: number, total: number): void {
+ setWatched((data: WatchedStoreData) => {
+ let item = data.items.find((v) => v.item.meta.id === media.meta.id);
+ if (!item) {
+ item = {
+ item: {
+ ...media,
+ meta: { ...media.meta },
+ series: media.series ? { ...media.series } : undefined,
+ },
+ progress: 0,
+ percentage: 0,
+ };
+ data.items.push(item);
+ }
+ // update actual item
+ item.progress = progress;
+ item.percentage = Math.round((progress / total) * 100);
+ return data;
+ });
},
getFilteredWatched() {
- // remove disabled providers
- // let filtered = watched.items.filter(
- // (item) => getProviderMetadata(item.providerId)?.enabled
- // );
let filtered = watched.items;
- // // get highest episode number for every anime/season
+ // get highest episode number for every anime/season
const highestEpisode: Record = {};
const highestWatchedItem: Record = {};
filtered = filtered.filter((item) => {
- if ([MWMediaType.ANIME, MWMediaType.SERIES].includes(item.type)) {
- const key = `${item.type}-${item.id}`;
+ if (item.item.series) {
+ const key = item.item.meta.id;
const current: [number, number] = [
- item.episodeId ? parseInt(item.episodeId, 10) : -1,
- item.seasonId ? parseInt(item.seasonId, 10) : -1,
+ item.item.series.episode,
+ item.item.series.season,
];
let existing = highestEpisode[key];
if (!existing) {
@@ -127,7 +120,7 @@ export function WatchedContextProvider(props: { children: ReactNode }) {
},
watched,
}),
- [watched]
+ [watched, setWatched]
);
return (
@@ -140,3 +133,23 @@ export function WatchedContextProvider(props: { children: ReactNode }) {
export function useWatchedContext() {
return useContext(WatchedContext);
}
+
+export function useWatchedItem(meta: DetailedMeta | null) {
+ const { watched, updateProgress } = useContext(WatchedContext);
+ const item = useMemo(
+ () => watched.items.find((v) => meta && v.item.meta.id === meta?.meta.id),
+ [watched, meta]
+ );
+
+ const callback = useCallback(
+ (progress: number, total: number) => {
+ if (meta) {
+ // TODO add series support
+ updateProgress({ meta: meta.meta }, progress, total);
+ }
+ },
+ [updateProgress, meta]
+ );
+
+ return { updateProgress: callback, watchedItem: item };
+}
diff --git a/src/state/watched/store.ts b/src/state/watched/store.ts
index 4ea10100..aada4131 100644
--- a/src/state/watched/store.ts
+++ b/src/state/watched/store.ts
@@ -8,7 +8,6 @@ export const VideoProgressStore = versionedStoreBuilder()
.addVersion({
version: 1,
migrate() {
- // TODO add migration back
return {
items: [],
};
@@ -17,7 +16,6 @@ export const VideoProgressStore = versionedStoreBuilder()
.addVersion({
version: 2,
migrate() {
- // TODO actually migrate
return {
items: [],
};
diff --git a/src/views/media/MediaView.tsx b/src/views/media/MediaView.tsx
index b019e688..4c92fd4d 100644
--- a/src/views/media/MediaView.tsx
+++ b/src/views/media/MediaView.tsx
@@ -13,6 +13,8 @@ import { MWMediaType } from "@/backend/metadata/types";
import { useGoBack } from "@/hooks/useGoBack";
import { IconPatch } from "@/components/buttons/IconPatch";
import { Icons } from "@/components/Icon";
+import { useWatchedItem } from "@/state/watched";
+import { ProgressListenerControl } from "@/components/video/controls/ProgressListenerControl";
import { MediaFetchErrorView } from "./MediaErrorView";
import { MediaScrapeLog } from "./MediaScrapeLog";
import { NotFoundMedia, NotFoundWrapper } from "../notfound/NotFoundView";
@@ -102,6 +104,8 @@ export function MediaView() {
});
const [stream, setStream] = useState(null);
+ const { updateProgress, watchedItem } = useWatchedItem(meta);
+
useEffect(() => {
exec(params.media).then((v) => {
setMeta(v ?? null);
@@ -115,8 +119,6 @@ export function MediaView() {
});
}, [exec, params.media]);
- // TODO watched store
-
if (loading) return ;
if (error) return ;
if (!meta || !selected)
@@ -142,6 +144,10 @@ export function MediaView() {
);
diff --git a/src/views/search/HomeView.tsx b/src/views/search/HomeView.tsx
index ac745ede..ffd9dd99 100644
--- a/src/views/search/HomeView.tsx
+++ b/src/views/search/HomeView.tsx
@@ -7,6 +7,7 @@ import {
useBookmarkContext,
} from "@/state/bookmark";
import { useWatchedContext } from "@/state/watched";
+import { WatchedMediaCard } from "@/components/media/WatchedMediaCard";
function Bookmarks() {
const { t } = useTranslation();
@@ -21,52 +22,45 @@ function Bookmarks() {
icon={Icons.BOOKMARK}
>
- {/* {bookmarks.map((v) => (
-
- ))} */}
+ {bookmarks.map((v) => (
+
+ ))}
);
}
-// function Watched() {
-// const { t } = useTranslation();
-// const { getFilteredBookmarks } = useBookmarkContext();
-// const { getFilteredWatched } = useWatchedContext();
+function Watched() {
+ const { t } = useTranslation();
+ const { getFilteredBookmarks } = useBookmarkContext();
+ const { getFilteredWatched } = useWatchedContext();
-// const bookmarks = getFilteredBookmarks();
-// const watchedItems = getFilteredWatched().filter(
-// (v) => !getIfBookmarkedFromPortable(bookmarks, v)
-// );
+ const bookmarks = getFilteredBookmarks();
+ const watchedItems = getFilteredWatched().filter(
+ (v) => !getIfBookmarkedFromPortable(bookmarks, v.item.meta)
+ );
-// if (watchedItems.length === 0) return null;
+ if (watchedItems.length === 0) return null;
-// return (
-//
-//
-// {/* {watchedItems.map((v) => (
-//
-// ))} */}
-//
-//
-// );
-// }
+ return (
+
+
+ {watchedItems.map((v) => (
+
+ ))}
+
+
+ );
+}
export function HomeView() {
return (
- {/* */}
- {/* */}
+
+
);
}