fix: ui fixes and koito import time config fix (#128)

* fix: add import time checking to koito import

* adjust interest graph css

* show musicbrainz link when not logged in

* remove chart animation

* change interest steps to 16
This commit is contained in:
Gabe Farrell 2026-01-12 17:44:33 -05:00 committed by GitHub
parent 231eb1b0fb
commit ddb0becc0f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 104 additions and 103 deletions

View file

@ -1,17 +1,8 @@
import { useQuery } from "@tanstack/react-query";
import {
getActivity,
getInterest,
type getActivityArgs,
type getInterestArgs,
type ListenActivityItem,
} from "api/api";
import Popup from "./Popup";
import { useState } from "react";
import { getInterest, type getInterestArgs } from "api/api";
import { useTheme } from "~/hooks/useTheme";
import ActivityOptsSelector from "./ActivityOptsSelector";
import type { Theme } from "~/styles/themes.css";
import { Area, AreaChart, Line, LineChart, Tooltip } from "recharts";
import { Area, AreaChart } from "recharts";
import { RechartsDevtools } from "@recharts/devtools";
function getPrimaryColor(theme: Theme): string {
@ -34,7 +25,7 @@ interface Props {
}
export default function InterestGraph({
buckets = 14,
buckets = 16,
artistId = 0,
albumId = 0,
trackId = 0,
@ -71,6 +62,10 @@ export default function InterestGraph({
);
}
// Note: I would really like to have the animation for the graph, however
// the line graph can get weirdly clipped before the animation is done
// so I think I just have to remove it for now.
return (
<div className="flex flex-col items-start w-full max-w-[500px]">
<h3>Interest over time</h3>
@ -81,13 +76,13 @@ export default function InterestGraph({
maxWidth: 440,
overflow: "visible",
}}
margin={{ top: 5, right: 0, left: 0, bottom: 10 }}
data={data}
margin={{ top: 15, bottom: 20 }}
>
<defs>
<linearGradient id="colorGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={color} stopOpacity={0.5} />
<stop offset="85%" stopColor={color} stopOpacity={0} />
<stop offset="95%" stopColor={color} stopOpacity={0} />
</linearGradient>
</defs>
<Area
@ -95,7 +90,7 @@ export default function InterestGraph({
type="natural"
stroke="none"
fill="url(#colorGradient)"
animationDuration={750}
animationDuration={0}
animationEasing="ease-in-out"
activeDot={false}
/>
@ -105,11 +100,11 @@ export default function InterestGraph({
stroke={color}
fill="none"
strokeWidth={2}
animationDuration={750}
animationDuration={0}
animationEasing="ease-in-out"
dot={false}
activeDot={false}
style={{ filter: `drop-shadow(0px 0px 5px ${color})` }}
style={{ filter: `drop-shadow(0px 0px 0px ${color})` }}
/>
</AreaChart>
</div>

View file

@ -99,97 +99,99 @@ export default function MediaLayout(props: Props) {
<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)}
<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
}`}
>
<Edit size={iconSize} />
</button>
{props.type !== "Track" && (
<MbzIcon size={iconSize} hover />
</Link>
)}
{user && (
<>
{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="Replace Image"
title="Edit Item"
className="hover:cursor-pointer"
onClick={() => setImageModalOpen(true)}
onClick={() => setRenameModalOpen(true)}
>
<ImageIcon size={iconSize} />
<Edit 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>
)}
{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>
</div>
{props.children}
</div>