完成播放列表按钮及布局

pull/2369/head
QiuLiang-99 2025-05-01 22:04:29 +08:00
parent c1e7faa7bf
commit a22a9ffc85
6 changed files with 129 additions and 38 deletions

View File

@ -3,9 +3,13 @@
<layout-aside id="left" /> <layout-aside id="left" />
<div id="right"> <div id="right">
<layout-toolbar id="toolbar" /> <layout-toolbar id="toolbar" />
<layout-view id="view" /> <div class="middle">
<layout-view id="view" />
<PlayListWindow v-if="isShowPlaylist" class="playlist-window" @close="closePlaylist()" />
</div>
<layout-play-bar id="player" /> <layout-play-bar id="player" />
</div> </div>
<layout-icons /> <layout-icons />
<layout-change-log-modal /> <layout-change-log-modal />
<layout-update-modal /> <layout-update-modal />
@ -18,29 +22,22 @@
<script setup> <script setup>
import { onMounted } from '@common/utils/vueTools' import { onMounted } from '@common/utils/vueTools'
// import BubbleCursor from '@common/utils/effects/cursor-effects/bubbleCursor'
// import '@common/utils/effects/snow.min'
import useApp from '@renderer/core/useApp' import useApp from '@renderer/core/useApp'
import PlayListWindow from '@renderer/components/common/PlayListWindow.vue'
import { isShowPlaylist } from '@renderer/store/player/state'
import { setShowPlaylist } from '@renderer/store/player/action'
const closePlaylist = () => {
setShowPlaylist(false)
}
useApp() useApp()
onMounted(() => { onMounted(() => {
document.getElementById('root').style.display = 'block' document.getElementById('root').style.display = 'block'
// const styles = getComputedStyle(document.documentElement)
// window.lxData.bubbleCursor = new BubbleCursor({
// fillStyle: styles.getPropertyValue('--color-primary-alpha-900'),
// strokeStyle: styles.getPropertyValue('--color-primary-alpha-700'),
// })
}) })
// onBeforeUnmount(() => {
// window.lxData.bubbleCursor?.destroy()
// })
</script> </script>
<style lang="less"> <style lang="less">
@import './assets/styles/index.less'; @import './assets/styles/index.less';
@import './assets/styles/layout.less'; @import './assets/styles/layout.less';
@ -49,10 +46,8 @@ html {
height: 100vh; height: 100vh;
} }
html, body { html, body {
// overflow: hidden;
box-sizing: border-box; box-sizing: border-box;
} }
body { body {
user-select: none; user-select: none;
height: 100%; height: 100%;
@ -77,13 +72,6 @@ body {
.transparent { .transparent {
background: transparent; background: transparent;
padding: @shadow-app; padding: @shadow-app;
// #waiting-mask {
// border-radius: @radius-border;
// left: @shadow-app;
// right: @shadow-app;
// top: @shadow-app;
// bottom: @shadow-app;
// }
#body { #body {
border-radius: @radius-border; border-radius: @radius-border;
} }
@ -91,10 +79,6 @@ body {
box-shadow: 0 0 @shadow-app rgba(0, 0, 0, 0.5); box-shadow: 0 0 @shadow-app rgba(0, 0, 0, 0.5);
border-radius: @radius-border; border-radius: @radius-border;
} }
// #container {
// border-radius: @radius-border;
// background-color: transparent;
// }
} }
.disableTransparent { .disableTransparent {
background-color: var(--color-content-background); background-color: var(--color-content-background);
@ -107,10 +91,6 @@ body {
border-top-left-radius: 0; border-top-left-radius: 0;
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
} }
// #view { // 5px
// margin-right: 5Px;
// }
} }
.fullscreen { .fullscreen {
background-color: var(--color-content-background); background-color: var(--color-content-background);
@ -132,28 +112,47 @@ body {
flex: none; flex: none;
width: @width-app-left; width: @width-app-left;
} }
#right { #right {
flex: auto; flex: auto;
display: flex; display: flex;
flex-flow: column nowrap; flex-direction: column;
transition: background-color @transition-normal; transition: background-color @transition-normal;
background-color: var(--color-main-background); background-color: var(--color-main-background);
border-top-left-radius: @radius-border; border-top-left-radius: @radius-border;
border-bottom-left-radius: @radius-border; border-bottom-left-radius: @radius-border;
overflow: hidden; overflow: hidden;
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.1); box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.1);
} }
#toolbar, #player {
#toolbar,
#player {
flex: none; flex: none;
} }
/* 中间区域横向布局 */
.middle {
flex: auto;
display: flex;
overflow: hidden;
min-height: 0;
}
/* 主内容区域自动伸缩 */
#view { #view {
position: relative; position: relative;
flex: auto; flex: auto;
// display: flex;
min-height: 0; min-height: 0;
} }
/* 播放列表窗口,默认宽度固定 */
.playlist-window {
width: 300px;
flex: none;
border-left: 1px solid var(--color-border);
background-color: var(--color-main-background);
}
.view-container { .view-container {
transition: opacity @transition-normal; transition: opacity @transition-normal;
} }
@ -163,6 +162,4 @@ body {
#view.show-modal > .view-container { #view.show-modal > .view-container {
opacity: .2; opacity: .2;
} }
</style> </style>

