From c64b1abe21064392c210351e867c30be2344a432 Mon Sep 17 00:00:00 2001 From: CosineSky <11737516+cosinesky@user.noreply.gitee.com> Date: Sat, 21 Dec 2024 13:01:59 +0800 Subject: [PATCH] - Synced with test branches. --- src/components/MainView.vue | 8 +- src/components/MusicAlbumView.vue | 341 ++++++++++++++++++++---------- src/views/HomePage.vue | 220 ++++++++++--------- 3 files changed, 354 insertions(+), 215 deletions(-) diff --git a/src/components/MainView.vue b/src/components/MainView.vue index 69253b3..107046c 100644 --- a/src/components/MainView.vue +++ b/src/components/MainView.vue @@ -1,4 +1,3 @@ -@@ -0,0 +1,126 @@ <script setup> import {ref} from "vue" import {getSongsByPlaylist} from "@/api/song"; @@ -25,12 +24,14 @@ getSongsByPlaylist({ class="tab-button" :class="{ 'active': currentTab === 'all' }" @click="handleTabClick('all')" - >鍏ㄩ儴</button> + >鍏ㄩ儴 + </button> <button class="tab-button" :class="{ 'active': currentTab === 'songs' }" @click="handleTabClick('songs')" - >闊充箰</button> + >闊充箰 + </button> </div> <div class="recommendations"> @@ -120,6 +121,7 @@ getSongsByPlaylist({ border-radius: 20px; margin-right: 20px; } + .active { background-color: #fff; color: #000; diff --git a/src/components/MusicAlbumView.vue b/src/components/MusicAlbumView.vue index ff98d05..9d4ccd8 100644 --- a/src/components/MusicAlbumView.vue +++ b/src/components/MusicAlbumView.vue @@ -1,23 +1,25 @@ <script setup> -import {computed, defineEmits, nextTick, onMounted, onUnmounted, ref} from "vue"; +import {computed, nextTick, onMounted, onUnmounted, ref, watch} from "vue"; import playButton from "../icon/playButton.vue"; import dots from "../icon/dots.vue"; import checkMark from "../icon/checkMark.vue"; -import {ElPopover} from "element-plus"; +import {ElMessage, ElPopover} from "element-plus"; import {backgroundColor, updateBackground} from "../utils/getBackgroundColor"; import pauseButton from "../icon/pauseButton.vue"; import {removePlaylist, removeSongFromPlaylist} from "../api/playlist"; const emit = defineEmits(); const props = defineProps({ - albumInfo: { + albumInfo: { // 绫诲瀷 锛歩d, userid, title ,description ,picPath,createTime,updateTime,songNum type: Object, required: true, }, - musicList: { + musicList: {// 绫诲瀷 锛歩d ,title, artist, album,description, picPath,uploadTime type: Object, required: true, }, + playFromLeftBar: null, + currentSongId: Number }); const gradientColor = computed(() => `linear-gradient(to bottom, ${backgroundColor.value} , #1F1F1F 50%)`) @@ -35,7 +37,7 @@ const recMusicList = ref([ }, ]) -let musicHoveredIndex = ref(-1); +let musicHoveredIndex = ref(null); let musicClickedIndex = ref(null); let musicPlayIndex = ref(null); let musicPauseIndex = ref(null); @@ -45,14 +47,12 @@ const resizeObserver = ref(null) // 鏀剧缉鏃剁殑缁勪欢澶勭悊 const handleResize = () => { - const albumContent = document.querySelector(".album-content"); - if (!albumContent) return; - const albums = document.querySelectorAll(".music-album-info"); const albumText = document.querySelectorAll(".album-text"); - + const albumContent = document.querySelector(".album-content"); // if (window.innerWidth > 0) // 涓撹緫闅愯棌 + console.log(albumContent.clientWidth); if (albumContent.clientWidth < 605) { albums.forEach(album => { album.style.visibility = "hidden"; @@ -60,6 +60,7 @@ const handleResize = () => { albumText.forEach(album => { album.style.visibility = "hidden"; }); + } else { albums.forEach(album => { album.style.visibility = "visible"; @@ -68,23 +69,25 @@ const handleResize = () => { album.style.visibility = "visible"; }); } - const albumImage = document.querySelector(".album-image"); const headerAlbumName = document.querySelector(".header-album-name"); // 姝屽崟鍥剧墖鍜屾枃瀛楃缉鏀� - if (albumImage && headerAlbumName) { - if (albumContent.clientWidth < 420) { - albumImage.style.width = "140px"; - albumImage.style.height = "140px"; - headerAlbumName.style.fontSize = "60px"; - headerAlbumName.style.marginBottom = "20px"; - } else { - albumImage.style.width = "220px"; - albumImage.style.height = "220px"; - headerAlbumName.style.fontSize = "100px"; - headerAlbumName.style.marginBottom = "35px"; - } + if (albumContent.clientWidth < 420) { + albumImage.style.width = "120px"; + albumImage.style.height = "120px"; + headerAlbumName.style.fontSize = "40px"; + headerAlbumName.style.marginBottom = "20px"; + } else { + albumImage.style.width = "160px"; + albumImage.style.height = "160px"; + headerAlbumName.style.fontSize = "80px"; + headerAlbumName.style.marginBottom = "35px"; } + //馃檹 + const fixedTipArea = document.querySelector(".fixed-tips"); + const fixedPlayArea = document.querySelector(".fixed-play-area"); + fixedPlayArea.style.width = (albumContent.clientWidth - 20) + "px"; + fixedTipArea.style.width = (albumContent.clientWidth - 16) + "px"; } const debounce = (fn, delay) => { @@ -115,8 +118,41 @@ onUnmounted(() => { if (resizeObserver.value) { resizeObserver.value.disconnect(); } + popovers.value = null; }) +const handelScroll = (event) => { + + const playArea = document.querySelector(".play-area"); + const fixedPlayArea = document.querySelector(".fixed-play-area"); + const tipArea = document.querySelector(".tips"); + const fixedTipArea = document.querySelector(".fixed-tips"); + const albumContent = document.querySelector(".album-content"); + + const offsetHeight = albumContent.offsetTop; + const stickyPlayY = playArea.offsetTop - offsetHeight; + const stickyTipY = tipArea.offsetTop - offsetHeight; + const curOffset = offsetHeight - albumContent.getBoundingClientRect().top; + + console.log(stickyPlayY, stickyTipY); + if (curOffset >= stickyPlayY) { + fixedPlayArea.style.opacity = "1"; + fixedPlayArea.style.top = offsetHeight + "px"; + + + fixedPlayArea.style.width = (albumContent.clientWidth - 20) + "px"; + } else { + fixedPlayArea.style.opacity = "0"; + } + if (curOffset + fixedPlayArea.scrollHeight >= stickyTipY) { + fixedTipArea.style.display = "flex"; + fixedTipArea.style.top = offsetHeight + fixedPlayArea.scrollHeight + 'px'; + + } else { + fixedTipArea.style.display = "none"; + } +} + window.onscroll = () => { const playArea = document.querySelector(".play-area"); const fixedPlayArea = document.querySelector(".fixed-play-area"); @@ -138,11 +174,28 @@ window.onscroll = () => { } } +watch(props.playFromLeftBar, () => { + playFromId(props.playFromLeftBar) +}) + + +const popovers = ref([]) +const getPopoverIndex = (popover) => { + if (popover) { + popovers.value.push(popover); + } +} +const closePopover = (e) => { + popovers.value.forEach((item) => { + item.hide(); + }) +} + + //TODO: const enterPersonalSpace = () => { } -// const editAlbumDescription = () => { -// } + const removeAlbum = (albumId) => { removePlaylist({ playlist_id: albumId, @@ -154,12 +207,13 @@ const removeAlbum = (albumId) => { const playFromId = (musicId) => { if (musicId === null) { // 浠庡ご寮€濮嬫挱鏀� - musicPlayIndex = musicList.value[0].id; + musicPlayIndex.value = props.musicList[0].id; } else { - musicPlayIndex = musicId; + musicPlayIndex.value = musicId; } + + emit('switchSongs', props.albumInfo, musicPlayIndex.value); musicPauseIndex = null; - emit('switchSongs', props.albumInfo, musicHoveredIndex.value); } const addToFavorite = (musicId) => { } @@ -182,28 +236,43 @@ const editAlbumDescription = (albumId) => { const editDesc = document.querySelector(".edit-desc"); editDesc.style.visibility = "visible"; } + const quitEdit = () => { const editDesc = document.querySelector(".edit-desc"); editDesc.style.visibility = "hidden"; } +const addRecommendMusic = (musicId) => { + console.log(musicId); + //TODO:娣诲姞姝屾洸鍒版寚瀹氱殑姝屽崟 + ElMessage({ + message: "娣诲姞鑷�: " + props.albumInfo.title, + grouping: true, + type: 'info', + offset: 16, + customClass: "reco-message", + duration: 4000, + }) +} + </script> <template> - <div class="album-content" :style="{backgroundImage: gradientColor}"> + <div class="album-content" :style="{backgroundImage: gradientColor}" @mousewheel="handelScroll"> <div class="header"> - <img :src="albumInfo.picPath" alt="" class="album-image" @load="updateBackground"/> + <!-- .<img src="../assets/pictures/songs/2.jpg" alt="" class="album-image" @load="updateBackground"/>--> + <img :src="albumInfo.picPath" alt="" class="album-image" @load="updateBackground(albumInfo.picPath)"/> <div class="header-content"> <p style="text-align: left;margin:20px 0 0 15px">姝屽崟</p> - <p class="header-album-name" style="font-weight: bolder;font-size:100px;margin:10px 0 35px 10px;"> + <p class="header-album-name" style="font-weight: bolder;font-size:80px;margin:10px 0 35px 10px;"> {{ albumInfo.title }}</p> <div class="header-content-detail"> - <p style="margin-left:6px">{{ musicList.length }} 棣栨瓕鏇�</p> - <p style="margin: 0 9px 0 6px"> 鈥� </p> + <p class="header-creator" @click="enterPersonalSpace">{{ albumInfo.description }}</p> + <p style="padding-right: 6px ">鈥�</p> <p v-if="albumInfo.updateTime !== undefined"> {{ albumInfo.updateTime.substring(0, 10) }} </p> - <p style="margin: 0 6px 0 9px"> 鈥� </p> - <p class="header-creator" @click="enterPersonalSpace">{{ albumInfo.description }}</p> + <p style="padding: 0 2px 0 6px">鈥�</p> + <p style="margin-left:6px">{{ musicList.length }} 棣栨瓕鏇�</p> </div> </div> </div> @@ -218,20 +287,24 @@ const quitEdit = () => { @click="pauseMusic(musicPlayIndex)" style="position: absolute; top:24%;left:25%;color: #000000"/> </div> + <!-- 锛歳ef涓嚱鏁版墽琛屾椂锛岀粍浠跺凡缁忔覆鏌撳ソ锛屽苟灏嗘湰缁勪欢浣滀负鍙傛暟浼犲叆鍑芥暟--> <el-popover - style="border-radius: 10px;" + style="border-radius: 10px" :width="400" trigger="click" + popper-class="my-popover" + :ref="getPopoverIndex" :hide-after=0> <template #reference> <dots class="more-info"/> </template> - <ul> - <li @click="editAlbumDescription">缂栬緫姝屽崟璇︽儏</li> - <li @click="removeAlbum(albumInfo.id)">鍒犻櫎姝屽崟</li> + <ul @click="closePopover"> + <li @click="()=>{editAlbumDescription(albumInfo.id)}">缂栬緫姝屽崟璇︽儏</li> + <li @click="">鍒犻櫎姝屽崟</li> </ul> </el-popover> </div> + <div class="fixed-play-area" :style="{background :`${backgroundColor}`}"> <div class="opacity-wrapper"> <div class="play-button"> @@ -249,14 +322,15 @@ const quitEdit = () => { <p style="position:absolute; left:45px">#</p> <p style="position:absolute; left:140px">鏍囬</p> <p class="album-text" style="position:absolute; left:62%">涓撹緫</p> - <p style="margin-left: auto; margin-right:100px">鏃堕棿</p> + <p style="margin-left: auto; margin-right:55px">鏃堕棿</p> </div> <div class="edit-desc" @blur="quitEdit"> <div data-testid="playlist-edit-details-modal" class="main-edit-desc"> <div class="edit-desc-header"> <h1 class="encore-text encore-text-title-small" data-encore-id="text">缂栬緫璇︽儏</h1> <button class="edit-desc-header-button" @click="quitEdit"> - <svg data-encore-id="icon" role="img" aria-label="鍏抽棴" aria-hidden="false" viewBox="0 0 16 16" + <svg data-encore-id="icon" role="img" aria-label="鍏抽棴" aria-hidden="false" + viewBox="0 0 16 16" class="small-svg"> <path d="M2.47 2.47a.75.75 0 0 1 1.06 0L8 6.94l4.47-4.47a.75.75 0 1 1 1.06 1.06L9.06 8l4.47 4.47a.75.75 0 1 1-1.06 1.06L8 9.06l-4.47 4.47a.75.75 0 0 1-1.06-1.06L6.94 8 2.47 3.53a.75.75 0 0 1 0-1.06Z"></path> @@ -268,7 +342,8 @@ const quitEdit = () => { <div class="edit-desc-img"> <div class="edit-desc-img-1" draggable="false"> <div class="edit-desc-img-1-1 edit-desc-img-1"> - <svg data-encore-id="icon" role="img" aria-hidden="true" data-testid="playlist" viewBox="0 0 24 24" + <svg data-encore-id="icon" role="img" aria-hidden="true" data-testid="playlist" + viewBox="0 0 24 24" class="large-svg"> <path d="M6 3h15v15.167a3.5 3.5 0 1 1-3.5-3.5H19V5H8v13.167a3.5 3.5 0 1 1-3.5-3.5H6V3zm0 13.667H4.5a1.5 1.5 0 1 0 1.5 1.5v-1.5zm13 0h-1.5a1.5 1.5 0 1 0 1.5 1.5v-1.5z"></path> @@ -277,20 +352,24 @@ const quitEdit = () => { </div> <div class="edit-desc-img-2"> <div class="edit-desc-img-2-1"> - <button data-testid="edit-image-button" class="edit-desc-img-2-button" aria-haspopup="true" + <button data-testid="edit-image-button" class="edit-desc-img-2-button" + aria-haspopup="true" type="button"> <div class="edit-desc-img-2-1-1 icon"> - <svg data-encore-id="icon" role="img" aria-hidden="true" viewBox="0 0 24 24" class="large-svg"> + <svg data-encore-id="icon" role="img" aria-hidden="true" viewBox="0 0 24 24" + class="large-svg"> <path d="M17.318 1.975a3.329 3.329 0 1 1 4.707 4.707L8.451 20.256c-.49.49-1.082.867-1.735 1.103L2.34 22.94a1 1 0 0 1-1.28-1.28l1.581-4.376a4.726 4.726 0 0 1 1.103-1.735L17.318 1.975zm3.293 1.414a1.329 1.329 0 0 0-1.88 0L5.159 16.963c-.283.283-.5.624-.636 1l-.857 2.372 2.371-.857a2.726 2.726 0 0 0 1.001-.636L20.611 5.268a1.329 1.329 0 0 0 0-1.879z"></path> </svg> - <span class="encore-text encore-text-body-medium" data-encore-id="text">閫夋嫨鐓х墖</span></div> + <span class="encore-text encore-text-body-medium" + data-encore-id="text">閫夋嫨鐓х墖</span></div> </button> </div> </div> <div class="edit-desc-img-3"> <button class="edit-desc-img-3-button" type="button"> - <svg data-encore-id="icon" role="img" aria-hidden="true" viewBox="0 0 16 16" class="small-svg"> + <svg data-encore-id="icon" role="img" aria-hidden="true" viewBox="0 0 16 16" + class="small-svg"> <path d="M3 8a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm6.5 0a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zM16 8a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"></path> </svg> @@ -298,7 +377,8 @@ const quitEdit = () => { </div> </div> <div class="edit-desc-input-name"> - <input data-testid="playlist-edit-details-name-input" id="text-input-c673a65959365e7f" type="text" + <input data-testid="playlist-edit-details-name-input" id="text-input-c673a65959365e7f" + type="text" class="edit-desc-input-name-1" placeholder="娣诲姞鍚嶇О" value="鎴戠殑 #9 姝屽崟"> </div> <div class="edit-desc-input-desc"> @@ -333,11 +413,13 @@ const quitEdit = () => { @dblclick="playFromId(music.id)" :style="{backgroundColor: musicClickedIndex===music.id? '#404040': musicHoveredIndex === music.id ? 'rgba(54,54,54,0.7)' :'rgba(0,0,0,0)', - }"> + }"> <!--@click浜嬩欢鍐欏湪script涓殑鍑芥暟閲� 鏃犳硶鍙婃椂瑙﹀彂:style涓殑鏍峰紡!!!--> <div :style="{visibility: musicHoveredIndex === music.id||musicPlayIndex === music.id ? 'hidden' : 'visible' }"> - {{music.number}} + {{ + musicList.indexOf(music) + 1 + }} </div> <play-button @click="playFromId(music.id)" style="position: absolute;left: 14px;cursor: pointer" v-if="(musicHoveredIndex === music.id&&musicPlayIndex!==music.id)||musicPauseIndex===music.id" @@ -352,7 +434,6 @@ const quitEdit = () => { src="https://open.spotifycdn.com/cdn/images/equaliser-animated-green.f5eb96f2.gif"> <div class="music-detailed-info"> - <!--TODO: img src to be changed--> <img class="music-image" :src="music.picPath" alt="姝屾洸鍥剧墖"/> @@ -367,23 +448,26 @@ const quitEdit = () => { {{ music.artist }}</p> </div> </div> + <div class="music-album-info" :style="{color:musicHoveredIndex === music.id? 'white' : '#b2b2b2'}"> {{ music.album }} </div> - <div class="music-time-info" :style="{color:musicHoveredIndex === music.id? 'white' : '#b2b2b2'}"> -<!-- {{ music.uploadTime.substring(0, 10) }}--> - </div> <div class="music-right-info"> - <el-popover class="music-dropdown-options" - :width="400" - trigger="click" - :hide-after=0> + <el-popover + :ref="getPopoverIndex" + class="music-dropdown-options" + popper-class="my-popover" + :width="400" + trigger="click" + :hide-after=0 + + > <template #reference> <check-mark class="check-mark" :style="{visibility: musicHoveredIndex === music.id ? 'visible' : 'hidden'}"/> </template> - <ul> - //TODO: 杩欓噷闇€瑕佹墍鏈夌殑姝屽崟 + <ul @click="closePopover"> + <!-- TODO: 杩欓噷闇€瑕佹墍鏈夌殑姝屽崟--> <li @click="addToFavorite(music.id)"></li> </ul> </el-popover> @@ -392,16 +476,21 @@ const quitEdit = () => { :style="{color:musicHoveredIndex === music.id? 'white' : '#b2b2b2'}">{{ music.upload_time }} + <!--TODO: 瑙e喅鎾斁鏃堕棿闂--> </div> - <el-popover class="music-dropdown-options" - :width="400" - trigger="click" - :hide-after=0> + <el-popover + :ref="getPopoverIndex" + class="music-dropdown-options" + popper-class="my-popover" + :width="400" + trigger="click" + :hide-after=0 + > <template #reference> <dots class="music-more-info"/> </template> - <ul> - <li @click="removeMusicFromAlbum(albumInfo.id, music.id)">鍒犻櫎姝屾洸</li> + <ul @click="closePopover"> + <li @click="removeMusicFromAlbum(music.id)">鍒犻櫎姝屾洸</li> </ul> </el-popover> @@ -411,13 +500,13 @@ const quitEdit = () => { </div> - - <!--鎺ㄨ崘姝屾洸--> + <!--TODO:鎺ㄨ崘姝屾洸鐨勭粏鑺傚鐞�--> <div class="other-info"> <div style="margin-left:20px;margin-bottom:20px;"> <div style="display: flex;text-align: left;justify-content: center;flex-direction: column"> <span style="color:white;font-size: 30px;font-weight: bolder">鎺ㄨ崘</span> - <span style="color:grey;font-size: 20px">鏍规嵁姝ゆ瓕鍗曞寘鍚殑鍐呭鎺ㄨ崘</span> + <span style="color:grey;font-size: 20px">鏍规嵁姝ゆ瓕鍗曞寘鍚殑鍐呭鎺ㄨ崘 + </span> </div> </div> @@ -437,7 +526,7 @@ const quitEdit = () => { <div :style="{visibility: musicHoveredIndex === music.id||musicPlayIndex === music.id ? 'hidden' : 'visible' }"> {{ - music.number + recMusicList.indexOf(music) + 1 }} </div> <play-button @click="playFromId(music.id)" style="position: absolute;left: 33px;cursor: pointer" @@ -454,17 +543,17 @@ const quitEdit = () => { <div class="music-detailed-info"> <!--TODO: img src to be changed--> <img class="music-image" - :src="music.img" + :src="music.picPath" alt="姝屾洸鍥剧墖"/> <div class="music-name-author" style="padding-left: 5px;"> <p @click="enterMusicDescription(music.id)" class="music-name" :style="{color : musicPlayIndex ===music.id? '#1ED660':''}" :class="[musicPlayIndex === music.id ? 'music-after-click' : '']" - >{{ music.name }}</p> + >{{ music.title }}</p> - <p @click="enterAuthorDescription(music.author)" class="music-author" + <p @click="enterAuthorDescription(music.artist)" class="music-author" :style="{color:musicHoveredIndex === music.id? 'white' : '#b2b2b2'}"> - {{ music.author }}</p> + {{ music.artist }}</p> </div> </div> @@ -473,35 +562,7 @@ const quitEdit = () => { {{ music.album }} </div> <div class="music-right-info"> - <el-popover class="music-dropdown-options" - :width="400" - trigger="click" - :hide-after=0> - <template #reference> - <check-mark class="check-mark" - :style="{visibility: musicHoveredIndex === music.id ? 'visible' : 'hidden'}"/> - </template> - <ul> - //TODO: 杩欓噷闇€瑕佹墍鏈夌殑姝屽崟 - <li @click="addToFavorite(music.id)"></li> - </ul> - </el-popover> - - <div style="margin-left: auto;margin-right: 15px; color: #b2b2b2" - :style="{color:musicHoveredIndex === music.id? 'white' : '#b2b2b2'}"> - {{ music.upload_time }} - </div> - <el-popover class="music-dropdown-options" - :width="400" - trigger="click" - :hide-after=0> - <template #reference> - <dots class="music-more-info"/> - </template> - <ul> - <li @click="removeMusicFromAlbum(music.id)">鍒犻櫎姝屾洸</li> - </ul> - </el-popover> + <button class="reco-add-button" @click="addRecommendMusic(music.id)">娣诲姞</button> </div> @@ -528,6 +589,7 @@ li:hover { border-radius: 12px; } + p { text-align: left; white-space: nowrap; @@ -537,10 +599,11 @@ p { } .header, .play-area, .tips, .musicList, .other-info { - z-index: 10; + z-index: 0; padding: 20px; width: 100%; box-sizing: border-box; + user-select: none; } .album-content { @@ -552,11 +615,11 @@ p { display: flex; flex-direction: column; width: 100%; + overflow-x: auto; /*鍗冧竾涓嶈兘鍒狅紝涓嶇劧鑳屾櫙榛戜竴鍗�*/ } .header { - z-index:0; display: flex; flex-direction: row; } @@ -568,8 +631,8 @@ p { .album-image { border-radius: 6%; - width: 220px; - height: 220px; + width: 160px; + height: 160px; margin-top: 30px; margin-left: 15px; margin-right: 20px; @@ -580,6 +643,8 @@ p { flex-direction: column; height: 100%; position: relative; + flex-grow: 1; + min-width: 0; } .header-content-detail { @@ -625,13 +690,13 @@ p { .fixed-play-area { top: 0; z-index: 11; - width: 100%; opacity: 0; transition: opacity 0.2s ease-out; border-radius: 12px 12px 0 0; - position: fixed; + position: fixed; /**/ display: flex; padding: 10px 0 10px 20px; + width: inherit; } @@ -695,6 +760,8 @@ p { display: flex; align-items: center; padding: 10px 0 10px 25px; + flex-grow: 1; + min-width: 0; } /*闊充箰琚偣鍑诲悗鐨勬牱寮�*/ @@ -740,6 +807,7 @@ p { position: absolute; left: 60%; color: #b2b2b2; + text-overflow: ellipsis; } .music-album-info:hover { @@ -819,10 +887,38 @@ li:hover { margin-top: 20px; } +.reco-add-button { + color: white; + margin-right: 16px; + box-sizing: border-box; + background-color: transparent; + border-radius: 9999px; + cursor: pointer; + position: relative; + text-align: center; + transition-duration: 33ms; + transition-property: background-color, border-color, color, box-shadow, filter, transform; + user-select: none; + vertical-align: middle; + transform: translate3d(0px, 0px, 0px); + padding-block: 3px; + padding-inline: 15px; + border: 1px solid #818181; + min-inline-size: 0; + min-block-size: 32px; + display: inline-flex; + align-items: center; + + &:hover { + border: 1px solid #f5f5f5; + scale: 1.1; + } +} + /* new-elements */ .edit-desc { visibility: hidden; - z-index: 1919810; + z-index: 1000; background-color: rgba(0, 0, 0, .7); bottom: 0; display: flex; @@ -838,6 +934,7 @@ li:hover { justify-content: center; overflow: hidden; } + .main-edit-desc { display: -webkit-box; display: -ms-flexbox; @@ -854,6 +951,7 @@ li:hover { min-height: 384px; width: 524px; } + .edit-desc-header { display: flex; -webkit-box-pack: justify; @@ -861,6 +959,7 @@ li:hover { justify-content: space-between; padding: 24px; } + .edit-desc-header-button { align-self: end; background-color: transparent; @@ -880,6 +979,7 @@ li:hover { -ms-flex-align: center; align-items: center; } + .edit-desc-text { display: grid; grid-template: 32px 132px 32px auto / 180px 1fr; @@ -891,6 +991,7 @@ li:hover { grid-gap: 16px; padding: 0 24px 24px; } + .edit-desc-img { grid-area: album-image; height: 180px; @@ -898,11 +999,13 @@ li:hover { position: relative; /* width: 180px; */ } + .edit-desc-img-1 { border-radius: 4px; height: 100%; width: 100%; } + .edit-desc-img-1-1 { display: -webkit-box; display: -ms-flexbox; @@ -917,15 +1020,18 @@ li:hover { justify-content: center; -webkit-box-shadow: 0 4px 60px rgba(0, 0, 0, .5); box-shadow: 0 4px 60px rgba(0, 0, 0, .5); + &:hover { display: none; } } + .large-svg { fill: currentcolor; width: 48px; height: 48px; } + .edit-desc-img-2 { bottom: 0; left: 0; @@ -933,10 +1039,12 @@ li:hover { right: 0; top: 0; } + .edit-desc-img-2-1 { height: 100%; width: 100%; } + .edit-desc-img-2-button { background-color: #282828; color: #fff; @@ -955,11 +1063,13 @@ li:hover { opacity: 0; padding: 0; } + .edit-desc-img-2-1-1 { margin-top: 16px; -webkit-transition: opacity .2s; transition: opacity .2s; } + .edit-desc-img-3 { right: 8px; height: 32px; @@ -967,6 +1077,7 @@ li:hover { top: 8px; width: 32px; } + @media (hover: hover) { .edit-desc-img-3-button:not([data-context-menu-open=true]) { opacity: 0; @@ -974,6 +1085,7 @@ li:hover { position: unset; } } + .edit-desc-img-3-button { background-color: rgba(0, 0, 0, .3); border: none; @@ -990,21 +1102,25 @@ li:hover { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; + &:hover { opacity: 0; pointer-events: none; position: unset; } } + .small-svg { height: 16px; width: 16px; } + .edit-desc-input-name { grid-area: title; position: relative; margin-right: 8px; } + .edit-desc-input-name-1 { background: hsla(0, 0%, 100%, .1); border: 1px solid transparent; @@ -1018,11 +1134,13 @@ li:hover { -webkit-box-shadow: inset 0 -2px #343030; box-shadow: inset 0 -2px 0 0 #343030; } + .edit-desc-input-desc { grid-area: description; margin-top: 8px; position: relative; } + .edit-desc-input-desc-1 { background: hsla(0, 0%, 100%, .1); border: 1px solid transparent; @@ -1035,6 +1153,7 @@ li:hover { width: 100%; height: 70%; } + .edit-desc-button { display: -webkit-box; display: -ms-flexbox; @@ -1045,6 +1164,7 @@ li:hover { -ms-flex-align: center; align-items: center; } + .edit-desc-button-1 { box-sizing: border-box; -webkit-tap-highlight-color: transparent; @@ -1067,6 +1187,7 @@ li:hover { min-inline-size: 0px; align-self: center; } + .edit-desc-button-1-1 { box-sizing: border-box; -webkit-tap-highlight-color: transparent; @@ -1086,6 +1207,7 @@ li:hover { transition-property: background-color, transform; transition-duration: 33ms; } + .encore-text { -webkit-box-sizing: border-box; box-sizing: border-box; @@ -1095,12 +1217,15 @@ li:hover { font-size: 13px; white-space: normal; } + .encore-text-title-small { font-size: 1.5rem; } + .final-tip { grid-area: disclaimer; } + .encore-text-marginal-bold { font-weight: 700; } diff --git a/src/views/HomePage.vue b/src/views/HomePage.vue index 260d568..4c006d0 100644 --- a/src/views/HomePage.vue +++ b/src/views/HomePage.vue @@ -1,8 +1,7 @@ /* eslint-disable */ <script setup> // Vue Basics -import {onMounted, ref, watch, computed} from "vue" -import {router} from "../router"; +import {computed, onMounted, ref} from "vue" // Assets import defaultBg from '../assets/pictures/Eason.png' @@ -11,10 +10,10 @@ import {LOOP_MODE, NORMAL_MODE, PAUSE, PLAY, RANDOM_MODE} from "../assets/base64 // Components import Header from "../components/Header"; import Comment from "../components/Comment"; -import MainView from "../components/MainView.vue"; import LeftSideBar from "../components/LeftSideBar"; import SearchView from "@/components/SearchView.vue"; import MusicAlbumView from "../components/MusicAlbumView.vue"; +import MainView from "../components/MainView.vue"; // APIs import {getSongsByPlaylist} from "../api/song"; @@ -331,7 +330,6 @@ const userToken = ref(JSON.parse(sessionStorage.getItem('user-token'))); const currentUserId = ref(userToken.value.id); - /* SONGS */ @@ -371,14 +369,14 @@ const switchSongs = (del) => { currentSongId.value = songs.value[currentSongIndex.value].id; } -const switchToSong = (index) => { - if (index === currentSongIndex.value) { +const switchToSong = (index, isDiffPlaylist) => { + if (index === currentSongIndex.value && !isDiffPlaylist) { return; } - + currentSongIndex.value = index; currentSongId.value = songs.value[index].id; - + if (song) { controlIcons.forEach(controlIcon => { controlIcon.src = PLAY; @@ -394,11 +392,13 @@ const switchToSong = (index) => { } const switchToPlaylist = (playlist, songId) => { + console.log(playlist, songId) + currentPlaylist.value = playlist; displayingPlaylist.value = playlist; currentPlaylistId.value = playlist.id; theme.change(currentPlaylist.value.picPath); - + getSongsByPlaylist({ playlist_id: currentPlaylistId.value, }).then((res) => { @@ -407,14 +407,14 @@ const switchToPlaylist = (playlist, songId) => { currentSongId.value = songId; for (let i = 0; i < songs.value.length; i++) { if (songs.value[i].id === songId) { - switchToSong(i); + switchToSong(i, true); parseLrc(songs.value[i].lyricsPath).then(res => { lyrics.value = res; }); break; } } - + }).catch(e => { console.log("Error while switching playlists!"); }); @@ -429,8 +429,10 @@ const currentPlaylist = ref(2); const currentPlaylistId = ref(2); const displayingPlaylist = ref(2); const receivePlaylistId = (value) => { + console.log(value) currentPlaylist.value = value; currentPlaylistId.value = value.id; + console.log("Current Playlist Id:", currentPlaylistId.value) getSongsByPlaylist({ playlist_id: currentPlaylistId.value, }).then((res) => { @@ -470,7 +472,7 @@ function receiveDataFromHeader(data) { 2 - Comments 3 - Search Results */ -const midComponents = ref(0); +const midComponents = ref(1); const setMidComponents = (val) => { midComponents.value = val; } @@ -506,7 +508,7 @@ onMounted(() => { songs.value = res.data.result; displayingSongs.value = res.data.result; currentSongId.value = songs.value[0].id; - + // TODO: currentSongIndex != currentSongId ? parseLrc(songs.value[currentSongIndex.value].lyricsPath).then(res => { lyrics.value = res; @@ -519,28 +521,31 @@ onMounted(() => { }); }) +let playFromLeftBarAlbum = ref(null); </script> <template> <div class="body" v-show="!isPlayingPage" @click="unSelectAlbum"> - + <!-- MAIN & RIGHT CONTENT --> <Header class="header" @headData="receiveDataFromHeader" allow-search></Header> <img class="logo" src="../assets/pictures/logos/logo3.png" alt=""> - <left-side-bar class="left-side-bar" @setCurrentPlaylist="receiveDisplayingPlaylist"/> + <left-side-bar class="left-side-bar" @playFromLeftBar="(id)=>{playFromLeftBarAlbum = id }" + @setCurrentPlaylist="receiveDisplayingPlaylist"/> <div class="content" :class="{ 'full-width': !showRightContent }"> <div class="main-view" :class="{ 'expanded': !showRightContent }"> <el-container v-if="midComponents == 0" class="playlist-container" style="overflow: auto; height: 730px ;border-radius: 12px"> <MainView/> </el-container> - <el-container v-if="midComponents == 1" class="playlist-container" - style="overflow: auto; height: 730px ;border-radius: 12px"> + <!--height: 730px --> + <div v-if="midComponents == 1" class="playlist-container" + style="overflow: scroll; border-radius: 12px"> <MusicAlbumView :album-info="displayingPlaylist" :music-list="displayingSongs" - @switchSongs="switchToPlaylist"/> - </el-container> + @switchSongs="switchToPlaylist" :playFromLeftBar="playFromLeftBarAlbum"/> + </div> <el-container v-if="midComponents == 2" class="playlist-container" - style="overflow: auto; height: 730px ;border-radius: 12px" > + style="overflow: auto; height: 730px ;border-radius: 12px"> <el-button class="exit-search" data-tooltip="閫€鍑�" :class="{ 'adjusted-position': showRightContent }" @@ -565,7 +570,7 @@ onMounted(() => { <h2>{{ songs[currentSongIndex].title }}</h2> <p>{{ songs[currentSongIndex].artist }}</p> </div> - + <div class="current-playlist" style="margin-top: 20px"> <el-container class="playlist-container" style="height: 64px"> <div class="playlist-item" style="display: flex; flex-direction: row"> @@ -580,10 +585,10 @@ onMounted(() => { </div> </div> </el-container> - <el-container class="playlist-container" style="overflow: auto; height: 384px"> + <el-container class="playlist-container" style="overflow: auto; height: 384px; display: flex; flex-direction: column"> <div v-for="(song, index) in songs" class="playlist-item" style="display: flex; flex-direction: row"> - <div @click="switchToSong(index)" style="cursor: pointer"> + <div @click="switchToSong(index, false)" style="cursor: pointer"> <img :src="song.picPath" alt="" :class="{ 'playing': index === currentSongIndex }" /> @@ -612,7 +617,7 @@ onMounted(() => { </div> </div> </div> - + <!-- FOOTER --> <footer> @@ -644,7 +649,7 @@ onMounted(() => { {{ songs[currentSongIndex].artist }}</p> </div> </div> - + <el-card class="bottom-controller bottom-component" style=" position: absolute; left: 50%; @@ -678,29 +683,29 @@ onMounted(() => { </el-card> <div class="right-controls"> - <div class="feature-icon" - data-tooltip="鍒嗕韩" - :class="{ active: isSharing }"> - <img src="../assets/icons/comment/share.png" alt="鍒嗕韩"> - </div> - - <div class="feature-icon" - data-tooltip="璇勮" - :class="{ active: midComponents === 2 }" - @click="setMidComponents(2)"> - <img src="../assets/icons/comment/comment.png" alt="璇勮"> - </div> - - <div class="feature-icon" - data-tooltip="鎾斁闃熷垪" - :class="{ active: showRightContent }" - @click="showRightContent = !showRightContent"> - <img src="../assets/icons/queue.png" alt="鎾斁闃熷垪"> - </div> - </div> + <div class="feature-icon" + data-tooltip="鍒嗕韩" + :class="{ active: isSharing }"> + <img src="../assets/icons/comment/share.png" alt="鍒嗕韩"> + </div> + + <div class="feature-icon" + data-tooltip="璇勮" + :class="{ active: midComponents === 2 }" + @click="setMidComponents(2)"> + <img src="../assets/icons/comment/comment.png" alt="璇勮"> + </div> + + <div class="feature-icon" + data-tooltip="鎾斁闃熷垪" + :class="{ active: showRightContent }" + @click="showRightContent = !showRightContent"> + <img src="../assets/icons/queue.png" alt="鎾斁闃熷垪"> + </div> + </div> </footer> </div> - + <!-- PLAYING PAGE --> <div v-show="isPlayingPage" class="playing-page"> @@ -711,7 +716,8 @@ onMounted(() => { :key="index" :class="{ active: index === currentLineIndex }" class="lyrics-line" - >{{ line.text }}</div> + >{{ line.text }} + </div> <h1 v-if="lyrics.length === 0" style=" font-size: 24px; color: #9d9d9d; @@ -720,8 +726,8 @@ onMounted(() => { ">Ouch锛佽姝屾洸鏆傛棤姝岃瘝锛�</h1> </div> </div> - -<!-- <div class="player" :style="{ backgroundImage: gradientColor }">--> + + <!-- <div class="player" :style="{ backgroundImage: gradientColor }">--> <div class="player"> <div class="background"></div> <div class="player-content"> @@ -853,7 +859,7 @@ h1 { background-color: rgb(19, 19, 19); /* rgba(0, 0, 0, 1); */ background-repeat: no-repeat; background-size: cover; - + /* 鍘熷厛main涓殑鍐呭 height: 700px; width: 95%; @@ -872,8 +878,9 @@ h1 { "left-sidebar main-view main-view" "now-playing-bar now-playing-bar now-playing-bar"; grid-template-columns: auto 1fr; - grid-template-rows: auto 1fr auto; - row-gap: 8px; + grid-template-rows: 10% 80% 10%; + grid-auto-rows: min-content; + column-gap: 8px; padding: 8px; overflow: hidden; @@ -889,15 +896,17 @@ h1 { left-side-bar { grid-area: left-sideBar; - + } .content { grid-area: main-view; + } footer { grid-area: now-playing-bar; + } /* MAIN MENU */ @@ -923,7 +932,6 @@ footer { justify-content: space-between; height: 75px; width: 100%; - margin: 20px 0 0 0; backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); } @@ -988,20 +996,26 @@ footer { /* CONTENT 鍖呭惈涓棿鍜屽彸杈规爮 鏄痝rid甯冨眬*/ .content { + height: 100%; display: grid; grid-template-columns: 1fr auto; + grid-template-rows: 100%; transition: all 0.3s ease; column-gap: 8px; + } .content.full-width { grid-template-columns: 100% !important; - + } /* LEFT CONTENT */ -.main-view > { +.main-view { + overflow: scroll; +} +.main-view > { display: flex; flex-direction: column; justify-content: center; @@ -1012,7 +1026,7 @@ footer { } .main-view.expanded { - + margin: 0; padding: 0; width: 100%; @@ -1121,6 +1135,7 @@ footer { } /* Containers Scrollbar Style */ +/* .playlist-container::-webkit-scrollbar { height: 10px; display: none; @@ -1130,6 +1145,7 @@ footer { height: 10px; display: none; } +*/ .album-container::-webkit-scrollbar { height: 10px; @@ -1389,7 +1405,7 @@ footer { } .main-view { - + } .swiper-slide { @@ -1425,7 +1441,7 @@ footer { } .main-view { - padding: 30px 20px 20px; + /*padding: 30px 20px 20px;*/ } .swiper-slide img { @@ -1586,6 +1602,7 @@ footer { transform: translateY(0); } } + /** .share-icon, .queue-icon, @@ -1609,66 +1626,66 @@ footer { */ .right-controls { - display: flex; - align-items: center; - gap: 16px; - position: absolute; - right: 80px; + display: flex; + align-items: center; + gap: 16px; + position: absolute; + right: 80px; } .feature-icon { - display: flex; - align-items: center; - justify-content: center; - width: 32px; - height: 32px; - border-radius: 50%; - background: rgba(255, 255, 255, 0.1); - transition: all 0.2s ease; - position: relative; - cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border-radius: 50%; + background: rgba(255, 255, 255, 0.1); + transition: all 0.2s ease; + position: relative; + cursor: pointer; } .feature-icon:hover { - background: rgba(255, 255, 255, 0.2); - transform: translateY(-2px); + background: rgba(255, 255, 255, 0.2); + transform: translateY(-2px); } .feature-icon img { - width: 16px; - height: 16px; - transition: all 0.2s ease; + width: 16px; + height: 16px; + transition: all 0.2s ease; } .feature-icon:hover img { - filter: brightness(1.2); + filter: brightness(1.2); } .feature-icon[data-tooltip]:hover::after { - content: attr(data-tooltip); - position: absolute; - top: -25px; - left: 50%; - transform: translateX(-50%); - background-color: #282828; - color: white; - padding: 4px 8px; - border-radius: 4px; - font-size: 12px; - white-space: nowrap; - z-index: 1000; + content: attr(data-tooltip); + position: absolute; + top: -25px; + left: 50%; + transform: translateX(-50%); + background-color: #282828; + color: white; + padding: 4px 8px; + border-radius: 4px; + font-size: 12px; + white-space: nowrap; + z-index: 1000; } .feature-icon.active { - background: #1db954; + background: #1db954; } .feature-icon.active img { - filter: brightness(0) invert(1); + filter: brightness(0) invert(1); } .feature-icon.active:hover { - background: #1ed760; + background: #1ed760; } /* 閫€鍑烘悳绱㈠浘鏍� */ @@ -1721,19 +1738,14 @@ footer { } - - - - - - +/* 娌″繀瑕� 鍦╝pp涓啓杩囦簡 html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; -} +}*/ .player { position: relative; @@ -1858,8 +1870,8 @@ html, body { } .comment-container { - position: relative; - background: transparent; + position: relative; + background: transparent; } </style> -- GitLab