diff --git a/src/components/EpisodeView.vue b/src/components/EpisodeView.vue index b1fe691ded92189697b2a8aa4e0dabb28d6bd6c4..cd922b65958ff216c3eaaf8a85ddb286ce5e8d08 100644 --- a/src/components/EpisodeView.vue +++ b/src/components/EpisodeView.vue @@ -10,16 +10,16 @@ import {removePlaylist, removeSongFromPlaylist} from "../api/playlist"; const emit = defineEmits(); const props = defineProps({ - episodeInfo: { // 绫诲瀷 锛歩d,title,artist,picPath,createTime,songNum - type: Object, - required: true, - }, - musicList: { // 绫诲瀷 锛歩d,title,artist,picPath,upload_time - type: Object, - required: true, - }, - playFromLeftBar: null, - currentSongId: Number + episodeInfo: { // 绫诲瀷 锛歩d,title,artist,picPath,createTime,songNum + type: Object, + required: true, + }, + musicList: { // 绫诲瀷 锛歩d,title,artist,picPath,upload_time + type: Object, + required: true, + }, + playFromLeftBar: null, + currentSongId: Number }); const gradientColor = computed(() => `linear-gradient(to bottom, ${backgroundColor.value} , #1F1F1F 50%)`) @@ -34,148 +34,148 @@ const resizeObserver = ref(null) // 鏀剧缉鏃剁殑缁勪欢澶勭悊 const handleResize = () => { - 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"; - }); - albumText.forEach(album => { - album.style.visibility = "hidden"; - }); - - } else { - albums.forEach(album => { - album.style.visibility = "visible"; - }); - albumText.forEach(album => { - album.style.visibility = "visible"; - }); - } - const albumImage = document.querySelector(".album-image"); - const headerAlbumName = document.querySelector(".header-album-name"); - // 姝屽崟鍥剧墖鍜屾枃瀛楃缉鏀� - 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 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"; + }); + albumText.forEach(album => { + album.style.visibility = "hidden"; + }); + + } else { + albums.forEach(album => { + album.style.visibility = "visible"; + }); + albumText.forEach(album => { + album.style.visibility = "visible"; + }); + } + const albumImage = document.querySelector(".album-image"); + const headerAlbumName = document.querySelector(".header-album-name"); + // 姝屽崟鍥剧墖鍜屾枃瀛楃缉鏀� + 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) => { - let timer - return (...args) => { - if (timer) { - clearTimeout(timer) - } - timer = setTimeout(() => { - fn(...args) - }, delay) - } + let timer + return (...args) => { + if (timer) { + clearTimeout(timer) + } + timer = setTimeout(() => { + fn(...args) + }, delay) + } } onMounted(() => { - resizeObserver.value = new ResizeObserver(debounce(handleResize, 50)); - console.log(resizeObserver.value) - nextTick(() => { - const albumContent = document.querySelector(".album-content"); - if (albumContent) { - resizeObserver.value.observe(albumContent); - } - }) + resizeObserver.value = new ResizeObserver(debounce(handleResize, 50)); + console.log(resizeObserver.value) + nextTick(() => { + const albumContent = document.querySelector(".album-content"); + if (albumContent) { + resizeObserver.value.observe(albumContent); + } + }) }) onUnmounted(() => { - if (resizeObserver.value) { - resizeObserver.value.disconnect(); - } - popovers.value = null; + 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"; - } + + 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"); - const tipArea = document.querySelector(".tips"); - const fixedTipArea = document.querySelector(".fixed-tips"); - const stickyPlayY = playArea.offsetTop; - const stickyTipY = tipArea.offsetTop; - - if (window.scrollY >= stickyPlayY) { - fixedPlayArea.style.opacity = "1"; - } else { - fixedPlayArea.style.opacity = "0"; - } - if (window.scrollY + fixedPlayArea.scrollHeight >= stickyTipY) { - fixedTipArea.style.display = "flex"; - fixedTipArea.style.top = fixedPlayArea.scrollHeight + 'px'; - } else { - fixedTipArea.style.display = "none"; - } + 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 stickyPlayY = playArea.offsetTop; + const stickyTipY = tipArea.offsetTop; + + if (window.scrollY >= stickyPlayY) { + fixedPlayArea.style.opacity = "1"; + } else { + fixedPlayArea.style.opacity = "0"; + } + if (window.scrollY + fixedPlayArea.scrollHeight >= stickyTipY) { + fixedTipArea.style.display = "flex"; + fixedTipArea.style.top = fixedPlayArea.scrollHeight + 'px'; + } else { + fixedTipArea.style.display = "none"; + } } watch(props.playFromLeftBar, () => { - playFromId(props.playFromLeftBar) + playFromId(props.playFromLeftBar) }) const popovers = ref([]) const getPopoverIndex = (popover) => { - if (popover) { - popovers.value.push(popover); - } + if (popover) { + popovers.value.push(popover); + } } const closePopover = (e) => { - popovers.value.forEach((item) => { - item.hide(); - }) + popovers.value.forEach((item) => { + item.hide(); + }) } @@ -184,31 +184,31 @@ const enterArtistSpace = () => { } const removeAlbum = (albumId) => { - removePlaylist({ - playlist_id: albumId, - }).then(res => { - console.log("Hi") - }) + removePlaylist({ + playlist_id: albumId, + }).then(res => { + console.log("Hi") + }) } const playFromId = (musicId) => { - if (musicId === null) { - // 浠庡ご寮€濮嬫挱鏀� - musicPlayIndex.value = props.musicList[0].id; - } else { - musicPlayIndex.value = musicId; - } - - emit('switchSongs', props.albumInfo, musicPlayIndex.value); - musicPauseIndex = null; + if (musicId === null) { + // 浠庡ご寮€濮嬫挱鏀� + musicPlayIndex.value = props.musicList[0].id; + } else { + musicPlayIndex.value = musicId; + } + + emit('switchSongs', props.albumInfo, musicPlayIndex.value); + musicPauseIndex = null; } const addToFavorite = (musicId) => { } const removeMusicFromAlbum = (albumId, songId) => { - removeSongFromPlaylist({ - playlist_id: albumId, - song_id: songId, - }) + removeSongFromPlaylist({ + playlist_id: albumId, + song_id: songId, + }) } const enterMusicDescription = (musicId) => { } @@ -216,476 +216,476 @@ const enterAuthorDescription = (authorName) => { } const pauseMusic = (musicId) => { - musicPauseIndex = musicId; + musicPauseIndex = musicId; } const addRecommendMusic = (musicId) => { - console.log(musicId); - //TODO:娣诲姞姝屾洸鍒版寚瀹氱殑姝屽崟 - ElMessage({ - message: "娣诲姞鑷�: " + props.albumInfo.title, - grouping: true, - type: 'info', - offset: 16, - customClass: "reco-message", - duration: 4000, - }) + 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}" @mousewheel="handelScroll"> - <div class="header"> - <img :src="episodeInfo.picPath" alt="" class="album-image" @load="updateBackground(episodeInfo.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:80px;margin:10px 0 35px 10px;"> - {{ episodeInfo.title }}</p> - <div class="header-content-detail"> - <p class="header-creator" @click="enterArtistSpace">{{ episodeInfo.artist }}</p> - <p style="padding-right: 6px ">鈥�</p> - <p v-if="episodeInfo.createTime !== undefined"> - {{ episodeInfo.createTime.substring(0, 10) }} </p> - <p style="padding: 0 2px 0 6px">鈥�</p> - <p style="margin-left:6px">{{ musicList.length }} 棣栨瓕鏇�</p> - </div> - </div> - </div> - - <div class="content"> - <div class="play-area"> - <div class="play-button"> - <play-button v-if="musicPlayIndex===null||musicPauseIndex!==null" - @click="playFromId(musicPauseIndex)" - style="position: absolute; top:20%;left:24%;color: #000000"/> - <pause-button v-if="musicPlayIndex!==null&&musicPauseIndex===null" - @click="pauseMusic(musicPlayIndex)" - style="position: absolute; top:24%;left:25%;color: #000000"/> - </div> - <!-- 锛歳ef涓嚱鏁版墽琛屾椂锛岀粍浠跺凡缁忔覆鏌撳ソ锛屽苟灏嗘湰缁勪欢浣滀负鍙傛暟浼犲叆鍑芥暟--> - <el-popover - 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 @click="closePopover"> - <li @click="">鍒犻櫎姝屽崟</li> - </ul> - </el-popover> - </div> - - <div class="fixed-play-area" :style="{background :`${backgroundColor}`}"> - <div class="opacity-wrapper"> - <div class="play-button"> - <play-button v-if="musicPlayIndex===null||musicPauseIndex!==null" - @click="playFromId(musicPauseIndex)" - style="position: absolute; top:20%;left:24%;color: #000000"/> - <pause-button v-if="musicPlayIndex!==null&&musicPauseIndex===null" - @click="pauseMusic(musicPlayIndex)" - style="position: absolute; top:24%;left:25%;color: #000000"/> - </div> - <p style="padding-left: 10px;font-weight: bold;font-size: 26px">{{ episodeInfo.title }}</p> - </div> - </div> - <div class="tips"> - <p style="position:absolute; left:45px">#</p> - <p style="position:absolute; left:140px">鏍囬</p> - <p style="margin-left: auto; margin-right:55px">鏃堕棿</p> - </div> - - <div class="fixed-tips"> - <p style="position:absolute; left:45px">#</p> - <p style="position:absolute; left:140px">鏍囬</p> - <p style="margin-left: auto; margin-right:75px">鏃堕棿</p> - </div> - - <div class="musicList"> - <div class="music-item" - v-for="music in musicList" - :key="music.id" - :aria-selected="musicClickedIndex === music.id ? 'True':'False'" - @mouseenter="()=>{musicHoveredIndex = music.id;}" - @mouseleave="()=>{musicHoveredIndex = -1}" - @click="musicClickedIndex=music.id" - @dblclick="playFromId(music.id)" - :style="{backgroundColor: musicClickedIndex===music.id? '#404040': + <div class="album-content" :style="{backgroundImage: gradientColor}" @mousewheel="handelScroll"> + <div class="header"> + <img :src="episodeInfo.picPath" alt="" class="album-image" @load="updateBackground(episodeInfo.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:80px;margin:10px 0 35px 10px;"> + {{ episodeInfo.title }}</p> + <div class="header-content-detail"> + <p class="header-creator" @click="enterArtistSpace">{{ episodeInfo.artist }}</p> + <p style="padding-right: 6px ">鈥�</p> + <p v-if="episodeInfo.createTime !== undefined"> + {{ episodeInfo.createTime.substring(0, 10) }} </p> + <p style="padding: 0 2px 0 6px">鈥�</p> + <p style="margin-left:6px">{{ musicList.length }} 棣栨瓕鏇�</p> + </div> + </div> + </div> + + <div class="content"> + <div class="play-area"> + <div class="play-button"> + <play-button v-if="musicPlayIndex===null||musicPauseIndex!==null" + @click="playFromId(musicPauseIndex)" + style="position: absolute; top:20%;left:24%;color: #000000"/> + <pause-button v-if="musicPlayIndex!==null&&musicPauseIndex===null" + @click="pauseMusic(musicPlayIndex)" + style="position: absolute; top:24%;left:25%;color: #000000"/> + </div> + <!-- 锛歳ef涓嚱鏁版墽琛屾椂锛岀粍浠跺凡缁忔覆鏌撳ソ锛屽苟灏嗘湰缁勪欢浣滀负鍙傛暟浼犲叆鍑芥暟--> + <el-popover + 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 @click="closePopover"> + <li @click="">鍒犻櫎姝屽崟</li> + </ul> + </el-popover> + </div> + + <div class="fixed-play-area" :style="{background :`${backgroundColor}`}"> + <div class="opacity-wrapper"> + <div class="play-button"> + <play-button v-if="musicPlayIndex===null||musicPauseIndex!==null" + @click="playFromId(musicPauseIndex)" + style="position: absolute; top:20%;left:24%;color: #000000"/> + <pause-button v-if="musicPlayIndex!==null&&musicPauseIndex===null" + @click="pauseMusic(musicPlayIndex)" + style="position: absolute; top:24%;left:25%;color: #000000"/> + </div> + <p style="padding-left: 10px;font-weight: bold;font-size: 26px">{{ episodeInfo.title }}</p> + </div> + </div> + <div class="tips"> + <p style="position:absolute; left:45px">#</p> + <p style="position:absolute; left:140px">鏍囬</p> + <p style="margin-left: auto; margin-right:55px">鏃堕棿</p> + </div> + + <div class="fixed-tips"> + <p style="position:absolute; left:45px">#</p> + <p style="position:absolute; left:140px">鏍囬</p> + <p style="margin-left: auto; margin-right:75px">鏃堕棿</p> + </div> + + <div class="musicList"> + <div class="music-item" + v-for="music in musicList" + :key="music.id" + :aria-selected="musicClickedIndex === music.id ? 'True':'False'" + @mouseenter="()=>{musicHoveredIndex = music.id;}" + @mouseleave="()=>{musicHoveredIndex = -1}" + @click="musicClickedIndex=music.id" + @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' }"> - {{ - 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" - :style="{color: musicPauseIndex===music.id ? '#1ed660' : 'white'}"/> - - <pause-button @click="pauseMusic(music.id)" - style="color:#1ed660 ;position: absolute;left: 17px;cursor: pointer" - v-if="musicPlayIndex===music.id&&musicHoveredIndex === music.id&&musicPauseIndex!==music.id"/> - <img width="17" height="17" alt="" - style="position: absolute;left: 24px;" - v-if="musicPlayIndex===music.id&&musicHoveredIndex !== music.id&&musicPauseIndex!==music.id" - src="https://open.spotifycdn.com/cdn/images/equaliser-animated-green.f5eb96f2.gif"> - - <div class="music-detailed-info"> - <img class="music-image" - :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.title }}</p> - - <p @click="enterAuthorDescription(music.artist)" class="music-author" - :style="{color:musicHoveredIndex === music.id? 'white' : '#b2b2b2'}"> - {{ music.artist }}</p> - </div> - </div> - - <div class="music-right-info"> - <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 @click="closePopover"> - <!-- 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 - }} - <!--TODO: 瑙e喅鎾斁鏃堕棿闂--> - </div> - <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 @click="closePopover"> - <li @click="removeMusicFromAlbum(music.id)">鍒犻櫎姝屾洸</li> - </ul> - </el-popover> - </div> - </div> - </div> - </div> - </div> + + <div + :style="{visibility: musicHoveredIndex === music.id||musicPlayIndex === music.id ? 'hidden' : 'visible' }"> + {{ + 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" + :style="{color: musicPauseIndex===music.id ? '#1ed660' : 'white'}"/> + + <pause-button @click="pauseMusic(music.id)" + style="color:#1ed660 ;position: absolute;left: 17px;cursor: pointer" + v-if="musicPlayIndex===music.id&&musicHoveredIndex === music.id&&musicPauseIndex!==music.id"/> + <img width="17" height="17" alt="" + style="position: absolute;left: 24px;" + v-if="musicPlayIndex===music.id&&musicHoveredIndex !== music.id&&musicPauseIndex!==music.id" + src="https://open.spotifycdn.com/cdn/images/equaliser-animated-green.f5eb96f2.gif"> + + <div class="music-detailed-info"> + <img class="music-image" + :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.title }}</p> + + <p @click="enterAuthorDescription(music.artist)" class="music-author" + :style="{color:musicHoveredIndex === music.id? 'white' : '#b2b2b2'}"> + {{ music.artist }}</p> + </div> + </div> + + <div class="music-right-info"> + <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 @click="closePopover"> + <!-- 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 + }} + <!--TODO: 瑙e喅鎾斁鏃堕棿闂--> + </div> + <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 @click="closePopover"> + <li @click="removeMusicFromAlbum(music.id)">鍒犻櫎姝屾洸</li> + </ul> + </el-popover> + </div> + </div> + </div> + </div> + </div> </template> <style scoped> li { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } li:hover { - background-color: #363636; - border-radius: 12px; + background-color: #363636; + border-radius: 12px; } p { - text-align: left; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin: 0; + text-align: left; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin: 0; } .header, .play-area, .tips, .musicList { - z-index: 0; - padding: 20px; - width: 100%; - box-sizing: border-box; - user-select: none; + z-index: 0; + padding: 20px; + width: 100%; + box-sizing: border-box; + user-select: none; } .album-content { - margin: 0; - padding: 0; - color: white; - background-color: rgb(31, 31, 31); - transition: background-color ease 0.6s; - display: flex; - flex-direction: column; - width: 100%; - overflow-x: auto; /*鍗冧竾涓嶈兘鍒狅紝涓嶇劧鑳屾櫙榛戜竴鍗�*/ + margin: 0; + padding: 0; + color: white; + background-color: rgb(31, 31, 31); + transition: background-color ease 0.6s; + display: flex; + flex-direction: column; + width: 100%; + overflow-x: auto; /*鍗冧竾涓嶈兘鍒狅紝涓嶇劧鑳屾櫙榛戜竴鍗�*/ } .header { - display: flex; - flex-direction: row; + display: flex; + flex-direction: row; } .content { - z-index: 1; - background-color: rgba(0, 0, 0, 0.20); + z-index: 1; + background-color: rgba(0, 0, 0, 0.20); } .album-image { - border-radius: 6%; - width: 160px; - height: 160px; - margin-top: 30px; - margin-left: 15px; - margin-right: 20px; + border-radius: 6%; + width: 160px; + height: 160px; + margin-top: 30px; + margin-left: 15px; + margin-right: 20px; } .header-content { - display: flex; - flex-direction: column; - height: 100%; - position: relative; - flex-grow: 1; - min-width: 0; + display: flex; + flex-direction: column; + height: 100%; + position: relative; + flex-grow: 1; + min-width: 0; } .header-content-detail { - padding: 10px; - align-items: center; - display: flex; - flex-direction: row; + padding: 10px; + align-items: center; + display: flex; + flex-direction: row; } .header-creator { - margin: 0 6px; - cursor: pointer; - font-weight: bolder + margin: 0 6px; + cursor: pointer; + font-weight: bolder } .header-creator:hover { - text-decoration: underline; + text-decoration: underline; } .play-area { - position: relative; + position: relative; } .more-info { - font-size: 35px; - position: absolute; - z-index: 13; - top: 33px; - left: 160px; - transition: width 0.1s ease-in-out; + font-size: 35px; + position: absolute; + z-index: 13; + top: 33px; + left: 160px; + transition: width 0.1s ease-in-out; } .more-info:focus { - outline: none; - + outline: none; + } .more-info:hover { - cursor: pointer; - transform: scale(1.15); + cursor: pointer; + transform: scale(1.15); } .fixed-play-area { - top: 0; - z-index: 11; - opacity: 0; - transition: opacity 0.2s ease-out; - border-radius: 12px 12px 0 0; - position: fixed; /**/ - display: flex; - padding: 10px 0 10px 20px; - width: inherit; - + top: 0; + z-index: 11; + opacity: 0; + transition: opacity 0.2s ease-out; + border-radius: 12px 12px 0 0; + position: fixed; /**/ + display: flex; + padding: 10px 0 10px 20px; + width: inherit; + } .opacity-wrapper { - display: flex; - align-items: center; - width: 100%; - height: 100%; - margin: -10px 0 -10px -20px; - padding: 10px 0 10px 20px; - background-color: rgba(0, 0, 0, 0.50); + display: flex; + align-items: center; + width: 100%; + height: 100%; + margin: -10px 0 -10px -20px; + padding: 10px 0 10px 20px; + background-color: rgba(0, 0, 0, 0.50); } .play-button { - margin-left: 40px; - background-color: #1ed660; - border-radius: 50%; - width: 60px; - height: 60px; - position: relative; - align-items: center; - justify-content: center; - transition: all 0.1s; + margin-left: 40px; + background-color: #1ed660; + border-radius: 50%; + width: 60px; + height: 60px; + position: relative; + align-items: center; + justify-content: center; + transition: all 0.1s; } .play-button:hover { - cursor: pointer; - transform: scale(1.05); - background-color: #1ed683; + cursor: pointer; + transform: scale(1.05); + background-color: #1ed683; } .tips { - z-index: 0; - display: flex; - position: relative; - padding: 5px 8px 5px 8px; + z-index: 0; + display: flex; + position: relative; + padding: 5px 8px 5px 8px; } .fixed-tips { - - z-index: 11; - width: 100%; - justify-content: space-between; - display: none; - padding: 10px 8px 10px 8px; - position: fixed; - background-color: #1f1f1f; - border-bottom: 1px solid #363636; + + z-index: 11; + width: 100%; + justify-content: space-between; + display: none; + padding: 10px 8px 10px 8px; + position: fixed; + background-color: #1f1f1f; + border-bottom: 1px solid #363636; } .musicList { - border-top: 1px solid #363636; - margin-top: 10px; + border-top: 1px solid #363636; + margin-top: 10px; } /*姣忚闊充箰鐨勬牱寮�*/ .music-item { - position: relative; - border-radius: 10px; - display: flex; - align-items: center; - padding: 10px 0 10px 25px; - flex-grow: 1; - min-width: 0; + position: relative; + border-radius: 10px; + display: flex; + align-items: center; + padding: 10px 0 10px 25px; + flex-grow: 1; + min-width: 0; } /*闊充箰琚偣鍑诲悗鐨勬牱寮�*/ .music-after-click { - color: #1ed660; + color: #1ed660; } /*宸︿晶淇℃伅*/ .music-detailed-info { - display: flex; - flex-direction: row; + display: flex; + flex-direction: row; } .music-image { - padding-left: 30px; - height: 50px; - width: 50px; /* Adjust as needed */ - border-radius: 10px; + padding-left: 30px; + height: 50px; + width: 50px; /* Adjust as needed */ + border-radius: 10px; } .music-name { - padding-bottom: 5px; - font-size: 18px + padding-bottom: 5px; + font-size: 18px } .music-name:hover { - cursor: pointer; - text-decoration: underline; + cursor: pointer; + text-decoration: underline; } .music-author { - color: #b2b2b2; - font-size: 15px + color: #b2b2b2; + font-size: 15px } .music-author:hover { - cursor: pointer; - text-decoration: underline; + cursor: pointer; + text-decoration: underline; } /*鍙充晶淇℃伅*/ .music-right-info { - margin-left: auto; - display: flex; - align-items: center; - flex-direction: row; + margin-left: auto; + display: flex; + align-items: center; + flex-direction: row; } .check-mark { - width: 20px; - height: auto; - margin-right: 40px; - color: black; - font-weight: bolder; - border-radius: 50%; + width: 20px; + height: auto; + margin-right: 40px; + color: black; + font-weight: bolder; + border-radius: 50%; } .check-mark:hover { - cursor: pointer; + cursor: pointer; } .check-mark:focus { - outline: none; + outline: none; } .music-more-info { - margin-right: 14px; - font-size: 22px; - transition: width 0.1s ease-in-out; + margin-right: 14px; + font-size: 22px; + transition: width 0.1s ease-in-out; } .music-more-info:focus { - outline: none; - transform: scale(1.05); + outline: none; + transform: scale(1.05); } .music-more-info:hover { - cursor: pointer; + cursor: pointer; } .music-dropdown-options { - border-radius: 6px; + border-radius: 6px; } ul { - background-color: #282828; - list-style-type: none; - padding: 0; - margin: 0; - border-radius: 10px; + background-color: #282828; + list-style-type: none; + padding: 0; + margin: 0; + border-radius: 10px; } li { - color: white; - padding: 15px 12px; + color: white; + padding: 15px 12px; } li:hover { - cursor: pointer; - text-decoration: underline; + cursor: pointer; + text-decoration: underline; } </style> diff --git a/src/components/MusicAlbumView.vue b/src/components/MusicAlbumView.vue index 119b39d0889871f207122cf735607dfa36ea584b..12a91cc16bcdfbad170ce792fa4d88bef061e79e 100644 --- a/src/components/MusicAlbumView.vue +++ b/src/components/MusicAlbumView.vue @@ -350,7 +350,6 @@ const addRecommendMusic = (musicId) => { </button> </div> <div class="edit-desc-text"> - <!-- <input accept="image/.jpg, image/.jpeg, image/.png" type="file" data-testid="image-file-picker" class="wcftliF4QjZKB1CYgEON">--> <div class="edit-desc-img"> <div class="edit-desc-img-1" draggable="false"> <div class="edit-desc-img-1-1 edit-desc-img-1"> diff --git a/src/views/HomePage.vue b/src/views/HomePage.vue index c614073111400d05e3d2172f163f32aedcc6421f..01a4cb4e783f353279c71ca14d2a3f46a2aba180 100644 --- a/src/views/HomePage.vue +++ b/src/views/HomePage.vue @@ -1,7 +1,7 @@ /* eslint-disable */ <script setup> // Vue Basics -import {computed, onMounted, ref} from "vue" +import {computed, onMounted, ref, watch} from "vue" // Assets import defaultBg from '../assets/pictures/Eason.png' @@ -336,6 +336,10 @@ const currentUserId = ref(userToken.value.id); */ // Playing Status const songs = ref([]); +const volumn = ref(1); +watch(volumn, (newValue) => { + song.volume = newValue; +}); const displayingSongs = ref([]); const isPaused = ref(false); const duration = ref(0); @@ -422,32 +426,32 @@ const switchToPlaylist = (playlist, songId) => { } const switchToEpisode = (episode, songId) => { - console.log(episode, songId) - - currentEpisode.value = episode; - displayingEpisode.value = episode; - currentEpisodeId.value = episode.id; - theme.change(currentEpisode.value.picPath); - - getSongsByEpisode({ - episode_id: currentEpisodeId.value, - }).then((res) => { - songs.value = res.data.result; - displayingSongs.value = res.data.result; - currentSongId.value = songId; - for (let i = 0; i < songs.value.length; i++) { - if (songs.value[i].id === songId) { - switchToSong(i, true); - parseLrc(songs.value[i].lyricsPath).then(res => { - lyrics.value = res; - }); - break; - } - } - - }).catch(e => { - console.log("Error while switching episodes!"); - }); + console.log(episode, songId) + + currentEpisode.value = episode; + displayingEpisode.value = episode; + currentEpisodeId.value = episode.id; + theme.change(currentEpisode.value.picPath); + + getSongsByEpisode({ + episode_id: currentEpisodeId.value, + }).then((res) => { + songs.value = res.data.result; + displayingSongs.value = res.data.result; + currentSongId.value = songId; + for (let i = 0; i < songs.value.length; i++) { + if (songs.value[i].id === songId) { + switchToSong(i, true); + parseLrc(songs.value[i].lyricsPath).then(res => { + lyrics.value = res; + }); + break; + } + } + + }).catch(e => { + console.log("Error while switching episodes!"); + }); } /* PLAYLISTS @@ -489,15 +493,15 @@ const currentEpisode = ref(2); const currentEpisodeId = ref(2); const displayingEpisode = ref(2); const receiveDisplayingEpisode = (value) => { - setMidComponents(4); - displayingEpisode.value = value; - getSongsByEpisode({ - episode_id: value.id, - }).then((res) => { - displayingSongs.value = res.data.result; - }).catch(e => { - console.log("Failed to get songs!"); - }); + setMidComponents(4); + displayingEpisode.value = value; + getSongsByEpisode({ + episode_id: value.id, + }).then((res) => { + displayingSongs.value = res.data.result; + }).catch(e => { + console.log("Failed to get songs!"); + }); }; /* SEARCH @@ -517,6 +521,7 @@ function receiveDataFromHeader(data) { function receiveDataFromHome() { setMidComponents(0); } + /* MID COMPONENTS 0 - Main View @@ -601,7 +606,7 @@ let playFromLeftBarAlbum = ref(null); style="overflow: auto; height: 730px ;border-radius: 12px"> <el-button class="exit-search" data-tooltip="閫€鍑�" - + :class="{ 'adjusted-position': showRightContent }" @click="setMidComponents(0)"></el-button> <Comment :song-id=currentSongId :user-id=currentUserId></Comment> @@ -614,11 +619,11 @@ let playFromLeftBarAlbum = ref(null); @click="setMidComponents(0)"></el-button> <SearchView :songResult="songResult" :playlistResult="playlistResult"/> </el-container> - <div v-if="midComponents == 4" class="playlist-container" - style="overflow: scroll; border-radius: 12px"> - <EpisodeView :episode-info="displayingEpisode" :music-list="displayingSongs" - @switchSongs="switchToEpisode" :playFromLeftBar="playFromLeftBarAlbum"/> - </div> + <div v-if="midComponents == 4" class="playlist-container" + style="overflow: scroll; border-radius: 12px"> + <EpisodeView :episode-info="displayingEpisode" :music-list="displayingSongs" + @switchSongs="switchToEpisode" :playFromLeftBar="playFromLeftBarAlbum"/> + </div> </div> <div v-if="showRightContent" class="right-content"> <div v-if="songs[currentSongIndex] !== undefined" class="music-player music-info"> @@ -742,7 +747,12 @@ let playFromLeftBarAlbum = ref(null); </div> </el-card> + <div class="right-controls"> + <div class="volumn-control" style="display: flex; flex-direction: row; align-items: center"> + <h1 style="margin: 0">馃攬</h1> + <input v-model="volumn" type="range" id="volumeControl" min="0" max="1" step="0.01"> + </div> <div class="feature-icon" data-tooltip="鍒嗕韩" :class="{ active: isSharing }"> @@ -787,7 +797,6 @@ let playFromLeftBarAlbum = ref(null); </div> </div> - <!-- <div class="player" :style="{ backgroundImage: gradientColor }">--> <div class="player"> <div class="background"></div> <div class="player-content"> @@ -938,7 +947,7 @@ h1 { "left-sidebar main-view main-view" "now-playing-bar now-playing-bar now-playing-bar"; grid-template-columns: auto 1fr; - grid-template-rows: 10% 80% 10%; + grid-template-rows: 10% 81% 9%; grid-auto-rows: min-content; column-gap: 8px; @@ -1934,4 +1943,46 @@ html, body { background: transparent; } +/* 璁剧疆鏁翠釜椤甸潰鐨勮緭鍏ヨ寖鍥存粦鏉℃牱寮� */ +#volumeControl { + -webkit-appearance: none; /* 鍘绘帀榛樿鏍峰紡 */ + appearance: none; + width: 120px; /* 璁剧疆瀹藉害 */ + height: 10px; /* 璁剧疆楂樺害 */ + background: #ddd; /* 璁剧疆榛樿鑳屾櫙棰滆壊 */ + border-radius: 5px; /* 璁剧疆鍦嗚 */ + outline: none; /* 鍘婚櫎鐒︾偣鏃剁殑杞粨 */ + transition: background 0.3s; /* 鑳屾櫙鑹插钩婊戣繃娓� */ +} + +/* 璁剧疆婊戞潯锛堣建閬擄級鐨勬牱寮� */ +#volumeControl::-webkit-slider-runnable-track { + height: 10px; /* 璁剧疆杞ㄩ亾楂樺害 */ + border-radius: 5px; /* 鍦嗚 */ + background: #1ed760; /* 璁剧疆杞ㄩ亾棰滆壊涓虹豢鑹� */ +} + +/* 璁剧疆婊戝潡鐨勬牱寮� */ +#volumeControl::-webkit-slider-thumb { + -webkit-appearance: none; /* 鍘绘帀榛樿鏍峰紡 */ + appearance: none; + width: 20px; /* 璁剧疆婊戝潡瀹藉害 */ + height: 20px; /* 璁剧疆婊戝潡楂樺害 */ + margin-top: -5px; + border-radius: 50%; /* 鍦嗗舰婊戝潡 */ + background: #fff; /* 璁剧疆婊戝潡鑳屾櫙棰滆壊涓虹櫧鑹� */ + border: 2px solid green; /* 璁剧疆婊戝潡杈规棰滆壊涓虹豢鑹� */ + cursor: pointer; /* 璁剧疆榧犳爣鎮仠鏃剁殑鎸囬拡鏍峰紡 */ +} + +/* 榧犳爣鎮诞鏃舵敼鍙樿建閬撹儗鏅鑹� */ +#volumeControl:hover { + background: #ccc; /* 鏀瑰彉鑳屾櫙棰滆壊 */ +} + +/* 璁剧疆婊戝潡琚偣鍑绘椂鐨勬牱寮� */ +#volumeControl:active::-webkit-slider-thumb { + background: #8bc34a; /* 鐐瑰嚮鏃舵粦鍧楃殑鑳屾櫙棰滆壊 */ + border-color: #66bb6a; /* 鐐瑰嚮鏃舵粦鍧楄竟妗嗛鑹� */ +} </style>