View File

@ -0,0 +1,24 @@
<template>
<button class="playlist-button" @click="togglePlaylist">
🎵 播放列表
</button>
</template>
<script setup>
import { setShowPlaylist } from '@renderer/store/player/action'
const togglePlaylist = () => {
setShowPlaylist(true)
}
</script>
<style scoped>
.playlist-button {
padding: 10px 20px;
background-color: #4caf50;
color: white;
border: none;
border-radius: 10px;
cursor: pointer;
}
.playlist-button:hover {
background-color: #45a049;
}
</style>

View File

@ -0,0 +1,62 @@
<template>
<div class="playlist-overlay">
<div class="playlist-window">
<button class="close-button" @click="emitClose"></button>
<h2>播放列表</h2>
<ul>
<li v-for="(song, index) in songs" :key="index">
{{ index + 1 }}. {{ song }}
</li>
</ul>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const emit = defineEmits(['close'])
const songs = ref([
'海阔天空 - Beyond',
'夜曲 - 周杰伦',
'告白气球 - 周杰伦',
'平凡之路 - 朴树',
])
const emitClose = () => {
emit('close')
}
</script>
<style scoped>
.playlist-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 999;
}
.playlist-window {
background-color: #222;
color: white;
padding: 20px;
border-radius: 10px;
width: 300px;
max-height: 80%;
overflow-y: auto;
position: relative;
}
.close-button {
position: absolute;
top: 10px;
right: 10px;
background: transparent;
color: white;
border: none;
font-size: 18px;
cursor: pointer;
}
</style>

View File

@ -17,6 +17,7 @@
<common-volume-btn /> <common-volume-btn />
<common-toggle-play-mode-btn /> <common-toggle-play-mode-btn />
<common-list-add-modal v-model:show="isShowAddMusicTo" :music-info="playMusicInfo.musicInfo" /> <common-list-add-modal v-model:show="isShowAddMusicTo" :music-info="playMusicInfo.musicInfo" />
<common-play-list-button />
</div> </div>
</template> </template>

View File

@ -12,6 +12,7 @@ import {
playMusicInfo, playMusicInfo,
playedList, playedList,
tempPlayList, tempPlayList,
isShowPlaylist,
} from './state' } from './state'
import { getListMusicsFromCache } from '@renderer/store/list/action' import { getListMusicsFromCache } from '@renderer/store/list/action'
import { downloadList } from '@renderer/store/download/state' import { downloadList } from '@renderer/store/download/state'
@ -61,6 +62,10 @@ export const setShowPlayerDetail = (val: boolean) => {
isShowPlayerDetail.value = val isShowPlayerDetail.value = val
} }
export const setShowPlaylist = (val: boolean) => {
isShowPlaylist.value = val
}
export const setShowPlayComment = (val: boolean) => { export const setShowPlayComment = (val: boolean) => {
isShowPlayComment.value = val isShowPlayComment.value = val
} }

View File

@ -36,6 +36,8 @@ export const statusText = ref('')
export const isShowPlayerDetail = ref(false) export const isShowPlayerDetail = ref(false)
export const isShowPlaylist = ref(false)
export const isShowPlayComment = ref(false) export const isShowPlayComment = ref(false)
export const isShowLrcSelectContent = ref(false) export const isShowLrcSelectContent = ref(false)