@behindthemusictree/app-kit-ui 37.0.0 → 38.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-DKQQLLMY.js → chunk-2GH7CSCE.js} +3 -3
- package/dist/{chunk-DKQQLLMY.js.map → chunk-2GH7CSCE.js.map} +1 -1
- package/dist/{chunk-FTYMRCJS.js → chunk-F7H5XPWU.js} +169 -80
- package/dist/chunk-F7H5XPWU.js.map +1 -0
- package/dist/{chunk-K4WMHUNM.js → chunk-NJYEQ3RS.js} +8 -8
- package/dist/chunk-NJYEQ3RS.js.map +1 -0
- package/dist/genre-tree/index.cjs +171 -80
- package/dist/genre-tree/index.cjs.map +1 -1
- package/dist/genre-tree/index.d.ts +53 -1
- package/dist/genre-tree/index.js +6 -2
- package/dist/index.cjs +177 -86
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -3
- package/dist/popup/index.cjs +8 -8
- package/dist/popup/index.cjs.map +1 -1
- package/dist/popup/index.js +2 -2
- package/package.json +5 -5
- package/dist/chunk-FTYMRCJS.js.map +0 -1
- package/dist/chunk-K4WMHUNM.js.map +0 -1
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/genre-tree/index.ts
|
|
21
21
|
var genre_tree_exports = {};
|
|
22
22
|
__export(genre_tree_exports, {
|
|
23
|
+
EntityDetailPanel: () => EntityDetailPanel,
|
|
23
24
|
GenreDetailPanel: () => GenreDetailPanel,
|
|
24
25
|
GenreInfoPanelBody: () => GenreInfoPanelBody,
|
|
25
26
|
GenreNodeActionBand: () => GenreNodeActionBand,
|
|
@@ -39,6 +40,7 @@ __export(genre_tree_exports, {
|
|
|
39
40
|
TrackPositionPlayPause: () => TrackPositionPlayPause,
|
|
40
41
|
searchStatus: () => searchStatus,
|
|
41
42
|
useArtistSearchGroup: () => useArtistSearchGroup,
|
|
43
|
+
useEntityPanel: () => useEntityPanel,
|
|
42
44
|
useGenrePlaylistPlayback: () => useGenrePlaylistPlayback,
|
|
43
45
|
useGenreRemoteSearchGroup: () => useGenreRemoteSearchGroup,
|
|
44
46
|
useSongSearchGroup: () => useSongSearchGroup
|
|
@@ -294,7 +296,7 @@ function InternalErrorPopup({ errorCode, contactEmail, ...rest }) {
|
|
|
294
296
|
" ",
|
|
295
297
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href: `mailto:${contactEmail}`, className: "text-[var(--color-primary)] hover:text-[var(--color-primary-hover)]", children: contactEmail })
|
|
296
298
|
] }) }),
|
|
297
|
-
errorCode && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "text-
|
|
299
|
+
errorCode && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "text-body text-[var(--color-neutral-500)] bg-[var(--color-neutral-100)] p-3 rounded-lg border border-[var(--color-neutral-100)]", children: [
|
|
298
300
|
"Error Code: ",
|
|
299
301
|
errorCode
|
|
300
302
|
] })
|
|
@@ -784,7 +786,7 @@ function useArtistSearchGroup(getBaseUrl, text, onSelect, enabled = true) {
|
|
|
784
786
|
artist.disambiguation
|
|
785
787
|
] })
|
|
786
788
|
] }),
|
|
787
|
-
artist.matchedAlias && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "block truncate text-
|
|
789
|
+
artist.matchedAlias && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "block truncate text-caption text-[var(--color-neutral-500)]", children: [
|
|
788
790
|
"also known as ",
|
|
789
791
|
artist.matchedAlias
|
|
790
792
|
] })
|
|
@@ -809,7 +811,7 @@ function useSongSearchGroup(getBaseUrl, text, onSelect, enabled = true) {
|
|
|
809
811
|
key: song.uuid,
|
|
810
812
|
content: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: (0, import_genre_tree7.isSongSearchResultPlayable)(song) ? void 0 : "opacity-60", children: [
|
|
811
813
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "block truncate font-medium", children: song.title }),
|
|
812
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "block truncate text-
|
|
814
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "block truncate text-caption text-[var(--color-neutral-500)]", children: [song.artists.map((artist) => artist.name).join(", "), song.genre?.name ?? "No genre"].filter(Boolean).join(" \xB7 ") })
|
|
813
815
|
] }),
|
|
814
816
|
onSelect: () => onSelect(song)
|
|
815
817
|
})),
|
|
@@ -832,9 +834,9 @@ function useGenreRemoteSearchGroup(getBaseUrl, text, onSelect, { key = "genres",
|
|
|
832
834
|
content: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
833
835
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "block truncate font-medium", children: [
|
|
834
836
|
genre.name,
|
|
835
|
-
genre.isUmbrella && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ml-2 text-
|
|
837
|
+
genre.isUmbrella && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ml-2 text-caption font-normal italic text-[var(--color-text-muted)]", children: "umbrella" })
|
|
836
838
|
] }),
|
|
837
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "block truncate text-
|
|
839
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "block truncate text-caption text-[var(--color-neutral-500)]", children: describe?.(genre) ?? `${genre.treeName} \xB7 ${genre.root.name}` })
|
|
838
840
|
] }),
|
|
839
841
|
onSelect: () => onSelect(genre)
|
|
840
842
|
})),
|
|
@@ -875,7 +877,7 @@ function GenreSearch({
|
|
|
875
877
|
key: genrePlaylist.uuid,
|
|
876
878
|
content: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
877
879
|
genrePlaylist.name,
|
|
878
|
-
genrePlaylist.isUmbrella && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ml-2 text-
|
|
880
|
+
genrePlaylist.isUmbrella && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ml-2 text-caption italic text-[var(--color-text-muted)]", children: "umbrella" })
|
|
879
881
|
] }),
|
|
880
882
|
onSelect: () => select(genrePlaylist)
|
|
881
883
|
}))
|
|
@@ -993,7 +995,7 @@ function Toast({ message, onClose, durationMs = 2200 }) {
|
|
|
993
995
|
role: "status",
|
|
994
996
|
"aria-live": "polite",
|
|
995
997
|
"aria-atomic": "true",
|
|
996
|
-
className: "pointer-events-auto w-full max-w-md rounded-md bg-[var(--color-surface)] px-4 py-4 text-
|
|
998
|
+
className: "pointer-events-auto w-full max-w-md rounded-md bg-[var(--color-surface)] px-4 py-4 text-body text-[var(--color-text)] shadow-lg ring-1 ring-black/10",
|
|
997
999
|
children: message
|
|
998
1000
|
}
|
|
999
1001
|
) }),
|
|
@@ -1003,7 +1005,7 @@ function Toast({ message, onClose, durationMs = 2200 }) {
|
|
|
1003
1005
|
|
|
1004
1006
|
// src/genre-tree/ShareDestinationButton.tsx
|
|
1005
1007
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1006
|
-
var className = "group flex min-w-0 flex-1 flex-col items-center justify-center gap-1.5 rounded-xl px-2 py-2 text-
|
|
1008
|
+
var className = "group flex min-w-0 flex-1 flex-col items-center justify-center gap-1.5 rounded-xl px-2 py-2 text-caption text-[var(--color-text)] transition-colors hover:bg-[var(--color-surface-muted)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] disabled:cursor-not-allowed disabled:opacity-50";
|
|
1007
1009
|
function Contents({ icon, label }) {
|
|
1008
1010
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
1009
1011
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "flex h-12 w-12 items-center justify-center rounded-full bg-[var(--color-surface-muted)] transition-colors group-hover:bg-[var(--color-border)]", children: icon }),
|
|
@@ -1033,9 +1035,9 @@ function SharePreviewCard({ target, url }) {
|
|
|
1033
1035
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "rounded-3xl bg-[var(--color-surface-muted)] p-4", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex min-h-32 overflow-hidden rounded-2xl bg-[var(--color-surface)] shadow-lg", children: [
|
|
1034
1036
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex w-28 shrink-0 items-center justify-center bg-[var(--color-primary)]/15 text-[var(--color-primary)]", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { "aria-hidden": "true", className: "h-10 w-10" }) }),
|
|
1035
1037
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col justify-center gap-1 p-4", children: [
|
|
1036
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-
|
|
1038
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-caption font-medium uppercase tracking-wide text-[var(--color-text-muted)]", children: typeLabel }),
|
|
1037
1039
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "truncate text-base font-semibold text-[var(--color-text)]", title: target.name, children: target.name }),
|
|
1038
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "truncate text-
|
|
1040
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "truncate text-body text-[var(--color-primary)]", title: url, children: url })
|
|
1039
1041
|
] })
|
|
1040
1042
|
] }) });
|
|
1041
1043
|
}
|
|
@@ -1176,8 +1178,8 @@ function SharePopup({ target, url, onClose }) {
|
|
|
1176
1178
|
}
|
|
1177
1179
|
)
|
|
1178
1180
|
] }),
|
|
1179
|
-
copyStatus === "failed" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { role: "alert", className: "text-center text-
|
|
1180
|
-
shareError && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { role: "alert", className: "text-center text-
|
|
1181
|
+
copyStatus === "failed" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { role: "alert", className: "text-center text-body text-[var(--color-red-500)]", children: "Could not copy the link." }),
|
|
1182
|
+
shareError && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { role: "alert", className: "text-center text-body text-[var(--color-red-500)]", children: shareError })
|
|
1181
1183
|
] })
|
|
1182
1184
|
}
|
|
1183
1185
|
),
|
|
@@ -1197,7 +1199,7 @@ function ShareActionButton({ target, url }) {
|
|
|
1197
1199
|
{
|
|
1198
1200
|
type: "button",
|
|
1199
1201
|
onClick: openSharePopup,
|
|
1200
|
-
className: "group flex flex-col items-center gap-1 w-16 text-
|
|
1202
|
+
className: "group flex flex-col items-center gap-1 w-16 text-caption text-center text-[var(--color-text)] focus-visible:outline-none",
|
|
1201
1203
|
"aria-label": `Share ${target.name}`,
|
|
1202
1204
|
title: `Share ${target.name}`,
|
|
1203
1205
|
children: [
|
|
@@ -1279,7 +1281,7 @@ function GenreActionBand({
|
|
|
1279
1281
|
disabled: item.disabled,
|
|
1280
1282
|
title: item.title,
|
|
1281
1283
|
onClick: item.onClick,
|
|
1282
|
-
className: "group flex flex-col items-center gap-1 w-16 text-
|
|
1284
|
+
className: "group flex flex-col items-center gap-1 w-16 text-caption text-center text-[var(--color-text)] focus-visible:outline-none disabled:opacity-50",
|
|
1283
1285
|
children: [
|
|
1284
1286
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "flex items-center justify-center w-10 h-10 rounded-full group-focus-visible:ring-2 group-focus-visible:ring-[var(--color-focus-ring)] bg-[var(--color-surface-muted)] transition-colors group-hover:bg-[var(--color-border)] group-disabled:group-hover:bg-[var(--color-surface-muted)]", children: item.icon }),
|
|
1285
1287
|
item.label
|
|
@@ -1298,7 +1300,7 @@ function GenreActionBand({
|
|
|
1298
1300
|
"aria-label": "Admin actions",
|
|
1299
1301
|
className: `px-3.5 py-3 ${items.length > 0 ? "border-t border-[var(--color-border)]" : ""}`,
|
|
1300
1302
|
children: [
|
|
1301
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "mb-2 text-
|
|
1303
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "mb-2 text-caption font-semibold uppercase tracking-wide text-[var(--color-text-muted)]", children: "Admin" }),
|
|
1302
1304
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex flex-wrap gap-1", children: renderItems(adminItems) })
|
|
1303
1305
|
]
|
|
1304
1306
|
}
|
|
@@ -1330,7 +1332,7 @@ function ClampedText({ children, className: className2 = "" }) {
|
|
|
1330
1332
|
type: "button",
|
|
1331
1333
|
"aria-expanded": expanded,
|
|
1332
1334
|
onClick: () => setExpanded((value) => !value),
|
|
1333
|
-
className: "mt-1 text-
|
|
1335
|
+
className: "mt-1 text-caption text-[var(--color-text-muted)] underline hover:text-[var(--color-text)]",
|
|
1334
1336
|
children: expanded ? "Show less" : "Show more"
|
|
1335
1337
|
}
|
|
1336
1338
|
)
|
|
@@ -1481,7 +1483,7 @@ function GenrePlaylistTracks({
|
|
|
1481
1483
|
".",
|
|
1482
1484
|
" ",
|
|
1483
1485
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "button", className: "underline", onClick: () => void refetch(), children: "Retry" })
|
|
1484
|
-
] }) : tracks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { children: "\u2014" }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("ul", { className: "mt-1 max-h-64 overflow-y-auto text-
|
|
1486
|
+
] }) : tracks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { children: "\u2014" }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("ul", { className: "mt-1 max-h-64 overflow-y-auto text-body [container-type:inline-size]", "aria-label": `${genreName} ${trackNoun.plural}`, children: [
|
|
1485
1487
|
tracks.map((track, index) => {
|
|
1486
1488
|
const label = track.artists?.length ? `${track.title} \u2014 ${track.artists.map((artist2) => artist2.name).join(", ")}` : track.title;
|
|
1487
1489
|
const isCurrent = playerTrackObject?.track.id === track.uuid;
|
|
@@ -1579,7 +1581,7 @@ function GenreDetailExtras({
|
|
|
1579
1581
|
const { summary, summarySourceUrl, essentialSongs } = overview;
|
|
1580
1582
|
const wikidataUrl = wikidataId ? `https://www.wikidata.org/wiki/${encodeURIComponent(wikidataId)}` : null;
|
|
1581
1583
|
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
1582
|
-
(summarySourceUrl || wikidataUrl) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ui6.PanelSection, { title: "Links", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap gap-x-3 gap-y-1 text-
|
|
1584
|
+
(summarySourceUrl || wikidataUrl) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ui6.PanelSection, { title: "Links", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap gap-x-3 gap-y-1 text-caption text-[var(--color-text)]", children: [
|
|
1583
1585
|
summarySourceUrl && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
1584
1586
|
"a",
|
|
1585
1587
|
{
|
|
@@ -1607,10 +1609,10 @@ function GenreDetailExtras({
|
|
|
1607
1609
|
}
|
|
1608
1610
|
)
|
|
1609
1611
|
] }) }),
|
|
1610
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ui6.PanelSection, { title: "Summary", children: renderSummary ? renderSummary(overview) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ClampedText, { className: "text-
|
|
1612
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ui6.PanelSection, { title: "Summary", children: renderSummary ? renderSummary(overview) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ClampedText, { className: "text-body text-[var(--color-text)]", children: summary ?? "\u2014" }, genreUuid) }),
|
|
1611
1613
|
family,
|
|
1612
1614
|
renderGenreDetailExtras?.(overview),
|
|
1613
|
-
(renderEssentialTracks || essentialSongs) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ui6.PanelSection, { title: `Essential ${trackNoun.plural}`, children: renderEssentialTracks ? renderEssentialTracks(overview) : essentialSongs && essentialSongs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("ul", { className: "text-
|
|
1615
|
+
(renderEssentialTracks || essentialSongs) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ui6.PanelSection, { title: `Essential ${trackNoun.plural}`, children: renderEssentialTracks ? renderEssentialTracks(overview) : essentialSongs && essentialSongs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("ul", { className: "text-body text-[var(--color-text)]", children: essentialSongs.map((track) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("li", { className: "py-1", children: track.title }, track.uuid)) }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-body text-[var(--color-text)]", children: "\u2014" }) }),
|
|
1614
1616
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
1615
1617
|
GenrePlaylistTracks,
|
|
1616
1618
|
{
|
|
@@ -1676,7 +1678,7 @@ function GenreInfoPanelBody({
|
|
|
1676
1678
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
1677
1679
|
toolbar,
|
|
1678
1680
|
genrePlaylist ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GenreNodeActionBand, { ...band, genrePlaylist, playback }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GenreActionBand, { ...band }),
|
|
1679
|
-
summary && catalogue && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "px-3.5 py-3 text-
|
|
1681
|
+
summary && catalogue && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "px-3.5 py-3 text-body text-[var(--color-text)]", children: [
|
|
1680
1682
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("p", { children: [
|
|
1681
1683
|
"Catalogue ",
|
|
1682
1684
|
noun.plural,
|
|
@@ -1766,7 +1768,7 @@ function useGenreDetailContent({
|
|
|
1766
1768
|
if (isError) return {
|
|
1767
1769
|
name: null,
|
|
1768
1770
|
title: "Genre unavailable",
|
|
1769
|
-
content: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { role: "alert", className: "p-4 text-
|
|
1771
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { role: "alert", className: "p-4 text-body text-[var(--color-text)]", children: "This genre could not be loaded." })
|
|
1770
1772
|
};
|
|
1771
1773
|
if (isPending || !detail || !view) return {
|
|
1772
1774
|
name: null,
|
|
@@ -1902,7 +1904,7 @@ function ChangeParentPopup({
|
|
|
1902
1904
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
1903
1905
|
}, [onClose]);
|
|
1904
1906
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(BasePopup_default, { title: `Change parent of ${genrePlaylist.name}`, onClose, showCancelButton: true, fitContent: true, children: [
|
|
1905
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("p", { className: "mb-3 text-
|
|
1907
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("p", { className: "mb-3 text-body text-[var(--color-text-muted)]", children: [
|
|
1906
1908
|
"Current parent: ",
|
|
1907
1909
|
genrePlaylist.parent?.name ?? "none"
|
|
1908
1910
|
] }),
|
|
@@ -1914,7 +1916,7 @@ function ChangeParentPopup({
|
|
|
1914
1916
|
placeholder: "Search a new parent\u2026"
|
|
1915
1917
|
}
|
|
1916
1918
|
) }),
|
|
1917
|
-
formErrors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { role: "alert", className: "mt-3 text-
|
|
1919
|
+
formErrors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { role: "alert", className: "mt-3 text-body text-[var(--color-red-500)]", children: formErrors.map(({ message }) => message).join(" ") })
|
|
1918
1920
|
] });
|
|
1919
1921
|
}
|
|
1920
1922
|
|
|
@@ -2000,7 +2002,7 @@ function ExternalLink({ href, children }) {
|
|
|
2000
2002
|
function ArtistPhoto({ image, name }) {
|
|
2001
2003
|
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("figure", { className: "flex flex-col gap-1.5 px-6 py-2.5", children: [
|
|
2002
2004
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("img", { src: image.url, alt: name, className: "h-64 w-full object-contain bg-[var(--color-surface-muted)] rounded" }),
|
|
2003
|
-
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("figcaption", { className: "text-
|
|
2005
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("figcaption", { className: "text-caption text-[var(--color-text-muted)]", children: [
|
|
2004
2006
|
"Photo: ",
|
|
2005
2007
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ExternalLink, { href: image.pageUrl, children: image.author ?? "Wikimedia Commons" }),
|
|
2006
2008
|
",",
|
|
@@ -2199,7 +2201,7 @@ function TrackItem({
|
|
|
2199
2201
|
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex max-w-full items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "title text-lg font-bold text-[var(--color-text)] max-w-full truncate", children: renderSongLink ? renderSongLink(track) : (0, import_genre_tree22.isSong)(track) ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(MusicBrainzRecordingLink, { song: track, className: "hover:underline focus-visible:underline", children: track.title }) : track.title }) }),
|
|
2200
2202
|
track.artists && track.artists.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "artist text-base max-w-full truncate text-[var(--color-text-muted)]", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_genre_tree23.ArtistNames, { artists: track.artists, renderArtistLink }) }) : ""
|
|
2201
2203
|
] }),
|
|
2202
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "genre-name-container flex items-center justify-start w-[21.6%] min-w-0 shrink-0", children: track.genre ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "genre-name max-w-full whitespace-normal break-words p-1 text-
|
|
2204
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "genre-name-container flex items-center justify-start w-[21.6%] min-w-0 shrink-0", children: track.genre ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "genre-name max-w-full whitespace-normal break-words p-1 text-caption font-bold", children: track.genre.name }) : "" }),
|
|
2203
2205
|
renderDuration && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2204
2206
|
"div",
|
|
2205
2207
|
{
|
|
@@ -2255,14 +2257,14 @@ function ArtistSongs({ artist, getBackendBaseUrl, renderArtistLink, renderSongLi
|
|
|
2255
2257
|
{
|
|
2256
2258
|
type: "button",
|
|
2257
2259
|
onClick: () => void play(),
|
|
2258
|
-
className: "flex w-fit items-center gap-1.5 px-3 py-1 text-
|
|
2260
|
+
className: "flex w-fit items-center gap-1.5 px-3 py-1 text-caption font-medium bg-gray-900 text-white rounded-full hover:bg-gray-700",
|
|
2259
2261
|
children: [
|
|
2260
2262
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react10.Play, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
2261
2263
|
"Play all"
|
|
2262
2264
|
]
|
|
2263
2265
|
}
|
|
2264
2266
|
),
|
|
2265
|
-
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { role: "group", "aria-label": "Sort songs by", className: "flex gap-1 text-
|
|
2267
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { role: "group", "aria-label": "Sort songs by", className: "flex gap-1 text-caption", children: SORTS.map((sort) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
2266
2268
|
"button",
|
|
2267
2269
|
{
|
|
2268
2270
|
type: "button",
|
|
@@ -2383,7 +2385,7 @@ function SongHistory({ uuid, getBackendBaseUrl }) {
|
|
|
2383
2385
|
if (history.status === "loading") body = /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_ui14.Skeleton, { className: "h-10", "aria-busy": "true" });
|
|
2384
2386
|
else if (history.status === "error") body = /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "text-red-600", children: "Could not load the history." });
|
|
2385
2387
|
else if (history.status === "success")
|
|
2386
|
-
body = history.entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "text-[var(--color-text-muted)]", children: "No changes yet." }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("ul", { className: "divide-y divide-[var(--color-border)]", children: history.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("li", { className: "py-1.5 text-
|
|
2388
|
+
body = history.entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "text-[var(--color-text-muted)]", children: "No changes yet." }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("ul", { className: "divide-y divide-[var(--color-border)]", children: history.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("li", { className: "py-1.5 text-body", children: [
|
|
2387
2389
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "font-medium", children: entry.action }),
|
|
2388
2390
|
entry.oldValue !== null || entry.newValue !== null ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "text-[var(--color-text-muted)]", children: [
|
|
2389
2391
|
" ",
|
|
@@ -2392,7 +2394,7 @@ function SongHistory({ uuid, getBackendBaseUrl }) {
|
|
|
2392
2394
|
" \u2192 ",
|
|
2393
2395
|
entry.newValue ?? "none"
|
|
2394
2396
|
] }) : null,
|
|
2395
|
-
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "block text-
|
|
2397
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "block text-caption text-[var(--color-text-muted)]", children: [
|
|
2396
2398
|
entry.actorPseudo ?? "Anonymous",
|
|
2397
2399
|
" \xB7 ",
|
|
2398
2400
|
dateFormat.format(new Date(entry.createdOn))
|
|
@@ -2410,15 +2412,8 @@ function SongHistory({ uuid, getBackendBaseUrl }) {
|
|
|
2410
2412
|
}
|
|
2411
2413
|
);
|
|
2412
2414
|
}
|
|
2413
|
-
function SongPanelContent({
|
|
2414
|
-
song,
|
|
2415
|
-
scope,
|
|
2416
|
-
getBackendBaseUrl,
|
|
2417
|
-
shareUrl,
|
|
2418
|
-
renderArtistLink,
|
|
2419
|
-
genrePath,
|
|
2420
|
-
onSelectGenre
|
|
2421
|
-
}) {
|
|
2415
|
+
function SongPanelContent(props) {
|
|
2416
|
+
const { song, scope, getBackendBaseUrl, shareUrl, renderArtistLink } = props;
|
|
2422
2417
|
const { playNewTrackListFromTrackUuid } = (0, import_genre_tree26.useTrackList)();
|
|
2423
2418
|
const { playerTrackObject, playState, handlePlayPauseAction } = (0, import_player11.usePlayer)();
|
|
2424
2419
|
const unplayableReason = (0, import_genre_tree26.songUnplayableReason)(song);
|
|
@@ -2428,12 +2423,14 @@ function SongPanelContent({
|
|
|
2428
2423
|
const musicBrainzUrl = (0, import_genre_tree26.musicBrainzRecordingUrl)(song);
|
|
2429
2424
|
const fields = [];
|
|
2430
2425
|
if (song.genre) {
|
|
2431
|
-
const path = genrePath.length > 0 ? genrePath : null;
|
|
2426
|
+
const path = props.genrePath && props.genrePath.length > 0 ? props.genrePath : null;
|
|
2427
|
+
const { onSelectGenre } = props;
|
|
2428
|
+
const genre = song.genre;
|
|
2432
2429
|
fields.push({
|
|
2433
2430
|
label: "Genre",
|
|
2434
|
-
value: path ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "flex flex-wrap items-center gap-x-1", children: path.map((genrePlaylist, index) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { children: [
|
|
2431
|
+
value: onSelectGenre ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", onClick: () => onSelectGenre(genre), className: "hover:underline", children: genre.name }) : path ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "flex flex-wrap items-center gap-x-1", children: path.map((genrePlaylist, index) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { children: [
|
|
2435
2432
|
index > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { "aria-hidden": "true", children: "\u203A " }),
|
|
2436
|
-
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", onClick: () =>
|
|
2433
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", onClick: () => props.onSelectGenrePlaylist?.(genrePlaylist), className: "hover:underline", children: genrePlaylist.name })
|
|
2437
2434
|
] }, genrePlaylist.uuid)) }) : song.genre.name
|
|
2438
2435
|
});
|
|
2439
2436
|
} else {
|
|
@@ -2470,12 +2467,12 @@ function SongPanelContent({
|
|
|
2470
2467
|
});
|
|
2471
2468
|
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
|
|
2472
2469
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "genre-action-band border-b border-[var(--color-border)]", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex flex-wrap gap-1 px-3.5 py-3", children: [
|
|
2473
|
-
unplayableReason ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "flex items-center px-2.5 text-
|
|
2470
|
+
unplayableReason ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "flex items-center px-2.5 text-body text-[var(--color-text-muted)]", children: unplayableReason }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
2474
2471
|
"button",
|
|
2475
2472
|
{
|
|
2476
2473
|
type: "button",
|
|
2477
2474
|
onClick: () => isCurrent ? handlePlayPauseAction() : playNewTrackListFromTrackUuid(song, scope),
|
|
2478
|
-
className: "group flex flex-col items-center gap-1 w-16 text-
|
|
2475
|
+
className: "group flex flex-col items-center gap-1 w-16 text-caption text-center text-[var(--color-text)] focus-visible:outline-none",
|
|
2479
2476
|
children: [
|
|
2480
2477
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "flex items-center justify-center w-10 h-10 rounded-full group-focus-visible:ring-2 group-focus-visible:ring-[var(--color-focus-ring)] bg-[var(--color-surface-muted)] transition-colors group-hover:bg-[var(--color-border)]", children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react11.Pause, { "aria-hidden": "true", className: "w-5 h-5" }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react11.Play, { "aria-hidden": "true", className: "w-5 h-5" }) }),
|
|
2481
2478
|
isPlaying ? "Pause" : "Play"
|
|
@@ -2499,11 +2496,10 @@ function useSongPanel({
|
|
|
2499
2496
|
getBackendBaseUrl,
|
|
2500
2497
|
getShareUrl,
|
|
2501
2498
|
renderArtistLink,
|
|
2502
|
-
getGenrePath,
|
|
2503
|
-
onSelectGenre,
|
|
2504
2499
|
expanded,
|
|
2505
2500
|
onExpandedChange,
|
|
2506
|
-
onClose
|
|
2501
|
+
onClose,
|
|
2502
|
+
...navigation
|
|
2507
2503
|
}) {
|
|
2508
2504
|
const result = (0, import_genre_tree27.useSong)(uuid, getBackendBaseUrl);
|
|
2509
2505
|
const panel = { expanded, onExpandedChange, onClose };
|
|
@@ -2547,8 +2543,10 @@ function useSongPanel({
|
|
|
2547
2543
|
getBackendBaseUrl,
|
|
2548
2544
|
shareUrl: shareUrl ?? void 0,
|
|
2549
2545
|
renderArtistLink,
|
|
2550
|
-
|
|
2551
|
-
|
|
2546
|
+
...navigation.getGenrePath ? {
|
|
2547
|
+
genrePath: song.genre ? navigation.getGenrePath(song.genre) : [],
|
|
2548
|
+
onSelectGenrePlaylist: navigation.onSelectGenrePlaylist
|
|
2549
|
+
} : { onSelectGenre: navigation.onSelectGenre }
|
|
2552
2550
|
}
|
|
2553
2551
|
)
|
|
2554
2552
|
};
|
|
@@ -2556,6 +2554,37 @@ function useSongPanel({
|
|
|
2556
2554
|
}
|
|
2557
2555
|
}
|
|
2558
2556
|
|
|
2557
|
+
// src/genre-tree/useEntityPanel.tsx
|
|
2558
|
+
function useEntityPanel({
|
|
2559
|
+
scope,
|
|
2560
|
+
getBackendBaseUrl,
|
|
2561
|
+
getArtistBackendBaseUrl,
|
|
2562
|
+
getShareUrl,
|
|
2563
|
+
renderArtistLink,
|
|
2564
|
+
renderSongLink,
|
|
2565
|
+
song,
|
|
2566
|
+
artist,
|
|
2567
|
+
...navigation
|
|
2568
|
+
}) {
|
|
2569
|
+
const songPanel = useSongPanel({
|
|
2570
|
+
...song,
|
|
2571
|
+
scope,
|
|
2572
|
+
getBackendBaseUrl,
|
|
2573
|
+
getShareUrl,
|
|
2574
|
+
renderArtistLink,
|
|
2575
|
+
...navigation
|
|
2576
|
+
});
|
|
2577
|
+
const artistPanel = useArtistPanel({
|
|
2578
|
+
...artist,
|
|
2579
|
+
scope,
|
|
2580
|
+
getBackendBaseUrl: getArtistBackendBaseUrl ?? getBackendBaseUrl,
|
|
2581
|
+
getShareUrl,
|
|
2582
|
+
renderArtistLink,
|
|
2583
|
+
renderSongLink
|
|
2584
|
+
});
|
|
2585
|
+
return songPanel ?? artistPanel;
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2559
2588
|
// src/genre-tree/SizeMetricToggle.tsx
|
|
2560
2589
|
var import_md = require("react-icons/md");
|
|
2561
2590
|
var import_ui16 = require("@behindthemusictree/ui");
|
|
@@ -2738,20 +2767,6 @@ function GenreTreeView({
|
|
|
2738
2767
|
const [expandedArtistUuid, setExpandedArtistUuid] = (0, import_react18.useState)(null);
|
|
2739
2768
|
const artistBaseUrl = artistSearchBaseUrl ?? getBackendBaseUrl;
|
|
2740
2769
|
const songBaseUrl = getBackendBaseUrl;
|
|
2741
|
-
const artistPanel = useArtistPanel({
|
|
2742
|
-
uuid: artistUuid,
|
|
2743
|
-
scope,
|
|
2744
|
-
getBackendBaseUrl: artistBaseUrl,
|
|
2745
|
-
getShareUrl: getShareUrlRef.current,
|
|
2746
|
-
renderArtistLink: renderArtistLink ?? ((artist) => artist.isSpecialPurpose ? artist.name : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("button", { type: "button", onClick: () => openArtist(artist.uuid), className: "hover:underline", children: artist.name })),
|
|
2747
|
-
expanded: controlledArtistExpanded ?? (artistUuid !== null && expandedArtistUuid === artistUuid),
|
|
2748
|
-
onExpandedChange: (on) => {
|
|
2749
|
-
if (controlledArtistExpanded === void 0) setExpandedArtistUuid(on ? artistUuid : null);
|
|
2750
|
-
onArtistExpandedChange?.(on);
|
|
2751
|
-
},
|
|
2752
|
-
renderSongLink: resolvedRenderSongLink,
|
|
2753
|
-
onClose: () => changeArtist(null)
|
|
2754
|
-
});
|
|
2755
2770
|
const resolvedRenderArtistLink = renderArtistLink ?? ((artist) => artist.isSpecialPurpose ? artist.name : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("button", { type: "button", onClick: () => openArtist(artist.uuid), className: "hover:underline", children: artist.name }));
|
|
2756
2771
|
const getGenrePath = (genre) => {
|
|
2757
2772
|
const path = [];
|
|
@@ -2763,27 +2778,38 @@ function GenreTreeView({
|
|
|
2763
2778
|
}
|
|
2764
2779
|
return path;
|
|
2765
2780
|
};
|
|
2766
|
-
const
|
|
2767
|
-
uuid: songUuid,
|
|
2781
|
+
const entityPanel = useEntityPanel({
|
|
2768
2782
|
scope,
|
|
2769
2783
|
getBackendBaseUrl: songBaseUrl,
|
|
2784
|
+
getArtistBackendBaseUrl: artistBaseUrl,
|
|
2770
2785
|
getShareUrl: getShareUrlRef.current,
|
|
2771
2786
|
renderArtistLink: resolvedRenderArtistLink,
|
|
2787
|
+
renderSongLink: resolvedRenderSongLink,
|
|
2788
|
+
song: {
|
|
2789
|
+
uuid: songUuid,
|
|
2790
|
+
expanded: controlledSongExpanded ?? (songUuid !== null && expandedSongUuid === songUuid),
|
|
2791
|
+
onExpandedChange: (on) => {
|
|
2792
|
+
if (controlledSongExpanded === void 0) setExpandedSongUuid(on ? songUuid : null);
|
|
2793
|
+
onSongExpandedChange?.(on);
|
|
2794
|
+
},
|
|
2795
|
+
onClose: () => changeSong(null)
|
|
2796
|
+
},
|
|
2797
|
+
artist: {
|
|
2798
|
+
uuid: artistUuid,
|
|
2799
|
+
expanded: controlledArtistExpanded ?? (artistUuid !== null && expandedArtistUuid === artistUuid),
|
|
2800
|
+
onExpandedChange: (on) => {
|
|
2801
|
+
if (controlledArtistExpanded === void 0) setExpandedArtistUuid(on ? artistUuid : null);
|
|
2802
|
+
onArtistExpandedChange?.(on);
|
|
2803
|
+
},
|
|
2804
|
+
onClose: () => changeArtist(null)
|
|
2805
|
+
},
|
|
2772
2806
|
getGenrePath,
|
|
2773
|
-
|
|
2807
|
+
onSelectGenrePlaylist: (genrePlaylist2) => {
|
|
2774
2808
|
changeSong(null);
|
|
2775
2809
|
selectGenrePlaylist(genrePlaylist2);
|
|
2776
|
-
}
|
|
2777
|
-
expanded: controlledSongExpanded ?? (songUuid !== null && expandedSongUuid === songUuid),
|
|
2778
|
-
onExpandedChange: (on) => {
|
|
2779
|
-
if (controlledSongExpanded === void 0) setExpandedSongUuid(on ? songUuid : null);
|
|
2780
|
-
onSongExpandedChange?.(on);
|
|
2781
|
-
},
|
|
2782
|
-
onClose: () => changeSong(null)
|
|
2810
|
+
}
|
|
2783
2811
|
});
|
|
2784
|
-
const
|
|
2785
|
-
const builtInArtistPanel = overlayPanel || selectedGenreUuid !== null || builtInSongPanel ? void 0 : artistPanel;
|
|
2786
|
-
const builtInPanel = builtInSongPanel ?? builtInArtistPanel;
|
|
2812
|
+
const builtInPanel = overlayPanel || selectedGenreUuid !== null ? void 0 : entityPanel;
|
|
2787
2813
|
const [uncontrolledCollapsed, setUncontrolledCollapsed] = (0, import_react18.useState)(false);
|
|
2788
2814
|
const [uncontrolledExpanded, setUncontrolledExpanded] = (0, import_react18.useState)(false);
|
|
2789
2815
|
const isCollapsed = collapsed ?? uncontrolledCollapsed;
|
|
@@ -2954,7 +2980,7 @@ function GenreTreeView({
|
|
|
2954
2980
|
) : null;
|
|
2955
2981
|
const renderArtistFilter = () => {
|
|
2956
2982
|
if (isLoading || !filterArtist) return null;
|
|
2957
|
-
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "inline-flex items-center overflow-hidden rounded-full bg-[var(--color-neutral-100)] text-
|
|
2983
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "inline-flex items-center overflow-hidden rounded-full bg-[var(--color-neutral-100)] text-body", children: [
|
|
2958
2984
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
2959
2985
|
"button",
|
|
2960
2986
|
{
|
|
@@ -3065,14 +3091,14 @@ function GenreTreeView({
|
|
|
3065
3091
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
3066
3092
|
"div",
|
|
3067
3093
|
{
|
|
3068
|
-
className: `actions-container absolute z-30 flex items-center gap-2 ${placement === "regions" ? "left-[calc(var(--layout-gutter)+var(--layout-panel-inset))] top-[calc(var(--layout-gutter)+var(--layout-panel-inset))] max-md:right-[calc(var(--layout-gutter)+var(--layout-panel-inset))] max-md:top-[var(--layout-band-top)] max-md:flex-col max-md:items-stretch" : "left-5 top-5"}`,
|
|
3094
|
+
className: `actions-container absolute z-30 flex items-center gap-2 ${placement === "regions" ? "left-[calc(var(--layout-gutter)+var(--layout-panel-inset))] top-[calc(var(--layout-gutter)+var(--layout-panel-inset))] md:left-[var(--layout-panel-inset)] md:top-[var(--layout-panel-inset)] max-md:right-[calc(var(--layout-gutter)+var(--layout-panel-inset))] max-md:top-[var(--layout-band-top)] max-md:flex-col max-md:items-stretch" : "left-5 top-5"}`,
|
|
3069
3095
|
children: actions
|
|
3070
3096
|
}
|
|
3071
3097
|
),
|
|
3072
3098
|
!isLoading && !isError && filterArtist && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
3073
3099
|
"div",
|
|
3074
3100
|
{
|
|
3075
|
-
className: `absolute left-1/2 z-30 hidden -translate-x-1/2 md:block ${placement === "regions" ? "top-[calc(var(--layout-gutter)+var(--layout-panel-inset))]" : "top-5"}`,
|
|
3101
|
+
className: `absolute left-1/2 z-30 hidden -translate-x-1/2 md:block ${placement === "regions" ? "top-[calc(var(--layout-gutter)+var(--layout-panel-inset))] md:top-[var(--layout-panel-inset)]" : "top-5"}`,
|
|
3076
3102
|
children: renderArtistFilter()
|
|
3077
3103
|
}
|
|
3078
3104
|
),
|
|
@@ -3342,7 +3368,7 @@ function TrackListSidebar({
|
|
|
3342
3368
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "from h-auto flex flex-col justify-center items-center mr-2", children: "From" }),
|
|
3343
3369
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "name-container flex flex-col justify-center items-center text-[var(--color-text)] font-bold pr-2 max-w-[27.5rem]", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "name max-w-full truncate", children: trackList.origin.label }) })
|
|
3344
3370
|
] }),
|
|
3345
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "info flex items-center text-
|
|
3371
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "info flex items-center text-body text-[var(--color-text-muted)]", children: [
|
|
3346
3372
|
trackList.origin.type === import_genre_tree30.TrackListOriginType.GENRE_PLAYLIST ? "Genre \u2022 " : trackList.origin.type === import_genre_tree30.TrackListOriginType.ARTIST ? "Artist \u2022 " : `${trackNoun.singular} playlist \u2022 `,
|
|
3347
3373
|
`${trackList.total} ${trackList.total > 1 ? trackNoun.plural : trackNoun.singular}`
|
|
3348
3374
|
] })
|
|
@@ -3652,8 +3678,72 @@ function Rating({ rating, handleChange }) {
|
|
|
3652
3678
|
) })
|
|
3653
3679
|
] }, i)) });
|
|
3654
3680
|
}
|
|
3681
|
+
|
|
3682
|
+
// src/genre-tree/EntityDetailPanel.tsx
|
|
3683
|
+
var import_react21 = require("react");
|
|
3684
|
+
var import_ui19 = require("@behindthemusictree/ui");
|
|
3685
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
3686
|
+
function EntityDetailPanel({
|
|
3687
|
+
scope,
|
|
3688
|
+
getBackendBaseUrl,
|
|
3689
|
+
getArtistBackendBaseUrl,
|
|
3690
|
+
getShareUrl,
|
|
3691
|
+
songUuid,
|
|
3692
|
+
onSongUuidChange,
|
|
3693
|
+
artistUuid,
|
|
3694
|
+
onArtistUuidChange,
|
|
3695
|
+
renderArtistLink,
|
|
3696
|
+
renderSongLink,
|
|
3697
|
+
collapsed,
|
|
3698
|
+
edgeTab,
|
|
3699
|
+
...navigation
|
|
3700
|
+
}) {
|
|
3701
|
+
const [expandedSongUuid, setExpandedSongUuid] = (0, import_react21.useState)(null);
|
|
3702
|
+
const [expandedArtistUuid, setExpandedArtistUuid] = (0, import_react21.useState)(null);
|
|
3703
|
+
const panel = useEntityPanel({
|
|
3704
|
+
scope,
|
|
3705
|
+
getBackendBaseUrl,
|
|
3706
|
+
getArtistBackendBaseUrl,
|
|
3707
|
+
getShareUrl,
|
|
3708
|
+
renderArtistLink: renderArtistLink ?? ((artist) => artist.isSpecialPurpose ? artist.name : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", onClick: () => onArtistUuidChange(artist.uuid), className: "hover:underline", children: artist.name })),
|
|
3709
|
+
renderSongLink: renderSongLink ?? ((song) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", onClick: () => onSongUuidChange(song.uuid), className: "hover:underline", children: song.title })),
|
|
3710
|
+
song: {
|
|
3711
|
+
uuid: songUuid,
|
|
3712
|
+
expanded: songUuid !== null && expandedSongUuid === songUuid,
|
|
3713
|
+
onExpandedChange: (on) => setExpandedSongUuid(on ? songUuid : null),
|
|
3714
|
+
onClose: () => onSongUuidChange(null)
|
|
3715
|
+
},
|
|
3716
|
+
artist: {
|
|
3717
|
+
uuid: artistUuid,
|
|
3718
|
+
expanded: artistUuid !== null && expandedArtistUuid === artistUuid,
|
|
3719
|
+
onExpandedChange: (on) => setExpandedArtistUuid(on ? artistUuid : null),
|
|
3720
|
+
onClose: () => onArtistUuidChange(null)
|
|
3721
|
+
},
|
|
3722
|
+
...navigation
|
|
3723
|
+
});
|
|
3724
|
+
if (!panel) return null;
|
|
3725
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3726
|
+
import_ui19.DetailPanel,
|
|
3727
|
+
{
|
|
3728
|
+
side: "left",
|
|
3729
|
+
title: panel.title,
|
|
3730
|
+
titleInSearch: true,
|
|
3731
|
+
onClose: panel.onClose,
|
|
3732
|
+
collapsed,
|
|
3733
|
+
expanded: panel.expanded,
|
|
3734
|
+
onExpandedChange: panel.onExpandedChange,
|
|
3735
|
+
aside: panel.extraContent,
|
|
3736
|
+
edgeTab,
|
|
3737
|
+
children: panel.extraContent && !panel.expanded ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
|
|
3738
|
+
panel.content,
|
|
3739
|
+
panel.extraContent
|
|
3740
|
+
] }) : panel.content
|
|
3741
|
+
}
|
|
3742
|
+
);
|
|
3743
|
+
}
|
|
3655
3744
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3656
3745
|
0 && (module.exports = {
|
|
3746
|
+
EntityDetailPanel,
|
|
3657
3747
|
GenreDetailPanel,
|
|
3658
3748
|
GenreInfoPanelBody,
|
|
3659
3749
|
GenreNodeActionBand,
|
|
@@ -3673,6 +3763,7 @@ function Rating({ rating, handleChange }) {
|
|
|
3673
3763
|
TrackPositionPlayPause,
|
|
3674
3764
|
searchStatus,
|
|
3675
3765
|
useArtistSearchGroup,
|
|
3766
|
+
useEntityPanel,
|
|
3676
3767
|
useGenrePlaylistPlayback,
|
|
3677
3768
|
useGenreRemoteSearchGroup,
|
|
3678
3769
|
useSongSearchGroup
|