mirror of
https://github.com/gabehf/Koito.git
synced 2026-03-08 23:18:15 -07:00
feat: add musicbrainz link where possible (#124)
This commit is contained in:
parent
d61e814306
commit
7cf7cd3a10
3 changed files with 195 additions and 80 deletions
|
|
@ -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<Response>
|
||||
export type MergeSearchCleanerFunc = (r: SearchResponse, id: number) => SearchResponse
|
||||
export type MergeFunc = (
|
||||
from: number,
|
||||
to: number,
|
||||
replaceImage: boolean
|
||||
) => Promise<Response>;
|
||||
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<string>("(--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<string>("(--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 (
|
||||
<main
|
||||
className="w-full flex flex-col flex-grow"
|
||||
style={{
|
||||
background: `linear-gradient(to bottom, ${bgColor}, var(--color-bg) 700px)`,
|
||||
transition: '1000',
|
||||
}}
|
||||
>
|
||||
<ImageDropHandler itemType={props.type.toLowerCase() === 'artist' ? 'artist' : 'album'} onComplete={replaceImageCallback} />
|
||||
<title>{title}</title>
|
||||
<meta property="og:title" content={title} />
|
||||
<meta
|
||||
name="description"
|
||||
content={title}
|
||||
/>
|
||||
<div className="w-19/20 mx-auto pt-12">
|
||||
<div className="flex gap-8 flex-wrap md:flex-nowrap relative">
|
||||
<div className="flex flex-col justify-around">
|
||||
<img style={{zIndex: 5}} src={imageUrl(props.img, "large")} alt={props.title} className="md:min-w-[385px] w-[220px] h-auto shadow-(--color-shadow) shadow-lg" />
|
||||
</div>
|
||||
<div className="flex flex-col items-start">
|
||||
<h3>{props.type}</h3>
|
||||
<h1>{props.title}</h1>
|
||||
{props.subContent}
|
||||
</div>
|
||||
{ user &&
|
||||
<div className="absolute left-1 sm:right-1 sm:left-auto -top-9 sm:top-1 flex gap-3 items-center">
|
||||
{ props.type === "Track" &&
|
||||
<>
|
||||
<button title="Add Listen" className="hover:cursor-pointer" onClick={() => setAddListenModalOpen(true)}><Plus size={iconSize} /></button>
|
||||
<AddListenModal open={addListenModalOpen} setOpen={setAddListenModalOpen} trackid={props.id} />
|
||||
</>
|
||||
}
|
||||
<button title="Edit Item" className="hover:cursor-pointer" onClick={() => setRenameModalOpen(true)}><Edit size={iconSize} /></button>
|
||||
<button title="Replace Image" className="hover:cursor-pointer" onClick={() => setImageModalOpen(true)}><ImageIcon size={iconSize} /></button>
|
||||
<button title="Merge Items" className="hover:cursor-pointer" onClick={() => setMergeModalOpen(true)}><Merge size={iconSize} /></button>
|
||||
<button title="Delete Item" className="hover:cursor-pointer" onClick={() => setDeleteModalOpen(true)}><Trash size={iconSize} /></button>
|
||||
<EditModal open={renameModalOpen} setOpen={setRenameModalOpen} type={props.type.toLowerCase()} id={props.id}/>
|
||||
<ImageReplaceModal open={imageModalOpen} setOpen={setImageModalOpen} id={props.imgItemId} musicbrainzId={props.musicbrainzId} type={props.type === "Track" ? "Album" : props.type} />
|
||||
<MergeModal currentTitle={props.title} mergeFunc={props.mergeFunc} mergeCleanerFunc={props.mergeCleanerFunc} type={props.type} currentId={props.id} open={mergeModalOpen} setOpen={setMergeModalOpen} />
|
||||
<DeleteModal open={deleteModalOpen} setOpen={setDeleteModalOpen} title={props.title} id={props.id} type={props.type} />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
{props.children}
|
||||
console.log("MBZ:", props.musicbrainzId);
|
||||
|
||||
return (
|
||||
<main
|
||||
className="w-full flex flex-col flex-grow"
|
||||
style={{
|
||||
background: `linear-gradient(to bottom, ${bgColor}, var(--color-bg) 700px)`,
|
||||
transition: "1000",
|
||||
}}
|
||||
>
|
||||
<ImageDropHandler
|
||||
itemType={props.type.toLowerCase() === "artist" ? "artist" : "album"}
|
||||
onComplete={replaceImageCallback}
|
||||
/>
|
||||
<title>{title}</title>
|
||||
<meta property="og:title" content={title} />
|
||||
<meta name="description" content={title} />
|
||||
<div className="w-19/20 mx-auto pt-12">
|
||||
<div className="flex gap-8 flex-wrap md:flex-nowrap relative">
|
||||
<div className="flex flex-col justify-around">
|
||||
<img
|
||||
style={{ zIndex: 5 }}
|
||||
src={imageUrl(props.img, "large")}
|
||||
alt={props.title}
|
||||
className="md:min-w-[385px] w-[220px] h-auto shadow-(--color-shadow) shadow-lg"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col items-start">
|
||||
<h3>{props.type}</h3>
|
||||
<h1>{props.title}</h1>
|
||||
{props.subContent}
|
||||
</div>
|
||||
{user && (
|
||||
<div className="absolute left-1 sm:right-1 sm:left-auto -top-9 sm:top-1 flex gap-3 items-center">
|
||||
{props.musicbrainzId && (
|
||||
<Link
|
||||
title="View on MusicBrainz"
|
||||
target="_blank"
|
||||
to={`https://musicbrainz.org/${props.type.toLowerCase()}/${
|
||||
props.musicbrainzId
|
||||
}`}
|
||||
>
|
||||
<MbzIcon size={iconSize} hover />
|
||||
</Link>
|
||||
)}
|
||||
{props.type === "Track" && (
|
||||
<>
|
||||
<button
|
||||
title="Add Listen"
|
||||
className="hover:cursor-pointer"
|
||||
onClick={() => setAddListenModalOpen(true)}
|
||||
>
|
||||
<Plus size={iconSize} />
|
||||
</button>
|
||||
<AddListenModal
|
||||
open={addListenModalOpen}
|
||||
setOpen={setAddListenModalOpen}
|
||||
trackid={props.id}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<button
|
||||
title="Edit Item"
|
||||
className="hover:cursor-pointer"
|
||||
onClick={() => setRenameModalOpen(true)}
|
||||
>
|
||||
<Edit size={iconSize} />
|
||||
</button>
|
||||
|
||||
{props.type !== "Track" && (
|
||||
<button
|
||||
title="Replace Image"
|
||||
className="hover:cursor-pointer"
|
||||
onClick={() => setImageModalOpen(true)}
|
||||
>
|
||||
<ImageIcon size={iconSize} />
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
title="Merge Items"
|
||||
className="hover:cursor-pointer"
|
||||
onClick={() => setMergeModalOpen(true)}
|
||||
>
|
||||
<Merge size={iconSize} />
|
||||
</button>
|
||||
<button
|
||||
title="Delete Item"
|
||||
className="hover:cursor-pointer"
|
||||
onClick={() => setDeleteModalOpen(true)}
|
||||
>
|
||||
<Trash size={iconSize} />
|
||||
</button>
|
||||
<EditModal
|
||||
open={renameModalOpen}
|
||||
setOpen={setRenameModalOpen}
|
||||
type={props.type.toLowerCase()}
|
||||
id={props.id}
|
||||
/>
|
||||
<ImageReplaceModal
|
||||
open={imageModalOpen}
|
||||
setOpen={setImageModalOpen}
|
||||
id={props.imgItemId}
|
||||
musicbrainzId={props.musicbrainzId}
|
||||
type={props.type === "Track" ? "Album" : props.type}
|
||||
/>
|
||||
<MergeModal
|
||||
currentTitle={props.title}
|
||||
mergeFunc={props.mergeFunc}
|
||||
mergeCleanerFunc={props.mergeCleanerFunc}
|
||||
type={props.type}
|
||||
currentId={props.id}
|
||||
open={mergeModalOpen}
|
||||
setOpen={setMergeModalOpen}
|
||||
/>
|
||||
<DeleteModal
|
||||
open={deleteModalOpen}
|
||||
setOpen={setDeleteModalOpen}
|
||||
title={props.title}
|
||||
id={props.id}
|
||||
type={props.type}
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
)}
|
||||
</div>
|
||||
{props.children}
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue