v2.0.0
This commit is contained in:
@@ -1,31 +1,31 @@
|
||||
<template>
|
||||
<div :class="$style.content">
|
||||
<canvas :class="$style.canvas" ref="dom_canvas"></canvas>
|
||||
<canvas ref="dom_canvas" :class="$style.canvas" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onBeforeUnmount, onMounted, useRefGetter, watch } from '@renderer/utils/vueTools'
|
||||
import { ref, onBeforeUnmount, onMounted } from '@common/utils/vueTools'
|
||||
import { getAnalyser } from '@renderer/plugins/player'
|
||||
import { isPlay } from '@renderer/core/share/player'
|
||||
import { player as eventPlayerNames } from '@renderer/event/names'
|
||||
import { isPlay } from '@renderer/store/player/state'
|
||||
// import { appSetting } from '@renderer/store/setting'
|
||||
|
||||
const themes = {
|
||||
green: 'rgba(77,175,124,.16)',
|
||||
blue: 'rgba(52,152,219,.16)',
|
||||
yellow: 'rgba(233,212,96,.22)',
|
||||
orange: 'rgba(245,171,53,.16)',
|
||||
red: 'rgba(214,69,65,.12)',
|
||||
pink: 'rgba(241,130,141,.16)',
|
||||
purple: 'rgba(155,89,182,.14)',
|
||||
grey: 'rgba(108,122,137,.16)',
|
||||
ming: 'rgba(51,110,123,.14)',
|
||||
blue2: 'rgba(79,98,208,.14)',
|
||||
black: 'rgba(39,39,39,.4)',
|
||||
mid_autumn: 'rgba(74,55,82,.1)',
|
||||
naruto: 'rgba(87,144,167,.15)',
|
||||
happy_new_year: 'rgba(192,57,43,.1)',
|
||||
}
|
||||
// const themes = {
|
||||
// green: 'rgba(77,175,124,.16)',
|
||||
// blue: 'rgba(52,152,219,.16)',
|
||||
// yellow: 'rgba(233,212,96,.22)',
|
||||
// orange: 'rgba(245,171,53,.16)',
|
||||
// red: 'rgba(214,69,65,.12)',
|
||||
// pink: 'rgba(241,130,141,.16)',
|
||||
// purple: 'rgba(155,89,182,.14)',
|
||||
// grey: 'rgba(108,122,137,.16)',
|
||||
// ming: 'rgba(51,110,123,.14)',
|
||||
// blue2: 'rgba(79,98,208,.14)',
|
||||
// black: 'rgba(39,39,39,.4)',
|
||||
// mid_autumn: 'rgba(74,55,82,.1)',
|
||||
// naruto: 'rgba(87,144,167,.15)',
|
||||
// happy_new_year: 'rgba(192,57,43,.1)',
|
||||
// }
|
||||
|
||||
const getBarWidth = canvasWidth => {
|
||||
let barWidth = (canvasWidth / 128) * 2.5
|
||||
@@ -60,18 +60,15 @@ export default {
|
||||
const maxNum = 255
|
||||
let frequencyAvg = 0
|
||||
|
||||
const theme = useRefGetter('theme')
|
||||
// const theme = useRefGetter('theme')
|
||||
// const setting = useRefGetter('setting')
|
||||
let themeColor = themes[theme.value || 'green']
|
||||
watch(theme, theme => {
|
||||
themeColor = themes[theme || 'green']
|
||||
})
|
||||
let themeColor = getComputedStyle(document.documentElement).getPropertyValue('--color-primary-light-200-alpha-800')
|
||||
// watch(theme, theme => {
|
||||
// themeColor = themes[theme || 'green']
|
||||
// })
|
||||
|
||||
// https://developer.mozilla.org/zh-CN/docs/Web/API/AnalyserNode/smoothingTimeConstant
|
||||
const renderFrame = () => {
|
||||
animationFrameId = null
|
||||
if (isPlaying) animationFrameId = window.requestAnimationFrame(renderFrame)
|
||||
|
||||
x = 0
|
||||
|
||||
analyser.getByteFrequencyData(dataArray)
|
||||
@@ -107,11 +104,14 @@ export default {
|
||||
|
||||
x += barWidth
|
||||
}
|
||||
|
||||
animationFrameId = null
|
||||
if (isPlaying) animationFrameId = window.requestAnimationFrame(renderFrame)
|
||||
}
|
||||
|
||||
const handlePlay = () => {
|
||||
isPlaying = true
|
||||
analyser.fftSize = 256
|
||||
// analyser.fftSize = 256
|
||||
bufferLength = analyser.frequencyBinCount
|
||||
// console.log(bufferLength)
|
||||
barWidth = getBarWidth(WIDTH)
|
||||
@@ -134,15 +134,15 @@ export default {
|
||||
barWidth = getBarWidth(WIDTH)
|
||||
}
|
||||
|
||||
window.eventHub.on(eventPlayerNames.play, handlePlay)
|
||||
window.eventHub.on(eventPlayerNames.pause, handlePause)
|
||||
window.eventHub.on(eventPlayerNames.error, handlePause)
|
||||
window.app_event.on('play', handlePlay)
|
||||
window.app_event.on('pause', handlePause)
|
||||
window.app_event.on('error', handlePause)
|
||||
window.addEventListener('resize', handleResize)
|
||||
onBeforeUnmount(() => {
|
||||
handlePause()
|
||||
window.eventHub.off(eventPlayerNames.play, handlePlay)
|
||||
window.eventHub.off(eventPlayerNames.pause, handlePause)
|
||||
window.eventHub.off(eventPlayerNames.error, handlePause)
|
||||
window.app_event.off('play', handlePlay)
|
||||
window.app_event.off('pause', handlePause)
|
||||
window.app_event.off('error', handlePause)
|
||||
window.removeEventListener('resize', handleResize)
|
||||
})
|
||||
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<template>
|
||||
<material-modal :show="show" :bg-close="bgClose" @close="handleClose" :teleport="teleport">
|
||||
<main :class="$style.main">
|
||||
<h2>{{ info.name }}<br/>{{ info.singer }}</h2>
|
||||
<base-btn :class="$style.btn" :key="type.type" @click="handleClick(type.type)" v-for="type in types"
|
||||
>{{getTypeName(type.type)}}{{ type.size && ` - ${type.size.toUpperCase()}` }}</base-btn>
|
||||
</main>
|
||||
</material-modal>
|
||||
<material-modal :show="show" :bg-close="bgClose" :teleport="teleport" @close="handleClose">
|
||||
<main :class="$style.main">
|
||||
<h2>{{ info.name }}<br>{{ info.singer }}</h2>
|
||||
<base-btn v-for="quality in qualitys" :key="quality.type" :class="$style.btn" @click="handleClick(quality.type)">
|
||||
{{ getTypeName(quality.type) }}{{ quality.size && ` - ${quality.size.toUpperCase()}` }}
|
||||
</base-btn>
|
||||
</main>
|
||||
</material-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions } from 'vuex'
|
||||
import { qualityList } from '@renderer/core/share'
|
||||
import { qualityList } from '@renderer/store'
|
||||
import { createDownloadTasks } from '@renderer/store/download/action'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@@ -19,13 +20,17 @@ export default {
|
||||
default: false,
|
||||
},
|
||||
musicInfo: {
|
||||
type: Object,
|
||||
type: [Object, null],
|
||||
required: true,
|
||||
},
|
||||
bgClose: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
teleport: String,
|
||||
teleport: {
|
||||
type: String,
|
||||
default: '#root',
|
||||
},
|
||||
},
|
||||
emits: ['update:show'],
|
||||
setup() {
|
||||
@@ -40,36 +45,35 @@ export default {
|
||||
sourceQualityList() {
|
||||
return this.qualityList[this.musicInfo.source] || []
|
||||
},
|
||||
types() {
|
||||
return this.info?.types?.filter(type => this.checkSource(type.type)) || []
|
||||
qualitys() {
|
||||
return this.info.meta?.qualitys?.filter(quality => this.checkSource(quality.type)) || []
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions('download', ['createDownload']),
|
||||
handleClick(type) {
|
||||
this.createDownload({ musicInfo: this.musicInfo, type })
|
||||
handleClick(quality) {
|
||||
createDownloadTasks([this.musicInfo], quality)
|
||||
this.handleClose()
|
||||
},
|
||||
handleClose() {
|
||||
this.$emit('update:show', false)
|
||||
},
|
||||
getTypeName(type) {
|
||||
switch (type) {
|
||||
case 'flac32bit':
|
||||
getTypeName(quality) {
|
||||
switch (quality) {
|
||||
case 'flac24bit':
|
||||
return this.$t('download__lossless') + ' FLAC Hires'
|
||||
case 'flac':
|
||||
case 'ape':
|
||||
case 'wav':
|
||||
return this.$t('download__lossless') + ' ' + type.toUpperCase()
|
||||
return this.$t('download__lossless') + ' ' + quality.toUpperCase()
|
||||
case '320k':
|
||||
return this.$t('download__high_quality') + ' ' + type.toUpperCase()
|
||||
return this.$t('download__high_quality') + ' ' + quality.toUpperCase()
|
||||
case '192k':
|
||||
case '128k':
|
||||
return this.$t('download__normal') + ' ' + type.toUpperCase()
|
||||
return this.$t('download__normal') + ' ' + quality.toUpperCase()
|
||||
}
|
||||
},
|
||||
checkSource(type) {
|
||||
return this.sourceQualityList.includes(type)
|
||||
checkSource(quality) {
|
||||
return this.sourceQualityList.includes(quality)
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -88,7 +92,7 @@ export default {
|
||||
justify-content: center;
|
||||
h2 {
|
||||
font-size: 13px;
|
||||
color: @color-theme_2-font;
|
||||
color: var(--color-font);
|
||||
line-height: 1.3;
|
||||
text-align: center;
|
||||
margin-bottom: 15px;
|
||||
@@ -103,14 +107,4 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
each(@themes, {
|
||||
:global(#root.@{value}) {
|
||||
.main {
|
||||
h2 {
|
||||
color: ~'@{color-@{value}-theme_2-font}';
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<template>
|
||||
<material-modal :show="show" :bg-close="bgClose" @close="handleClose" :teleport="teleport">
|
||||
<main :class="$style.main">
|
||||
<h2>{{$t('download__multiple_tip', { len: list.length })}}<br/>{{$t('download__multiple_tip2')}}</h2>
|
||||
<base-btn :class="$style.btn" @click="handleClick('128k')">{{$t('download__normal')}} - 128K</base-btn>
|
||||
<base-btn :class="$style.btn" @click="handleClick('320k')">{{$t('download__high_quality')}} - 320K</base-btn>
|
||||
<base-btn :class="$style.btn" @click="handleClick('flac')">{{$t('download__lossless')}} - FLAC</base-btn>
|
||||
<base-btn :class="$style.btn" @click="handleClick('flac32bit')">{{$t('download__lossless')}} - FLAC Hires</base-btn>
|
||||
</main>
|
||||
</material-modal>
|
||||
<material-modal :show="show" :bg-close="bgClose" :teleport="teleport" @close="handleClose">
|
||||
<main :class="$style.main">
|
||||
<h2>{{ $t('download__multiple_tip', { len: list.length }) }}<br>{{ $t('download__multiple_tip2') }}</h2>
|
||||
<base-btn :class="$style.btn" @click="handleClick('128k')">{{ $t('download__normal') }} - 128K</base-btn>
|
||||
<base-btn :class="$style.btn" @click="handleClick('320k')">{{ $t('download__high_quality') }} - 320K</base-btn>
|
||||
<base-btn :class="$style.btn" @click="handleClick('flac')">{{ $t('download__lossless') }} - FLAC</base-btn>
|
||||
<base-btn :class="$style.btn" @click="handleClick('flac24bit')">{{ $t('download__lossless') }} - FLAC Hires</base-btn>
|
||||
</main>
|
||||
</material-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions } from 'vuex'
|
||||
import { createDownloadTasks } from '@renderer/store/download/action'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@@ -29,13 +29,15 @@ export default {
|
||||
return []
|
||||
},
|
||||
},
|
||||
teleport: String,
|
||||
teleport: {
|
||||
type: String,
|
||||
default: '#root',
|
||||
},
|
||||
},
|
||||
emits: ['update:show', 'confirm'],
|
||||
methods: {
|
||||
...mapActions('download', ['createDownloadMultiple']),
|
||||
handleClick(type) {
|
||||
this.createDownloadMultiple({ list: [...this.list], type })
|
||||
handleClick(quality) {
|
||||
createDownloadTasks(this.list.filter(item => item.source != 'local'), quality)
|
||||
this.handleClose()
|
||||
this.$emit('confirm')
|
||||
},
|
||||
@@ -59,7 +61,7 @@ export default {
|
||||
justify-content: center;
|
||||
h2 {
|
||||
font-size: 13px;
|
||||
color: @color-theme_2-font;
|
||||
color: var(--color-font);
|
||||
line-height: 1.3;
|
||||
text-align: center;
|
||||
margin-bottom: 15px;
|
||||
@@ -74,14 +76,4 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
each(@themes, {
|
||||
:global(#root.@{value}) {
|
||||
.main {
|
||||
h2 {
|
||||
color: ~'@{color-@{value}-theme_2-font}';
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
<template>
|
||||
<material-modal :show="show" :bg-close="bgClose" @close="handleClose" :teleport="teleport" max-width="70%">
|
||||
<main :class="$style.main">
|
||||
<h2>{{$t('list_add__' + (isMove ? 'title_first_move' : 'title_first_add'))}} <span :class="$style.name">{{this.musicInfo && `${musicInfo.name}`}}</span> {{$t('list_add__title_last')}}</h2>
|
||||
<div class="scroll" :class="$style.btnContent">
|
||||
<base-btn :class="$style.btn" :aria-label="$t('list_add__btn_title', { name: item.name })" :key="item.id" :disabled="item.isExist" @click="handleClick(index)" v-for="(item, index) in lists">{{item.name}}</base-btn>
|
||||
<base-btn :class="[$style.btn, $style.newList, isEditing ? $style.editing : null]" @click="handleEditing($event)" :aria-label="$t('lists__new_list_btn')">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" viewBox="0 0 42 42" space="preserve">
|
||||
<use xlink:href="#icon-addTo"></use>
|
||||
</svg>
|
||||
<input :class="$style.newListInput" :value="newListName" type="text" :placeholder="$t('lists__new_list_input')" @keyup.enter="handleSaveList($event)" @blur="handleSaveList($event)"/>
|
||||
</base-btn>
|
||||
<span :class="$style.btn" :key="i" v-for="i in spaceNum"></span>
|
||||
</div>
|
||||
</main>
|
||||
</material-modal>
|
||||
<material-modal :show="show" :bg-close="bgClose" :teleport="teleport" max-width="70%" min-width="200px" @close="handleClose">
|
||||
<main :class="$style.main">
|
||||
<h2>{{ $t('list_add__' + (isMove ? 'title_first_move' : 'title_first_add')) }} <span :class="$style.name">{{ currentMusicInfo.name }}</span> {{ $t('list_add__title_last') }}</h2>
|
||||
<div class="scroll" :class="$style.btnContent">
|
||||
<base-btn v-for="(item, index) in lists" :key="item.id" :class="$style.btn" :aria-label="$t('list_add__btn_title', { name: item.name })" :disabled="item.isExist" @click="handleClick(index)">{{ item.name }}</base-btn>
|
||||
<base-btn :class="[$style.btn, $style.newList, isEditing ? $style.editing : null]" :aria-label="$t('lists__new_list_btn')" @click="handleEditing($event)">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" viewBox="0 0 42 42" space="preserve">
|
||||
<use xlink:href="#icon-addTo" />
|
||||
</svg>
|
||||
<input :class="$style.newListInput" :value="newListName" type="text" :placeholder="$t('lists__new_list_input')" @keyup.enter="handleSaveList($event)" @blur="handleSaveList($event)">
|
||||
</base-btn>
|
||||
<span v-for="i in spaceNum" :key="i" :class="$style.btn" />
|
||||
</div>
|
||||
</main>
|
||||
</material-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { computed } from '@renderer/utils/vueTools'
|
||||
import { defaultList, loveList, userLists } from '@renderer/core/share/list'
|
||||
import { getList } from '@renderer/core/share/utils'
|
||||
// import { mapMutations } from 'vuex'
|
||||
import { watch, ref } from '@common/utils/vueTools'
|
||||
import { defaultList, loveList, userLists } from '@renderer/store/list/state'
|
||||
import { addListMusics, moveListMusics, createUserList, getMusicExistListIds } from '@renderer/store/list/action'
|
||||
import useKeyDown from '@renderer/utils/compositions/useKeyDown'
|
||||
|
||||
export default {
|
||||
@@ -30,7 +30,8 @@ export default {
|
||||
default: false,
|
||||
},
|
||||
musicInfo: {
|
||||
type: Object,
|
||||
type: [Object, null],
|
||||
required: true,
|
||||
},
|
||||
bgClose: {
|
||||
type: Boolean,
|
||||
@@ -54,24 +55,48 @@ export default {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
teleport: String,
|
||||
teleport: {
|
||||
type: String,
|
||||
default: '#root',
|
||||
},
|
||||
},
|
||||
emits: ['update:show'],
|
||||
setup(props) {
|
||||
const keyModDown = useKeyDown('mod')
|
||||
const lists = ref([])
|
||||
|
||||
const lists = computed(() => {
|
||||
if (!props.musicInfo) return []
|
||||
const targetMid = props.musicInfo.songmid
|
||||
return [
|
||||
const currentMusicInfo = ref({})
|
||||
|
||||
const checkMusicExist = (musicInfo) => {
|
||||
const mid = musicInfo.id
|
||||
getMusicExistListIds(mid).then(ids => {
|
||||
if (mid != musicInfo.id) return
|
||||
for (const list of lists.value) {
|
||||
if (ids.includes(list.id)) list.isExist = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
watch(() => props.show, show => {
|
||||
if (!show) return
|
||||
if (!props.musicInfo) return lists.value = []
|
||||
|
||||
currentMusicInfo.value = 'progress' in props.musicInfo ? props.musicInfo.metadata.musicInfo : props.musicInfo
|
||||
|
||||
lists.value = [
|
||||
defaultList,
|
||||
loveList,
|
||||
...userLists,
|
||||
].filter(l => !props.excludeListId.includes(l.id)).map(l => ({ ...l, isExist: getList(l.id).some(s => s.songmid == targetMid) }))
|
||||
].filter(l => !props.excludeListId.includes(l.id)).map(l => ({ ...l, isExist: false }))
|
||||
|
||||
checkMusicExist(currentMusicInfo.value)
|
||||
})
|
||||
|
||||
return {
|
||||
keyModDown,
|
||||
lists,
|
||||
checkMusicExist,
|
||||
currentMusicInfo,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -94,7 +119,6 @@ export default {
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
},
|
||||
methods: {
|
||||
...mapMutations('list', ['listAdd', 'listMove', 'createUserList']),
|
||||
handleResize() {
|
||||
const width = window.innerWidth
|
||||
this.rowNum = width < 1920
|
||||
@@ -105,9 +129,10 @@ export default {
|
||||
},
|
||||
handleClick(index) {
|
||||
this.isMove
|
||||
? this.listMove({ fromId: this.fromListId, toId: this.lists[index].id, musicInfo: this.musicInfo })
|
||||
: this.listAdd({ id: this.lists[index].id, musicInfo: this.musicInfo })
|
||||
? moveListMusics(this.fromListId, this.lists[index].id, [this.currentMusicInfo])
|
||||
: addListMusics(this.lists[index].id, [this.currentMusicInfo])
|
||||
|
||||
this.lists[index].isExist = true
|
||||
if (this.keyModDown && !this.isMove) return
|
||||
this.$nextTick(() => {
|
||||
this.handleClose()
|
||||
@@ -127,7 +152,7 @@ export default {
|
||||
this.newListName = event.target.value = ''
|
||||
this.isEditing = false
|
||||
if (!name) return
|
||||
this.createUserList({ name })
|
||||
createUserList({ name })
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -140,7 +165,7 @@ export default {
|
||||
.main {
|
||||
// padding: 15px 0;
|
||||
// max-width: 70%;
|
||||
min-width: 200px;
|
||||
// min-width: 200px;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
@@ -149,7 +174,7 @@ export default {
|
||||
// overflow: hidden;
|
||||
h2 {
|
||||
font-size: 13px;
|
||||
color: @color-theme_2-font;
|
||||
color: var(--color-font);
|
||||
line-height: 1.3;
|
||||
text-align: center;
|
||||
padding: 15px;
|
||||
@@ -157,7 +182,7 @@ export default {
|
||||
}
|
||||
|
||||
.name {
|
||||
color: @color-theme;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.btn-content {
|
||||
@@ -184,9 +209,9 @@ export default {
|
||||
}
|
||||
|
||||
.newList {
|
||||
border: 1px dashed @color-theme-hover;
|
||||
background-color: @color-theme_2-background_2;
|
||||
color: @color-theme-hover;
|
||||
border: 1px dashed var(--color-primary-font-hover);
|
||||
// background-color: var(--color-main-background);
|
||||
color: var(--color-primary-font-hover);
|
||||
opacity: .7;
|
||||
|
||||
svg {
|
||||
@@ -243,22 +268,4 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
each(@themes, {
|
||||
:global(#root.@{value}) {
|
||||
.main {
|
||||
h2 {
|
||||
color: ~'@{color-@{value}-theme_2-font}';
|
||||
}
|
||||
}
|
||||
.name {
|
||||
color: ~'@{color-@{value}-theme}';
|
||||
}
|
||||
.newList {
|
||||
border-color: ~'@{color-@{value}-theme-hover}';
|
||||
color: ~'@{color-@{value}-theme-hover}';
|
||||
background-color: ~'@{color-@{value}-theme_2-background_2}';
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
<template>
|
||||
<material-modal :show="show" :bg-close="bgClose" @close="handleClose" max-width="70%">
|
||||
<main :class="$style.main">
|
||||
<h2>{{$t('list_add__multiple_' + (isMove ? 'title_move' : 'title_add'), { num: musicList.length })}}</h2>
|
||||
<div class="scroll" :class="$style.btnContent">
|
||||
<base-btn :class="$style.btn" :aria-label="$t('list_add__multiple_btn_title', { name: item.name })" :key="item.id" @click="handleClick(index)" v-for="(item, index) in lists">{{item.name}}</base-btn>
|
||||
<base-btn :class="[$style.btn, $style.newList, isEditing ? $style.editing : null]" @click="handleEditing($event)" :aria-label="$t('lists__new_list_btn')">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" viewBox="0 0 42 42" space="preserve">
|
||||
<use xlink:href="#icon-addTo"></use>
|
||||
</svg>
|
||||
<input :class="$style.newListInput" :value="newListName" type="text" :placeholder="$t('lists__new_list_input')" @keyup.enter="handleSaveList($event)" @blur="handleSaveList($event)"/>
|
||||
</base-btn>
|
||||
<span :class="$style.btn" :key="i" v-for="i in spaceNum"></span>
|
||||
</div>
|
||||
</main>
|
||||
</material-modal>
|
||||
<material-modal :show="show" :bg-close="bgClose" max-width="70%" :teleport="teleport" @close="handleClose">
|
||||
<main :class="$style.main">
|
||||
<h2>{{ $t('list_add__multiple_' + (isMove ? 'title_move' : 'title_add'), { num: musicList.length }) }}</h2>
|
||||
<div class="scroll" :class="$style.btnContent">
|
||||
<base-btn v-for="(item, index) in lists" :key="item.id" :class="$style.btn" :aria-label="$t('list_add__multiple_btn_title', { name: item.name })" @click="handleClick(index)">{{ item.name }}</base-btn>
|
||||
<base-btn :class="[$style.btn, $style.newList, isEditing ? $style.editing : null]" :aria-label="$t('lists__new_list_btn')" @click="handleEditing($event)">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" viewBox="0 0 42 42" space="preserve">
|
||||
<use xlink:href="#icon-addTo" />
|
||||
</svg>
|
||||
<input :class="$style.newListInput" :value="newListName" type="text" :placeholder="$t('lists__new_list_input')" @keyup.enter="handleSaveList($event)" @blur="handleSaveList($event)">
|
||||
</base-btn>
|
||||
<span v-for="i in spaceNum" :key="i" :class="$style.btn" />
|
||||
</div>
|
||||
</main>
|
||||
</material-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { computed } from '@renderer/utils/vueTools'
|
||||
import { defaultList, loveList, userLists } from '@renderer/core/share/list'
|
||||
import { computed } from '@common/utils/vueTools'
|
||||
import { defaultList, loveList, userLists } from '@renderer/store/list/state'
|
||||
import { addListMusics, moveListMusics, createUserList } from '@renderer/store/list/action'
|
||||
import useKeyDown from '@renderer/utils/compositions/useKeyDown'
|
||||
|
||||
export default {
|
||||
@@ -56,7 +56,10 @@ export default {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
teleport: String,
|
||||
teleport: {
|
||||
type: String,
|
||||
default: '#root',
|
||||
},
|
||||
},
|
||||
emits: ['update:show', 'confirm'],
|
||||
setup(props) {
|
||||
@@ -95,7 +98,6 @@ export default {
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
},
|
||||
methods: {
|
||||
...mapMutations('list', ['listAddMultiple', 'listMoveMultiple', 'createUserList']),
|
||||
handleResize() {
|
||||
const width = window.innerWidth
|
||||
this.rowNum = width < 1920
|
||||
@@ -105,9 +107,11 @@ export default {
|
||||
: width < 3840 ? 5 : 6
|
||||
},
|
||||
handleClick(index) {
|
||||
const list = 'progress' in this.musicList[0] ? this.musicList.map(t => t.metadata.musicInfo) : this.musicList
|
||||
|
||||
this.isMove
|
||||
? this.listMoveMultiple({ fromId: this.fromListId, toId: this.lists[index].id, list: this.musicList })
|
||||
: this.listAddMultiple({ id: this.lists[index].id, list: this.musicList })
|
||||
? moveListMusics(this.fromListId, this.lists[index].id, list)
|
||||
: addListMusics(this.lists[index].id, list)
|
||||
|
||||
if (this.keyModDown && !this.isMove) return
|
||||
this.$nextTick(() => {
|
||||
@@ -129,7 +133,7 @@ export default {
|
||||
this.newListName = event.target.value = ''
|
||||
this.isEditing = false
|
||||
if (!name) return
|
||||
this.createUserList({ name })
|
||||
createUserList({ name })
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -151,7 +155,7 @@ export default {
|
||||
// overflow: hidden;
|
||||
h2 {
|
||||
font-size: 13px;
|
||||
color: @color-theme_2-font;
|
||||
color: var(--color-font);
|
||||
line-height: 1.3;
|
||||
text-align: center;
|
||||
padding: 15px;
|
||||
@@ -182,9 +186,9 @@ export default {
|
||||
}
|
||||
|
||||
.newList {
|
||||
border: 1px dashed @color-theme-hover;
|
||||
background-color: @color-theme_2-background_2;
|
||||
color: @color-theme-hover;
|
||||
border: 1px dashed var(--color-primary-font-hover);
|
||||
// background-color: var(--color-main-background);
|
||||
color: var(--color-primary-font-hover);
|
||||
opacity: .7;
|
||||
|
||||
svg {
|
||||
@@ -241,20 +245,4 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
each(@themes, {
|
||||
:global(#root.@{value}) {
|
||||
.main {
|
||||
h2 {
|
||||
color: ~'@{color-@{value}-theme_2-font}';
|
||||
}
|
||||
}
|
||||
.newList {
|
||||
border-color: ~'@{color-@{value}-theme-hover}';
|
||||
color: ~'@{color-@{value}-theme-hover}';
|
||||
background-color: ~'@{color-@{value}-theme_2-background_2}';
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
<template>
|
||||
<div :class="[$style.progress, className]">
|
||||
<div :class="[$style.progressBar, $style.progressBar2, {[$style.barTransition]: isActiveTransition}]" @transitionend="handleTransitionEnd" :style="{ transform: `scaleX(${progress || 0})` }"></div>
|
||||
<div v-show="dragging" :class="[$style.progressBar, $style.progressBar3]" :style="{ transform: `scaleX(${dragProgress || 0})` }"></div>
|
||||
</div>
|
||||
<div :class="$style.progressMask" @mousedown="handleMsDown" ref="dom_progress"></div>
|
||||
<div :class="[$style.progress, className]">
|
||||
<div :class="[$style.progressBar, $style.progressBar2, {[$style.barTransition]: isActiveTransition}]" :style="{ transform: `scaleX(${progress || 0})` }" @transitionend="handleTransitionEnd" />
|
||||
<div v-show="dragging" :class="[$style.progressBar, $style.progressBar3]" :style="{ transform: `scaleX(${dragProgress || 0})` }" />
|
||||
</div>
|
||||
<div ref="dom_progress" :class="$style.progressMask" @mousedown="handleMsDown" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onBeforeUnmount } from '@renderer/utils/vueTools'
|
||||
import { player as eventPlayerNames } from '@renderer/event/names'
|
||||
import { playProgress } from '@renderer/core/share/playProgress'
|
||||
import { ref, onBeforeUnmount } from '@common/utils/vueTools'
|
||||
import { playProgress } from '@renderer/store/player/playProgress'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
className: String,
|
||||
className: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
progress: {
|
||||
type: Number,
|
||||
required: true,
|
||||
@@ -70,7 +72,7 @@ export default {
|
||||
})
|
||||
|
||||
const setProgress = num => {
|
||||
window.eventHub.emit(eventPlayerNames.setProgress, num)
|
||||
window.app_event.setProgress(num)
|
||||
}
|
||||
|
||||
// const handleSetProgress = event => {
|
||||
@@ -93,11 +95,11 @@ export default {
|
||||
|
||||
.progress {
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
height: 5px;
|
||||
// overflow: hidden;
|
||||
transition: @transition-theme;
|
||||
transition: @transition-normal;
|
||||
transition-property: background-color;
|
||||
background-color: @color-player-progress;
|
||||
background-color: var(--color-primary-light-100-alpha-800);
|
||||
// background-color: #f5f5f5;
|
||||
position: relative;
|
||||
border-radius: 20px;
|
||||
@@ -120,16 +122,16 @@ export default {
|
||||
border-radius: 20px;
|
||||
}
|
||||
.progress-bar1 {
|
||||
background-color: @color-player-progress-bar1;
|
||||
background-color: var(--color-primary-light-100-alpha-600);
|
||||
}
|
||||
|
||||
.progress-bar2 {
|
||||
background-color: @color-player-progress-bar2;
|
||||
background-color: var(--color-primary-light-100-alpha-400);
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.progress-bar3 {
|
||||
background-color: @color-player-progress-bar2;
|
||||
background-color: var(--color-primary-light-100-alpha-200);
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.3);
|
||||
opacity: 0.5;
|
||||
}
|
||||
@@ -140,20 +142,4 @@ export default {
|
||||
transition-duration: 0.2s;
|
||||
}
|
||||
|
||||
each(@themes, {
|
||||
:global(#root.@{value}) {
|
||||
.progress {
|
||||
background-color: ~'@{color-@{value}-player-progress}';
|
||||
}
|
||||
.progress-bar1 {
|
||||
background-color: ~'@{color-@{value}-player-progress-bar1}';
|
||||
}
|
||||
.progress-bar2 {
|
||||
background-color: ~'@{color-@{value}-player-progress-bar2}';
|
||||
}
|
||||
.progress-bar3 {
|
||||
background-color: ~'@{color-@{value}-player-progress-bar2}';
|
||||
}
|
||||
}
|
||||
})
|
||||
</style>
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
<template>
|
||||
<div :class="[$style.volumeContent, className]">
|
||||
<div :class="[$style.volume, {[$style.muted]: setting.player.isMute} ]">
|
||||
<div :class="$style.volumeBar" ref="dom_volumeBar" :style="{ transform: `scaleX(${volume || 0})` }"></div>
|
||||
<div :class="[$style.volumeContent, className]">
|
||||
<div :class="[$style.volume, {[$style.muted]: appSetting['player.isMute']} ]">
|
||||
<div ref="dom_volumeBar" :class="$style.volumeBar" :style="{ transform: `scaleX(${volume || 0})` }" />
|
||||
</div>
|
||||
<div :class="$style.volumeMask" :aria-label="`${$t('player__volume')}${parseInt(volume * 100)}%`" @mousedown="handleVolumeMsDown" />
|
||||
</div>
|
||||
<div :class="$style.volumeMask" @mousedown="handleVolumeMsDown" :aria-label="`${$t('player__volume')}${parseInt(volume * 100)}%`"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onBeforeUnmount } from '@renderer/utils/vueTools'
|
||||
import { ref, onBeforeUnmount } from '@common/utils/vueTools'
|
||||
// import { player as eventPlayerNames } from '@renderer/event/names'
|
||||
import { volume, isMute, setVolume, setMute } from '@renderer/core/share/volume'
|
||||
|
||||
import { volume, isMute } from '@renderer/store/player/volume'
|
||||
import { appSetting } from '@renderer/store/setting'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
className: {
|
||||
type: String,
|
||||
},
|
||||
setting: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
@@ -38,9 +37,9 @@ export default {
|
||||
if (val < 0) val = 0
|
||||
if (val > 1) val = 1
|
||||
|
||||
setVolume(volumeEvent.msDownVolume = val)
|
||||
window.app_event.setVolume(volumeEvent.msDownVolume = val)
|
||||
|
||||
if (isMute.value) setMute(false)
|
||||
if (isMute.value) window.app_event.setVolumeIsMute(false)
|
||||
}
|
||||
const handleVolumeMsUp = () => {
|
||||
volumeEvent.isMsDown = false
|
||||
@@ -50,7 +49,7 @@ export default {
|
||||
let volume = volumeEvent.msDownVolume + (event.clientX - volumeEvent.msDownX) / dom_volumeBar.value.clientWidth
|
||||
if (volume > 1) volume = 1
|
||||
else if (volume < 0) volume = 0
|
||||
setVolume(volume)
|
||||
window.app_event.setVolume(volume)
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', handleVolumeMsMove)
|
||||
@@ -65,6 +64,7 @@ export default {
|
||||
dom_volumeBar,
|
||||
volume,
|
||||
isMute,
|
||||
appSetting,
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -81,7 +81,7 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
opacity: .5;
|
||||
transition: opacity @transition-theme;
|
||||
transition: opacity @transition-normal;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -93,9 +93,9 @@ export default {
|
||||
height: 0.25em;
|
||||
border-radius: 10px;
|
||||
// overflow: hidden;
|
||||
transition: @transition-theme;
|
||||
transition: @transition-normal;
|
||||
transition-property: background-color, opacity;
|
||||
background-color: @color-player-progress-bar1;
|
||||
background-color: var(--color-button-background);
|
||||
// background-color: #f5f5f5;
|
||||
position: relative;
|
||||
border-radius: @radius-progress-border;
|
||||
@@ -117,7 +117,7 @@ export default {
|
||||
height: 100%;
|
||||
border-radius: @radius-progress-border;
|
||||
transition-duration: 0.2s;
|
||||
background-color: @color-btn;
|
||||
background-color: var(--color-button-background);
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
@@ -129,16 +129,4 @@ export default {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
each(@themes, {
|
||||
:global(#root.@{value}) {
|
||||
.volume {
|
||||
background-color: ~'@{color-@{value}-player-progress-bar1}';
|
||||
}
|
||||
|
||||
.volume-bar {
|
||||
background-color: ~'@{color-@{value}-btn}';
|
||||
}
|
||||
}
|
||||
})
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user