diff --git a/src/components/buttons/IconPatch.tsx b/src/components/buttons/IconPatch.tsx index 945c91bb..32492f3c 100644 --- a/src/components/buttons/IconPatch.tsx +++ b/src/components/buttons/IconPatch.tsx @@ -2,7 +2,7 @@ import { Icon, Icons } from "@/components/Icon"; export interface IconPatchProps { active?: boolean; - onClick?: () => void; + onClick?: (event: React.MouseEvent) => void; clickable?: boolean; className?: string; icon: Icons; diff --git a/src/components/media/MediaCard.tsx b/src/components/media/MediaCard.tsx index 17ada085..668eb9b6 100644 --- a/src/components/media/MediaCard.tsx +++ b/src/components/media/MediaCard.tsx @@ -10,6 +10,7 @@ import { MediaItem } from "@/utils/mediaTypes"; import { IconPatch } from "../buttons/IconPatch"; import { Icons } from "../Icon"; +import { MediaCardBookmarkButton } from "../player/Player"; export interface MediaCardProps { media: MediaItem; @@ -22,6 +23,7 @@ export interface MediaCardProps { }; percentage?: number; closable?: boolean; + shouldShowBookMark?: boolean; onClose?: () => void; } @@ -45,6 +47,7 @@ function MediaCardContent({ series, percentage, closable, + shouldShowBookMark = true, onClose, }: MediaCardProps) { const { t } = useTranslation(); @@ -153,6 +156,19 @@ function MediaCardContent({ icon={Icons.X} /> + + {shouldShowBookMark && ( +
+ +
+ )}

{media.title} diff --git a/src/components/media/WatchedMediaCard.tsx b/src/components/media/WatchedMediaCard.tsx index b7640efd..422f6ba3 100644 --- a/src/components/media/WatchedMediaCard.tsx +++ b/src/components/media/WatchedMediaCard.tsx @@ -22,6 +22,7 @@ function formatSeries(series?: ShowProgressResult | null) { export interface WatchedMediaCardProps { media: MediaItem; closable?: boolean; + shouldShowBookMark?: boolean; onClose?: () => void; } @@ -46,6 +47,7 @@ export function WatchedMediaCard(props: WatchedMediaCardProps) { percentage={percentage} onClose={props.onClose} closable={props.closable} + shouldShowBookMark={props.shouldShowBookMark} /> ); } diff --git a/src/components/player/internals/BookmarkButton.tsx b/src/components/player/internals/BookmarkButton.tsx index abf3af1d..dc758d40 100644 --- a/src/components/player/internals/BookmarkButton.tsx +++ b/src/components/player/internals/BookmarkButton.tsx @@ -1,8 +1,10 @@ import { useCallback } from "react"; +import { IconPatch } from "@/components/buttons/IconPatch"; import { Icons } from "@/components/Icon"; import { useBookmarkStore } from "@/stores/bookmarks"; import { usePlayerStore } from "@/stores/player/store"; +import { MediaItem } from "@/utils/mediaTypes"; import { VideoPlayerButton } from "./Button"; @@ -28,3 +30,39 @@ export function BookmarkButton() { /> ); } + +export function MediaCardBookmarkButton(props: { media: MediaItem }) { + const addBookmark = useBookmarkStore((s) => s.addBookmark); + const removeBookmark = useBookmarkStore((s) => s.removeBookmark); + const bookmarks = useBookmarkStore((s) => s.bookmarks); + const isBookmarked = !!bookmarks[props.media.id]; + + const toggleBookmark = useCallback( + (event: React.MouseEvent) => { + event.preventDefault(); + if (!props.media.year) return; + if (isBookmarked) { + removeBookmark(props.media.id); + } else { + addBookmark({ + tmdbId: props.media.id, + title: props.media.title, + releaseYear: props.media.year, + type: props.media.type, + poster: props.media.poster, + }); + } + }, + [isBookmarked, props.media, addBookmark, removeBookmark], + ); + + if (!props.media.year) return null; + + return ( + + ); +} diff --git a/src/pages/parts/home/BookmarksPart.tsx b/src/pages/parts/home/BookmarksPart.tsx index 848e1aa5..98b86fbe 100644 --- a/src/pages/parts/home/BookmarksPart.tsx +++ b/src/pages/parts/home/BookmarksPart.tsx @@ -58,6 +58,7 @@ export function BookmarksPart() { media={v} closable={editing} onClose={() => removeBookmark(v.id)} + shouldShowBookMark={false} /> ))}