Skip to content

Commit a741d3b

Browse files
authored
Merge pull request #658 from bcc-code/feature/reorder-private-playlists
feat: reorder private playlists
2 parents 00827d4 + 9ce57c7 commit a741d3b

3 files changed

Lines changed: 62 additions & 2 deletions

File tree

components/track/TrackItem.vue

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const props = withDefaults(
1515
addDropdownItems?: (items: DropdownMenuItem[], track: TrackModel) => void;
1616
isAlbumKnown?: boolean;
1717
origin?: string;
18+
showDragHandle?: boolean;
1819
}>(),
1920
{
2021
isAlbumKnown: false,
@@ -94,6 +95,13 @@ const selectedTrack: Ref<TrackModel | null> = ref(null);
9495
class="group relative col-span-full grid cursor-pointer grid-cols-subgrid gap-3 py-3"
9596
@click.stop="playTrack"
9697
>
98+
<div
99+
v-if="showDragHandle"
100+
class="drag-handle invisible absolute left-0 top-1/2 z-20 -translate-x-1/2 -translate-y-1/2 cursor-grab text-label-3 active:cursor-grabbing group-hover:visible group-active:visible"
101+
>
102+
<NuxtIcon name="icon.sort" />
103+
</div>
104+
97105
<div
98106
class="absolute -inset-x-4 -inset-y-0 rounded-xl bg-background-2 opacity-0 group-hover:opacity-100"
99107
></div>

components/track/TrackList.vue

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script lang="ts" setup>
2+
import { useDraggable } from "vue-draggable-plus";
23
import type { TrackModel } from "@bcc-code/bmm-sdk-fetch";
34
45
const props = withDefaults(
@@ -11,16 +12,22 @@ const props = withDefaults(
1112
showThumbnails?: boolean;
1213
addDropdownItems?: (items: DropdownMenuItem[], track: TrackModel) => void;
1314
origin?: string;
15+
reorder?: boolean;
1416
}>(),
1517
{
1618
skeletonCount: 5,
1719
addDropdownItems: undefined,
1820
trackTypeIsKnown: undefined,
1921
albumIsKnown: false,
2022
origin: "",
23+
reorder: false,
2124
},
2225
);
2326
27+
const emit = defineEmits<{
28+
reorder: [tracks: TrackModel[]];
29+
}>();
30+
2431
const { setQueue } = useNuxtApp().$mediaPlayer;
2532
2633
const isTrackTypeKnown = () => {
@@ -35,10 +42,37 @@ const isTrackTypeKnown = () => {
3542
) || false
3643
);
3744
};
45+
46+
const orderableTracks = ref<TrackModel[]>([]);
47+
onMounted(() => {
48+
if (props.tracks) {
49+
orderableTracks.value = props.tracks;
50+
}
51+
});
52+
const trackList = ref<HTMLOListElement>();
53+
useDraggable<TrackModel>(trackList, orderableTracks, {
54+
animation: 200,
55+
disabled: !props.reorder,
56+
ghostClass: "opacity-50",
57+
handle: ".drag-handle",
58+
onSort({ oldIndex, newIndex }) {
59+
if (oldIndex === undefined || newIndex === undefined || !props.tracks) {
60+
return;
61+
}
62+
const tracks = [...props.tracks];
63+
const [removed] = tracks.splice(oldIndex, 1);
64+
if (!removed) {
65+
return;
66+
}
67+
tracks.splice(newIndex, 0, removed);
68+
emit("reorder", tracks);
69+
},
70+
});
3871
</script>
3972

4073
<template>
4174
<ol
75+
ref="trackList"
4276
class="grid w-full grid-cols-tracklist grid-rows-1 gap-x-4 divide-y divide-label-separator"
4377
>
4478
<template v-if="showSkeleton">
@@ -58,6 +92,7 @@ const isTrackTypeKnown = () => {
5892
:add-dropdown-items="props.addDropdownItems"
5993
:is-album-known="props.albumIsKnown"
6094
:origin="props.origin"
95+
:show-drag-handle="props.reorder"
6196
@play-track="setQueue(tracks, i, props.origin)"
6297
>
6398
</TrackItem>

pages/playlist/private/[id]/index.vue

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ const addDropdownItems = (items: DropdownMenuItem[], track: TrackModel) => {
5050
},
5151
});
5252
};
53+
54+
const handleReorder = (tracks: TrackModel[]) => {
55+
if (!collection.value || !collection.value.canEdit) {
56+
return;
57+
}
58+
new TrackCollectionApi().trackCollectionIdPut({
59+
id: collectionId,
60+
updateTrackCollectionCommand: {
61+
id: collectionId,
62+
name: collection.value.name || "",
63+
trackReferences: tracksToTrackReferences(tracks),
64+
},
65+
});
66+
collection.value.tracks = tracks;
67+
};
5368
</script>
5469

5570
<template>
@@ -106,11 +121,13 @@ const addDropdownItems = (items: DropdownMenuItem[], track: TrackModel) => {
106121
</TrackCollectionHeader>
107122

108123
<TrackList
124+
:key="`tracklist:can-edit:${collection?.canEdit}`"
109125
:skeleton-count="5"
110126
:show-skeleton="pending"
111127
:tracks="collection?.tracks || null"
112128
:add-dropdown-items="addDropdownItems"
113-
>
114-
</TrackList>
129+
:reorder="collection?.canEdit"
130+
@reorder="handleReorder"
131+
/>
115132
</div>
116133
</template>

0 commit comments

Comments
 (0)