From 6cb781e452594826df0ed45fa2e88761a750c440 Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Thu, 16 Jan 2025 12:43:54 -0700 Subject: [PATCH] init 2 part media card Part 1 is the default Part 2 is more options pane --- src/assets/css/index.css | 10 - src/components/Icon.tsx | 2 + src/components/media/MediaCard.tsx | 394 +++++++++++++++++++---------- 3 files changed, 261 insertions(+), 145 deletions(-) diff --git a/src/assets/css/index.css b/src/assets/css/index.css index 803ac3a7..49788ee8 100644 --- a/src/assets/css/index.css +++ b/src/assets/css/index.css @@ -85,16 +85,6 @@ html[data-no-scroll], html[data-no-scroll] body { min-height: 100dvh; } -.info-button { - display: inline-block; - padding: 0.75em; - margin: -0.75em; - position: absolute; - bottom: 0; - right: 0; - transform: translate(-15px, -10px) -} - /*generated with Input range slider CSS style generator (version 20211225) https://toughengineer.github.io/demo/slider-styler*/ :root { diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx index c678e291..620a51b8 100644 --- a/src/components/Icon.tsx +++ b/src/components/Icon.tsx @@ -72,6 +72,7 @@ export enum Icons { STRETCH = "stretch", CLOUD_ARROW_UP = "cloud_arrow_up", FILE_ARROW_DOWN = "file_arrow_down", + ELLIPSIS = "ellipsis", } export interface IconProps { @@ -161,6 +162,7 @@ const iconList: Record = { stretch: ``, cloud_arrow_up: ``, file_arrow_down: ``, + ellipsis: ``, }; function ChromeCastButton() { diff --git a/src/components/media/MediaCard.tsx b/src/components/media/MediaCard.tsx index 86140d0b..14a7ea8a 100644 --- a/src/components/media/MediaCard.tsx +++ b/src/components/media/MediaCard.tsx @@ -1,5 +1,5 @@ import classNames from "classnames"; -import { useCallback } from "react"; +import { useCallback, useState } from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; @@ -48,7 +48,12 @@ function MediaCardContent({ percentage, closable, onClose, -}: MediaCardProps) { + overlayVisible, + setOverlayVisible, +}: MediaCardProps & { + overlayVisible: boolean; + setOverlayVisible: React.Dispatch>; +}) { const { t } = useTranslation(); const percentageString = `${Math.round(percentage ?? 0).toFixed(0)}%`; @@ -68,142 +73,255 @@ function MediaCardContent({ dotListContent.push(t("media.unreleased")); } + const handleMoreInfoClick = (e: React.MouseEvent) => { + e.preventDefault(); + + const searchParam = encodeURIComponent(encodeURI(media.id)); + const url = + media.type === "movie" + ? `https://www.themoviedb.org/movie/${searchParam}` + : `https://www.themoviedb.org/tv/${searchParam}`; + + window.open(url, "_blank"); + }; + + const handleMouseLeave = () => { + setOverlayVisible(false); + }; + return ( - e.key === "Enter" && e.currentTarget.click()} - > - - -
+ {!overlayVisible ? ( + e.key === "Enter" && e.currentTarget.click()} > - {series ? ( -
-

- {t("media.episodeDisplay", { - season: series.season || 1, - episode: series.episode, - })} -

-
- ) : null} - - {percentage !== undefined ? ( - <> -
-
-
-
-
-
-
- - ) : null} - -
e.preventDefault()} - > - -
- - {searchQuery.length > 0 ? ( -
e.preventDefault()}> - -
- ) : null} - -
+ - closable && onClose?.()} - icon={Icons.X} - /> -
-
-

- {media.title} -

-
- - +
+ {/* End Overlay */} + + + ) : ( +
+ + - + +
+ {series ? ( +
+

+ {t("media.episodeDisplay", { + season: series.season || 1, + episode: series.episode, + })} +

+
+ ) : null} + + {percentage !== undefined ? ( + <> +
+
+
+
+
+
+
+ + ) : null} +
+

+ {media.title} +

+
+ +
+ +
- - + )} +
); } export function MediaCard(props: MediaCardProps) { - const content = ; + const [overlayVisible, setOverlayVisible] = useState(false); + + const content = ( + + ); const isReleased = useCallback( () => checkReleased(props.media), @@ -227,15 +345,21 @@ export function MediaCard(props: MediaCardProps) { if (!canLink) return {content}; return ( - + {!overlayVisible ? ( + + {content} + + ) : ( +
{content}
)} - > - {content} - +
); }