@behindthemusictree/app-kit-ui 24.0.1 → 26.1.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-BPCFNBFO.js → chunk-KPWV4LEJ.js} +163 -75
- package/dist/chunk-KPWV4LEJ.js.map +1 -0
- package/dist/genre-tree/index.cjs +180 -92
- package/dist/genre-tree/index.cjs.map +1 -1
- package/dist/genre-tree/index.d.ts +21 -5
- package/dist/genre-tree/index.js +1 -1
- package/dist/index.cjs +180 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-BPCFNBFO.js.map +0 -1
|
@@ -38,8 +38,9 @@ module.exports = __toCommonJS(genre_tree_exports);
|
|
|
38
38
|
|
|
39
39
|
// src/genre-tree/GenreTreeView.tsx
|
|
40
40
|
var import_react10 = require("react");
|
|
41
|
+
var import_react_query3 = require("@tanstack/react-query");
|
|
41
42
|
var import_lucide_react8 = require("lucide-react");
|
|
42
|
-
var
|
|
43
|
+
var import_ui14 = require("@behindthemusictree/ui");
|
|
43
44
|
var import_genre_tree_view4 = require("@behindthemusictree/genre-tree-view");
|
|
44
45
|
var import_genre_tree17 = require("@behindthemusictree/app-kit/genre-tree");
|
|
45
46
|
var import_genre_tree18 = require("@behindthemusictree/app-kit/genre-tree");
|
|
@@ -668,6 +669,11 @@ var import_genre_tree_view2 = require("@behindthemusictree/genre-tree-view");
|
|
|
668
669
|
var import_player4 = require("@behindthemusictree/app-kit/player");
|
|
669
670
|
var import_popup3 = require("@behindthemusictree/app-kit/popup");
|
|
670
671
|
var import_transport6 = require("@behindthemusictree/app-kit/transport");
|
|
672
|
+
|
|
673
|
+
// src/genre-tree/playlist-tree/size-metric.ts
|
|
674
|
+
var genrePlaylistSize = (genrePlaylist, metric) => metric === "views" ? genrePlaylist.viewsCount : genrePlaylist.tracksCount;
|
|
675
|
+
|
|
676
|
+
// src/genre-tree/playlist-tree/TreeWheel.tsx
|
|
671
677
|
var import_track_noun4 = require("@behindthemusictree/app-kit/track-noun");
|
|
672
678
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
673
679
|
function GenrePlaylistTreeWheel({
|
|
@@ -688,6 +694,9 @@ function GenrePlaylistTreeWheel({
|
|
|
688
694
|
allowWheelRotation,
|
|
689
695
|
showToolbar,
|
|
690
696
|
controlsOrientation,
|
|
697
|
+
sizeMetric = "songs",
|
|
698
|
+
floatingControlsLeading,
|
|
699
|
+
busy,
|
|
691
700
|
defaultViewport,
|
|
692
701
|
onViewportChange,
|
|
693
702
|
playback,
|
|
@@ -703,12 +712,12 @@ function GenrePlaylistTreeWheel({
|
|
|
703
712
|
id: genrePlaylist.uuid,
|
|
704
713
|
parentId: genrePlaylist.parent?.uuid ?? null,
|
|
705
714
|
name: genrePlaylist.name,
|
|
706
|
-
itemCount: genrePlaylist
|
|
715
|
+
itemCount: genrePlaylistSize(genrePlaylist, sizeMetric),
|
|
707
716
|
actionable: Boolean(genrePlaylist.criteria),
|
|
708
717
|
side: genrePlaylist.criteria?.side ?? void 0,
|
|
709
718
|
wikidataId: genrePlaylist.criteria?.wikidataId ?? null
|
|
710
719
|
})),
|
|
711
|
-
[genrePlaylists]
|
|
720
|
+
[genrePlaylists, sizeMetric]
|
|
712
721
|
);
|
|
713
722
|
const handlePlayPause = (0, import_react5.useCallback)(
|
|
714
723
|
(nodeId) => {
|
|
@@ -760,7 +769,7 @@ function GenrePlaylistTreeWheel({
|
|
|
760
769
|
{
|
|
761
770
|
className,
|
|
762
771
|
nodes,
|
|
763
|
-
itemCountLabel: `${(0, import_track_noun4.capitalize)(trackNoun.singular)} count`,
|
|
772
|
+
itemCountLabel: sizeMetric === "views" ? "Views" : `${(0, import_track_noun4.capitalize)(trackNoun.singular)} count`,
|
|
764
773
|
playingNodeId,
|
|
765
774
|
playState: isPlaying ? "playing" : "paused",
|
|
766
775
|
onPlayPause: handlePlayPause,
|
|
@@ -778,6 +787,8 @@ function GenrePlaylistTreeWheel({
|
|
|
778
787
|
allowWheelRotation,
|
|
779
788
|
showToolbar,
|
|
780
789
|
controlsOrientation,
|
|
790
|
+
floatingControlsLeading,
|
|
791
|
+
busy,
|
|
781
792
|
defaultViewport,
|
|
782
793
|
onViewportChange,
|
|
783
794
|
...infoPanelCuration,
|
|
@@ -811,6 +822,9 @@ function GenrePlaylistTreeWheelRadialPopCore(props) {
|
|
|
811
822
|
allowWheelRotation,
|
|
812
823
|
showToolbar,
|
|
813
824
|
controlsOrientation,
|
|
825
|
+
sizeMetric = "songs",
|
|
826
|
+
floatingControlsLeading,
|
|
827
|
+
busy,
|
|
814
828
|
outline = false,
|
|
815
829
|
defaultViewport,
|
|
816
830
|
onViewportChange,
|
|
@@ -818,10 +832,6 @@ function GenrePlaylistTreeWheelRadialPopCore(props) {
|
|
|
818
832
|
} = props;
|
|
819
833
|
const focus = props;
|
|
820
834
|
const infoPanelCuration = {
|
|
821
|
-
editMode: props.editMode,
|
|
822
|
-
onEditModeChange: props.onEditModeChange,
|
|
823
|
-
renderTitleEditor: props.renderTitleEditor,
|
|
824
|
-
renderParentsEditor: props.renderParentsEditor,
|
|
825
835
|
renderDangerZone: props.renderDangerZone,
|
|
826
836
|
expanded: props.expanded,
|
|
827
837
|
onExpandedChange: props.onExpandedChange,
|
|
@@ -838,14 +848,15 @@ function GenrePlaylistTreeWheelRadialPopCore(props) {
|
|
|
838
848
|
id: genrePlaylist.uuid,
|
|
839
849
|
parentId: genrePlaylist.parent?.uuid ?? null,
|
|
840
850
|
name: genrePlaylist.name,
|
|
841
|
-
itemCount: genrePlaylist
|
|
851
|
+
itemCount: genrePlaylistSize(genrePlaylist, sizeMetric),
|
|
842
852
|
actionable: Boolean(genrePlaylist.criteria),
|
|
843
853
|
detached: !genrePlaylist.criteria,
|
|
844
854
|
side: genrePlaylist.criteria?.side ?? void 0,
|
|
845
855
|
wikidataId: genrePlaylist.criteria?.wikidataId ?? null,
|
|
846
|
-
umbrella: genrePlaylist.isUmbrella
|
|
856
|
+
umbrella: genrePlaylist.isUmbrella,
|
|
857
|
+
scene: genrePlaylist.scene ?? void 0
|
|
847
858
|
})),
|
|
848
|
-
[genrePlaylists]
|
|
859
|
+
[genrePlaylists, sizeMetric]
|
|
849
860
|
);
|
|
850
861
|
const handlePlayPause = (0, import_react6.useCallback)(
|
|
851
862
|
(nodeId) => {
|
|
@@ -887,7 +898,7 @@ function GenrePlaylistTreeWheelRadialPopCore(props) {
|
|
|
887
898
|
const treeProps = {
|
|
888
899
|
className,
|
|
889
900
|
nodes,
|
|
890
|
-
itemCountLabel: `${(0, import_track_noun5.capitalize)(trackNoun.singular)} count`,
|
|
901
|
+
itemCountLabel: sizeMetric === "views" ? "Views" : `${(0, import_track_noun5.capitalize)(trackNoun.singular)} count`,
|
|
891
902
|
playingNodeId,
|
|
892
903
|
playState: isPlaying ? "playing" : "paused",
|
|
893
904
|
onPlayPause: handlePlayPause,
|
|
@@ -912,6 +923,8 @@ function GenrePlaylistTreeWheelRadialPopCore(props) {
|
|
|
912
923
|
...treeProps,
|
|
913
924
|
allowWheelRotation,
|
|
914
925
|
controlsOrientation,
|
|
926
|
+
floatingControlsLeading,
|
|
927
|
+
busy,
|
|
915
928
|
defaultViewport,
|
|
916
929
|
onViewportChange,
|
|
917
930
|
...focus.onFocusGenreChange ? { focusNodeId: focus.focusGenreUuid, onFocusChange: focus.onFocusGenreChange } : { focusNodeId: void 0, onFocusChange: void 0 }
|
|
@@ -977,6 +990,7 @@ function GenreSearch({
|
|
|
977
990
|
});
|
|
978
991
|
const extraItems = query !== "" && query !== selectedName ? extraResults?.items ?? [] : [];
|
|
979
992
|
const label = extraResults ? "Search" : "Search a genre";
|
|
993
|
+
const loading = query !== "" && query !== selectedName && (extraResults?.loading ?? false);
|
|
980
994
|
const showList = results.length > 0 || extraItems.length > 0;
|
|
981
995
|
const heading = "px-3 pt-2 pb-1 text-xs font-medium uppercase text-[var(--color-text-muted)]";
|
|
982
996
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "genre-search relative w-[calc(var(--layout-detail-panel-w,25.5rem)-2*var(--layout-panel-inset,1rem))] shrink-0", children: [
|
|
@@ -1002,11 +1016,34 @@ function GenreSearch({
|
|
|
1002
1016
|
},
|
|
1003
1017
|
placeholder: placeholder ?? `${label}\u2026`,
|
|
1004
1018
|
"aria-label": label,
|
|
1019
|
+
"aria-busy": loading,
|
|
1005
1020
|
className: "h-[var(--layout-search-h,3rem)] pl-6 pr-20 text-base transition-[padding] duration-200 ease-out motion-reduce:transition-none bg-[var(--color-surface)] border-[var(--color-border)] rounded-full shadow-md"
|
|
1006
1021
|
}
|
|
1007
1022
|
),
|
|
1008
1023
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "absolute right-3 top-1/2 flex items-center -translate-y-1/2", children: [
|
|
1009
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.
|
|
1024
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1025
|
+
"span",
|
|
1026
|
+
{
|
|
1027
|
+
"data-loading": loading,
|
|
1028
|
+
className: "relative p-2 text-[var(--color-text-muted)] pointer-events-none",
|
|
1029
|
+
children: [
|
|
1030
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1031
|
+
import_lucide_react3.Search,
|
|
1032
|
+
{
|
|
1033
|
+
"aria-hidden": "true",
|
|
1034
|
+
className: `w-6 h-6 transition-opacity duration-200 motion-reduce:transition-none ${loading ? "opacity-0" : ""}`
|
|
1035
|
+
}
|
|
1036
|
+
),
|
|
1037
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1038
|
+
import_lucide_react3.LoaderCircle,
|
|
1039
|
+
{
|
|
1040
|
+
"aria-hidden": "true",
|
|
1041
|
+
className: `absolute inset-2 w-6 h-6 transition-opacity duration-200 motion-reduce:transition-none ${loading ? "opacity-100 delay-300 animate-spin motion-reduce:animate-none" : "opacity-0"}`
|
|
1042
|
+
}
|
|
1043
|
+
)
|
|
1044
|
+
]
|
|
1045
|
+
}
|
|
1046
|
+
),
|
|
1010
1047
|
canClear && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1011
1048
|
"button",
|
|
1012
1049
|
{
|
|
@@ -1189,13 +1226,28 @@ function ChangeParentPopup({
|
|
|
1189
1226
|
genrePlaylists,
|
|
1190
1227
|
scope,
|
|
1191
1228
|
getBackendBaseUrl,
|
|
1192
|
-
onClose
|
|
1229
|
+
onClose,
|
|
1230
|
+
onParentChanged
|
|
1193
1231
|
}) {
|
|
1194
1232
|
const { mutate, isPending, formErrors } = (0, import_genre_tree11.useUpdateGenre)(scope, getBackendBaseUrl);
|
|
1195
1233
|
const candidates = (0, import_react8.useMemo)(
|
|
1196
1234
|
() => (0, import_genre_tree11.getReparentCandidates)(genrePlaylists, genrePlaylist.uuid),
|
|
1197
1235
|
[genrePlaylists, genrePlaylist.uuid]
|
|
1198
1236
|
);
|
|
1237
|
+
const handleSelect = (newParent) => {
|
|
1238
|
+
const genre = genrePlaylist.criteria.uuid;
|
|
1239
|
+
const parentPlaylistUuid = genrePlaylist.parent?.uuid;
|
|
1240
|
+
const from = parentPlaylistUuid ? genrePlaylists.find(({ uuid }) => uuid === parentPlaylistUuid)?.criteria?.uuid ?? null : null;
|
|
1241
|
+
mutate(
|
|
1242
|
+
{ uuid: genre, data: { parent: newParent.criteria.uuid } },
|
|
1243
|
+
{
|
|
1244
|
+
onSuccess: () => {
|
|
1245
|
+
onClose();
|
|
1246
|
+
onParentChanged?.({ genre, from, to: newParent.criteria.uuid });
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
);
|
|
1250
|
+
};
|
|
1199
1251
|
(0, import_react8.useEffect)(() => {
|
|
1200
1252
|
const handleKeyDown = (event) => {
|
|
1201
1253
|
if (event.key === "Escape") onClose();
|
|
@@ -1212,7 +1264,7 @@ function ChangeParentPopup({
|
|
|
1212
1264
|
GenreSearch,
|
|
1213
1265
|
{
|
|
1214
1266
|
genrePlaylists: candidates,
|
|
1215
|
-
onSelect:
|
|
1267
|
+
onSelect: handleSelect,
|
|
1216
1268
|
placeholder: "Search a new parent\u2026"
|
|
1217
1269
|
}
|
|
1218
1270
|
) }),
|
|
@@ -1643,8 +1695,30 @@ function useArtistPanel({
|
|
|
1643
1695
|
}
|
|
1644
1696
|
}
|
|
1645
1697
|
|
|
1646
|
-
// src/genre-tree/
|
|
1698
|
+
// src/genre-tree/SizeMetricToggle.tsx
|
|
1699
|
+
var import_md = require("react-icons/md");
|
|
1700
|
+
var import_ui13 = require("@behindthemusictree/ui");
|
|
1647
1701
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1702
|
+
function SizeMetricToggle({
|
|
1703
|
+
value,
|
|
1704
|
+
onChange
|
|
1705
|
+
}) {
|
|
1706
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
1707
|
+
import_ui13.SegmentedControl,
|
|
1708
|
+
{
|
|
1709
|
+
"aria-label": "Size nodes by",
|
|
1710
|
+
value,
|
|
1711
|
+
onChange,
|
|
1712
|
+
options: [
|
|
1713
|
+
{ value: "songs", label: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_md.MdMusicNote, { size: 18, "aria-hidden": true }), "aria-label": "Size by songs", title: "Node size by song count" },
|
|
1714
|
+
{ value: "views", label: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_md.MdVisibility, { size: 18, "aria-hidden": true }), "aria-label": "Size by views", title: "Node size by song views" }
|
|
1715
|
+
]
|
|
1716
|
+
}
|
|
1717
|
+
);
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
// src/genre-tree/GenreTreeView.tsx
|
|
1721
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1648
1722
|
var PREVIOUS_BUTTON_CSS = `
|
|
1649
1723
|
.genre-tree-view .search-overlay .gtv-info-panel-previous { display: none; }
|
|
1650
1724
|
.genre-tree-view:has(.search-overlay .gtv-info-panel-previous) .genre-search input { padding-left: 2.75rem; }
|
|
@@ -1666,7 +1740,7 @@ function GenreNodeActionBand({ genrePlaylist, scope, playback, ...bandProps }) {
|
|
|
1666
1740
|
console.error("Failed to load genre playlist tracks:", error);
|
|
1667
1741
|
});
|
|
1668
1742
|
};
|
|
1669
|
-
return /* @__PURE__ */ (0,
|
|
1743
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1670
1744
|
GenreActionBand,
|
|
1671
1745
|
{
|
|
1672
1746
|
...bandProps,
|
|
@@ -1681,6 +1755,7 @@ function GenreTreeView({
|
|
|
1681
1755
|
scope,
|
|
1682
1756
|
handleGenreCreationAction,
|
|
1683
1757
|
handleGenreRenameAction,
|
|
1758
|
+
onParentChanged,
|
|
1684
1759
|
getBackendBaseUrl,
|
|
1685
1760
|
additionalActions,
|
|
1686
1761
|
viewMode: controlledViewMode,
|
|
@@ -1696,6 +1771,8 @@ function GenreTreeView({
|
|
|
1696
1771
|
criteriaOverviewSchema,
|
|
1697
1772
|
renderGenreDetailExtras,
|
|
1698
1773
|
controlsOrientation = "horizontal",
|
|
1774
|
+
sizeMetric: controlledSizeMetric,
|
|
1775
|
+
onSizeMetricChange,
|
|
1699
1776
|
renderArtistLink,
|
|
1700
1777
|
artistUuid: controlledArtistUuid,
|
|
1701
1778
|
onArtistUuidChange,
|
|
@@ -1709,10 +1786,6 @@ function GenreTreeView({
|
|
|
1709
1786
|
renderSongLeading,
|
|
1710
1787
|
renderSongActions,
|
|
1711
1788
|
renderTracksToolbar,
|
|
1712
|
-
editMode,
|
|
1713
|
-
onEditModeChange,
|
|
1714
|
-
renderTitleEditor,
|
|
1715
|
-
renderParentsEditor,
|
|
1716
1789
|
renderDangerZone,
|
|
1717
1790
|
expanded,
|
|
1718
1791
|
onExpandedChange,
|
|
@@ -1725,12 +1798,20 @@ function GenreTreeView({
|
|
|
1725
1798
|
const [internalArtistUuid, setInternalArtistUuid] = (0, import_react10.useState)(null);
|
|
1726
1799
|
const isArtistControlled = controlledArtistUuid !== void 0;
|
|
1727
1800
|
const artistUuid = isArtistControlled ? controlledArtistUuid : internalArtistUuid;
|
|
1801
|
+
const [internalSizeMetric, setInternalSizeMetric] = (0, import_react10.useState)("songs");
|
|
1802
|
+
const sizeMetric = controlledSizeMetric ?? internalSizeMetric;
|
|
1803
|
+
const deferredSizeMetric = (0, import_react10.useDeferredValue)(sizeMetric);
|
|
1804
|
+
const changeSizeMetric = (metric) => {
|
|
1805
|
+
if (controlledSizeMetric === void 0) setInternalSizeMetric(metric);
|
|
1806
|
+
onSizeMetricChange?.(metric);
|
|
1807
|
+
};
|
|
1728
1808
|
const changeArtist = (uuid) => {
|
|
1729
1809
|
if (!isArtistControlled) setInternalArtistUuid(uuid);
|
|
1730
1810
|
onArtistUuidChange?.(uuid);
|
|
1731
1811
|
};
|
|
1732
1812
|
const {
|
|
1733
1813
|
isLoading,
|
|
1814
|
+
isFetching: isTreeFetching,
|
|
1734
1815
|
genrePlaylistByNodeId,
|
|
1735
1816
|
visibleGenrePlaylists,
|
|
1736
1817
|
groupedGenrePlaylistsByRoot,
|
|
@@ -1755,6 +1836,8 @@ function GenreTreeView({
|
|
|
1755
1836
|
criteriaOverviewSchema,
|
|
1756
1837
|
artistUuid
|
|
1757
1838
|
});
|
|
1839
|
+
const isGenreUpdating = (0, import_react_query3.useIsMutating)({ mutationKey: import_genre_tree18.genreUpdateMutationKey }) > 0;
|
|
1840
|
+
const busy = deferredSizeMetric !== sizeMetric || isTreeFetching || isGenreUpdating;
|
|
1758
1841
|
const artistResult = (0, import_genre_tree18.useArtist)(artistUuid, artistSearchBaseUrl ?? getBackendBaseUrl);
|
|
1759
1842
|
const filterArtistName = artistResult.status === "success" ? artistResult.artist.name : null;
|
|
1760
1843
|
const filterArtist = (0, import_react10.useMemo)(
|
|
@@ -1771,7 +1854,7 @@ function GenreTreeView({
|
|
|
1771
1854
|
const artistPanel = useArtistPanel({
|
|
1772
1855
|
uuid: artistUuid,
|
|
1773
1856
|
getBackendBaseUrl: artistBaseUrl,
|
|
1774
|
-
renderArtistLink: renderArtistLink ?? ((artist) => artist.isSpecialPurpose ? artist.name : /* @__PURE__ */ (0,
|
|
1857
|
+
renderArtistLink: renderArtistLink ?? ((artist) => artist.isSpecialPurpose ? artist.name : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", onClick: () => openArtist(artist.uuid), className: "hover:underline", children: artist.name })),
|
|
1775
1858
|
expanded: controlledArtistExpanded ?? (artistUuid !== null && expandedArtistUuid === artistUuid),
|
|
1776
1859
|
onExpandedChange: (on) => {
|
|
1777
1860
|
if (controlledArtistExpanded === void 0) setExpandedArtistUuid(on ? artistUuid : null);
|
|
@@ -1809,10 +1892,6 @@ function GenreTreeView({
|
|
|
1809
1892
|
const detailExpanded = detailOverlay ? !!detailOverlay.expanded : isExpanded;
|
|
1810
1893
|
const onDetailExpandedChange = detailOverlay ? detailOverlay.onExpandedChange : changeExpanded;
|
|
1811
1894
|
const infoPanelCuration = {
|
|
1812
|
-
editMode,
|
|
1813
|
-
onEditModeChange,
|
|
1814
|
-
renderTitleEditor,
|
|
1815
|
-
renderParentsEditor,
|
|
1816
1895
|
renderDangerZone,
|
|
1817
1896
|
expanded: placement === "regions" ? isExpanded : expanded,
|
|
1818
1897
|
onExpandedChange: placement === "regions" ? changeExpanded : onExpandedChange,
|
|
@@ -1834,15 +1913,15 @@ function GenreTreeView({
|
|
|
1834
1913
|
label: "Artists",
|
|
1835
1914
|
items: artistSearchResult.artists.map((artist) => ({
|
|
1836
1915
|
key: artist.uuid,
|
|
1837
|
-
content: /* @__PURE__ */ (0,
|
|
1838
|
-
/* @__PURE__ */ (0,
|
|
1916
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
1917
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "block truncate font-medium", children: [
|
|
1839
1918
|
artist.name,
|
|
1840
|
-
artist.disambiguation && /* @__PURE__ */ (0,
|
|
1919
|
+
artist.disambiguation && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "font-normal text-[var(--color-neutral-500)]", children: [
|
|
1841
1920
|
" \xB7 ",
|
|
1842
1921
|
artist.disambiguation
|
|
1843
1922
|
] })
|
|
1844
1923
|
] }),
|
|
1845
|
-
artist.matchedAlias && /* @__PURE__ */ (0,
|
|
1924
|
+
artist.matchedAlias && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "block truncate text-xs text-[var(--color-neutral-500)]", children: [
|
|
1846
1925
|
"also known as ",
|
|
1847
1926
|
artist.matchedAlias
|
|
1848
1927
|
] })
|
|
@@ -1852,7 +1931,8 @@ function GenreTreeView({
|
|
|
1852
1931
|
onArtistSelect?.(artist);
|
|
1853
1932
|
}
|
|
1854
1933
|
})),
|
|
1855
|
-
status: artistSearchResult.isError ? "Search failed" : artistSearchResult.settled && artistSearchResult.artists.length === 0 ? "No artists found" : ""
|
|
1934
|
+
status: artistSearchResult.isError ? "Search failed" : artistSearchResult.settled && artistSearchResult.artists.length === 0 ? "No artists found" : "",
|
|
1935
|
+
loading: artistSearchResult.pending
|
|
1856
1936
|
} : void 0;
|
|
1857
1937
|
const handleSelectedNodeChange = (node) => {
|
|
1858
1938
|
selectNode(node);
|
|
@@ -1873,15 +1953,15 @@ function GenreTreeView({
|
|
|
1873
1953
|
(node, { toolbar, ancestors, family }) => {
|
|
1874
1954
|
const genrePlaylist = genrePlaylistByNodeId.get(node.id);
|
|
1875
1955
|
const criteria = genrePlaylist?.criteria;
|
|
1876
|
-
if (!genrePlaylist || !criteria) return { primary: /* @__PURE__ */ (0,
|
|
1956
|
+
if (!genrePlaylist || !criteria) return { primary: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
1877
1957
|
toolbar,
|
|
1878
1958
|
family
|
|
1879
1959
|
] }), aside: ancestors };
|
|
1880
1960
|
const genreUuid = criteria.uuid;
|
|
1881
1961
|
return {
|
|
1882
|
-
primary: /* @__PURE__ */ (0,
|
|
1962
|
+
primary: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
1883
1963
|
toolbar,
|
|
1884
|
-
/* @__PURE__ */ (0,
|
|
1964
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1885
1965
|
GenreNodeActionBand,
|
|
1886
1966
|
{
|
|
1887
1967
|
node,
|
|
@@ -1891,14 +1971,15 @@ function GenreTreeView({
|
|
|
1891
1971
|
onAddChild: readOnly ? void 0 : () => handleGenreCreationAction(criteria),
|
|
1892
1972
|
onRename: readOnly ? void 0 : () => handleGenreRenameAction(criteria),
|
|
1893
1973
|
onChangeParent: readOnly ? void 0 : () => showPopup(
|
|
1894
|
-
/* @__PURE__ */ (0,
|
|
1974
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1895
1975
|
ChangeParentPopup,
|
|
1896
1976
|
{
|
|
1897
1977
|
genrePlaylist: { ...genrePlaylist, criteria },
|
|
1898
1978
|
genrePlaylists: visibleGenrePlaylists,
|
|
1899
1979
|
scope,
|
|
1900
1980
|
getBackendBaseUrl,
|
|
1901
|
-
onClose: hidePopup
|
|
1981
|
+
onClose: hidePopup,
|
|
1982
|
+
onParentChanged
|
|
1902
1983
|
}
|
|
1903
1984
|
)
|
|
1904
1985
|
),
|
|
@@ -1906,7 +1987,7 @@ function GenreTreeView({
|
|
|
1906
1987
|
playback
|
|
1907
1988
|
}
|
|
1908
1989
|
),
|
|
1909
|
-
/* @__PURE__ */ (0,
|
|
1990
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1910
1991
|
GenreDetailExtras,
|
|
1911
1992
|
{
|
|
1912
1993
|
family,
|
|
@@ -1938,6 +2019,7 @@ function GenreTreeView({
|
|
|
1938
2019
|
handleGenreRenameAction,
|
|
1939
2020
|
showPopup,
|
|
1940
2021
|
hidePopup,
|
|
2022
|
+
onParentChanged,
|
|
1941
2023
|
visibleGenrePlaylists,
|
|
1942
2024
|
playback,
|
|
1943
2025
|
filterArtist,
|
|
@@ -1955,7 +2037,7 @@ function GenreTreeView({
|
|
|
1955
2037
|
);
|
|
1956
2038
|
const isRotationControlled = controlledAllowWheelRotation !== void 0;
|
|
1957
2039
|
const allowWheelRotation = controlledAllowWheelRotation ?? internalAllowWheelRotation;
|
|
1958
|
-
const detailTab = placement === "regions" && (selectedNodeId || detailOverlay) ? /* @__PURE__ */ (0,
|
|
2040
|
+
const detailTab = placement === "regions" && (selectedNodeId || detailOverlay) ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1959
2041
|
PanelEdgeTab,
|
|
1960
2042
|
{
|
|
1961
2043
|
side: "left",
|
|
@@ -1963,8 +2045,8 @@ function GenreTreeView({
|
|
|
1963
2045
|
center: detailExpanded ? null : isCollapsed ? { label: "Show panel", onClick: () => changeCollapsed(false) } : onDetailExpandedChange ? { label: "Extend panel", onClick: () => onDetailExpandedChange(true) } : null
|
|
1964
2046
|
}
|
|
1965
2047
|
) : null;
|
|
1966
|
-
const actions = /* @__PURE__ */ (0,
|
|
1967
|
-
!isLoading && /* @__PURE__ */ (0,
|
|
2048
|
+
const actions = /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
2049
|
+
!isLoading && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1968
2050
|
GenreSearch,
|
|
1969
2051
|
{
|
|
1970
2052
|
genrePlaylists: visibleGenrePlaylists,
|
|
@@ -1976,8 +2058,8 @@ function GenreTreeView({
|
|
|
1976
2058
|
extraResults: artistExtraResults
|
|
1977
2059
|
}
|
|
1978
2060
|
),
|
|
1979
|
-
!isLoading && filterArtist && /* @__PURE__ */ (0,
|
|
1980
|
-
/* @__PURE__ */ (0,
|
|
2061
|
+
!isLoading && filterArtist && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "inline-flex items-center overflow-hidden rounded-full bg-[var(--color-neutral-100)] text-sm", children: [
|
|
2062
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1981
2063
|
"button",
|
|
1982
2064
|
{
|
|
1983
2065
|
type: "button",
|
|
@@ -1989,7 +2071,7 @@ function GenreTreeView({
|
|
|
1989
2071
|
children: filterArtist.name
|
|
1990
2072
|
}
|
|
1991
2073
|
),
|
|
1992
|
-
/* @__PURE__ */ (0,
|
|
2074
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1993
2075
|
"button",
|
|
1994
2076
|
{
|
|
1995
2077
|
type: "button",
|
|
@@ -2000,8 +2082,8 @@ function GenreTreeView({
|
|
|
2000
2082
|
}
|
|
2001
2083
|
)
|
|
2002
2084
|
] }),
|
|
2003
|
-
!isLoading && !isControlled && /* @__PURE__ */ (0,
|
|
2004
|
-
|
|
2085
|
+
!isLoading && !isControlled && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2086
|
+
import_ui14.SegmentedControl,
|
|
2005
2087
|
{
|
|
2006
2088
|
"aria-label": "Tree view mode",
|
|
2007
2089
|
value: viewMode,
|
|
@@ -2014,14 +2096,14 @@ function GenreTreeView({
|
|
|
2014
2096
|
]
|
|
2015
2097
|
}
|
|
2016
2098
|
),
|
|
2017
|
-
!isLoading && showDisplayOptions && /* @__PURE__ */ (0,
|
|
2099
|
+
!isLoading && showDisplayOptions && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2018
2100
|
"div",
|
|
2019
2101
|
{
|
|
2020
2102
|
className: "flex items-center gap-1",
|
|
2021
2103
|
role: "group",
|
|
2022
2104
|
"aria-label": "Tree display options",
|
|
2023
|
-
children: !isRotationControlled && viewMode !== "stacked" && viewMode !== "outline" && /* @__PURE__ */ (0,
|
|
2024
|
-
|
|
2105
|
+
children: !isRotationControlled && viewMode !== "stacked" && viewMode !== "outline" && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2106
|
+
import_ui14.Button,
|
|
2025
2107
|
{
|
|
2026
2108
|
variant: allowWheelRotation ? "default" : "outline",
|
|
2027
2109
|
size: "sm",
|
|
@@ -2031,8 +2113,8 @@ function GenreTreeView({
|
|
|
2031
2113
|
)
|
|
2032
2114
|
}
|
|
2033
2115
|
),
|
|
2034
|
-
!isLoading && !readOnly && showAddRoot && /* @__PURE__ */ (0,
|
|
2035
|
-
|
|
2116
|
+
!isLoading && !readOnly && showAddRoot && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2117
|
+
import_ui14.IconTextButton,
|
|
2036
2118
|
{
|
|
2037
2119
|
icon: import_lucide_react8.Plus,
|
|
2038
2120
|
text: "Add root",
|
|
@@ -2040,33 +2122,33 @@ function GenreTreeView({
|
|
|
2040
2122
|
}
|
|
2041
2123
|
)
|
|
2042
2124
|
] });
|
|
2043
|
-
return /* @__PURE__ */ (0,
|
|
2125
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
2044
2126
|
"div",
|
|
2045
2127
|
{
|
|
2046
2128
|
ref: rootRef,
|
|
2047
2129
|
className: ["genre-tree-view relative flex flex-col h-full", placement === "regions" && REGIONS_CLASS, className].filter(Boolean).join(" "),
|
|
2048
2130
|
children: [
|
|
2049
|
-
/* @__PURE__ */ (0,
|
|
2050
|
-
/* @__PURE__ */ (0,
|
|
2131
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("style", { children: PREVIOUS_BUTTON_CSS }),
|
|
2132
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2051
2133
|
"div",
|
|
2052
2134
|
{
|
|
2053
2135
|
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))]" : "left-5 top-5"}`,
|
|
2054
2136
|
children: actions
|
|
2055
2137
|
}
|
|
2056
2138
|
),
|
|
2057
|
-
detailTab && /* @__PURE__ */ (0,
|
|
2139
|
+
detailTab && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2058
2140
|
"div",
|
|
2059
2141
|
{
|
|
2060
2142
|
className: `absolute top-1/2 z-30 -translate-y-1/2 transition-[opacity,visibility] duration-150 ease-out ${isTreeReady ? "opacity-100" : "pointer-events-none invisible opacity-0"} ${detailExpanded ? "right-[calc(var(--layout-center-right)-var(--layout-edge-tab-w))]" : isCollapsed ? "left-0" : "left-[calc(var(--layout-gutter)+var(--layout-left-w))]"}`,
|
|
2061
2143
|
children: detailTab
|
|
2062
2144
|
}
|
|
2063
2145
|
),
|
|
2064
|
-
/* @__PURE__ */ (0,
|
|
2146
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "content-container flex-1 min-h-0 flex flex-row gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "tree-view-container flex-1 min-w-0 flex flex-col h-full", children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_genre_tree_view4.GenreTreeViewSkeleton, { viewMode }) : viewMode === "wheel" ? (
|
|
2065
2147
|
// The info panel's top edge aligns with the tree's; the search bar floats `--layout-panel-inset` below it,
|
|
2066
2148
|
// and the header inset (the bar's height plus that inset) extends the header's fill behind the bar,
|
|
2067
2149
|
// Google Maps style; the 8px bottom padding mirrors the inset above the bar, and the hidden title's height is zeroed.
|
|
2068
2150
|
// The panel's own Zoom in button is hidden: the search bar carries it.
|
|
2069
|
-
/* @__PURE__ */ (0,
|
|
2151
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "tree-container search-overlay relative flex-1 w-full min-h-0 [--gtv-info-panel-header-inset:calc(var(--layout-search-h,2.5rem)+var(--layout-panel-inset,0.5rem))] [&_.gtv-info-panel-header]:pb-2 [&_.gtv-info-panel-title--hidden]:h-0 [&_.gtv-toolbar]:hidden", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(GenreTreeWheelHandoff, { skeleton: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_genre_tree_view4.GenreTreeWheelSkeleton, {}), onRevealedChange: setIsWheelRevealed, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2070
2152
|
GenrePlaylistTreeWheel,
|
|
2071
2153
|
{
|
|
2072
2154
|
scope,
|
|
@@ -2084,6 +2166,9 @@ function GenreTreeView({
|
|
|
2084
2166
|
readOnly,
|
|
2085
2167
|
allowWheelRotation,
|
|
2086
2168
|
controlsOrientation,
|
|
2169
|
+
sizeMetric: filterArtist ? "songs" : deferredSizeMetric,
|
|
2170
|
+
busy,
|
|
2171
|
+
floatingControlsLeading: filterArtist ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SizeMetricToggle, { value: sizeMetric, onChange: changeSizeMetric }),
|
|
2087
2172
|
defaultViewport,
|
|
2088
2173
|
onViewportChange,
|
|
2089
2174
|
...infoPanelCuration
|
|
@@ -2091,7 +2176,7 @@ function GenreTreeView({
|
|
|
2091
2176
|
) }) })
|
|
2092
2177
|
) : viewMode === "pop-core" ? (
|
|
2093
2178
|
// Same as the wheel: the header inset extends its fill behind the floating search bar, Google Maps style.
|
|
2094
|
-
/* @__PURE__ */ (0,
|
|
2179
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "tree-container search-overlay relative flex-1 w-full min-h-0 [--gtv-info-panel-header-inset:calc(var(--layout-search-h,2.5rem)+var(--layout-panel-inset,0.5rem))] [&_.gtv-info-panel-header]:pb-2 [&_.gtv-info-panel-title--hidden]:h-0 [&_.gtv-toolbar]:hidden [&_.gtv-info-panel-zoom-in]:hidden", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(GenreTreeWheelHandoff, { skeleton: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_genre_tree_view4.GenreTreeWheelSkeleton, {}), onRevealedChange: setIsWheelRevealed, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2095
2180
|
GenrePlaylistTreeWheelRadialPopCore,
|
|
2096
2181
|
{
|
|
2097
2182
|
scope,
|
|
@@ -2109,13 +2194,16 @@ function GenreTreeView({
|
|
|
2109
2194
|
readOnly,
|
|
2110
2195
|
allowWheelRotation,
|
|
2111
2196
|
controlsOrientation,
|
|
2197
|
+
sizeMetric: filterArtist ? "songs" : deferredSizeMetric,
|
|
2198
|
+
busy,
|
|
2199
|
+
floatingControlsLeading: filterArtist ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SizeMetricToggle, { value: sizeMetric, onChange: changeSizeMetric }),
|
|
2112
2200
|
defaultViewport,
|
|
2113
2201
|
onViewportChange,
|
|
2114
2202
|
...infoPanelCuration,
|
|
2115
2203
|
...focus
|
|
2116
2204
|
}
|
|
2117
2205
|
) }) })
|
|
2118
|
-
) : viewMode === "outline" ? /* @__PURE__ */ (0,
|
|
2206
|
+
) : viewMode === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "tree-container flex-1 min-h-0 w-full overflow-y-auto relative [--gtv-info-panel-header-inset:calc(var(--layout-search-h,2.5rem)+var(--layout-panel-inset,0.5rem)+0.75rem)] [&_.gtv-toolbar]:hidden", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2119
2207
|
GenrePlaylistTreeWheelRadialPopCore,
|
|
2120
2208
|
{
|
|
2121
2209
|
outline: true,
|
|
@@ -2134,13 +2222,13 @@ function GenreTreeView({
|
|
|
2134
2222
|
readOnly,
|
|
2135
2223
|
...infoPanelCuration
|
|
2136
2224
|
}
|
|
2137
|
-
) }) : /* @__PURE__ */ (0,
|
|
2225
|
+
) }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "tree-container relative flex flex-col gap-4 w-full pt-14 overflow-x-auto overflow-y-auto text-[var(--color-text)] [&_.gtv-toolbar]:hidden", children: Object.entries(groupedGenrePlaylistsByRoot).map(
|
|
2138
2226
|
([uuid, genrePlaylistTreePerRoot], rootIndex) => {
|
|
2139
|
-
return /* @__PURE__ */ (0,
|
|
2227
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2140
2228
|
"div",
|
|
2141
2229
|
{
|
|
2142
2230
|
className: "tree-per-root-container relative shrink-0 h-[28rem] mt-2 mr-16 p-2 bg-[var(--color-neutral-100)] rounded-lg",
|
|
2143
|
-
children: /* @__PURE__ */ (0,
|
|
2231
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "graph-container relative z-10 h-full", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2144
2232
|
GenrePlaylistTreePerRoot,
|
|
2145
2233
|
{
|
|
2146
2234
|
scope,
|
|
@@ -2184,7 +2272,7 @@ var import_genre_tree19 = require("@behindthemusictree/app-kit/genre-tree");
|
|
|
2184
2272
|
var import_genre_tree20 = require("@behindthemusictree/app-kit/genre-tree");
|
|
2185
2273
|
var import_genre_tree21 = require("@behindthemusictree/app-kit/genre-tree");
|
|
2186
2274
|
var import_track_noun6 = require("@behindthemusictree/app-kit/track-noun");
|
|
2187
|
-
var
|
|
2275
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
2188
2276
|
function TrackListSidebar({
|
|
2189
2277
|
className = "",
|
|
2190
2278
|
renderDuration,
|
|
@@ -2209,7 +2297,7 @@ function TrackListSidebar({
|
|
|
2209
2297
|
}, [hasMore, loadMore]);
|
|
2210
2298
|
const { hideTrackListSidebar } = (0, import_genre_tree20.useTrackListSidebarVisibility)();
|
|
2211
2299
|
const positionClasses = layout === "inline" ? "relative w-full flex h-full flex-col" : "fixed right-0 w-[50rem]";
|
|
2212
|
-
return trackList ? /* @__PURE__ */ (0,
|
|
2300
|
+
return trackList ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
2213
2301
|
"div",
|
|
2214
2302
|
{
|
|
2215
2303
|
"data-theme": "dark",
|
|
@@ -2219,16 +2307,16 @@ function TrackListSidebar({
|
|
|
2219
2307
|
/* Match player height exactly */
|
|
2220
2308
|
} : void 0,
|
|
2221
2309
|
children: [
|
|
2222
|
-
/* @__PURE__ */ (0,
|
|
2223
|
-
/* @__PURE__ */ (0,
|
|
2224
|
-
/* @__PURE__ */ (0,
|
|
2225
|
-
/* @__PURE__ */ (0,
|
|
2310
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "header flex h-16 px-4 py-2 text-[var(--color-text)]", children: [
|
|
2311
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "origin flex text-xl ", children: [
|
|
2312
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "from h-auto flex flex-col justify-center items-center mr-2", children: "From" }),
|
|
2313
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.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_runtime29.jsx)("div", { className: "name max-w-full truncate", children: trackList.origin.label }) })
|
|
2226
2314
|
] }),
|
|
2227
|
-
/* @__PURE__ */ (0,
|
|
2315
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "info flex flex-col justify-center items-center pt-1 mr-2 text-[var(--color-text-muted)]", children: [
|
|
2228
2316
|
trackList.origin.type === import_genre_tree21.TrackListOriginType.GENRE_PLAYLIST ? "\u2022 Genre playlist \u2022 " : trackList.origin.type === import_genre_tree21.TrackListOriginType.ARTIST ? "\u2022 Artist \u2022 " : `\u2022 ${trackNoun.singular} playlist \u2022 `,
|
|
2229
2317
|
`${trackList.total} ${trackList.total > 1 ? trackNoun.plural : trackNoun.singular} \u2022`
|
|
2230
2318
|
] }),
|
|
2231
|
-
/* @__PURE__ */ (0,
|
|
2319
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
2232
2320
|
"button",
|
|
2233
2321
|
{
|
|
2234
2322
|
type: "button",
|
|
@@ -2239,12 +2327,12 @@ function TrackListSidebar({
|
|
|
2239
2327
|
}
|
|
2240
2328
|
)
|
|
2241
2329
|
] }),
|
|
2242
|
-
/* @__PURE__ */ (0,
|
|
2330
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
2243
2331
|
"ul",
|
|
2244
2332
|
{
|
|
2245
2333
|
className: layout === "inline" ? "track-list flex-1 min-h-0 overflow-auto list-none p-0 m-0" : "track-list overflow-auto max-h-[calc(100vh-63.5px-79px-56px-3.5px)] list-none p-0 m-0",
|
|
2246
2334
|
children: [
|
|
2247
|
-
trackList.tracks.map((track, index) => /* @__PURE__ */ (0,
|
|
2335
|
+
trackList.tracks.map((track, index) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
2248
2336
|
TrackItem,
|
|
2249
2337
|
{
|
|
2250
2338
|
track,
|
|
@@ -2254,7 +2342,7 @@ function TrackListSidebar({
|
|
|
2254
2342
|
renderArtistLink
|
|
2255
2343
|
}
|
|
2256
2344
|
) }, track.uuid)),
|
|
2257
|
-
hasMore && /* @__PURE__ */ (0,
|
|
2345
|
+
hasMore && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("li", { ref: loadMoreSentinelRef, "aria-hidden": "true", className: "h-px" })
|
|
2258
2346
|
]
|
|
2259
2347
|
}
|
|
2260
2348
|
)
|
|
@@ -2269,7 +2357,7 @@ var import_lucide_react9 = require("lucide-react");
|
|
|
2269
2357
|
var import_tailwind_merge2 = require("tailwind-merge");
|
|
2270
2358
|
var import_player11 = require("@behindthemusictree/app-kit/player");
|
|
2271
2359
|
var import_genre_tree22 = require("@behindthemusictree/app-kit/genre-tree");
|
|
2272
|
-
var
|
|
2360
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
2273
2361
|
var PANEL_ID = "player-panel";
|
|
2274
2362
|
var iconButtonClassName = "flex h-6 w-6 shrink-0 items-center justify-center p-0 rounded-md hover:bg-white/10";
|
|
2275
2363
|
var DEFAULT_EXTENDED_WIDTH = "calc(100vw - var(--layout-center-left) - var(--layout-gutter))";
|
|
@@ -2299,7 +2387,7 @@ function PlayerPanel({
|
|
|
2299
2387
|
label: "Extend song list panel",
|
|
2300
2388
|
onClick: () => setIsExtendRequested(true)
|
|
2301
2389
|
};
|
|
2302
|
-
return /* @__PURE__ */ (0,
|
|
2390
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
2303
2391
|
"div",
|
|
2304
2392
|
{
|
|
2305
2393
|
id: PANEL_ID,
|
|
@@ -2312,7 +2400,7 @@ function PlayerPanel({
|
|
|
2312
2400
|
),
|
|
2313
2401
|
style: isExtended ? { width: extendedWidth } : void 0,
|
|
2314
2402
|
children: [
|
|
2315
|
-
/* @__PURE__ */ (0,
|
|
2403
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
2316
2404
|
PanelEdgeTab,
|
|
2317
2405
|
{
|
|
2318
2406
|
side: "right",
|
|
@@ -2322,7 +2410,7 @@ function PlayerPanel({
|
|
|
2322
2410
|
className: "absolute right-full top-1/2 -translate-y-1/2"
|
|
2323
2411
|
}
|
|
2324
2412
|
),
|
|
2325
|
-
/* @__PURE__ */ (0,
|
|
2413
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
2326
2414
|
"div",
|
|
2327
2415
|
{
|
|
2328
2416
|
className: (0, import_tailwind_merge2.twMerge)(
|
|
@@ -2330,26 +2418,26 @@ function PlayerPanel({
|
|
|
2330
2418
|
isExtended ? "flex-row" : "flex-col"
|
|
2331
2419
|
),
|
|
2332
2420
|
children: [
|
|
2333
|
-
/* @__PURE__ */ (0,
|
|
2334
|
-
/* @__PURE__ */ (0,
|
|
2335
|
-
/* @__PURE__ */ (0,
|
|
2336
|
-
/* @__PURE__ */ (0,
|
|
2421
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex w-[var(--layout-right-w)] shrink-0 flex-col", children: [
|
|
2422
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex shrink-0 items-center justify-between gap-2 border-b border-zinc-800 p-2", children: [
|
|
2423
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "min-w-0 truncate text-sm font-semibold", children: playerTrackObject?.track?.title }),
|
|
2424
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "flex shrink-0 items-center gap-1", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
2337
2425
|
"button",
|
|
2338
2426
|
{
|
|
2339
2427
|
type: "button",
|
|
2340
2428
|
onClick: onClose,
|
|
2341
2429
|
className: iconButtonClassName,
|
|
2342
2430
|
"aria-label": "Close player",
|
|
2343
|
-
children: /* @__PURE__ */ (0,
|
|
2431
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react9.X, { size: 16 })
|
|
2344
2432
|
}
|
|
2345
2433
|
) })
|
|
2346
2434
|
] }),
|
|
2347
|
-
/* @__PURE__ */ (0,
|
|
2348
|
-
/* @__PURE__ */ (0,
|
|
2349
|
-
playerTrackObject?.loadError && /* @__PURE__ */ (0,
|
|
2435
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "relative w-full shrink-0", children: [
|
|
2436
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_player11.PlayerVideoSurface, { className: "aspect-video w-full bg-black" }),
|
|
2437
|
+
playerTrackObject?.loadError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "absolute bottom-2 left-2 right-2 text-xs text-red-400", children: playerTrackObject.loadError })
|
|
2350
2438
|
] })
|
|
2351
2439
|
] }),
|
|
2352
|
-
isTrackListSidebarVisible && /* @__PURE__ */ (0,
|
|
2440
|
+
isTrackListSidebarVisible && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
2353
2441
|
TrackListSidebar,
|
|
2354
2442
|
{
|
|
2355
2443
|
layout: "inline",
|
|
@@ -2372,11 +2460,11 @@ function PlayerPanel({
|
|
|
2372
2460
|
var import_uuid = require("uuid");
|
|
2373
2461
|
var import_ai = require("react-icons/ai");
|
|
2374
2462
|
var import_genre_tree23 = require("@behindthemusictree/app-kit/genre-tree");
|
|
2375
|
-
var
|
|
2463
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
2376
2464
|
function Rating({ rating, handleChange }) {
|
|
2377
2465
|
const instanceId = (0, import_uuid.v4)();
|
|
2378
|
-
return /* @__PURE__ */ (0,
|
|
2379
|
-
/* @__PURE__ */ (0,
|
|
2466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex items-center", children: [...Array(6)].map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: `relative ${i === 0 ? "mr-4" : "mr-1"}`, children: [
|
|
2467
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
2380
2468
|
"input",
|
|
2381
2469
|
{
|
|
2382
2470
|
id: `star-${instanceId}-${i}`,
|
|
@@ -2388,16 +2476,16 @@ function Rating({ rating, handleChange }) {
|
|
|
2388
2476
|
onChange: handleChange
|
|
2389
2477
|
}
|
|
2390
2478
|
),
|
|
2391
|
-
/* @__PURE__ */ (0,
|
|
2392
|
-
/* @__PURE__ */ (0,
|
|
2479
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("label", { htmlFor: `star-${instanceId}-${i}`, className: "cursor-pointer", children: i === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex", children: [
|
|
2480
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
2393
2481
|
import_ai.AiOutlineStar,
|
|
2394
2482
|
{
|
|
2395
2483
|
className: `w-7 h-7 absolute top-0 left-0 ${rating === import_genre_tree23.FORM_RATING_NULL_VALUE ? "text-[var(--color-accent-rating)]" : "text-[var(--color-text-muted)]"}`
|
|
2396
2484
|
}
|
|
2397
2485
|
),
|
|
2398
|
-
/* @__PURE__ */ (0,
|
|
2486
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "flex-grow w-8" }),
|
|
2399
2487
|
" "
|
|
2400
|
-
] }) : /* @__PURE__ */ (0,
|
|
2488
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
2401
2489
|
import_ai.AiFillStar,
|
|
2402
2490
|
{
|
|
2403
2491
|
className: `w-7 h-7 absolute top-0 left-0 ${(rating ?? -1) >= i ? "text-[var(--color-accent-rating)]" : "text-[var(--color-text-muted)]"}`
|