From 7cf7cd3a10182f5dd4e20f4c9fe04fbaa6b1dfae Mon Sep 17 00:00:00 2001 From: Gabe Farrell <90876006+gabehf@users.noreply.github.com> Date: Sun, 11 Jan 2026 01:39:56 -0500 Subject: [PATCH] feat: add musicbrainz link where possible (#124) --- client/app/components/icons/MbzIcon.tsx | 23 ++ client/app/routes/MediaItems/MediaLayout.tsx | 250 +++++++++++++------ client/app/routes/MediaItems/Track.tsx | 2 +- 3 files changed, 195 insertions(+), 80 deletions(-) create mode 100644 client/app/components/icons/MbzIcon.tsx diff --git a/client/app/components/icons/MbzIcon.tsx b/client/app/components/icons/MbzIcon.tsx new file mode 100644 index 0000000..1ce66ad --- /dev/null +++ b/client/app/components/icons/MbzIcon.tsx @@ -0,0 +1,23 @@ +interface Props { + size: number; + hover?: boolean; +} +export default function MbzIcon({ size, hover }: Props) { + let classNames = ""; + if (hover) { + classNames += "icon-hover-fill"; + } + return ( +
+ + + +
+ ); +} diff --git a/client/app/routes/MediaItems/MediaLayout.tsx b/client/app/routes/MediaItems/MediaLayout.tsx index 93c25e1..45190e9 100644 --- a/client/app/routes/MediaItems/MediaLayout.tsx +++ b/client/app/routes/MediaItems/MediaLayout.tsx @@ -10,97 +10,189 @@ import DeleteModal from "~/components/modals/DeleteModal"; import RenameModal from "~/components/modals/EditModal/EditModal"; import EditModal from "~/components/modals/EditModal/EditModal"; import AddListenModal from "~/components/modals/AddListenModal"; +import MbzIcon from "~/components/icons/MbzIcon"; +import { Link } from "react-router"; -export type MergeFunc = (from: number, to: number, replaceImage: boolean) => Promise -export type MergeSearchCleanerFunc = (r: SearchResponse, id: number) => SearchResponse +export type MergeFunc = ( + from: number, + to: number, + replaceImage: boolean +) => Promise; +export type MergeSearchCleanerFunc = ( + r: SearchResponse, + id: number +) => SearchResponse; interface Props { - type: "Track" | "Album" | "Artist" - title: string - img: string - id: number - musicbrainzId: string - imgItemId: number - mergeFunc: MergeFunc - mergeCleanerFunc: MergeSearchCleanerFunc - children: React.ReactNode - subContent: React.ReactNode + type: "Track" | "Album" | "Artist"; + title: string; + img: string; + id: number; + musicbrainzId: string; + imgItemId: number; + mergeFunc: MergeFunc; + mergeCleanerFunc: MergeSearchCleanerFunc; + children: React.ReactNode; + subContent: React.ReactNode; } export default function MediaLayout(props: Props) { - const [bgColor, setBgColor] = useState("(--color-bg)"); - const [mergeModalOpen, setMergeModalOpen] = useState(false); - const [deleteModalOpen, setDeleteModalOpen] = useState(false); - const [imageModalOpen, setImageModalOpen] = useState(false); - const [renameModalOpen, setRenameModalOpen] = useState(false); - const [addListenModalOpen, setAddListenModalOpen] = useState(false); - const { user } = useAppContext(); + const [bgColor, setBgColor] = useState("(--color-bg)"); + const [mergeModalOpen, setMergeModalOpen] = useState(false); + const [deleteModalOpen, setDeleteModalOpen] = useState(false); + const [imageModalOpen, setImageModalOpen] = useState(false); + const [renameModalOpen, setRenameModalOpen] = useState(false); + const [addListenModalOpen, setAddListenModalOpen] = useState(false); + const { user } = useAppContext(); - useEffect(() => { - average(imageUrl(props.img, 'small'), { amount: 1 }).then((color) => { - setBgColor(`rgba(${color[0]},${color[1]},${color[2]},0.4)`); - }); - }, [props.img]); + useEffect(() => { + average(imageUrl(props.img, "small"), { amount: 1 }).then((color) => { + setBgColor(`rgba(${color[0]},${color[1]},${color[2]},0.4)`); + }); + }, [props.img]); - const replaceImageCallback = () => { - window.location.reload() - } + const replaceImageCallback = () => { + window.location.reload(); + }; - const title = `${props.title} - Koito` + const title = `${props.title} - Koito`; - const mobileIconSize = 22 - const normalIconSize = 30 + const mobileIconSize = 22; + const normalIconSize = 30; - let vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0) + let vw = Math.max( + document.documentElement.clientWidth || 0, + window.innerWidth || 0 + ); - let iconSize = vw > 768 ? normalIconSize : mobileIconSize + let iconSize = vw > 768 ? normalIconSize : mobileIconSize; - return ( -
- - {title} - - -
-
-
- {props.title} -
-
-

{props.type}

-

{props.title}

- {props.subContent} -
- { user && -
- { props.type === "Track" && - <> - - - - } - - - - - - - - -
- } -
- {props.children} + console.log("MBZ:", props.musicbrainzId); + + return ( +
+ + {title} + + +
+
+
+ {props.title} +
+
+

{props.type}

+

{props.title}

+ {props.subContent} +
+ {user && ( +
+ {props.musicbrainzId && ( + + + + )} + {props.type === "Track" && ( + <> + + + + )} + + + {props.type !== "Track" && ( + + )} + + + + + +
-
- ); + )} +
+ {props.children} + +
+ ); } diff --git a/client/app/routes/MediaItems/Track.tsx b/client/app/routes/MediaItems/Track.tsx index 5690232..87ce4ea 100644 --- a/client/app/routes/MediaItems/Track.tsx +++ b/client/app/routes/MediaItems/Track.tsx @@ -33,7 +33,7 @@ export default function Track() { title={track.title} img={track.image} id={track.id} - musicbrainzId={album.musicbrainz_id} + musicbrainzId={track.musicbrainz_id} imgItemId={track.album_id} mergeFunc={mergeTracks} mergeCleanerFunc={(r, id) => {