diff --git a/src/assets/styles/global.css b/src/assets/styles/global.css index db8dc5e..09ff02c 100644 --- a/src/assets/styles/global.css +++ b/src/assets/styles/global.css @@ -266,6 +266,11 @@ Custom background-color: rgba(255, 255, 255, 0.9); } +.active-breadcrumb { + font-weight: bold; + text-decoration: underline; + text-underline-offset: 2px; /* makes it more visible */ +} /* Toastify customizations diff --git a/src/assets/styles/player.css b/src/assets/styles/player.css index 7a7e43e..469d26d 100644 --- a/src/assets/styles/player.css +++ b/src/assets/styles/player.css @@ -22,7 +22,7 @@ } body { - font-family: "Mukta", sans-serif; + font-family: sans-serif; width: 100%; height: 100%; margin: 0; @@ -264,7 +264,7 @@ body { margin-top: 1rem; padding: 0 1rem 1rem; text-align: center; - font-family: "Mukta", sans-serif; + font-family: sans-serif; font-size: 0.85rem; line-height: 1.4; color: var(--lrc-text-color); diff --git a/src/components/TRip/BreadcrumbNav.jsx b/src/components/TRip/BreadcrumbNav.jsx index 1a83ccb..f83384f 100644 --- a/src/components/TRip/BreadcrumbNav.jsx +++ b/src/components/TRip/BreadcrumbNav.jsx @@ -9,20 +9,25 @@ export default function BreadcrumbNav({ currentPage }) { return (
-
+
Self Service
diff --git a/src/components/TRip/MediaRequestForm.jsx b/src/components/TRip/MediaRequestForm.jsx index 065d0aa..0d4554d 100644 --- a/src/components/TRip/MediaRequestForm.jsx +++ b/src/components/TRip/MediaRequestForm.jsx @@ -271,7 +271,7 @@ export default function MediaRequestForm() { if (albumsToFetch.length === 0) return; const fetchTracksSequentially = async () => { - const minDelay = 400; // ms between API requests + const minDelay = 200; // ms between API requests setIsFetching(true); const totalAlbums = albumsToFetch.length; @@ -588,8 +588,8 @@ export default function MediaRequestForm() { className="cursor-pointer" aria-label={`Select all tracks for album ${album}`} /> - - {album} + + {truncate(album, 32)} {loadingAlbumId === id && } ({release_date}) @@ -614,7 +614,7 @@ export default function MediaRequestForm() { className="font-medium text-blue-600 hover:underline cursor-pointer bg-transparent border-none p-0" aria-label={`Download track ${track.title} `} > - {track.title} + {truncate(track.title, 80)} {track.audioQuality} {track.version && ( @@ -650,8 +650,9 @@ export default function MediaRequestForm() {
- )} - + ) + } + ); } diff --git a/src/components/TRip/RequestManagement.jsx b/src/components/TRip/RequestManagement.jsx index bca355a..289b375 100644 --- a/src/components/TRip/RequestManagement.jsx +++ b/src/components/TRip/RequestManagement.jsx @@ -38,7 +38,11 @@ export default function RequestManagement() { setRequests(Array.isArray(data.jobs) ? data.jobs : []); } catch (err) { console.error(err); - toast.error("Failed to fetch jobs list"); + if (!toast.isActive('fetch-fail-toast')) { + toast.error("Failed to fetch jobs list", { + toastId: 'fetch-fail-toast', + }); + } } }; @@ -84,17 +88,20 @@ export default function RequestManagement() { }, [requests]); useEffect(() => { - let filtered = [...requests]; - if (filterType) filtered = filtered.filter((r) => r.type === filterType); - if (filterStatus) filtered = filtered.filter((r) => r.status === filterStatus); + const filtered = requests.filter((r) => { + const typeMatch = !filterType || r.type === filterType; + const statusMatch = filterStatus === "all" || filterStatus === null || r.status === filterStatus; + return typeMatch && statusMatch; + }); setFilteredRequests(filtered); }, [filterType, filterStatus, requests]); + const getStatusColorClass = (status) => { switch (status) { case "queued": return "bg-yellow-500 text-black"; - case "started": - case "compressing": return "bg-blue-500 text-white"; + case "started": return "bg-blue-500 text-white"; + case "compressing": return "bg-orange-500 text-white"; case "finished": return "bg-green-500 text-white"; case "failed": return "bg-red-500 text-white"; default: return "bg-gray-500 text-white"; @@ -118,7 +125,7 @@ export default function RequestManagement() { if (p === null || p === undefined || p === "") return "—"; const num = Number(p); if (Number.isNaN(num)) return "—"; - const pct = num > 1 ? Math.round(num) : Math.round(num * 100); + const pct = num > 1 ? Math.round(num) : num; return `${pct}%`; }; @@ -255,7 +262,7 @@ export default function RequestManagement() {
({ label: s, value: s }))]} + options={[{ label: "All Statuses", value: "all" }, ...STATUS_OPTIONS.map((s) => ({ label: s, value: s }))]} onChange={(e) => setFilterStatus(e.value)} placeholder="Filter by Status" className="min-w-[180px]" @@ -273,7 +280,9 @@ export default function RequestManagement() { responsiveLayout="scroll" onRowClick={handleRowClick} > + textWithEllipsis(row.id, "8rem")} /> textWithEllipsis(row.target, "10rem")} /> + row.tracks} /> formatProgress(row.progress)} style={{ width: "8rem", textAlign: "center" }} sortable /> {selectedRequest ? (
-

Target: {selectedRequest.target}

- -

+ {selectedRequest.id && ( +

ID: {selectedRequest.id}

+ )} + {selectedRequest.target && ( +

Target: {selectedRequest.target}

+ )} + {selectedRequest.tracks && ( +

# Tracks: {selectedRequest.tracks}

+ )} + {selectedRequest.status && (

Status:{" "} {selectedRequest.status} -

+

)} {selectedRequest.progress !== undefined && selectedRequest.progress !== null && (

Progress: {formatProgress(selectedRequest.progress)}

@@ -352,21 +368,6 @@ export default function RequestManagement() {

)} - {Array.isArray(selectedRequest.tracks) && selectedRequest.tracks.length > 0 && ( -
- Tracks: -
    - {selectedRequest.tracks.map((t, idx) => { - if (t && typeof t === "object") { - const tid = "track_id" in t ? t.track_id : t.id ?? idx; - const st = t.status ?? "—"; - return
  • {`${tid} — ${st}`}
  • ; - } - return
  • {String(t)}
  • ; - })} -
-
- )}
) : (

Loading...

diff --git a/src/config.js b/src/config.js index 3cf57b5..4861a53 100644 --- a/src/config.js +++ b/src/config.js @@ -12,6 +12,6 @@ export const API_URL = "https://api.codey.lol"; export const socialLinks = { }; -export const MAJOR_VERSION = "0.0" -export const RELEASE_FLAG = "Alpha"; +export const MAJOR_VERSION = "0.1" +export const RELEASE_FLAG = null; export const ENVIRONMENT = import.meta.env.DEV ? "Dev" : "Prod"; \ No newline at end of file diff --git a/src/layouts/Nav.astro b/src/layouts/Nav.astro index 239713b..53bcac2 100644 --- a/src/layouts/Nav.astro +++ b/src/layouts/Nav.astro @@ -41,7 +41,11 @@ const currentPath = Astro.url.pathname; const isExternal = item.href?.startsWith("http"); const isAuthedPath = item.auth ?? false; const normalize = (url) => url?.replace(/\/+$/, '') || '/'; - const isActive = !isExternal && normalize(item.href) === normalize(currentPath); + const normalizedCurrent = normalize(currentPath).replace(/\/$/, ""); // remove trailing slash + const normalizedHref = normalize(item.href).replace(/\/$/, ""); + const isActive = !isExternal && ( + normalizedCurrent === normalizedHref || + normalizedCurrent.startsWith(normalizedHref + "/")); const nextItem = navItems[index + 1]; const shouldShowThinBar = nextItem //&& !nextItem.blockSeparator; diff --git a/src/utils/buildTime.js b/src/utils/buildTime.js index 78e21fd..7c4bab1 100644 --- a/src/utils/buildTime.js +++ b/src/utils/buildTime.js @@ -5,6 +5,6 @@ export const buildTime = new Date().toLocaleString(undefined, { }); export var buildNumber = generate(MAJOR_VERSION); -if (RELEASE_FLAG.length) { +if (RELEASE_FLAG && RELEASE_FLAG.length) { buildNumber = `${buildNumber} (${RELEASE_FLAG})`; } \ No newline at end of file