-
Notifications
You must be signed in to change notification settings - Fork 8
/
TrackList.vue
115 lines (104 loc) · 2.96 KB
/
TrackList.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<script lang="ts" setup>
import { TrackModel } from "@bcc-code/bmm-sdk-fetch";
import { MediaPlaylistInjectionKey } from "~/plugins/3.mediaPlayer";
import { DropdownMenuItem } from "../DropdownMenu.vue";
const props = withDefaults(
defineProps<{
showSkeleton?: boolean;
skeletonCount?: number;
tracks: TrackModel[] | null;
}>(),
{
skeletonCount: 5,
}
);
const { setCurrentTrack, addTrackToQueue } = inject(MediaPlaylistInjectionKey)!;
const showDropDownForTrack: Ref<null | string> = ref(null);
const isTrackTypeKnown = () => {
const firstType = props.tracks?.[0]?.subtype;
return (
props.tracks?.every(
(track: TrackModel) =>
track.subtype === firstType ||
(track.subtype === "song" && firstType === "singsong") ||
(track.subtype === "singsong" && firstType === "song")
) || false
);
};
const toggleDropdownForTrack = (trackReference: string) => {
if (showDropDownForTrack.value === trackReference) {
showDropDownForTrack.value = null;
} else {
showDropDownForTrack.value = trackReference;
}
};
const dropdownMenuItemsForTrack = (track: TrackModel) => {
const items: DropdownMenuItem[] = [];
items.push({
icon: "icon.play",
text: "Play next",
clickFunction: () => setCurrentTrack(track),
});
if (track?.meta?.parent?.id) {
items.push({
icon: "icon.category.album",
text: "Go to album",
link: { name: "album-id", params: { id: track.meta.parent.id } },
});
}
items.push({
icon: "icon.queue",
text: "Add to Queue",
clickFunction: () => addTrackToQueue(track),
});
// TODO: add link
items.push({
icon: "icon.category.playlist",
text: "Add to Playlist",
});
items.push({
icon: "icon.share",
text: "Share track",
link: { name: "browse" }, // TODO: change link
});
items.push({
icon: "icon.person",
text: "Go to contributors",
link: { name: "browse" }, // TODO: change link
});
items.push({
icon: "icon.information",
text: "More information",
link: { name: "browse" }, // TODO: change link
});
return items;
};
</script>
<template>
<ol class="w-full divide-y divide-label-separator">
<template v-if="showSkeleton">
<li
v-for="skeleton in skeletonCount"
:key="skeleton"
class="my-6 h-11 w-full animate-pulse rounded-lg bg-background-2 dark:bg-background-dark-2"
></li>
</template>
<template v-else>
<TrackItem
v-for="(track, i) in tracks"
:key="track.id"
:track="track"
:is-track-type-known="isTrackTypeKnown()"
show-thumbnail
@play-track="setCurrentTrack(track)"
@open-options="toggleDropdownForTrack(`${track.id}-${i}`)"
>
<DropdownMenu
v-if="showDropDownForTrack === `${track.id}-${i}`"
:items="dropdownMenuItemsForTrack(track)"
@close="toggleDropdownForTrack(`${track.id}-${i}`)"
></DropdownMenu>
</TrackItem>
</template>
</ol>
</template>