Browse Source

feat: Add add to playlist dropdown component

Owen Diffey 2 weeks ago
parent
commit
5444fa007d
1 changed files with 92 additions and 0 deletions
  1. 92 0
      frontend/src/pages/NewStation/Components/AddToPlaylistDropdown.vue

+ 92 - 0
frontend/src/pages/NewStation/Components/AddToPlaylistDropdown.vue

@@ -0,0 +1,92 @@
+<script lang="ts" setup>
+import { defineAsyncComponent, ref } from "vue";
+import {
+	AddSongToPlaylistResponse,
+	RemoveSongFromPlaylistResponse
+} from "@musare_types/actions/PlaylistsActions";
+import Toast from "toasters";
+import { PlaylistModel } from "@musare_types/models/Playlist";
+import { storeToRefs } from "pinia";
+import { Song } from "@/types/song";
+import { useWebsocketsStore } from "@/stores/websockets";
+import { useUserPlaylistsStore } from "@/pages/NewStation/stores/userPlaylists";
+import { useModalsStore } from "@/stores/modals";
+import Checkbox from "@/pages/NewStation/Components/Checkbox.vue";
+import DropdownListItem from "@/pages/NewStation/Components/DropdownListItem.vue";
+
+const DropdownList = defineAsyncComponent(
+	() => import("@/pages/NewStation/Components/DropdownList.vue")
+);
+
+const props = defineProps<{
+	media: Song;
+}>();
+
+const { openModal } = useModalsStore();
+const userPlaylistsStore = useUserPlaylistsStore();
+const { playlists } = storeToRefs(userPlaylistsStore);
+const { socket } = useWebsocketsStore();
+
+const dropdown = ref();
+
+const existsInPlaylist = (playlist: PlaylistModel & { weight: number }) =>
+	!!playlist.songs.find(
+		media => media.mediaSource === props.media.mediaSource
+	);
+
+const addToPlaylist = (playlist: PlaylistModel & { weight: number }) => {
+	socket.dispatch(
+		"playlists.addSongToPlaylist",
+		false,
+		props.media.mediaSource,
+		playlist._id,
+		(res: AddSongToPlaylistResponse) => new Toast(res.message)
+	);
+};
+
+const removeFromPlaylist = (playlist: PlaylistModel & { weight: number }) => {
+	socket.dispatch(
+		"playlists.removeSongFromPlaylist",
+		props.media.mediaSource,
+		playlist._id,
+		(res: RemoveSongFromPlaylistResponse) => new Toast(res.message)
+	);
+};
+
+const toggleInPlaylist = (playlist: PlaylistModel & { weight: number }) => {
+	if (existsInPlaylist(playlist)) removeFromPlaylist(playlist);
+	else addToPlaylist(playlist);
+};
+
+const createPlaylist = () => {
+	dropdown.value.collapse();
+
+	openModal("createPlaylist");
+};
+</script>
+
+<template>
+	<DropdownList ref="dropdown">
+		<slot />
+
+		<template #options>
+			<DropdownListItem
+				icon="edit"
+				label="Create playlist"
+				@click="createPlaylist"
+			/>
+			<DropdownListItem
+				v-for="playlist in playlists"
+				:key="`playlist-${playlist._id}`"
+			>
+				<label class="dropdown-list-item__action">
+					<Checkbox
+						:model-value="existsInPlaylist(playlist)"
+						@click.prevent="() => toggleInPlaylist(playlist)"
+					/>
+					{{ playlist.displayName }}
+				</label>
+			</DropdownListItem>
+		</template>
+	</DropdownList>
+</template>