升级到 vue3
This commit is contained in:
@@ -0,0 +1,338 @@
|
||||
<template lang="pug">
|
||||
div(:class="$style.songList")
|
||||
transition(enter-active-class="animated-fast fadeIn" leave-active-class="animated-fast fadeOut")
|
||||
div(:class="$style.list")
|
||||
div.thead(:class="$style.thead")
|
||||
table
|
||||
thead
|
||||
tr
|
||||
th.nobreak.center(:class="$style.th" :style="{ width: rowWidth.r1 }") #
|
||||
th.nobreak(:class="$style.th" :style="{ width: rowWidth.r2 }") {{$t('music_name')}}
|
||||
th.nobreak(:class="$style.th" :style="{ width: rowWidth.r3 }") {{$t('music_singer')}}
|
||||
th.nobreak(:class="$style.th" :style="{ width: rowWidth.r4 }") {{$t('music_album')}}
|
||||
th.nobreak(:class="$style.th" :style="{ width: rowWidth.r5 }") {{$t('music_time')}}
|
||||
th.nobreak(:class="$style.th" :style="{ width: rowWidth.r6 }") {{$t('action')}}
|
||||
div(:class="$style.content")
|
||||
div(v-show="list.length" :class="$style.content" ref="dom_listContent")
|
||||
base-virtualized-list(:list="list" key-name="songmid" ref="listRef" :item-height="listItemHeight"
|
||||
containerClass="scroll" contentClass="list" @contextmenu.capture="handleListRightClick")
|
||||
template(#default="{ item, index }")
|
||||
div.list-item(@click="handleListItemClick($event, index)" @contextmenu="handleListItemRightClick($event, index)"
|
||||
:class="[{ selected: rightClickSelectedIndex == index }, { active: selectedList.includes(item) }]")
|
||||
div.list-item-cell.nobreak.center(:style="{ width: rowWidth.r1 }" style="padding-left: 3px; padding-right: 3px;" :class="$style.noSelect" @click.stop) {{index + 1}}
|
||||
div.list-item-cell.auto(:style="{ width: rowWidth.r2 }" :tips="item.name + ((item._types.ape || item._types.flac || item._types.wav) ? ` - ${$t('tag__lossless')}` : item._types['320k'] ? ` - ${$t('tag__high_quality')}` : '')")
|
||||
span.select {{item.name}}
|
||||
span.badge.badge-theme-success(:class="[$style.labelQuality, $style.noSelect]" v-if="item._types.ape || item._types.flac || item._types.wav") {{$t('tag__lossless')}}
|
||||
span.badge.badge-theme-info(:class="[$style.labelQuality, $style.noSelect]" v-else-if="item._types['320k']") {{$t('tag__high_quality')}}
|
||||
div.list-item-cell(:style="{ width: rowWidth.r3 }" :tips="item.singer")
|
||||
span.select {{item.singer}}
|
||||
div.list-item-cell(:style="{ width: rowWidth.r4 }" :tips="item.albumName")
|
||||
span.select {{item.albumName}}
|
||||
div.list-item-cell(:style="{ width: rowWidth.r5 }")
|
||||
span(:class="[$style.time, $style.noSelect]") {{item.interval || '--/--'}}
|
||||
div.list-item-cell(:style="{ width: rowWidth.r6 }" style="padding-left: 0; padding-right: 0;")
|
||||
material-list-buttons(:index="index" :class="$style.btns"
|
||||
:remove-btn="false" @btn-click="handleListBtnClick"
|
||||
:download-btn="assertApiSupport(item.source)")
|
||||
template(#footer)
|
||||
div(:class="$style.pagination")
|
||||
material-pagination(:count="total" :limit="limit" :page="page" @btn-click="$emit('togglePage', $event)")
|
||||
transition(enter-active-class="animated-fast fadeIn" leave-active-class="animated-fast fadeOut")
|
||||
div(v-show="!list.length" :class="$style.noitem")
|
||||
p(v-html="noItem")
|
||||
//- material-flow-btn(:show="isShowEditBtn && assertApiSupport(source)" :remove-btn="false" @btn-click="handleFlowBtnClick")
|
||||
teleport(to="#view")
|
||||
common-download-modal(v-model:show="isShowDownload" :musicInfo="selectedDownloadMusicInfo")
|
||||
common-download-multiple-modal(v-model:show="isShowDownloadMultiple" :list="selectedList" @confirm="removeAllSelect")
|
||||
common-list-add-modal(v-model:show="isShowListAdd" :musicInfo="selectedAddMusicInfo")
|
||||
common-list-add-multiple-modal(v-model:show="isShowListAddMultiple" :musicList="selectedList" @confirm="removeAllSelect")
|
||||
base-menu(:menus="menus" :location="menuLocation" item-name="name" :isShow="isShowItemMenu" @menu-click="handleMenuClick")
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { clipboardWriteText, assertApiSupport } from '@renderer/utils'
|
||||
import { ref, useCssModule } from '@renderer/utils/vueTools'
|
||||
import useList from './useList'
|
||||
import useMenu from './useMenu'
|
||||
import usePlay from './usePlay'
|
||||
import useMusicDownload from './useMusicDownload'
|
||||
import useMusicAdd from './useMusicAdd'
|
||||
import useMusicActions from './useMusicActions'
|
||||
export default {
|
||||
name: 'MaterialOnlineList',
|
||||
props: {
|
||||
list: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
},
|
||||
},
|
||||
page: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
rowWidth: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
r1: '5%',
|
||||
r2: 'auto',
|
||||
r3: '22%',
|
||||
r4: '22%',
|
||||
r5: '8%',
|
||||
r6: '13%',
|
||||
}
|
||||
},
|
||||
},
|
||||
noItem: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
emits: ['show-menu', 'togglePage'],
|
||||
setup(props, { emit }) {
|
||||
const rightClickSelectedIndex = ref(-1)
|
||||
const dom_listContent = ref(null)
|
||||
const listRef = ref(null)
|
||||
|
||||
const styles = useCssModule()
|
||||
|
||||
const {
|
||||
selectedList,
|
||||
listItemHeight,
|
||||
handleSelectData,
|
||||
removeAllSelect,
|
||||
} = useList({ props, emit })
|
||||
|
||||
const {
|
||||
handlePlayMusic,
|
||||
handlePlayMusicLater,
|
||||
doubleClickPlay,
|
||||
} = usePlay({ selectedList, props, removeAllSelect })
|
||||
|
||||
const {
|
||||
isShowListAdd,
|
||||
isShowListAddMultiple,
|
||||
selectedAddMusicInfo,
|
||||
handleShowMusicAddModal,
|
||||
} = useMusicAdd({ selectedList, props })
|
||||
|
||||
const {
|
||||
isShowDownload,
|
||||
isShowDownloadMultiple,
|
||||
selectedDownloadMusicInfo,
|
||||
handleShowDownloadModal,
|
||||
} = useMusicDownload({ selectedList, props })
|
||||
|
||||
const {
|
||||
handleSearch,
|
||||
handleOpenMusicDetail,
|
||||
} = useMusicActions({ props })
|
||||
|
||||
const {
|
||||
menus,
|
||||
menuLocation,
|
||||
isShowItemMenu,
|
||||
showMenu,
|
||||
hideMenu,
|
||||
menuClick,
|
||||
} = useMenu({
|
||||
listRef,
|
||||
assertApiSupport,
|
||||
emit,
|
||||
|
||||
handleShowDownloadModal,
|
||||
handlePlayMusic,
|
||||
handlePlayMusicLater,
|
||||
handleSearch,
|
||||
handleShowMusicAddModal,
|
||||
handleOpenMusicDetail,
|
||||
})
|
||||
|
||||
const handleListItemClick = (event, index) => {
|
||||
if (rightClickSelectedIndex.value > -1) return
|
||||
handleSelectData(index)
|
||||
doubleClickPlay(index)
|
||||
}
|
||||
const handleListItemRightClick = (event, index) => {
|
||||
rightClickSelectedIndex.value = index
|
||||
showMenu(event, props.list[index], index)
|
||||
}
|
||||
const handleMenuClick = (action) => {
|
||||
let index = rightClickSelectedIndex.value
|
||||
rightClickSelectedIndex.value = -1
|
||||
menuClick(action, index)
|
||||
}
|
||||
const handleListRightClick = (event) => {
|
||||
if (!event.target.classList.contains('select')) return
|
||||
event.stopImmediatePropagation()
|
||||
let classList = dom_listContent.value.classList
|
||||
classList.add(styles.copying)
|
||||
window.requestAnimationFrame(() => {
|
||||
let str = window.getSelection().toString()
|
||||
classList.remove(styles.copying)
|
||||
str = str.split(/\n\n/).map(s => s.replace(/\n/g, ' ')).join('\n').trim()
|
||||
if (!str.length) return
|
||||
clipboardWriteText(str)
|
||||
})
|
||||
}
|
||||
const handleListBtnClick = ({ action, index }) => {
|
||||
switch (action) {
|
||||
case 'download':
|
||||
handleShowDownloadModal(index, true)
|
||||
break
|
||||
case 'play':
|
||||
handlePlayMusic(index, true)
|
||||
break
|
||||
case 'search':
|
||||
handleSearch(index)
|
||||
break
|
||||
case 'listAdd':
|
||||
handleShowMusicAddModal(index, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
const scrollToTop = () => {
|
||||
listRef.value.scrollTo(0, true)
|
||||
}
|
||||
|
||||
return {
|
||||
listItemHeight,
|
||||
handleListItemClick,
|
||||
selectedList,
|
||||
handleListItemRightClick,
|
||||
removeAllSelect,
|
||||
handleListBtnClick,
|
||||
rightClickSelectedIndex,
|
||||
dom_listContent,
|
||||
listRef,
|
||||
|
||||
menus,
|
||||
isShowItemMenu,
|
||||
menuLocation,
|
||||
handleMenuClick,
|
||||
hideMenu,
|
||||
|
||||
handleListRightClick,
|
||||
assertApiSupport,
|
||||
|
||||
isShowListAdd,
|
||||
isShowListAddMultiple,
|
||||
selectedAddMusicInfo,
|
||||
|
||||
isShowDownload,
|
||||
isShowDownloadMultiple,
|
||||
selectedDownloadMusicInfo,
|
||||
|
||||
scrollToTop,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="less" module>
|
||||
@import '@renderer/assets/styles/layout.less';
|
||||
.song-list {
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.list {
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
height: 100%;
|
||||
}
|
||||
.thead {
|
||||
flex: none;
|
||||
}
|
||||
.th:first-child {
|
||||
color: @color-theme_2-font-label;
|
||||
// padding-left: 10px;
|
||||
}
|
||||
.content {
|
||||
flex: auto;
|
||||
min-height: 0;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
|
||||
&.copying {
|
||||
.no-select {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
:global(.list) {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
:global(.list-item-cell) {
|
||||
font-size: 12px !important;
|
||||
:global(.badge) {
|
||||
margin-left: 3px;
|
||||
}
|
||||
&:first-child {
|
||||
// padding-left: 10px;
|
||||
font-size: 11px !important;
|
||||
color: @color-theme_2-font-label !important;
|
||||
}
|
||||
}
|
||||
:global(.badge) {
|
||||
opacity: .85;
|
||||
}
|
||||
}
|
||||
.pagination {
|
||||
text-align: center;
|
||||
padding: 15px 0;
|
||||
// left: 50%;
|
||||
// transform: translateX(-50%);
|
||||
}
|
||||
.noitem {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
p {
|
||||
font-size: 24px;
|
||||
color: @color-theme_2-font-label;
|
||||
}
|
||||
}
|
||||
|
||||
each(@themes, {
|
||||
:global(#root.@{value}) {
|
||||
.th:first-child {
|
||||
color: ~'@{color-@{value}-theme_2-font-label}';
|
||||
}
|
||||
:global(.list) {
|
||||
:global(.list-item-cell) {
|
||||
&:first-child {
|
||||
color: ~'@{color-@{value}-theme_2-font-label}' !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.noitem {
|
||||
p {
|
||||
color: ~'@{color-@{value}-theme_2-font-label}';
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</style>
|
||||
@@ -0,0 +1,105 @@
|
||||
import { computed, useRefGetter, watch, ref, onBeforeUnmount } from '@renderer/utils/vueTools'
|
||||
import { windowSizeList } from '@common/config'
|
||||
|
||||
const useKeyEvent = ({ handleSelectAllData }) => {
|
||||
const keyEvent = {
|
||||
isShiftDown: false,
|
||||
isModDown: false,
|
||||
}
|
||||
|
||||
const handle_key_shift_down = () => {
|
||||
if (!keyEvent.isShiftDown) keyEvent.isShiftDown = true
|
||||
}
|
||||
const handle_key_shift_up = () => {
|
||||
if (keyEvent.isShiftDown) keyEvent.isShiftDown = false
|
||||
}
|
||||
const handle_key_mod_down = () => {
|
||||
if (!keyEvent.isModDown) keyEvent.isModDown = true
|
||||
}
|
||||
const handle_key_mod_up = () => {
|
||||
if (keyEvent.isModDown) keyEvent.isModDown = false
|
||||
}
|
||||
const handle_key_mod_a_down = ({ event }) => {
|
||||
if (event.target.tagName == 'INPUT') return
|
||||
event.preventDefault()
|
||||
if (event.repeat) return
|
||||
keyEvent.isModDown = false
|
||||
handleSelectAllData()
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.eventHub.off('key_shift_down', handle_key_shift_down)
|
||||
window.eventHub.off('key_shift_up', handle_key_shift_up)
|
||||
window.eventHub.off('key_mod_down', handle_key_mod_down)
|
||||
window.eventHub.off('key_mod_up', handle_key_mod_up)
|
||||
window.eventHub.off('key_mod+a_down', handle_key_mod_a_down)
|
||||
})
|
||||
window.eventHub.on('key_shift_down', handle_key_shift_down)
|
||||
window.eventHub.on('key_shift_up', handle_key_shift_up)
|
||||
window.eventHub.on('key_mod_down', handle_key_mod_down)
|
||||
window.eventHub.on('key_mod_up', handle_key_mod_up)
|
||||
window.eventHub.on('key_mod+a_down', handle_key_mod_a_down)
|
||||
|
||||
return keyEvent
|
||||
}
|
||||
|
||||
|
||||
export default ({ props }) => {
|
||||
const selectedList = ref([])
|
||||
const setting = useRefGetter('setting')
|
||||
let lastSelectIndex = -1
|
||||
const listItemHeight = computed(() => {
|
||||
return parseInt(windowSizeList.find(item => item.id == setting.value.windowSizeId).fontSize) / 16 * 37
|
||||
})
|
||||
|
||||
const removeAllSelect = () => {
|
||||
selectedList.value = []
|
||||
}
|
||||
const handleSelectAllData = () => {
|
||||
removeAllSelect()
|
||||
selectedList.value = [...props.list]
|
||||
}
|
||||
const keyEvent = useKeyEvent({ handleSelectAllData })
|
||||
|
||||
const handleSelectData = clickIndex => {
|
||||
if (keyEvent.isShiftDown) {
|
||||
if (selectedList.value.length) {
|
||||
removeAllSelect()
|
||||
if (lastSelectIndex != clickIndex) {
|
||||
let isNeedReverse = false
|
||||
if (clickIndex < lastSelectIndex) {
|
||||
let temp = lastSelectIndex
|
||||
lastSelectIndex = clickIndex
|
||||
clickIndex = temp
|
||||
isNeedReverse = true
|
||||
}
|
||||
selectedList.value = props.list.slice(lastSelectIndex, clickIndex + 1)
|
||||
if (isNeedReverse) selectedList.value.reverse()
|
||||
}
|
||||
} else {
|
||||
selectedList.value.push(props.list[clickIndex])
|
||||
lastSelectIndex = clickIndex
|
||||
}
|
||||
} else if (keyEvent.isModDown) {
|
||||
lastSelectIndex = clickIndex
|
||||
let item = props.list[clickIndex]
|
||||
let index = selectedList.value.indexOf(item)
|
||||
if (index < 0) {
|
||||
selectedList.value.push(item)
|
||||
} else {
|
||||
selectedList.value.splice(index, 1)
|
||||
}
|
||||
} else if (selectedList.value.length) {
|
||||
removeAllSelect()
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => props.list, removeAllSelect)
|
||||
|
||||
return {
|
||||
selectedList,
|
||||
listItemHeight,
|
||||
removeAllSelect,
|
||||
handleSelectData,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
import { computed, ref, useI18n, useCssModule, nextTick } from '@renderer/utils/vueTools'
|
||||
import musicSdk from '@renderer/utils/music'
|
||||
|
||||
export default ({
|
||||
listRef,
|
||||
assertApiSupport,
|
||||
emit,
|
||||
|
||||
handleShowDownloadModal,
|
||||
handlePlayMusic,
|
||||
handlePlayMusicLater,
|
||||
handleSearch,
|
||||
handleShowMusicAddModal,
|
||||
handleOpenMusicDetail,
|
||||
}) => {
|
||||
const itemMenuControl = ref({
|
||||
play: true,
|
||||
addTo: true,
|
||||
playLater: true,
|
||||
download: true,
|
||||
search: true,
|
||||
sourceDetail: true,
|
||||
})
|
||||
const { t } = useI18n()
|
||||
const styles = useCssModule()
|
||||
const menuLocation = ref({ x: 0, y: 0 })
|
||||
const isShowItemMenu = ref(false)
|
||||
|
||||
const menus = computed(() => {
|
||||
return [
|
||||
{
|
||||
name: t('list__play'),
|
||||
action: 'play',
|
||||
disabled: !itemMenuControl.value.play,
|
||||
},
|
||||
{
|
||||
name: t('list__download'),
|
||||
action: 'download',
|
||||
disabled: !itemMenuControl.value.download,
|
||||
},
|
||||
{
|
||||
name: t('list__play_later'),
|
||||
action: 'playLater',
|
||||
disabled: !itemMenuControl.value.playLater,
|
||||
},
|
||||
{
|
||||
name: t('list__search'),
|
||||
action: 'search',
|
||||
disabled: !itemMenuControl.value.search,
|
||||
},
|
||||
{
|
||||
name: t('list__add_to'),
|
||||
action: 'addTo',
|
||||
disabled: !itemMenuControl.value.addTo,
|
||||
},
|
||||
{
|
||||
name: t('list__source_detail'),
|
||||
action: 'sourceDetail',
|
||||
disabled: !itemMenuControl.value.sourceDetail,
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
const showMenu = (event, musicInfo) => {
|
||||
itemMenuControl.value.sourceDetail = !!musicSdk[musicInfo.source].getMusicDetailPageUrl
|
||||
// this.listMenu.itemMenuControl.play =
|
||||
// this.listMenu.itemMenuControl.playLater =
|
||||
itemMenuControl.download = assertApiSupport(musicInfo.source)
|
||||
let dom_container = event.target.closest('.' + styles.songList)
|
||||
const getOffsetValue = (target, x = 0, y = 0) => {
|
||||
if (target === dom_container) return { x, y }
|
||||
if (!target) return { x: 0, y: 0 }
|
||||
x += target.offsetLeft
|
||||
y += target.offsetTop
|
||||
return getOffsetValue(target.offsetParent, x, y)
|
||||
}
|
||||
let { x, y } = getOffsetValue(event.target)
|
||||
menuLocation.value.x = x + event.offsetX
|
||||
menuLocation.value.y = y + event.offsetY - listRef.value.getScrollTop()
|
||||
emit('show-menu')
|
||||
nextTick(() => {
|
||||
isShowItemMenu.value = true
|
||||
})
|
||||
}
|
||||
|
||||
const hideMenu = () => {
|
||||
isShowItemMenu.value = false
|
||||
}
|
||||
|
||||
const menuClick = (action, index) => {
|
||||
// console.log(action)
|
||||
hideMenu()
|
||||
if (!action) return
|
||||
|
||||
switch (action.action) {
|
||||
case 'download':
|
||||
handleShowDownloadModal(index)
|
||||
break
|
||||
case 'play':
|
||||
handlePlayMusic(index)
|
||||
break
|
||||
case 'playLater':
|
||||
handlePlayMusicLater(index)
|
||||
break
|
||||
case 'search':
|
||||
handleSearch(index)
|
||||
break
|
||||
case 'addTo':
|
||||
handleShowMusicAddModal(index)
|
||||
break
|
||||
case 'sourceDetail':
|
||||
handleOpenMusicDetail(index)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
menus,
|
||||
menuLocation,
|
||||
isShowItemMenu,
|
||||
showMenu,
|
||||
menuClick,
|
||||
hideMenu,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { useRouter } from '@renderer/utils/vueTools'
|
||||
import musicSdk from '@renderer/utils/music'
|
||||
import { openUrl } from '@renderer/utils'
|
||||
|
||||
|
||||
export default ({ props }) => {
|
||||
const router = useRouter()
|
||||
|
||||
const handleSearch = index => {
|
||||
const info = props.list[index]
|
||||
router.push({
|
||||
path: 'search',
|
||||
query: {
|
||||
text: `${info.name} ${info.singer}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const handleOpenMusicDetail = index => {
|
||||
const minfo = props.list[index]
|
||||
const url = musicSdk[minfo.source].getMusicDetailPageUrl(minfo)
|
||||
if (!url) return
|
||||
openUrl(url)
|
||||
}
|
||||
|
||||
return {
|
||||
handleSearch,
|
||||
handleOpenMusicDetail,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ref, nextTick } from '@renderer/utils/vueTools'
|
||||
|
||||
export default ({ selectedList, props }) => {
|
||||
const isShowListAdd = ref(false)
|
||||
const isShowListAddMultiple = ref(false)
|
||||
const selectedAddMusicInfo = ref(null)
|
||||
|
||||
const handleShowMusicAddModal = (index, single) => {
|
||||
if (selectedList.value.length && !single) {
|
||||
isShowListAddMultiple.value = true
|
||||
} else {
|
||||
selectedAddMusicInfo.value = props.list[index]
|
||||
nextTick(() => {
|
||||
isShowListAdd.value = true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isShowListAdd,
|
||||
isShowListAddMultiple,
|
||||
selectedAddMusicInfo,
|
||||
handleShowMusicAddModal,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ref, nextTick } from '@renderer/utils/vueTools'
|
||||
|
||||
export default ({ selectedList, props }) => {
|
||||
const isShowDownload = ref(false)
|
||||
const isShowDownloadMultiple = ref(false)
|
||||
const musicInfo = ref(null)
|
||||
|
||||
const handleShowDownloadModal = (index, single) => {
|
||||
if (selectedList.value.length && !single) {
|
||||
isShowDownloadMultiple.value = true
|
||||
} else {
|
||||
musicInfo.value = props.list[index]
|
||||
nextTick(() => {
|
||||
isShowDownload.value = true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isShowDownload,
|
||||
isShowDownloadMultiple,
|
||||
selectedDownloadMusicInfo: musicInfo,
|
||||
handleShowDownloadModal,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import { useCommit } from '@renderer/utils/vueTools'
|
||||
import { defaultList } from '@renderer/core/share/list'
|
||||
import { getList } from '@renderer/core/share/utils'
|
||||
|
||||
export default ({ selectedList, props, removeAllSelect }) => {
|
||||
let clickTime = 0
|
||||
let clickIndex = -1
|
||||
|
||||
const listAddMultiple = useCommit('list', 'listAddMultiple')
|
||||
const listAdd = useCommit('list', 'listAdd')
|
||||
const setList = useCommit('player', 'setList')
|
||||
const setTempPlayList = useCommit('player', 'setTempPlayList')
|
||||
|
||||
const handlePlayMusic = (index, single) => {
|
||||
let targetSong = props.list[index]
|
||||
const defaultListMusics = getList(defaultList.id)
|
||||
if (selectedList.value.length && !single) {
|
||||
listAddMultiple({ id: defaultList.id, list: [...selectedList.value] })
|
||||
removeAllSelect()
|
||||
} else {
|
||||
listAdd({ id: defaultList.id, musicInfo: targetSong })
|
||||
}
|
||||
let targetIndex = defaultListMusics.findIndex(s => s.songmid === targetSong.songmid)
|
||||
if (targetIndex > -1) {
|
||||
setList({
|
||||
listId: defaultList.id,
|
||||
index: targetIndex,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handlePlayMusicLater = (index, single) => {
|
||||
if (selectedList.length && !single) {
|
||||
setTempPlayList(selectedList.value.map(s => ({ listId: '__temp__', musicInfo: s })))
|
||||
removeAllSelect()
|
||||
} else {
|
||||
setTempPlayList([{ listId: '__temp__', musicInfo: props.list[index] }])
|
||||
}
|
||||
}
|
||||
|
||||
const doubleClickPlay = index => {
|
||||
if (
|
||||
window.performance.now() - clickTime > 400 ||
|
||||
clickIndex !== index
|
||||
) {
|
||||
clickTime = window.performance.now()
|
||||
clickIndex = index
|
||||
return
|
||||
}
|
||||
handlePlayMusic(index, true)
|
||||
clickTime = 0
|
||||
clickIndex = -1
|
||||
}
|
||||
|
||||
return {
|
||||
handlePlayMusic,
|
||||
handlePlayMusicLater,
|
||||
doubleClickPlay,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user