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

@@ -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>