Browse Source

refactor(EditPlaylist): Implemented custom draggable

Owen Diffey 2 years ago
parent
commit
9eb7dc3900
1 changed files with 28 additions and 37 deletions
  1. 28 37
      frontend/src/components/modals/EditPlaylist/index.vue

+ 28 - 37
frontend/src/components/modals/EditPlaylist/index.vue

@@ -6,7 +6,6 @@ import {
 	onMounted,
 	onBeforeUnmount
 } from "vue";
-import { Sortable } from "sortablejs-vue3";
 import Toast from "toasters";
 import { storeToRefs } from "pinia";
 import { useWebsocketsStore } from "@/stores/websockets";
@@ -29,6 +28,9 @@ const ImportPlaylists = defineAsyncComponent(
 const QuickConfirm = defineAsyncComponent(
 	() => import("@/components/QuickConfirm.vue")
 );
+const Draggable = defineAsyncComponent(
+	() => import("@/components/Draggable.vue")
+);
 
 const props = defineProps({
 	modalUuid: { type: String, default: "" }
@@ -72,13 +74,6 @@ const isEditable = () =>
 		playlist.value.type === "user-disliked") &&
 	(userId.value === playlist.value.createdBy || userRole.value === "admin");
 
-const dragOptions = computed(() => ({
-	animation: 200,
-	group: "songs",
-	disabled: !isEditable(),
-	ghostClass: "draggable-list-ghost"
-}));
-
 const init = () => {
 	gettingSongs.value = true;
 	socket.dispatch("playlists.getPlaylist", playlistId.value, res => {
@@ -94,10 +89,10 @@ const isAdmin = () => userRole.value === "admin";
 const isOwner = () =>
 	loggedIn.value && userId.value === playlist.value.createdBy;
 
-const repositionSong = ({ oldIndex, newIndex }) => {
+const repositionSong = ({ moved }) => {
+	const { oldIndex, newIndex } = moved;
 	if (oldIndex === newIndex) return; // we only need to update when song is moved
 	const song = playlistSongs.value[oldIndex];
-
 	socket.dispatch(
 		"playlists.repositionSong",
 		playlist.value._id,
@@ -117,21 +112,29 @@ const repositionSong = ({ oldIndex, newIndex }) => {
 	);
 };
 
-const moveSongToTop = (song, index) => {
+const moveSongToTop = index => {
 	songItems.value[`song-item-${index}`].$refs.songActions.tippy.hide();
-
+	playlistSongs.value.splice(0, 0, playlistSongs.value.splice(index, 1)[0]);
 	repositionSong({
-		oldIndex: index,
-		newIndex: 0
+		moved: {
+			oldIndex: index,
+			newIndex: 0
+		}
 	});
 };
 
-const moveSongToBottom = (song, index) => {
+const moveSongToBottom = index => {
 	songItems.value[`song-item-${index}`].$refs.songActions.tippy.hide();
-
+	playlistSongs.value.splice(
+		playlistSongs.value.length - 1,
+		0,
+		playlistSongs.value.splice(index, 1)[0]
+	);
 	repositionSong({
-		oldIndex: index,
-		newIndex: playlistSongs.value.length
+		moved: {
+			oldIndex: index,
+			newIndex: playlistSongs.value.length - 1
+		}
 	});
 };
 
@@ -404,25 +407,23 @@ onBeforeUnmount(() => {
 					</div>
 
 					<aside class="menu">
-						<sortable
+						<draggable
 							:component-data="{
 								name: !drag ? 'draggable-list-transition' : null
 							}"
 							v-if="playlistSongs.length > 0"
-							:list="playlistSongs"
+							:name="`edit-playlist-${modalUuid}`"
+							v-model:list="playlistSongs"
 							item-key="_id"
-							:options="dragOptions"
 							@start="drag = true"
 							@end="drag = false"
 							@update="repositionSong"
+							:disabled="!isEditable()"
 						>
 							<template #item="{ element, index }">
 								<div class="menu-list scrollable-list">
 									<song-item
 										:song="element"
-										:class="{
-											'item-draggable': isEditable()
-										}"
 										:ref="
 											el =>
 												(songItems[
@@ -479,12 +480,7 @@ onBeforeUnmount(() => {
 											<i
 												class="material-icons"
 												v-if="isEditable() && index > 0"
-												@click="
-													moveSongToTop(
-														element,
-														index
-													)
-												"
+												@click="moveSongToTop(index)"
 												content="Move to top of Playlist"
 												v-tippy
 												>vertical_align_top</i
@@ -495,12 +491,7 @@ onBeforeUnmount(() => {
 													playlistSongs.length - 1 !==
 														index
 												"
-												@click="
-													moveSongToBottom(
-														element,
-														index
-													)
-												"
+												@click="moveSongToBottom(index)"
 												class="material-icons"
 												content="Move to bottom of Playlist"
 												v-tippy
@@ -510,7 +501,7 @@ onBeforeUnmount(() => {
 									</song-item>
 								</div>
 							</template>
-						</sortable>
+						</draggable>
 						<p v-else-if="gettingSongs" class="nothing-here-text">
 							Loading songs...
 						</p>