mirror of
https://github.com/movie-web/movie-web.git
synced 2024-12-26 15:51:51 +01:00
add bookmarks in new store
This commit is contained in:
parent
aff39d1999
commit
18ec79af07
@ -1,12 +1,28 @@
|
||||
import { useCallback } from "react";
|
||||
|
||||
import { Icons } from "@/components/Icon";
|
||||
import { useBookmarkStore } from "@/stores/bookmarks";
|
||||
import { usePlayerStore } from "@/stores/player/store";
|
||||
|
||||
import { VideoPlayerButton } from "./Button";
|
||||
|
||||
export function BookmarkButton() {
|
||||
const addBookmark = useBookmarkStore((s) => s.addBookmark);
|
||||
const removeBookmark = useBookmarkStore((s) => s.removeBookmark);
|
||||
const bookmarks = useBookmarkStore((s) => s.bookmarks);
|
||||
const meta = usePlayerStore((s) => s.meta);
|
||||
const isBookmarked = !!bookmarks[meta?.tmdbId ?? ""];
|
||||
|
||||
const toggleBookmark = useCallback(() => {
|
||||
if (!meta) return;
|
||||
if (isBookmarked) removeBookmark(meta.tmdbId);
|
||||
else addBookmark(meta);
|
||||
}, [isBookmarked, meta, addBookmark, removeBookmark]);
|
||||
|
||||
return (
|
||||
<VideoPlayerButton
|
||||
onClick={() => window.open("https://youtu.be/TENzstSjsus", "_blank")}
|
||||
icon={Icons.BOOKMARK_OUTLINE}
|
||||
onClick={() => toggleBookmark()}
|
||||
icon={isBookmarked ? Icons.BOOKMARK : Icons.BOOKMARK_OUTLINE}
|
||||
iconSizeClass="text-base"
|
||||
className="p-3"
|
||||
/>
|
||||
|
@ -7,33 +7,29 @@ import { Icons } from "@/components/Icon";
|
||||
import { SectionHeading } from "@/components/layout/SectionHeading";
|
||||
import { MediaGrid } from "@/components/media/MediaGrid";
|
||||
import { WatchedMediaCard } from "@/components/media/WatchedMediaCard";
|
||||
import { useBookmarkContext } from "@/state/bookmark";
|
||||
import { useWatchedContext } from "@/state/watched";
|
||||
import { useBookmarkStore } from "@/stores/bookmarks";
|
||||
import { MediaItem } from "@/utils/mediaTypes";
|
||||
|
||||
export function BookmarksPart() {
|
||||
const { t } = useTranslation();
|
||||
const { getFilteredBookmarks, setItemBookmark } = useBookmarkContext();
|
||||
const bookmarks = getFilteredBookmarks();
|
||||
const bookmarks = useBookmarkStore((s) => s.bookmarks);
|
||||
const removeBookmark = useBookmarkStore((s) => s.removeBookmark);
|
||||
const [editing, setEditing] = useState(false);
|
||||
const [gridRef] = useAutoAnimate<HTMLDivElement>();
|
||||
const { watched } = useWatchedContext();
|
||||
|
||||
const bookmarksSorted = useMemo(() => {
|
||||
return bookmarks
|
||||
.map((v) => {
|
||||
return {
|
||||
...v,
|
||||
watched: watched.items
|
||||
.sort((a, b) => b.watchedAt - a.watchedAt)
|
||||
.find((watchedItem) => watchedItem.item.meta.id === v.id),
|
||||
};
|
||||
})
|
||||
.sort(
|
||||
(a, b) => (b.watched?.watchedAt || 0) - (a.watched?.watchedAt || 0)
|
||||
);
|
||||
}, [watched.items, bookmarks]);
|
||||
// TODO sort on last watched
|
||||
const items = useMemo(() => {
|
||||
const output: MediaItem[] = [];
|
||||
Object.entries(bookmarks).forEach((entry) => {
|
||||
output.push({
|
||||
id: entry[0],
|
||||
...entry[1],
|
||||
});
|
||||
});
|
||||
return output;
|
||||
}, [bookmarks]);
|
||||
|
||||
if (bookmarks.length === 0) return null;
|
||||
if (items.length === 0) return null;
|
||||
|
||||
return (
|
||||
<div>
|
||||
@ -44,14 +40,13 @@ export function BookmarksPart() {
|
||||
<EditButton editing={editing} onEdit={setEditing} />
|
||||
</SectionHeading>
|
||||
<MediaGrid ref={gridRef}>
|
||||
{bookmarksSorted.map((v) => (
|
||||
<div key={v.id}>Bookmark</div>
|
||||
// <WatchedMediaCard
|
||||
// key={v.id}
|
||||
// media={v}
|
||||
// closable={editing}
|
||||
// onClose={() => setItemBookmark(v, false)}
|
||||
// />
|
||||
{items.map((v) => (
|
||||
<WatchedMediaCard
|
||||
key={v.id}
|
||||
media={v}
|
||||
closable={editing}
|
||||
onClose={() => removeBookmark(v.id)}
|
||||
/>
|
||||
))}
|
||||
</MediaGrid>
|
||||
</div>
|
||||
|
@ -7,27 +7,34 @@ import { Icons } from "@/components/Icon";
|
||||
import { SectionHeading } from "@/components/layout/SectionHeading";
|
||||
import { MediaGrid } from "@/components/media/MediaGrid";
|
||||
import { WatchedMediaCard } from "@/components/media/WatchedMediaCard";
|
||||
import { useBookmarkStore } from "@/stores/bookmarks";
|
||||
import { useProgressStore } from "@/stores/progress";
|
||||
import { MediaItem } from "@/utils/mediaTypes";
|
||||
|
||||
export function WatchingPart() {
|
||||
const { t } = useTranslation();
|
||||
const bookmarks = useBookmarkStore((s) => s.bookmarks);
|
||||
const progressItems = useProgressStore((s) => s.items);
|
||||
const removeItem = useProgressStore((s) => s.removeItem);
|
||||
const [editing, setEditing] = useState(false);
|
||||
const [gridRef] = useAutoAnimate<HTMLDivElement>();
|
||||
|
||||
const sortedProgressItems = useMemo(() => {
|
||||
const output: MediaItem[] = [];
|
||||
let output: MediaItem[] = [];
|
||||
Object.entries(progressItems).forEach((entry) => {
|
||||
output.push({
|
||||
id: entry[0],
|
||||
...entry[1],
|
||||
});
|
||||
});
|
||||
|
||||
output = output.filter((v) => {
|
||||
const isBookMarked = !!bookmarks[v.id];
|
||||
return !isBookMarked;
|
||||
});
|
||||
// TODO sort on last modified date
|
||||
return output;
|
||||
}, [progressItems]);
|
||||
}, [progressItems, bookmarks]);
|
||||
|
||||
if (sortedProgressItems.length === 0) return null;
|
||||
|
||||
|
45
src/stores/bookmarks/index.ts
Normal file
45
src/stores/bookmarks/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { create } from "zustand";
|
||||
import { persist } from "zustand/middleware";
|
||||
import { immer } from "zustand/middleware/immer";
|
||||
|
||||
import { PlayerMeta } from "@/stores/player/slices/source";
|
||||
|
||||
export interface BookmarkMediaItem {
|
||||
title: string;
|
||||
year: number;
|
||||
poster?: string;
|
||||
type: "show" | "movie";
|
||||
}
|
||||
|
||||
export interface ProgressStore {
|
||||
bookmarks: Record<string, BookmarkMediaItem>;
|
||||
addBookmark(meta: PlayerMeta): void;
|
||||
removeBookmark(id: string): void;
|
||||
}
|
||||
|
||||
// TODO add migration from previous bookmark store
|
||||
export const useBookmarkStore = create(
|
||||
persist(
|
||||
immer<ProgressStore>((set) => ({
|
||||
bookmarks: {},
|
||||
removeBookmark(id) {
|
||||
set((s) => {
|
||||
delete s.bookmarks[id];
|
||||
});
|
||||
},
|
||||
addBookmark(meta) {
|
||||
set((s) => {
|
||||
s.bookmarks[meta.tmdbId] = {
|
||||
type: meta.type,
|
||||
title: meta.title,
|
||||
year: meta.releaseYear,
|
||||
poster: meta.poster,
|
||||
};
|
||||
});
|
||||
},
|
||||
})),
|
||||
{
|
||||
name: "__MW::bookmarks",
|
||||
}
|
||||
)
|
||||
);
|
Loading…
Reference in New Issue
Block a user