feat: 歌单支持拖动排序

This commit is contained in:
539943419 committed 2024-09-27 15:03:43 +08:00
1 parent 38e1b098d2
commit 55381df4f6
8 files changed
+117 -29

No files matched your search

+4 -4
View File
@@ -135,9 +135,9 @@ provide('rootDirectory', rootDirectory)
: view.title
}}
</span>
<div class="tab-point" :style="{ backgroundColor: view.color }"></div>
<div class="tab-control">
<n-icon class="tag-control-icon icon" @click="view.switchShow()" v-if="view.allowCopy">
<div class="tab-point" :style="{ backgroundColor: view.color }"></div>
<n-icon class="tag-control-icon icon" @click="view.switchShow()">
<EyeOutline v-show="view.visible" class="icon-inner" />
<EyeOffOutline v-show="!view.visible" class="icon-inner" />
</n-icon>
@@ -148,7 +148,7 @@ provide('rootDirectory', rootDirectory)
view.currentFiles,
index + 1
)
">
" v-if="view.allowCopy">
<CopyOutline />
</n-icon>
<n-icon class="tag-control-icon icon" @click="deleteView(index)">
@@ -241,7 +241,7 @@ $tag-width: 170px;
height: 5px;
aspect-ratio: 1;
border-radius: 66px;
margin-left: 5px;
margin-right: 5px;
}
.tab-control {
+18
View File
@@ -12,6 +12,13 @@ import VirtualDirectory, { VirtualFile } from '@/class/VirtualDirectory'
import config from '@/config'
import useDataBus from '@/hooks/useDataBus'
const props = defineProps({
disable: {
type: Boolean,
default: false
}
})
const dataBus = useDataBus()
const { uploadSizeLimit } = config
@@ -57,8 +64,16 @@ const removeDirectory = async (files: File[]) => {
}
}
}
const check = (event: DragEvent) => [
...(event.dataTransfer?.files ?? []),
...(dataBus.get('dragData_vFiles') ?? []),
...(dataBus.get('dragData_vDirectory') ?? [])
].length !== 0
const handleDragOver = async (event: DragEvent) => {
if (props.disable || check(event) === false) {
return
}
event.preventDefault()
if (showMask.value === 1) {
return
@@ -71,6 +86,9 @@ const handleDragLeave = async () => {
}
const handleDrop = async (event: DragEvent) => {
if (props.disable || check(event) === false) {
return
}
showMask.value = 0
event.preventDefault()
event.stopPropagation()
+4
View File
@@ -17,6 +17,10 @@ export default function useDataBus() {
const value = dataStorage[key];
dataStorage[key] = undefined;
return value;
},
get(key: string | number) {
const value = dataStorage[key];
return value;
}
};
}
@@ -2,10 +2,15 @@ import { createApp, Reactive } from "vue";
import aplayerListNew from "../src/aplayerListNew.vue";
import apType from "../types/ap";
type aplayerMiaoOption = {
onDragItemStart?: () => void,
onDragItemEnd?: () => void,
}
/**
* 对aplayer进行一些自定义的风格优化
*/
const useAplayerMiao = (ap: Reactive<apType>) => {
const useAplayerMiao = (ap: Reactive<apType>, options?: aplayerMiaoOption) => {
const container = ap.container as HTMLDivElement;
// 隐藏旧版歌单
@@ -30,7 +35,7 @@ const useAplayerMiao = (ap: Reactive<apType>) => {
});
container.appendChild(new_list_dom);
const app = createApp(aplayerListNew, { ap });
const app = createApp(aplayerListNew, { ap, ...(options ?? {}) });
app.mount(new_list_dom);
ap.on("destroy", () => {
@@ -45,6 +45,8 @@ const handleDropVFiles = (files: VirtualFile[]) => {
const aplayer = ref<any>(null);
const disableDropReceiver = ref(false)
let ap: apType
let vueApp: any
@@ -59,7 +61,14 @@ onMounted(() => {
theme: "#60e8a2"
}
ap = reactive<apType>(new APlayer(aplayerOption))
vueApp = useAplayerMiao(ap)
vueApp = useAplayerMiao(ap, {
onDragItemStart: () => {
disableDropReceiver.value = true
},
onDragItemEnd: () => {
disableDropReceiver.value = false
},
})
ap.on('listremove', (...args: any) => {
const {index} = args[0] as {index: number}
const _name = ap.list.audios[index].name
@@ -1,33 +1,43 @@
<template>
<ol :style="{ maxHeight: ap.options.listMaxHeight }" :key="refreshKey">
<li v-for="(audio, index) in ap.list.audios" :class="activeAudioIndex == index ? 'aplayer-list-light' : ''"
class="aplayer-list-new" @click="switchAudio(index)" :key="audio.id">
<span class="aplayer-list-cur" :style="{ backgroundColor: apTheme }"></span>
<span class="aplayer-list-index">{{ index + 1 }}</span>
<span class="aplayer-list-title">{{ audio.name }}</span>
<span class="aplayer-list-author" v-show="audio.artist">{{ audio.artist }}</span>
<div class="aplayer-list-control">
<div class="aplayer-list-control-btn" @click.stop="listAudioUp(index)">
<ChevronUpOutline class="aplayer-list-control-btn-svg" />
</div>
<div class="aplayer-list-control-btn" @click.stop="listAudioDown(index)">
<ChevronDownOutline class="aplayer-list-control-btn-svg" />
</div>
<div class="aplayer-list-control-btn" @click.stop="listAudioRemove(index)">
<CloseOutline class="aplayer-list-control-btn-svg" />
</div>
</div>
</li>
<ol :style="{ maxHeight: ap.options.listMaxHeight }" :key="refreshKey" >
<VueDraggable v-model="ap.list.audios" @start="onDragStart" @end="onDragEnd" item-key="id" handle=".aplayer-list-control-btn-reorder">
<!-- <template #item="{ element, index }"> -->
<li v-for="(element, index) in ap.list.audios" :class="activeAudioIndex == index ? 'aplayer-list-light' : ''"
class="aplayer-list-new" @click="switchAudio(index)" :key="element.id">
<span class="aplayer-list-cur" :style="{ backgroundColor: apTheme }"></span>
<span class="aplayer-list-index">{{ index + 1 }}</span>
<span class="aplayer-list-title">{{ element.name }}</span>
<span class="aplayer-list-author" v-show="element.artist">{{ element.artist }}</span>
<div class="aplayer-list-control">
<div class="aplayer-list-control-btn" @click.stop="listAudioUp(index)" v-if="false">
<ChevronUpOutline class="aplayer-list-control-btn-svg" />
</div>
<div class="aplayer-list-control-btn" @click.stop="listAudioDown(index)" v-if="false">
<ChevronDownOutline class="aplayer-list-control-btn-svg" />
</div>
<div class="aplayer-list-control-btn" @click.stop="listAudioRemove(index)">
<CloseOutline class="aplayer-list-control-btn-svg" />
</div>
<div class="aplayer-list-control-btn aplayer-list-control-btn-reorder">
<ReorderFourOutline class="aplayer-list-control-btn-svg" />
</div>
</div>
</li>
<!-- </template> -->
</VueDraggable>
</ol>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { ChevronUpOutline, ChevronDownOutline, CloseOutline } from '@vicons/ionicons5';
import { ChevronUpOutline, ChevronDownOutline, CloseOutline, ReorderFourOutline } from '@vicons/ionicons5';
import { VueDraggable } from 'vue-draggable-plus'
import apType, { audioType } from '../types/ap';
const props = defineProps<{
ap: apType
onDragItemStart: () => void,
onDragItemEnd: () => void
}>()
const refreshKey = ref(Math.random())
@@ -97,7 +107,21 @@ const listAudioDown = (index: number) => {
const listAudioRemove = (index: number) => {
props.ap.list.remove(index)
}
const {onDragStart, onDragEnd} = (() => {
let curr: audioType
return {
onDragStart: () => {
curr = props.ap.list.audios[props.ap.list.index]
},
onDragEnd: () => {
listRefreshIndex(curr)
}
}
})()
// const onDragEnd = (_e: any) => {
// const curr = props.ap.list.audios[props.ap.list.index]
// listRefreshIndex(curr)
// }
onMounted(() => {
console.log(props.ap)
@@ -105,6 +129,12 @@ onMounted(() => {
</script>
<style lang="scss" scoped>
.aplayer-list-new {
height: fit-content !important;
.aplayer-list-cur {
height: calc( 100% - 8px ) !important;
}
}
.aplayer-list-control {
float: right;
height: 32px;
@@ -136,4 +166,4 @@ onMounted(() => {
.aplayer .aplayer-list-new svg path {
fill: #ffffff00;
}
</style>
</style>