更新歌曲播放栏布局
parent
2003c5a0c9
commit
716120ea61
|
@ -222,6 +222,8 @@
|
|||
"player__refresh_url": "Music URL expired, refreshing...",
|
||||
"player__stop": "Paused",
|
||||
"player__volume": "Volume: ",
|
||||
"player__volume_mute_label": "Mute",
|
||||
"player__volume_muted": "muted",
|
||||
"search": "Search",
|
||||
"search__hot_search": "Top Searches",
|
||||
"search__type_music": "Song",
|
||||
|
|
|
@ -222,6 +222,8 @@
|
|||
"player__refresh_url": "URL过期,正在刷新URL...",
|
||||
"player__stop": "暂停播放",
|
||||
"player__volume": "当前音量:",
|
||||
"player__volume_mute_label": "静音",
|
||||
"player__volume_muted": "已静音",
|
||||
"search": "搜索",
|
||||
"search__hot_search": "热门搜索",
|
||||
"search__type_music": "歌曲",
|
||||
|
|
|
@ -222,6 +222,8 @@
|
|||
"player__refresh_url": "URL過期,正在刷新URL...",
|
||||
"player__stop": "暫停播放",
|
||||
"player__volume": "當前音量:",
|
||||
"player__volume_mute_label": "靜音",
|
||||
"player__volume_muted": "已靜音",
|
||||
"search": "搜索",
|
||||
"search__hot_search": "熱門搜索",
|
||||
"search__type_music": "歌曲",
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><title>Volume High</title><path d="M126 192H56a8 8 0 00-8 8v112a8 8 0 008 8h69.65a15.93 15.93 0 0110.14 3.54l91.47 74.89A8 8 0 00240 392V120a8 8 0 00-12.74-6.43l-91.47 74.89A15 15 0 01126 192zM320 320c9.74-19.38 16-40.84 16-64 0-23.48-6-44.42-16-64M368 368c19.48-33.92 32-64.06 32-112s-12-77.74-32-112M416 416c30-46 48-91.43 48-160s-18-113-48-160" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/></svg>
|
After Width: | Height: | Size: 532 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><title>Volume Low</title><path d="M189.65 192H120a8 8 0 00-8 8v112a8 8 0 008 8h69.65a16 16 0 0110.14 3.63l91.47 75a8 8 0 0012.74-6.46V119.83a8 8 0 00-12.74-6.44l-91.47 75a16 16 0 01-10.14 3.61zM384 320c9.74-19.41 16-40.81 16-64 0-23.51-6-44.4-16-64" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/></svg>
|
After Width: | Height: | Size: 434 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><title>Volume Medium</title><path d="M157.65 192H88a8 8 0 00-8 8v112a8 8 0 008 8h69.65a16 16 0 0110.14 3.63l91.47 75a8 8 0 0012.74-6.46V119.83a8 8 0 00-12.74-6.44l-91.47 75a16 16 0 01-10.14 3.61zM352 320c9.74-19.41 16-40.81 16-64 0-23.51-6-44.4-16-64M400 368c19.48-34 32-64 32-112s-12-77.7-32-112" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/></svg>
|
After Width: | Height: | Size: 482 B |
|
@ -0,0 +1,9 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512">
|
||||
<title>Volume Mute</title>
|
||||
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32"
|
||||
d="M416 432L64 80" />
|
||||
<path fill="currentColor"
|
||||
d="M224 136.92v33.8a4 4 0 001.17 2.82l24 24a4 4 0 006.83-2.82v-74.15a24.53 24.53 0 00-12.67-21.72 23.91 23.91 0 00-25.55 1.83 8.27 8.27 0 00-.66.51l-31.94 26.15a4 4 0 00-.29 5.92l17.05 17.06a4 4 0 005.37.26zM224 375.08l-78.07-63.92a32 32 0 00-20.28-7.16H64v-96h50.72a4 4 0 002.82-6.83l-24-24a4 4 0 00-2.82-1.17H56a24 24 0 00-24 24v112a24 24 0 0024 24h69.76l91.36 74.8a8.27 8.27 0 00.66.51 23.93 23.93 0 0025.85 1.69A24.49 24.49 0 00256 391.45v-50.17a4 4 0 00-1.17-2.82l-24-24a4 4 0 00-6.83 2.82zM125.82 336zM352 256c0-24.56-5.81-47.88-17.75-71.27a16 16 0 00-28.5 14.54C315.34 218.06 320 236.62 320 256q0 4-.31 8.13a8 8 0 002.32 6.25l19.66 19.67a4 4 0 006.75-2A146.89 146.89 0 00352 256zM416 256c0-51.19-13.08-83.89-34.18-120.06a16 16 0 00-27.64 16.12C373.07 184.44 384 211.83 384 256c0 23.83-3.29 42.88-9.37 60.65a8 8 0 001.9 8.26l16.77 16.76a4 4 0 006.52-1.27C410.09 315.88 416 289.91 416 256z" />
|
||||
<path fill="currentColor"
|
||||
d="M480 256c0-74.26-20.19-121.11-50.51-168.61a16 16 0 10-27 17.22C429.82 147.38 448 189.5 448 256c0 47.45-8.9 82.12-23.59 113a4 4 0 00.77 4.55L443 391.39a4 4 0 006.4-1C470.88 348.22 480 307 480 256z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><title>Volume Off</title><path d="M237.65 192H168a8 8 0 00-8 8v112a8 8 0 008 8h69.65a16 16 0 0110.14 3.63l91.47 75a8 8 0 0012.74-6.46V119.83a8 8 0 00-12.74-6.44l-91.47 75a16 16 0 01-10.14 3.61z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/></svg>
|
After Width: | Height: | Size: 379 B |
|
@ -0,0 +1,150 @@
|
|||
<template>
|
||||
<teleport to="#root">
|
||||
<div :class="[$style.popup, {[$style.top]: isShowTop}, {[$style.active]: props.visible}]" :style="popupStyle" :aria-hidden="!props.visible" @click.stop>
|
||||
<div ref="dom_content" class="scroll" :class="$style.list">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, onMounted, onBeforeUnmount, reactive, defineEmits } from '@common/utils/vueTools'
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean
|
||||
el: HTMLElement | null
|
||||
}>()
|
||||
|
||||
interface Emitter {
|
||||
(event: 'update:visible', visible: boolean): void
|
||||
}
|
||||
const emit = defineEmits<Emitter>()
|
||||
|
||||
const dom_content = ref<HTMLElement | null>(null)
|
||||
const isShowTop = ref(false)
|
||||
|
||||
const popupStyle = reactive({
|
||||
maxHeight: 'none',
|
||||
top: '0px',
|
||||
left: '0px',
|
||||
'--arrow-left': '0px',
|
||||
})
|
||||
|
||||
const arrowHeight = 9
|
||||
const arrowWidth = 8
|
||||
|
||||
watch(() => props.visible, (visible) => {
|
||||
if (!visible || !dom_content.value || !props.el) return
|
||||
const rect = props.el.getBoundingClientRect()
|
||||
const maxHeight = document.body.clientHeight
|
||||
const elTop = rect.top - window.lx.rootOffset
|
||||
const bottomTopVal = elTop + rect.height
|
||||
const contentHeight = dom_content.value.scrollHeight + arrowHeight + 10
|
||||
if (bottomTopVal + contentHeight < maxHeight || (contentHeight > elTop && elTop <= maxHeight - bottomTopVal)) {
|
||||
isShowTop.value = false
|
||||
popupStyle.top = bottomTopVal + arrowHeight + 'px'
|
||||
popupStyle.maxHeight = maxHeight - bottomTopVal - arrowHeight - 10 + 'px'
|
||||
} else {
|
||||
isShowTop.value = true
|
||||
let maxContentHeight = elTop - arrowHeight - 10
|
||||
popupStyle.top = (elTop - (elTop < contentHeight ? elTop : contentHeight) + 10) + 'px'
|
||||
popupStyle.maxHeight = maxContentHeight + 'px'
|
||||
}
|
||||
|
||||
const maxWidth = document.body.clientWidth - 20
|
||||
let center = dom_content.value.clientWidth / 2
|
||||
let left = rect.left + rect.width / 2 - window.lx.rootOffset - center
|
||||
if (left < 10) {
|
||||
center -= 10 - left
|
||||
left = 10
|
||||
} else if (left + dom_content.value.clientWidth > maxWidth) {
|
||||
let newLeft = maxWidth - dom_content.value.clientWidth
|
||||
center = center + left - newLeft
|
||||
left = newLeft
|
||||
}
|
||||
popupStyle.left = left + 'px'
|
||||
popupStyle['--arrow-left'] = center - arrowWidth + 'px'
|
||||
})
|
||||
|
||||
const handleHide = (evt?: MouseEvent) => {
|
||||
// if (evt && (evt.target as HTMLElement)?.parentNode != dom_content.value && props.visible) return emit('update:visible', false)
|
||||
// console.log(this.$refs)
|
||||
// if (evt && (evt.target == dom_btn.value || dom_btn.value?.contains(evt.target as HTMLElement))) return
|
||||
// setTimeout(() => {
|
||||
// popupVisible.value = false
|
||||
emit('update:visible', false)
|
||||
// }, 50)
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', handleHide)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
document.removeEventListener('click', handleHide)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="less" module>
|
||||
@import '@renderer/assets/styles/layout.less';
|
||||
|
||||
.popup {
|
||||
position: absolute;
|
||||
// top: -100%;
|
||||
// width: 645px;
|
||||
// left: 8px;
|
||||
// margin-top: 12px;
|
||||
max-width: 98%;
|
||||
border-radius: 4px;
|
||||
background-color: var(--color-content-background);
|
||||
opacity: 0;
|
||||
transform: scale(.8, .8);
|
||||
transform-origin: 0 0 0;
|
||||
transition: .16s ease;
|
||||
transition-property: transform, opacity;
|
||||
max-height: 250px;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
filter: drop-shadow(0px 0px 4px rgba(0, 0, 0, .15));
|
||||
display: flex;
|
||||
|
||||
&:before {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: var(--arrow-left);
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 8px solid transparent;
|
||||
border-right: 8px solid transparent;
|
||||
border-bottom: 8px solid var(--color-content-background);
|
||||
}
|
||||
|
||||
&.active {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
pointer-events: initial;
|
||||
}
|
||||
|
||||
&.top {
|
||||
filter: drop-shadow(0px 1px 4px rgba(0, 0, 0, .15));
|
||||
transform-origin: 50% 100% 0;
|
||||
|
||||
&:before {
|
||||
top: 100%;
|
||||
border-bottom: none;
|
||||
border-top: 8px solid var(--color-content-background);
|
||||
}
|
||||
}
|
||||
}
|
||||
.list {
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
// box-shadow: 0 0 4px rgba(0, 0, 0, .2);
|
||||
}
|
||||
|
||||
</style>
|
|
@ -102,7 +102,7 @@ export default {
|
|||
background-color: var(--color-primary-light-100-alpha-800);
|
||||
// background-color: #f5f5f5;
|
||||
position: relative;
|
||||
border-radius: 20px;
|
||||
// border-radius: 20px;
|
||||
}
|
||||
.progress-mask {
|
||||
position: absolute;
|
||||
|
@ -119,7 +119,7 @@ export default {
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
transform-origin: 0;
|
||||
border-radius: 20px;
|
||||
// border-radius: 20px;
|
||||
}
|
||||
.progress-bar1 {
|
||||
background-color: var(--color-primary-light-100-alpha-600);
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
<template>
|
||||
<material-popup-btn ref="btn_ref" :class="$style.btnContent">
|
||||
<button :class="$style.btn" :aria-label="nextTogglePlayName">
|
||||
<svg
|
||||
v-if="appSetting['player.togglePlayMethod'] == 'listLoop'"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xlink="http://www.w3.org/1999/xlink"
|
||||
height="80%" viewBox="0 0 24 24" space="preserve"
|
||||
>
|
||||
<use xlink:href="#icon-list-loop" />
|
||||
</svg>
|
||||
<svg
|
||||
v-else-if="appSetting['player.togglePlayMethod'] == 'random'"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xlink="http://www.w3.org/1999/xlink"
|
||||
width="100%" viewBox="0 0 24 24" space="preserve"
|
||||
>
|
||||
<use xlink:href="#icon-list-random" />
|
||||
</svg>
|
||||
<svg
|
||||
v-else-if="appSetting['player.togglePlayMethod'] == 'list'"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xlink="http://www.w3.org/1999/xlink"
|
||||
width="100%" viewBox="0 0 32 32" space="preserve"
|
||||
>
|
||||
<use xlink:href="#icon-list-order" />
|
||||
</svg>
|
||||
<svg
|
||||
v-else-if="appSetting['player.togglePlayMethod'] == 'singleLoop'"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xlink="http://www.w3.org/1999/xlink"
|
||||
width="100%" viewBox="0 0 24 24" space="preserve"
|
||||
>
|
||||
<use xlink:href="#icon-single-loop" />
|
||||
</svg>
|
||||
<svg v-else version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="100%" viewBox="0 0 32 32" space="preserve">
|
||||
<use xlink:href="#icon-single" />
|
||||
</svg>
|
||||
</button>
|
||||
<template #content>
|
||||
<div :class="$style.setting">
|
||||
<button :class="[$style.btn, {[$style.active]: appSetting['player.togglePlayMethod'] == 'listLoop'}]" :aria-label="$t('player__play_toggle_mode_list_loop')" @click="toggleMode('listLoop')">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" height="100%" viewBox="0 0 24 24" space="preserve">
|
||||
<use xlink:href="#icon-list-loop" />
|
||||
</svg>
|
||||
</button>
|
||||
<button :class="[$style.btn, {[$style.active]: appSetting['player.togglePlayMethod'] == 'random'}]" :aria-label="$t('player__play_toggle_mode_random')" @click="toggleMode('random')">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="100%" viewBox="0 0 24 24" space="preserve">
|
||||
<use xlink:href="#icon-list-random" />
|
||||
</svg>
|
||||
</button>
|
||||
<button :class="[$style.btn, {[$style.active]: appSetting['player.togglePlayMethod'] == 'singleLoop'}]" :aria-label="$t('player__play_toggle_mode_single_loop')" @click="toggleMode('list')">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="100%" viewBox="0 0 32 32" space="preserve">
|
||||
<use xlink:href="#icon-list-order" />
|
||||
</svg>
|
||||
</button>
|
||||
<button :class="[$style.btn, {[$style.active]: appSetting['player.togglePlayMethod'] == 'list'}]" :aria-label="$t('player__play_toggle_mode_list')" @click="toggleMode('singleLoop')">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="100%" viewBox="0 0 24 24" space="preserve">
|
||||
<use xlink:href="#icon-single-loop" />
|
||||
</svg>
|
||||
</button>
|
||||
<button :class="[$style.btn, {[$style.active]: appSetting['player.togglePlayMethod'] == 'none'}]" :aria-label="$t('player__play_toggle_mode_off')" @click="toggleMode('none')">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="100%" viewBox="0 0 32 32" space="preserve">
|
||||
<use xlink:href="#icon-single" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</material-popup-btn>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from '@common/utils/vueTools'
|
||||
// import useNextTogglePlay from '@renderer/utils/compositions/useNextTogglePlay'
|
||||
// import useToggleDesktopLyric from '@renderer/utils/compositions/useToggleDesktopLyric'
|
||||
// import { musicInfo, playMusicInfo } from '@renderer/store/player/state'
|
||||
import { appSetting } from '@renderer/store/setting'
|
||||
import useNextTogglePlay from '@renderer/utils/compositions/useNextTogglePlay'
|
||||
|
||||
const btn_ref = ref(null)
|
||||
|
||||
const {
|
||||
nextTogglePlayName,
|
||||
toggleNextPlayMode,
|
||||
} = useNextTogglePlay()
|
||||
|
||||
const toggleMode = (mode) => {
|
||||
btn_ref.value.hide()
|
||||
toggleNextPlayMode(mode)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" module>
|
||||
@import '@renderer/assets/styles/layout.less';
|
||||
.btnContent {
|
||||
flex: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.btn {
|
||||
position: relative;
|
||||
// color: var(--color-button-font);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: color @transition-normal;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
width: 24px;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
padding: 0;
|
||||
|
||||
svg {
|
||||
transition: opacity @transition-fast;
|
||||
opacity: .6;
|
||||
filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.2));
|
||||
}
|
||||
&:hover {
|
||||
svg {
|
||||
opacity: .9;
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
svg {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.setting {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
font-size: 14px;
|
||||
gap: 10px;
|
||||
label span {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<div :class="[$style.volumeContent, className]">
|
||||
<div :class="[$style.volume, {[$style.muted]: appSetting['player.isMute']} ]">
|
||||
<div :class="[$style.volume ]">
|
||||
<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 :class="$style.volumeMask" @mousedown="handleVolumeMsDown" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -39,7 +39,7 @@ export default {
|
|||
|
||||
window.app_event.setVolume(volumeEvent.msDownVolume = val)
|
||||
|
||||
if (isMute.value) window.app_event.setVolumeIsMute(false)
|
||||
// if (isMute.value) window.app_event.setVolumeIsMute(false)
|
||||
}
|
||||
const handleVolumeMsUp = () => {
|
||||
volumeEvent.isMsDown = false
|
||||
|
@ -76,8 +76,9 @@ export default {
|
|||
.volume-content {
|
||||
flex: none;
|
||||
position: relative;
|
||||
width: 80px;
|
||||
margin-right: 10px;
|
||||
width: 100px;
|
||||
padding: 5px 0;
|
||||
// margin-right: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
opacity: .5;
|
||||
|
@ -90,20 +91,20 @@ export default {
|
|||
.volume {
|
||||
// cursor: pointer;
|
||||
width: 100%;
|
||||
height: 0.25em;
|
||||
border-radius: 10px;
|
||||
height: 5px;
|
||||
// border-radius: 10px;
|
||||
// overflow: hidden;
|
||||
transition: @transition-normal;
|
||||
transition-property: background-color, opacity;
|
||||
background-color: var(--color-button-background);
|
||||
background-color: var(--color-primary-alpha-700);
|
||||
// background-color: #f5f5f5;
|
||||
position: relative;
|
||||
border-radius: @radius-progress-border;
|
||||
// border-radius: @radius-progress-border;
|
||||
}
|
||||
|
||||
.muted {
|
||||
opacity: .5;
|
||||
}
|
||||
// .muted {
|
||||
// opacity: .5;
|
||||
// }
|
||||
|
||||
.volume-bar {
|
||||
position: absolute;
|
||||
|
@ -115,9 +116,9 @@ export default {
|
|||
transition-timing-function: ease;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: @radius-progress-border;
|
||||
// border-radius: @radius-progress-border;
|
||||
transition-duration: 0.2s;
|
||||
background-color: var(--color-button-background);
|
||||
background-color: var(--color-button-font);
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
<template>
|
||||
<material-popup-btn :class="$style.btnContent">
|
||||
<button :class="$style.btn" :aria-label="isMute ? $t('player__volume_muted') : `${$t('player__volume')}${parseInt(volume * 100)}%`">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="100%" viewBox="0 0 24 24" space="preserve">
|
||||
<use :xlink:href="icon" />
|
||||
</svg>
|
||||
</button>
|
||||
<template #content>
|
||||
<div :class="$style.setting">
|
||||
<span>{{ Math.trunc(volume * 100) }}%</span>
|
||||
<common-volume-bar />
|
||||
<base-checkbox
|
||||
id="player__volume_mute"
|
||||
:model-value="isMute"
|
||||
:label="$t('player__volume_mute_label')"
|
||||
@update:model-value="saveVolumeIsMute($event)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</material-popup-btn>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from '@common/utils/vueTools'
|
||||
// import useNextTogglePlay from '@renderer/utils/compositions/useNextTogglePlay'
|
||||
// import useToggleDesktopLyric from '@renderer/utils/compositions/useToggleDesktopLyric'
|
||||
// import { musicInfo, playMusicInfo } from '@renderer/store/player/state'
|
||||
import { saveVolumeIsMute } from '@renderer/store/setting'
|
||||
import { volume, isMute } from '@renderer/store/player/volume'
|
||||
|
||||
const icon = computed(() => {
|
||||
return isMute.value
|
||||
? '#icon-volume-mute-outline'
|
||||
: volume.value == 0
|
||||
? '#icon-volume-off-outline'
|
||||
: volume.value < 0.3
|
||||
? '#icon-volume-low-outline'
|
||||
: volume.value < 0.7
|
||||
? '#icon-volume-medium-outline'
|
||||
: '#icon-volume-high-outline'
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" module>
|
||||
@import '@renderer/assets/styles/layout.less';
|
||||
.btnContent {
|
||||
flex: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.btn {
|
||||
position: relative;
|
||||
// color: var(--color-button-font);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: color @transition-normal;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
width: 24px;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
padding: 0;
|
||||
|
||||
svg {
|
||||
transition: opacity @transition-fast;
|
||||
opacity: .6;
|
||||
filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.2));
|
||||
}
|
||||
&:hover {
|
||||
svg {
|
||||
opacity: .9;
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
svg {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.setting {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
font-size: 14px;
|
||||
gap: 8px;
|
||||
label span {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
|
@ -170,13 +170,12 @@
|
|||
<path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z" />
|
||||
</g>
|
||||
<g id="icon-list-order" fill="currentColor">
|
||||
<!-- 0 0 24 24-->
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M4 10h12v2H4zm0-4h12v2H4zm0 8h8v2H4zm10 0v6l5-3z" />
|
||||
<!-- 0 0 32 32-->
|
||||
<path d="M5.221 12.905h18.571v3.095h-18.571zM5.221 6.714h18.571v3.095h-18.571zM5.221 19.095h12.381v3.095h-12.381zM20.697 19.095v9.286l7.738-4.643z" />
|
||||
</g>
|
||||
<g id="icon-single" fill="currentColor">
|
||||
<path d="M18,6.8v9.9h-2.1v-5.3c0-0.8,0-1.2,0-1.4c0-0.2-0.1-0.3-0.3-0.4c-0.1-0.1-0.5-0.1-1-0.1h-0.2V8.4c1-0.3,1.8-0.8,2.3-1.6H18z" />
|
||||
<polygon points="6,18 14.5,12 6,6 " />
|
||||
<path d="M26.75 6.683v17.738h-3.762v-9.496c0-1.433 0-2.15 0-2.508s-0.179-0.537-0.538-0.717c-0.179-0.179-0.896-0.179-1.792-0.179h-0.358v-1.971c1.792-0.537 3.225-1.433 4.121-2.867h2.329z" />
|
||||
<path d="M5.25 26.75l15.229-10.75-15.229-10.75z" />
|
||||
</g>
|
||||
<g id="icon-desktop-lyric-on" fill="currentColor">
|
||||
<path d="M162.64,335.554H81.017V152.1H55.143V359.7h107.5V335.554ZM288.807,291.4a117.012,117.012,0,0,0-11.222-20.092,29.568,29.568,0,0,0-13.365-10.562,54.323,54.323,0,0,0,17.225-7.7,50.6,50.6,0,0,0,12.579-12.23,52.253,52.253,0,0,0,7.648-15.724,64.034,64.034,0,0,0,2.573-18.345,67.706,67.706,0,0,0-3.5-22.316,42.831,42.831,0,0,0-11.007-17.233,51.262,51.262,0,0,0-19.227-11.118q-11.722-3.969-28.018-3.971H192.459V359.7H217.9v-92.44h12.008a37.092,37.092,0,0,1,10.078,1.271,24.136,24.136,0,0,1,8.291,4.209,32.591,32.591,0,0,1,7.076,7.941A76.14,76.14,0,0,1,261.79,293.3L289.664,359.7H318.4Zm-13.938-67.106a30.684,30.684,0,0,1-7.862,11.118,33.47,33.47,0,0,1-12.293,6.83,53.247,53.247,0,0,1-16.225,2.3H217.9V175.928H241.92q17.01,0,26.374,8.259t9.363,24.937A38.647,38.647,0,0,1,274.869,224.292ZM456.714,325.229a100.649,100.649,0,0,1-21.156,8.657,84.575,84.575,0,0,1-23.015,3.1q-28.448,0-43.17-20.489t-14.724-60.833a133.161,133.161,0,0,1,4-34.228q4-15.009,11.436-25.413a50.462,50.462,0,0,1,18.083-15.883,51.244,51.244,0,0,1,23.8-5.48,82.427,82.427,0,0,1,23.73,3.256,89.743,89.743,0,0,1,21.013,9.451v-27.8a94.1,94.1,0,0,0-21.442-7.544,112.019,112.019,0,0,0-24.158-2.462q-19.158,0-34.594,7.624a74.755,74.755,0,0,0-26.3,21.68q-10.865,14.056-16.724,34.228T327.632,258.2q0,51.461,21.227,77.748t60.825,26.286a111.234,111.234,0,0,0,47.03-10.324V325.229Z" />
|
||||
|
|
|
@ -1,43 +1,27 @@
|
|||
<template>
|
||||
<div :class="$style.controlBtn">
|
||||
<common-volume-bar />
|
||||
<div :class="$style.titleBtn" :aria-label="toggleDesktopLyricBtnTitle" @click="toggleDesktopLyric" @contextmenu="toggleLockDesktopLyric">
|
||||
<!-- <common-volume-bar /> -->
|
||||
<button :class="$style.titleBtn" :aria-label="$t('player__add_music_to')" @click="addMusicTo">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="90%" viewBox="0 0 512 512" space="preserve">
|
||||
<use xlink:href="#icon-add-2" />
|
||||
</svg>
|
||||
</button>
|
||||
<button :class="$style.titleBtn" :aria-label="toggleDesktopLyricBtnTitle" @click="toggleDesktopLyric" @contextmenu="toggleLockDesktopLyric">
|
||||
<svg v-show="appSetting['desktopLyric.enable']" version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" height="100%" viewBox="0 0 512 512" space="preserve">
|
||||
<use xlink:href="#icon-desktop-lyric-on" />
|
||||
</svg>
|
||||
<svg v-show="!appSetting['desktopLyric.enable']" version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" height="100%" viewBox="0 0 512 512" space="preserve">
|
||||
<use xlink:href="#icon-desktop-lyric-off" />
|
||||
</svg>
|
||||
</div>
|
||||
<div :class="$style.titleBtn" :aria-label="nextTogglePlayName" @click="toggleNextPlayMode">
|
||||
<svg v-if="appSetting['player.togglePlayMethod'] == 'listLoop'" version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" height="80%" viewBox="0 0 24 24" space="preserve">
|
||||
<use xlink:href="#icon-list-loop" />
|
||||
</svg>
|
||||
<svg v-else-if="appSetting['player.togglePlayMethod'] == 'random'" version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="100%" viewBox="0 0 24 24" space="preserve">
|
||||
<use xlink:href="#icon-list-random" />
|
||||
</svg>
|
||||
<svg v-else-if="appSetting['player.togglePlayMethod'] == 'list'" version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="120%" viewBox="0 0 24 24" space="preserve">
|
||||
<use xlink:href="#icon-list-order" />
|
||||
</svg>
|
||||
<svg v-else-if="appSetting['player.togglePlayMethod'] == 'singleLoop'" version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="100%" viewBox="0 0 24 24" space="preserve">
|
||||
<use xlink:href="#icon-single-loop" />
|
||||
</svg>
|
||||
<svg v-else version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="120%" viewBox="0 0 24 24" space="preserve">
|
||||
<use xlink:href="#icon-single" />
|
||||
</svg>
|
||||
</div>
|
||||
<div :class="$style.titleBtn" :aria-label="$t('player__add_music_to')" @click="addMusicTo">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" height="80%" viewBox="0 0 512 512" space="preserve">
|
||||
<use xlink:href="#icon-add-2" />
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
<common-volume-btn />
|
||||
<common-toggle-play-mode-btn />
|
||||
<common-list-add-modal v-model:show="isShowAddMusicTo" :music-info="playMusicInfo.musicInfo" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from '@common/utils/vueTools'
|
||||
import useNextTogglePlay from '@renderer/utils/compositions/useNextTogglePlay'
|
||||
import useToggleDesktopLyric from '@renderer/utils/compositions/useToggleDesktopLyric'
|
||||
import { musicInfo, playMusicInfo } from '@renderer/store/player/state'
|
||||
import { appSetting } from '@renderer/store/setting'
|
||||
|
@ -45,30 +29,18 @@ import { appSetting } from '@renderer/store/setting'
|
|||
export default {
|
||||
setup() {
|
||||
const isShowAddMusicTo = ref(false)
|
||||
|
||||
|
||||
const {
|
||||
nextTogglePlayName,
|
||||
toggleNextPlayMode,
|
||||
} = useNextTogglePlay()
|
||||
|
||||
const {
|
||||
toggleDesktopLyricBtnTitle,
|
||||
toggleDesktopLyric,
|
||||
toggleLockDesktopLyric,
|
||||
} = useToggleDesktopLyric()
|
||||
|
||||
|
||||
const addMusicTo = () => {
|
||||
if (!musicInfo.id) return
|
||||
isShowAddMusicTo.value = true
|
||||
}
|
||||
|
||||
return {
|
||||
appSetting,
|
||||
isShowAddMusicTo,
|
||||
nextTogglePlayName,
|
||||
toggleNextPlayMode,
|
||||
toggleDesktopLyricBtnTitle,
|
||||
toggleDesktopLyric,
|
||||
toggleLockDesktopLyric,
|
||||
|
@ -83,23 +55,34 @@ export default {
|
|||
@import '@renderer/assets/styles/layout.less';
|
||||
|
||||
.controlBtn {
|
||||
padding-left: 20px;
|
||||
padding-right: 10px;
|
||||
flex: none;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
gap: 10px;
|
||||
|
||||
button {
|
||||
color: var(--color-button-font);
|
||||
}
|
||||
}
|
||||
|
||||
.titleBtn {
|
||||
flex: none;
|
||||
margin-left: 5px;
|
||||
height: 100%;
|
||||
width: 20px;
|
||||
color: var(--color-button-font);
|
||||
width: 24px;
|
||||
transition: @transition-fast;
|
||||
transition-property: color, opacity;
|
||||
// color: var(--color-button-font);
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
width: 24px;
|
||||
padding: 0;
|
||||
|
||||
transition: opacity 0.2s ease;
|
||||
opacity: .6;
|
||||
cursor: pointer;
|
||||
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
<template>
|
||||
<div :class="$style.controlBtn">
|
||||
<div :class="$style.btn" :aria-label="$t('player__add_music_to')" @click="addMusicTo">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="90%" viewBox="0 0 512 512" space="preserve">
|
||||
<use xlink:href="#icon-add-2" />
|
||||
</svg>
|
||||
</div>
|
||||
<div :class="$style.btn" :aria-label="toggleDesktopLyricBtnTitle" @click="toggleDesktopLyric" @contextmenu="toggleLockDesktopLyric">
|
||||
<svg v-show="appSetting['desktopLyric.enable']" version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" height="100%" viewBox="0 0 512 512" space="preserve">
|
||||
<use xlink:href="#icon-desktop-lyric-on" />
|
||||
</svg>
|
||||
<svg v-show="!appSetting['desktopLyric.enable']" version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" height="100%" viewBox="0 0 512 512" space="preserve">
|
||||
<use xlink:href="#icon-desktop-lyric-off" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from '@common/utils/vueTools'
|
||||
import useToggleDesktopLyric from '@renderer/utils/compositions/useToggleDesktopLyric'
|
||||
import { musicInfo, playMusicInfo } from '@renderer/store/player/state'
|
||||
import { appSetting } from '@renderer/store/setting'
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const isShowAddMusicTo = ref(false)
|
||||
|
||||
const {
|
||||
toggleDesktopLyricBtnTitle,
|
||||
toggleDesktopLyric,
|
||||
toggleLockDesktopLyric,
|
||||
} = useToggleDesktopLyric()
|
||||
|
||||
|
||||
const addMusicTo = () => {
|
||||
if (!musicInfo.id) return
|
||||
isShowAddMusicTo.value = true
|
||||
}
|
||||
|
||||
return {
|
||||
appSetting,
|
||||
isShowAddMusicTo,
|
||||
toggleDesktopLyricBtnTitle,
|
||||
toggleDesktopLyric,
|
||||
toggleLockDesktopLyric,
|
||||
addMusicTo,
|
||||
playMusicInfo,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" module>
|
||||
@import '@renderer/assets/styles/layout.less';
|
||||
|
||||
.controlBtn {
|
||||
padding-left: 5px;
|
||||
padding-right: 20px;
|
||||
flex: none;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
flex: none;
|
||||
height: 100%;
|
||||
width: 26px;
|
||||
color: var(--color-button-font);
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
transition: opacity 0.2s ease;
|
||||
opacity: .6;
|
||||
cursor: pointer;
|
||||
|
||||
svg {
|
||||
filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.2));
|
||||
}
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
&:active {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
|
@ -1,26 +1,25 @@
|
|||
<template>
|
||||
<div :class="$style.player">
|
||||
<div :class="$style.left" :aria-label="$t('player__pic_tip')" @contextmenu="handleToMusicLocation" @click="showPlayerDetail">
|
||||
<div :class="$style.progress">
|
||||
<common-progress-bar v-if="!isShowPlayerDetail" :progress="progress" :handle-transition-end="handleTransitionEnd" :is-active-transition="isActiveTransition" />
|
||||
</div>
|
||||
<div :class="$style.picContent" :aria-label="$t('player__pic_tip')" @contextmenu="handleToMusicLocation" @click="showPlayerDetail">
|
||||
<img v-if="musicInfo.pic" :src="musicInfo.pic" loading="lazy" decoding="async" @error="imgError">
|
||||
<svg v-else version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" height="102%" width="100%" viewBox="0 0 60 60" space="preserve">
|
||||
<use :xlink:href="`#${$style.iconPic}`" />
|
||||
</svg>
|
||||
<div v-else :class="$style.emptyPic">L<span>X</span></div>
|
||||
</div>
|
||||
<div :class="$style.middle">
|
||||
<div :class="$style.column1">
|
||||
<div :class="$style.container">
|
||||
<div :class="$style.title" :aria-label="title + $t('copy_tip')" @click="handleCopy(title)">{{ title }}</div>
|
||||
<control-btns />
|
||||
</div>
|
||||
</div>
|
||||
<div :class="$style.column2">
|
||||
<common-progress-bar v-if="!isShowPlayerDetail" :progress="progress" :handle-transition-end="handleTransitionEnd" :is-active-transition="isActiveTransition" />
|
||||
</div>
|
||||
<div :class="$style.column3">
|
||||
<template v-if="!isShowPlayerDetail"><span :class="$style.statusText">{{ statusText }}</span><span>{{ nowPlayTimeStr }}</span><span style="margin: 0 5px;">/</span><span>{{ maxPlayTimeStr }}</span></template>
|
||||
<div :class="$style.infoContent">
|
||||
<div :class="$style.title" :aria-label="title + $t('copy_tip')" @click="handleCopy(title)">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div :class="$style.status">{{ statusText }}</div>
|
||||
</div>
|
||||
<div :class="$style.right">
|
||||
<div :class="$style.timeContent">
|
||||
<span>{{ nowPlayTimeStr }}</span>
|
||||
<span style="margin: 0 1px;">/</span>
|
||||
<span>{{ maxPlayTimeStr }}</span>
|
||||
</div>
|
||||
<control-btns />
|
||||
<div :class="$style.playBtnContent">
|
||||
<div :class="$style.playBtn" :aria-label="$t('player__prev')" style="transform: rotate(180deg);" @click="playPrev()">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" height="100%" viewBox="0 0 220.847 220.847" space="preserve">
|
||||
<use xlink:href="#icon-nextMusic" />
|
||||
|
@ -40,18 +39,6 @@
|
|||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" style="display: none;">
|
||||
<g :id="$style.iconPic">
|
||||
<path d="M29,0C12.984,0,0,12.984,0,29c0,16.016,12.984,29,29,29s29-12.984,29-29C58,12.984,45.016,0,29,0zM29,36.08c-3.91,0-7.08-3.17-7.08-7.08c0-3.91,3.17-7.08,7.08-7.08s7.08,3.17,7.08,7.08C36.08,32.91,32.91,36.08,29,36.08z" />
|
||||
<path :class="$style.c1" d="M6.487,22.932c-0.077,0-0.156-0.009-0.234-0.027c-0.537-0.13-0.868-0.67-0.739-1.206c0.946-3.935,2.955-7.522,5.809-10.376s6.441-4.862,10.376-5.809c0.536-0.127,1.077,0.202,1.206,0.739c0.129,0.536-0.202,1.076-0.739,1.206c-3.575,0.859-6.836,2.685-9.429,5.277s-4.418,5.854-5.277,9.429C7.349,22.624,6.938,22.932,6.487,22.932z" />
|
||||
<path :class="$style.c1" d="M36.066,52.514c-0.451,0-0.861-0.308-0.972-0.767c-0.129-0.536,0.202-1.076,0.739-1.206c3.576-0.859,6.837-2.685,9.43-5.277s4.418-5.854,5.277-9.429c0.129-0.538,0.668-0.868,1.206-0.739c0.537,0.13,0.868,0.67,0.739,1.206c-0.946,3.935-2.955,7.522-5.809,10.376s-6.441,4.862-10.377,5.809C36.223,52.505,36.144,52.514,36.066,52.514z" />
|
||||
<path :class="$style.c1" d="M11.313,24.226c-0.075,0-0.151-0.008-0.228-0.026c-0.538-0.125-0.873-0.663-0.747-1.2c0.72-3.09,2.282-5.904,4.52-8.141c2.236-2.237,5.051-3.8,8.141-4.52c0.535-0.131,1.075,0.209,1.2,0.747c0.126,0.537-0.209,1.075-0.747,1.2c-2.725,0.635-5.207,2.014-7.18,3.986s-3.352,4.455-3.986,7.18C12.179,23.914,11.768,24.226,11.313,24.226z" />
|
||||
<path :class="$style.c1" d="M34.773,47.688c-0.454,0-0.865-0.312-0.973-0.773c-0.126-0.537,0.209-1.075,0.747-1.2c2.725-0.635,5.207-2.014,7.18-3.986s3.352-4.455,3.986-7.18c0.125-0.538,0.662-0.88,1.2-0.747c0.538,0.125,0.873,0.663,0.747,1.2c-0.72,3.09-2.282,5.904-4.52,8.141c-2.236,2.237-5.051,3.8-8.141,4.52C34.925,47.68,34.849,47.688,34.773,47.688z" />
|
||||
<path :class="$style.c1" d="M16.14,25.519c-0.071,0-0.143-0.008-0.215-0.023c-0.539-0.118-0.881-0.651-0.763-1.19c0.997-4.557,4.586-8.146,9.143-9.143c0.537-0.116,1.071,0.222,1.19,0.763c0.118,0.539-0.224,1.072-0.763,1.19c-3.796,0.831-6.786,3.821-7.617,7.617C17.013,25.2,16.6,25.519,16.14,25.519z" />
|
||||
<path :class="$style.c1" d="M33.48,42.861c-0.46,0-0.873-0.318-0.976-0.786c-0.118-0.539,0.224-1.072,0.763-1.19c3.796-0.831,6.786-3.821,7.617-7.617c0.118-0.541,0.65-0.881,1.19-0.763c0.539,0.118,0.881,0.651,0.763,1.19c-0.997,4.557-4.586,8.146-9.143,9.143C33.623,42.854,33.552,42.861,33.48,42.861z" />
|
||||
<path :class="$style.c2" d="M29,38.08c-5.007,0-9.08-4.073-9.08-9.08s4.073-9.08,9.08-9.08s9.08,4.073,9.08,9.08S34.007,38.08,29,38.08z M29,23.92c-2.801,0-5.08,2.279-5.08,5.08s2.279,5.08,5.08,5.08s5.08-2.279,5.08-5.08S31.801,23.92,29,23.92z" />
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -157,29 +144,51 @@ export default {
|
|||
@import '@renderer/assets/styles/layout.less';
|
||||
|
||||
.player {
|
||||
position: relative;
|
||||
height: @height-player;
|
||||
background-color: var(--color-main-background);
|
||||
border-top: 1px solid var(--color-primary-alpha-900);
|
||||
// border-top: 1px solid var(--color-primary-alpha-900);
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
contain: strict;
|
||||
padding: 5px 0;
|
||||
padding: 11px 6px 6px;
|
||||
z-index: 2;
|
||||
// box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.1);
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
&:before {
|
||||
.mixin-after;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--color-main-background);
|
||||
opacity: .8;
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
.left {
|
||||
width: @height-player - 2;
|
||||
.progress {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding-bottom: 5px;
|
||||
// height: 15px;
|
||||
}
|
||||
|
||||
.picContent {
|
||||
height: 100%;
|
||||
aspect-ratio: 1 / 1;
|
||||
|
||||
// color: var(--color-primary);
|
||||
// transition: @transition-normal;
|
||||
// transition-property: color;
|
||||
flex: none;
|
||||
padding: 2PX;
|
||||
opacity: 1;
|
||||
// transition: @transition-normal;
|
||||
transition: opacity @transition-fast;
|
||||
// transition-property: opacity;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
@ -190,9 +199,9 @@ export default {
|
|||
opacity: .8;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: currentColor;
|
||||
}
|
||||
// svg {
|
||||
// fill: currentColor;
|
||||
// }
|
||||
img {
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.3);
|
||||
max-width: 100%;
|
||||
|
@ -203,58 +212,77 @@ export default {
|
|||
border-radius: @radius-border;
|
||||
// border: 2px solid @color-theme_2-background_1;
|
||||
}
|
||||
|
||||
.emptyPic {
|
||||
background-color: var(--color-primary-light-900-alpha-200);
|
||||
border-radius: @radius-border;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--color-primary-light-400-alpha-200);
|
||||
user-select: none;
|
||||
font-size: 20px;
|
||||
font-family: Consolas, "Courier New", monospace;
|
||||
|
||||
span {
|
||||
padding-left: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.middle {
|
||||
|
||||
.infoContent {
|
||||
padding-left: 10px;
|
||||
flex: auto;
|
||||
height: 100%;
|
||||
padding: 2px 10px 2px 8px;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
font-size: 14px;
|
||||
color: var(--color-font);
|
||||
min-width: 0;
|
||||
}
|
||||
.right {
|
||||
|
||||
.title {
|
||||
max-width: 100%;
|
||||
font-size: 13px;
|
||||
color: var(--color-font-label);
|
||||
.mixin-ellipsis-1;
|
||||
}
|
||||
.status {
|
||||
padding-top: 5px;
|
||||
height: 23px;
|
||||
.mixin-ellipsis-1;
|
||||
line-height: 1.5;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.timeContent {
|
||||
flex: none;
|
||||
color: var(--color-font);
|
||||
font-size: 13px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.playBtnContent {
|
||||
height: 100%;
|
||||
flex: none;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
padding-left: 15px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
.column1 {
|
||||
flex: auto;
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
.container {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
flex: 0 1 auto;
|
||||
min-width: 0;
|
||||
padding-right: 5px;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
.mixin-ellipsis-1;
|
||||
padding-left: 10px;
|
||||
padding-right: 15px;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.play-btn {
|
||||
+ .play-btn {
|
||||
margin-left: 15px;
|
||||
}
|
||||
flex: none;
|
||||
height: 46%;
|
||||
height: 52%;
|
||||
// margin-top: -2px;
|
||||
// transition: @transition-normal;
|
||||
// transition-property: color;
|
||||
transition: @transition-fast;
|
||||
transition-property: color, opacity;
|
||||
color: var(--color-button-font);
|
||||
transition: opacity 0.2s ease;
|
||||
opacity: 1;
|
||||
cursor: pointer;
|
||||
|
||||
|
@ -270,54 +298,4 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.column2 {
|
||||
flex: none;
|
||||
padding: 3px 0;
|
||||
height: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
.column3 {
|
||||
transition: @transition-normal;
|
||||
transition-property: color;
|
||||
color: var(--color-font);
|
||||
flex: none;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
padding-top: 2px;
|
||||
// justify-content: space-between;
|
||||
height: 22px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 0.98em;
|
||||
transition: @transition-normal;
|
||||
transition-property: color;
|
||||
color: var(--color-font-label);
|
||||
.mixin-ellipsis-1;
|
||||
// padding: 0 5px;
|
||||
padding-right: 5px;
|
||||
flex: 1 1 0;
|
||||
// text-align: center;
|
||||
line-height: 1.2;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
#icon-pic {
|
||||
// color: var(--color-primary);
|
||||
.c1 {
|
||||
transition: @transition-normal;
|
||||
transition-property: fill;
|
||||
// fill: @color-player-pic-c1;
|
||||
}
|
||||
.c2 {
|
||||
transition: @transition-normal;
|
||||
transition-property: fill;
|
||||
// fill: @color-player-pic-c2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="$style.timeLabel"><span :class="$style.status" style="margin-left: 15px">{{ status }}</span><span>{{ nowPlayTimeStr }}</span><span style="margin: 0 5px;">/</span><span>{{ maxPlayTimeStr }}</span></div>
|
||||
<div :class="$style.timeLabel"><span :class="$style.status" style="margin-right: 15px">{{ status }}</span><span>{{ nowPlayTimeStr }}</span><span style="margin: 0 5px;">/</span><span>{{ maxPlayTimeStr }}</span></div>
|
||||
</div>
|
||||
<div :class="$style.playControl">
|
||||
<div :class="$style.playBtn" style="transform: rotate(180deg);" :aria-label="$t('player__prev')" @click="playPrev()">
|
||||
|
|
|
@ -1,32 +1,22 @@
|
|||
<template lang="pug">
|
||||
div(:class="$style.footerLeftControlBtns")
|
||||
common-volume-bar
|
||||
div(:class="[$style.footerLeftControlBtn, $style.lrcBtn]" @click="toggleDesktopLyric" @contextmenu="toggleLockDesktopLyric" :aria-label="toggleDesktopLyricBtnTitle")
|
||||
button(:class="[$style.footerLeftControlBtn, $style.lrcBtn]" @click="toggleDesktopLyric" @contextmenu="toggleLockDesktopLyric" :aria-label="toggleDesktopLyricBtnTitle")
|
||||
svg(v-show="appSetting['desktopLyric.enable']" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='125%' viewBox='0 0 512 512' space='preserve')
|
||||
use(xlink:href='#icon-desktop-lyric-on')
|
||||
svg(v-show="!appSetting['desktopLyric.enable']" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='125%' viewBox='0 0 512 512' space='preserve')
|
||||
use(xlink:href='#icon-desktop-lyric-off')
|
||||
div(:class="[$style.footerLeftControlBtn, { [$style.active]: appSetting['player.audioVisualization'] }]" @click="toggleAudioVisualization" :aria-label="$t('audio_visualization')")
|
||||
button(:class="[$style.footerLeftControlBtn, { [$style.active]: appSetting['player.audioVisualization'] }]" @click="toggleAudioVisualization" :aria-label="$t('audio_visualization')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' width='95%' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-audio-wave')
|
||||
div(:class="[$style.footerLeftControlBtn, { [$style.active]: isShowLrcSelectContent }]" @click="toggleVisibleLrc" :aria-label="$t('lyric__select')")
|
||||
button(:class="[$style.footerLeftControlBtn, { [$style.active]: isShowLrcSelectContent }]" @click="toggleVisibleLrc" :aria-label="$t('lyric__select')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' width='95%' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-text')
|
||||
div(:class="[$style.footerLeftControlBtn, {[$style.active]: isShowPlayComment}]" @click="toggleVisibleComment" :aria-label="$t('comment__show')")
|
||||
button(:class="[$style.footerLeftControlBtn, {[$style.active]: isShowPlayComment}]" @click="toggleVisibleComment" :aria-label="$t('comment__show')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' width='95%' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-comment')
|
||||
div(:class="$style.footerLeftControlBtn" @click="toggleNextPlayMode" :aria-label="nextTogglePlayName")
|
||||
svg(v-show="appSetting['player.togglePlayMethod'] == 'listLoop'" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-list-loop')
|
||||
svg(v-show="appSetting['player.togglePlayMethod'] == 'random'" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-list-random')
|
||||
svg(v-show="appSetting['player.togglePlayMethod'] == 'list'" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' width='120%' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-list-order')
|
||||
svg(v-show="appSetting['player.togglePlayMethod'] == 'singleLoop'" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' width='110%' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-single-loop')
|
||||
svg(v-show="!appSetting['player.togglePlayMethod']" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' width='120%' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-single')
|
||||
div(:class="$style.footerLeftControlBtn" @click="isShowAddMusicTo = true" :aria-label="$t('player__add_music_to')")
|
||||
common-volume-btn
|
||||
common-toggle-play-mode-btn
|
||||
button(:class="$style.footerLeftControlBtn" @click="isShowAddMusicTo = true" :aria-label="$t('player__add_music_to')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' viewBox='0 0 512 512' space='preserve')
|
||||
use(xlink:href='#icon-add-2')
|
||||
common-list-add-modal(v-model:show="isShowAddMusicTo" :musicInfo="playMusicInfo.musicInfo")
|
||||
|
@ -117,29 +107,34 @@ export default {
|
|||
@import '@renderer/assets/styles/layout.less';
|
||||
|
||||
.footerLeftControlBtns {
|
||||
color: var(--color-font);
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
|
||||
button {
|
||||
width: 20px;
|
||||
color: var(--color-font);
|
||||
}
|
||||
|
||||
.footerLeftControlBtn {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
// width: 18px;
|
||||
// height: 18px;
|
||||
opacity: .5;
|
||||
cursor: pointer;
|
||||
transition: opacity @transition-normal;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
|
||||
&:hover {
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
+.footerLeftControlBtn {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--color-primary);
|
||||
opacity: .8;
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<div ref="dom_btn" :class="$style.content" @click="handleShowPopup">
|
||||
<slot />
|
||||
<base-popup v-model:visible="visible" :el="dom_btn">
|
||||
<slot name="content" />
|
||||
</base-popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, defineExpose } from '@common/utils/vueTools'
|
||||
|
||||
const visible = ref(false)
|
||||
const dom_btn = ref<HTMLElement | null>(null)
|
||||
|
||||
const handleShowPopup = (evt: MouseEvent) => {
|
||||
if (visible.value) evt.stopPropagation()
|
||||
setTimeout(() => {
|
||||
// if (!)
|
||||
visible.value = !visible.value
|
||||
}, 50)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
hide() {
|
||||
visible.value = false
|
||||
},
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="less" module>
|
||||
@import '@renderer/assets/styles/layout.less';
|
||||
.content {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -25,6 +25,7 @@ window.lx = {
|
|||
restorePlayInfo: null,
|
||||
worker: createWorkers(),
|
||||
isDev: process.env.NODE_ENV == 'production',
|
||||
rootOffset: window.dt ? 0 : 8,
|
||||
}
|
||||
|
||||
window.lxData = {}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { ref, reactive, shallowRef, markRaw, computed } from '@common/utils/vueTools'
|
||||
import { ref, reactive, shallowRef, markRaw, computed, watch } from '@common/utils/vueTools'
|
||||
import { windowSizeList as configWindowSizeList } from '@common/config'
|
||||
import { appSetting } from './setting'
|
||||
import pkg from '../../../package.json'
|
||||
|
@ -117,6 +117,9 @@ export const userApi = reactive<{
|
|||
})
|
||||
|
||||
export const isFullscreen = ref(false)
|
||||
watch(isFullscreen, isFullscreen => {
|
||||
window.lx.rootOffset = window.dt || isFullscreen ? 0 : 8
|
||||
}, { immediate: true })
|
||||
|
||||
export const themeShouldUseDarkColors = ref(window.shouldUseDarkColors)
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ interface Lx {
|
|||
songlistKey: string | null
|
||||
songlistPosition?: number
|
||||
}
|
||||
rootOffset: number
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import { onMounted, onBeforeUnmount, watch, reactive, ref } from '@common/utils/vueTools'
|
||||
import { isFullscreen } from '@renderer/store'
|
||||
|
||||
let rootOffset = window.dt ? 0 : 8
|
||||
|
||||
export default ({ visible, location, onHide }) => {
|
||||
const transition1 = 'transform, opacity'
|
||||
|
@ -61,13 +59,9 @@ export default ({ visible, location, onHide }) => {
|
|||
visible ? handleShow() : handleHide()
|
||||
}, { immediate: true })
|
||||
|
||||
watch(isFullscreen, isFullscreen => {
|
||||
rootOffset = window.dt || isFullscreen ? 0 : 8
|
||||
}, { immediate: true })
|
||||
|
||||
watch(location, location => {
|
||||
menuStyles.left = location.x - rootOffset + 2 + 'px'
|
||||
menuStyles.top = location.y - rootOffset + 'px'
|
||||
menuStyles.left = location.x - window.lx.rootOffset + 2 + 'px'
|
||||
menuStyles.top = location.y - window.lx.rootOffset + 'px'
|
||||
// nextTick(() => {
|
||||
if (show) {
|
||||
if (menuStyles.transitionProperty != transition2) menuStyles.transitionProperty = transition2
|
||||
|
|
|
@ -4,13 +4,13 @@ import {
|
|||
} from '@common/utils/vueTools'
|
||||
import { useI18n } from '@renderer/plugins/i18n'
|
||||
|
||||
const playNextModes = [
|
||||
'listLoop',
|
||||
'random',
|
||||
'list',
|
||||
'singleLoop',
|
||||
'none',
|
||||
] as const
|
||||
// const playNextModes = [
|
||||
// 'listLoop',
|
||||
// 'random',
|
||||
// 'list',
|
||||
// 'singleLoop',
|
||||
// 'none',
|
||||
// ] as const
|
||||
|
||||
export default () => {
|
||||
const t = useI18n()
|
||||
|
@ -24,10 +24,11 @@ export default () => {
|
|||
}
|
||||
})
|
||||
|
||||
const toggleNextPlayMode = () => {
|
||||
let index = playNextModes.indexOf(appSetting['player.togglePlayMethod'])
|
||||
if (++index >= playNextModes.length) index = 0
|
||||
setTogglePlayMode(playNextModes[index] ?? playNextModes[0])
|
||||
const toggleNextPlayMode = (mode: LX.AppSetting['player.togglePlayMethod']) => {
|
||||
if (mode == appSetting['player.togglePlayMethod']) return
|
||||
// let index = playNextModes.indexOf(appSetting['player.togglePlayMethod'])
|
||||
// if (++index >= playNextModes.length) index = 0
|
||||
setTogglePlayMode(mode)
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
Loading…
Reference in New Issue