refactor(Player): 将播放器组件从App.vue中提取到独立的Player.vue组件
提取播放器逻辑到独立的Player.vue组件,以提高代码的可维护性和复用性。同时,更新了相关依赖和样式,确保功能不受影响。
This commit is contained in:
		
							parent
							
								
									831ff82c8a
								
							
						
					
					
						commit
						6743b694c8
					
				| 
						 | 
				
			
			@ -5,12 +5,20 @@
 | 
			
		|||
	"description": "A Vue-based browser extension.",
 | 
			
		||||
	"content_scripts": [
 | 
			
		||||
		{
 | 
			
		||||
			"matches": ["https://monster-siren.hypergryph.com/"],
 | 
			
		||||
			"js": ["content.js"],
 | 
			
		||||
			"matches": [
 | 
			
		||||
				"https://monster-siren.hypergryph.com/"
 | 
			
		||||
			],
 | 
			
		||||
			"js": [
 | 
			
		||||
				"content.js"
 | 
			
		||||
			],
 | 
			
		||||
			"run_at": "document_end"
 | 
			
		||||
		}
 | 
			
		||||
	],
 | 
			
		||||
	"host_permissions": ["https://monster-siren.hypergryph.com/*", "http://localhost:5173/*"],
 | 
			
		||||
	"host_permissions": [
 | 
			
		||||
		"https://monster-siren.hypergryph.com/*",
 | 
			
		||||
		"http://localhost:5173/*",
 | 
			
		||||
		"https://res01.hycdn.cn/*"
 | 
			
		||||
	],
 | 
			
		||||
	"icons": {
 | 
			
		||||
		"16": "vite.svg",
 | 
			
		||||
		"48": "vite.svg",
 | 
			
		||||
| 
						 | 
				
			
			@ -19,9 +27,12 @@
 | 
			
		|||
	"background": {
 | 
			
		||||
		"service_worker": "background.js"
 | 
			
		||||
	},
 | 
			
		||||
	"permissions": ["tabs", "webRequest"],
 | 
			
		||||
  "content_security_policy": {
 | 
			
		||||
    "extension_pages": "default-src 'self'; script-src 'self' http://localhost:5173; style-src 'self' 'unsafe-inline'; connect-src 'self' ws://localhost:5173 https://monster-siren.hypergryph.com; img-src 'self' https://web.hycdn.cn;",
 | 
			
		||||
    "sandbox": "sandbox"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
	"permissions": [
 | 
			
		||||
		"tabs",
 | 
			
		||||
		"webRequest"
 | 
			
		||||
	],
 | 
			
		||||
	"content_security_policy": {
 | 
			
		||||
		"extension_pages": "default-src 'self'; script-src 'self' http://localhost:5173; style-src 'self' 'unsafe-inline'; connect-src 'self' ws://localhost:5173 https://monster-siren.hypergryph.com; img-src 'self' https://web.hycdn.cn; media-src 'self' https://res01.hycdn.cn;",
 | 
			
		||||
		"sandbox": "sandbox"
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								src/App.vue
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/App.vue
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1,10 +1,9 @@
 | 
			
		|||
<script setup lang="ts">
 | 
			
		||||
import { useRoute } from 'vue-router'
 | 
			
		||||
import { usePlayQueueStore } from './stores/usePlayQueueStore'
 | 
			
		||||
 | 
			
		||||
const playQueueStore = usePlayQueueStore()
 | 
			
		||||
import Player from './components/Player.vue'
 | 
			
		||||
 | 
			
		||||
const route = useRoute()
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
| 
						 | 
				
			
			@ -54,22 +53,7 @@ const route = useRoute()
 | 
			
		|||
							</div>
 | 
			
		||||
						</button>
 | 
			
		||||
 | 
			
		||||
						<div class="text-white w-48 h-9 bg-neutral-800/80 border border-[#ffffff39] rounded-full text-center backdrop-blur-3xl flex gap-2 overflow-hidden" v-if="playQueueStore.list.length !== 0">
 | 
			
		||||
							<img :src="playQueueStore.list[playQueueStore.currentIndex].album?.coverUrl ?? ''" class="rounded-full" />
 | 
			
		||||
							<div class="flex-1 flex items-center">
 | 
			
		||||
								<span class="">{{ playQueueStore.list[playQueueStore.currentIndex].song.name }}</span>
 | 
			
		||||
							</div>
 | 
			
		||||
							<button class="h-9 w-9 flex justify-center items-center" @click="() => {
 | 
			
		||||
								playQueueStore.isPlaying = !playQueueStore.isPlaying
 | 
			
		||||
							}">
 | 
			
		||||
								<div class="w-4 h-4" v-if="playQueueStore.isPlaying">
 | 
			
		||||
									<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M6 5H8V19H6V5ZM16 5H18V19H16V5Z"></path></svg>
 | 
			
		||||
								</div>
 | 
			
		||||
								<div class="w-4 h-4" v-else>
 | 
			
		||||
									<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M19.376 12.4161L8.77735 19.4818C8.54759 19.635 8.23715 19.5729 8.08397 19.3432C8.02922 19.261 8 19.1645 8 19.0658V4.93433C8 4.65818 8.22386 4.43433 8.5 4.43433C8.59871 4.43433 8.69522 4.46355 8.77735 4.5183L19.376 11.584C19.6057 11.7372 19.6678 12.0477 19.5146 12.2774C19.478 12.3323 19.4309 12.3795 19.376 12.4161Z"></path></svg>
 | 
			
		||||
								</div>
 | 
			
		||||
							</button>
 | 
			
		||||
						</div>
 | 
			
		||||
						<Player />
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,8 +16,8 @@ export default {
 | 
			
		|||
		const song: {
 | 
			
		||||
			data: ApiResponse
 | 
			
		||||
		} = await msrInstance.get(`song/${cid}`)
 | 
			
		||||
		if (song.data.code!== 0) { return new Error(`Cannot get song: ${song.data.msg}`) }
 | 
			
		||||
		return { song: song.data.data as Song }
 | 
			
		||||
		if (song.data.code!== 0) { throw new Error(`Cannot get song: ${song.data.msg}`) }
 | 
			
		||||
		return song.data.data as Song
 | 
			
		||||
	},
 | 
			
		||||
	async getAlbums() {
 | 
			
		||||
		const albums: {
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +36,6 @@ export default {
 | 
			
		|||
		} = await msrInstance.get(`album/${cid}/data`)
 | 
			
		||||
		let data = album.data.data as Album
 | 
			
		||||
		data.artistes = (albumMeta.data.data as Album).artistes
 | 
			
		||||
		console.log(albumMeta)
 | 
			
		||||
		return data
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										44
									
								
								src/components/Player.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/components/Player.vue
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
<script setup lang="ts">
 | 
			
		||||
import { usePlayQueueStore } from '../stores/usePlayQueueStore'
 | 
			
		||||
import { useTemplateRef, watch } from 'vue'
 | 
			
		||||
 | 
			
		||||
const playQueueStore = usePlayQueueStore()
 | 
			
		||||
 | 
			
		||||
const player = useTemplateRef('playerRef')
 | 
			
		||||
 | 
			
		||||
watch(() => playQueueStore.isPlaying, (newValue) => {
 | 
			
		||||
	if (newValue) { player.value?.play() }
 | 
			
		||||
	else { player.value?.pause() }
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
	<div>
 | 
			
		||||
		<audio :src="playQueueStore.list[playQueueStore.currentIndex] ? playQueueStore.list[playQueueStore.currentIndex].song.sourceUrl : ''" ref="playerRef" autoplay v-if="playQueueStore.list.length !== 0"></audio>
 | 
			
		||||
 | 
			
		||||
		<div
 | 
			
		||||
			class="text-white w-48 h-9 bg-neutral-800/80 border border-[#ffffff39] rounded-full text-center backdrop-blur-3xl flex gap-2 overflow-hidden"
 | 
			
		||||
			v-if="playQueueStore.list.length !== 0">
 | 
			
		||||
			<img :src="playQueueStore.list[playQueueStore.currentIndex].album?.coverUrl ?? ''" class="rounded-full" />
 | 
			
		||||
			<div class="flex-1 flex items-center">
 | 
			
		||||
				<span class="">{{ playQueueStore.list[playQueueStore.currentIndex].song.name }}</span>
 | 
			
		||||
			</div>
 | 
			
		||||
			<button class="h-9 w-9 flex justify-center items-center" @click="() => {
 | 
			
		||||
				playQueueStore.isPlaying = !playQueueStore.isPlaying
 | 
			
		||||
			}">
 | 
			
		||||
				<div class="w-4 h-4" v-if="playQueueStore.isPlaying">
 | 
			
		||||
					<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
 | 
			
		||||
						<path d="M6 5H8V19H6V5ZM16 5H18V19H16V5Z"></path>
 | 
			
		||||
					</svg>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="w-4 h-4" v-else>
 | 
			
		||||
					<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
 | 
			
		||||
						<path
 | 
			
		||||
							d="M19.376 12.4161L8.77735 19.4818C8.54759 19.635 8.23715 19.5729 8.08397 19.3432C8.02922 19.261 8 19.1645 8 19.0658V4.93433C8 4.65818 8.22386 4.43433 8.5 4.43433C8.59871 4.43433 8.69522 4.46355 8.77735 4.5183L19.376 11.584C19.6057 11.7372 19.6678 12.0477 19.5146 12.2774C19.478 12.3323 19.4309 12.3795 19.376 12.4161Z">
 | 
			
		||||
						</path>
 | 
			
		||||
					</svg>
 | 
			
		||||
				</div>
 | 
			
		||||
			</button>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			@ -13,8 +13,12 @@ const playQueue = usePlayQueueStore()
 | 
			
		|||
 | 
			
		||||
onMounted(async () => {
 | 
			
		||||
	try {
 | 
			
		||||
		const res = await apis.getAlbum(albumId as string)
 | 
			
		||||
		let res = await apis.getAlbum(albumId as string)
 | 
			
		||||
		for (const track in res.songs) {
 | 
			
		||||
			res.songs[parseInt(track)] = await apis.getSong(res.songs[parseInt(track)].cid)
 | 
			
		||||
		}
 | 
			
		||||
		album.value = res
 | 
			
		||||
		console.log(res)
 | 
			
		||||
	} catch (error) {
 | 
			
		||||
		console.log(error)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +39,7 @@ function playTheAlbum() {
 | 
			
		|||
 | 
			
		||||
	let newPlayQueue = []
 | 
			
		||||
	for (const track of album.value?.songs ?? []) {
 | 
			
		||||
		console.log(track)
 | 
			
		||||
		newPlayQueue.push({
 | 
			
		||||
			song: track,
 | 
			
		||||
			album: album.value
 | 
			
		||||
| 
						 | 
				
			
			@ -67,8 +72,7 @@ function playTheAlbum() {
 | 
			
		|||
				<div class="flex gap-2">
 | 
			
		||||
					<button
 | 
			
		||||
						class="bg-sky-500/20 hover:bg-sky-500/30 active:bg-sky-600/30 active:shadow-inner border border-[#ffffff39] rounded-full w-56 h-10 text-base text-white flex justify-center items-center gap-2"
 | 
			
		||||
						@click="playTheAlbum"
 | 
			
		||||
					>
 | 
			
		||||
						@click="playTheAlbum">
 | 
			
		||||
						<div class="w-4 h-4">
 | 
			
		||||
							<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
 | 
			
		||||
								<path
 | 
			
		||||
| 
						 | 
				
			
			@ -115,8 +119,8 @@ function playTheAlbum() {
 | 
			
		|||
					<div class="flex flex-col justify-center">
 | 
			
		||||
						<div class="text-white text-base">{{ track.name }}</div>
 | 
			
		||||
						<div class="text-white/50 text-sm"
 | 
			
		||||
							v-if="artistsOrganize(track.artistes) !== artistsOrganize(album?.artistes ?? [])">
 | 
			
		||||
							{{ artistsOrganize(track.artistes) }}
 | 
			
		||||
							v-if="artistsOrganize(track.artists ?? []) !== artistsOrganize(album?.artistes ?? [])">
 | 
			
		||||
							{{ artistsOrganize(track.artists ?? []) }}
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</button>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								src/vite-env.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								src/vite-env.d.ts
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -12,7 +12,8 @@ type Song = {
 | 
			
		|||
  lyricUrl?: string | null
 | 
			
		||||
  mvUrl?: string | null
 | 
			
		||||
  mvCoverUrl?: string | null
 | 
			
		||||
  artistes: string[]
 | 
			
		||||
  artistes?: string[]
 | 
			
		||||
  artists?: string[]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Album = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user