Skip to content

Commit 309c323

Browse files
committedJan 9, 2024
🔧 build: support ESM and upgrade to Vite 5
- 临时解决下载歌曲无法正常播放 #113
1 parent 6a1e606 commit 309c323

19 files changed

+543
-451
lines changed
 

‎.editorconfig

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1+
# 根配置文件
2+
## 编辑器在查找配置时会停止查找更高层次的配置文件
13
root = true
24

5+
# 通配符,匹配所有文件
36
[*]
7+
# 设置字符集为 UTF-8,确保文件中的文本使用 UTF-8 编码
48
charset = utf-8
9+
# 使用空格作为缩进风格
510
indent_style = space
11+
# 设置每个缩进级别的空格数量为 2
612
indent_size = 2
13+
# 设置行尾换行符为LF(Line Feed)
714
end_of_line = lf
15+
# 在文件的末尾插入一个新行
816
insert_final_newline = true
9-
trim_trailing_whitespace = true
17+
# 删除每一行末尾的尾随空格
18+
trim_trailing_whitespace = true

‎README.md

-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ docker run -d --name SPlayer -p 7899:7899 imsyy/splayer:latest
229229
- [NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi)
230230
- [YesPlayMusic](https://github.com/qier222/YesPlayMusic)
231231
- [UnblockNeteaseMusic](https://github.com/UnblockNeteaseMusic/server)
232-
- [BlurLyric](https://github.com/Project-And-Factory/BlurLyric)
233232
- [Vue-mmPlayer](https://github.com/maomao1996/Vue-mmPlayer)
234233

235234
## 📢 免责声明

‎components.d.ts

-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ declare module 'vue' {
7777
NSelect: typeof import('naive-ui')['NSelect']
7878
NSkeleton: typeof import('naive-ui')['NSkeleton']
7979
NSlider: typeof import('naive-ui')['NSlider']
80-
NSpace: typeof import('naive-ui')['NSpace']
8180
NSpin: typeof import('naive-ui')['NSpin']
8281
NSwitch: typeof import('naive-ui')['NSwitch']
8382
NTab: typeof import('naive-ui')['NTab']
File renamed without changes.

‎electron/main/mainIpcMain.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { ipcMain, dialog, app, clipboard, shell } from "electron";
22
import { readDirAsync } from "@main/utils/readDirAsync";
33
import { parseFile } from "music-metadata";
4-
import { write } from "node-id3";
54
import { download } from "electron-dl";
65
import getNeteaseMusicUrl from "@main/utils/getNeteaseMusicUrl";
6+
import NodeID3 from "node-id3";
77
import axios from "axios";
88
import fs from "fs/promises";
99

@@ -203,6 +203,8 @@ const mainIpcMain = (win) => {
203203
directory: path,
204204
filename: `${songName}.${songType}`,
205205
});
206+
// 若不为 mp3,则不进行元信息写入
207+
if (songType !== "mp3") return true;
206208
// 下载封面
207209
const coverDownload = await download(win, songData.cover, {
208210
directory: path,
@@ -218,10 +220,10 @@ const mainIpcMain = (win) => {
218220
image: coverDownload.getSavePath(),
219221
};
220222
// 保存修改后的元数据
221-
write(songTag, songDownload.getSavePath());
223+
const isSuccess = NodeID3.write(songTag, songDownload.getSavePath());
222224
// 删除封面
223225
await fs.unlink(coverDownload.getSavePath());
224-
return true;
226+
return isSuccess;
225227
} else {
226228
console.log(`目录不存在:${path}`);
227229
return false;

‎electron/main/utils/checkUpdates.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { dialog, shell } from "electron";
22
import { is } from "@electron-toolkit/utils";
3-
import { autoUpdater } from "electron-updater";
3+
import pkg from "electron-updater";
4+
5+
const { autoUpdater } = pkg;
46

57
// 更新弹窗
68
const hasNewVersion = (info) => {

‎package.json

+15-14
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
"github": "https://github.com/imsyy/SPlayer",
99
"repository": "github:imsyy/SPlayer",
1010
"engines": {
11-
"node": ">=16.16.0"
11+
"node": ">=18.16.0",
12+
"npm": ">=9.6.7",
13+
"pnpm": ">=8.14.0"
1214
},
13-
"packageManager": "pnpm@8.12.0",
1415
"scripts": {
1516
"format": "prettier --write .",
1617
"lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts,.vue --fix",
@@ -23,8 +24,8 @@
2324
"build:linux": "npm run build && electron-builder --linux --config"
2425
},
2526
"dependencies": {
26-
"@electron-toolkit/preload": "^2.0.0",
27-
"@electron-toolkit/utils": "^2.0.1",
27+
"@electron-toolkit/preload": "^3.0.0",
28+
"@electron-toolkit/utils": "^3.0.0",
2829
"@material/material-color-utilities": "^0.2.7",
2930
"NeteaseCloudMusicApi": "^4.14.0",
3031
"axios": "^1.6.5",
@@ -33,11 +34,11 @@
3334
"electron-store": "^8.1.0",
3435
"electron-updater": "^6.1.7",
3536
"express": "^4.18.2",
36-
"express-http-proxy": "^1.6.3",
37+
"express-http-proxy": "^2.0.0",
3738
"howler": "^2.2.4",
3839
"js-cookie": "^3.0.5",
3940
"localforage": "^1.10.0",
40-
"music-metadata": "7.13.4",
41+
"music-metadata": "7.14.0",
4142
"node-id3": "^0.2.6",
4243
"pinia": "^2.1.7",
4344
"pinia-plugin-persistedstate": "^3.2.1",
@@ -49,22 +50,22 @@
4950
"devDependencies": {
5051
"@electron-toolkit/eslint-config": "^1.0.2",
5152
"@rushstack/eslint-patch": "^1.6.1",
52-
"@vitejs/plugin-vue": "^4.6.2",
53-
"@vue/eslint-config-prettier": "^8.0.0",
53+
"@vitejs/plugin-vue": "^5.0.2",
54+
"@vue/eslint-config-prettier": "^9.0.0",
5455
"ajv": "^8.12.0",
55-
"electron": "^27.2.1",
56+
"electron": "^28.1.2",
5657
"electron-builder": "^24.9.1",
5758
"electron-log": "^5.0.3",
58-
"electron-vite": "^1.0.29",
59+
"electron-vite": "^2.0.0",
5960
"eslint": "^8.56.0",
6061
"eslint-plugin-vue": "^9.19.2",
61-
"naive-ui": "^2.37.0",
62+
"naive-ui": "^2.37.3",
6263
"prettier": "^3.1.1",
6364
"sass": "^1.69.7",
6465
"terser": "^5.26.0",
65-
"unplugin-auto-import": "^0.16.7",
66-
"unplugin-vue-components": "^0.25.2",
67-
"vite": "^4.5.1",
66+
"unplugin-auto-import": "^0.17.3",
67+
"unplugin-vue-components": "^0.26.0",
68+
"vite": "^5.0.11",
6869
"vite-plugin-compression": "^0.5.1",
6970
"vite-plugin-pwa": "^0.17.4",
7071
"vue": "3.4.4"

‎pnpm-lock.yaml

+303-189
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/assets/icon.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,6 @@
9090
"password": "M2 17h20v2H2v-2zm1.15-4.05L4 11.47l.85 1.48l1.3-.75l-.85-1.48H7v-1.5H5.3l.85-1.47L4.85 7L4 8.47L3.15 7l-1.3.75l.85 1.47H1v1.5h1.7l-.85 1.48l1.3.75zm6.7-.75l1.3.75l.85-1.48l.85 1.48l1.3-.75l-.85-1.48H15v-1.5h-1.7l.85-1.47l-1.3-.75L12 8.47L11.15 7l-1.3.75l.85 1.47H9v1.5h1.7l-.85 1.48zM23 9.22h-1.7l.85-1.47l-1.3-.75L20 8.47L19.15 7l-1.3.75l.85 1.47H17v1.5h1.7l-.85 1.48l1.3.75l.85-1.48l.85 1.48l1.3-.75l-.85-1.48H23v-1.5z",
9191
"star": "m12 17.27l4.15 2.51c.76.46 1.69-.22 1.49-1.08l-1.1-4.72l3.67-3.18c.67-.58.31-1.68-.57-1.75l-4.83-.41l-1.89-4.46c-.34-.81-1.5-.81-1.84 0L9.19 8.63l-4.83.41c-.88.07-1.24 1.17-.57 1.75l3.67 3.18l-1.1 4.72c-.2.86.73 1.54 1.49 1.08l4.15-2.5z",
9292
"record": "M17 18.25v3.25H7v-3.25c0-1.38 2.24-2.5 5-2.5s5 1.12 5 2.5M12 5.5a6.5 6.5 0 0 1 6.5 6.5c0 1.25-.35 2.42-.96 3.41L16 14.04c.32-.61.5-1.31.5-2.04c0-2.5-2-4.5-4.5-4.5s-4.5 2-4.5 4.5c0 .73.18 1.43.5 2.04l-1.54 1.37c-.61-.99-.96-2.16-.96-3.41A6.5 6.5 0 0 1 12 5.5m0-4A10.5 10.5 0 0 1 22.5 12c0 2.28-.73 4.39-1.96 6.11l-1.5-1.35c.92-1.36 1.46-3 1.46-4.76A8.5 8.5 0 0 0 12 3.5A8.5 8.5 0 0 0 3.5 12c0 1.76.54 3.4 1.46 4.76l-1.5 1.35A10.473 10.473 0 0 1 1.5 12A10.5 10.5 0 0 1 12 1.5m0 8a2.5 2.5 0 0 1 2.5 2.5a2.5 2.5 0 0 1-2.5 2.5A2.5 2.5 0 0 1 9.5 12A2.5 2.5 0 0 1 12 9.5Z",
93-
"storage": "M4 20h16c1.1 0 2-.9 2-2s-.9-2-2-2H4c-1.1 0-2 .9-2 2s.9 2 2 2m0-3h2v2H4zM2 6c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2s-.9-2-2-2H4c-1.1 0-2 .9-2 2m4 1H4V5h2zm-2 7h16c1.1 0 2-.9 2-2s-.9-2-2-2H4c-1.1 0-2 .9-2 2s.9 2 2 2m0-3h2v2H4z"
93+
"storage": "M4 20h16c1.1 0 2-.9 2-2s-.9-2-2-2H4c-1.1 0-2 .9-2 2s.9 2 2 2m0-3h2v2H4zM2 6c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2s-.9-2-2-2H4c-1.1 0-2 .9-2 2m4 1H4V5h2zm-2 7h16c1.1 0 2-.9 2-2s-.9-2-2-2H4c-1.1 0-2 .9-2 2s.9 2 2 2m0-3h2v2H4z",
94+
"lrc-text": "M13.8 22H5c-1.7 0-3-1.3-3-3v-1h11.1c-.1.3-.1.7-.1 1c0 1.1.3 2.1.8 3m0-6H5V5c0-1.7 1.3-3 3-3h11c1.7 0 3 1.3 3 3v1h-2V5c0-.6-.4-1-1-1s-1 .4-1 1v8.1c-1.8.3-3.3 1.4-4.2 2.9M8 8h7V6H8zm0 4h6v-2H8zm9 4v6l5-3z"
9495
}

‎src/components/Player/FullPlayer.vue

+19-14
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,14 @@
4949
<div v-show="playerControlShow" class="menu">
5050
<div class="left">
5151
<!-- 歌词模式 -->
52-
<div v-if="isHasLrc" class="n-icon" @click="pureLyricMode = !pureLyricMode">
53-
<n-text>词</n-text>
54-
</div>
52+
<n-icon
53+
v-if="isHasLrc"
54+
:class="['lrc-open', { open: pureLyricMode }]"
55+
size="28"
56+
@click="pureLyricMode = !pureLyricMode"
57+
>
58+
<SvgIcon icon="lrc-text" />
59+
</n-icon>
5560
</div>
5661
<div class="right">
5762
<!-- 全屏切换 -->
@@ -406,17 +411,6 @@ onUnmounted(() => {
406411
justify-content: flex-end;
407412
flex: 1;
408413
}
409-
.left {
410-
justify-content: flex-start;
411-
.n-icon {
412-
margin-left: 0;
413-
margin-right: 12px;
414-
.n-text {
415-
font-size: 26px;
416-
font-weight: bold;
417-
}
418-
}
419-
}
420414
.n-icon {
421415
margin-left: 12px;
422416
width: 40px;
@@ -441,6 +435,17 @@ onUnmounted(() => {
441435
transform: scale(1);
442436
}
443437
}
438+
.left {
439+
justify-content: flex-start;
440+
.n-icon {
441+
margin-left: 0;
442+
&.lrc-open {
443+
&.open {
444+
opacity: 0.8;
445+
}
446+
}
447+
}
448+
}
444449
}
445450
.main-player {
446451
display: flex;

‎src/utils/Player.js

+35
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,41 @@ const getPlaySongName = () => {
779779
return songName + " - " + songArtist;
780780
};
781781

782+
export const playAllSongs = async (playlist, mode = "normal") => {
783+
try {
784+
// pinia
785+
const music = musicData();
786+
const status = siteStatus();
787+
if (!playlist) return false;
788+
// 关闭心动模式
789+
status.playHeartbeatMode = false;
790+
// 更改模式和歌单
791+
status.playMode = mode;
792+
music.playList = playlist.slice();
793+
// 是否处于歌单内
794+
const songId = music.getPlaySongData?.id;
795+
const existingIndex = playlist.findIndex((song) => song.id === songId);
796+
// 若不处于
797+
if (existingIndex === -1 || !songId) {
798+
console.log("不在歌单内");
799+
music.playSongData = playlist[0];
800+
status.playIndex = 0;
801+
// 初始化播放器
802+
await initPlayer(true);
803+
} else {
804+
console.log("处于歌单内");
805+
music.playSongData = playlist[existingIndex];
806+
status.playIndex = existingIndex;
807+
// 播放
808+
fadePlayOrPause();
809+
}
810+
$message.info("已开始播放", { showIcon: false });
811+
} catch (error) {
812+
console.error("播放全部歌曲出错:", error);
813+
$message.error("播放全部歌曲出现错误");
814+
}
815+
};
816+
782817
/*
783818
* 清除定时器
784819
*/

‎src/views/Cloud.vue

+13-33
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,17 @@
1717
<!-- 功能区 -->
1818
<n-flex class="menu" justify="space-between">
1919
<n-flex class="left">
20-
<n-button type="primary" class="play" circle strong secondary @click="playAllSongs">
20+
<n-button
21+
:disabled="userCloudData?.length === 0"
22+
:focusable="false"
23+
type="primary"
24+
class="play"
25+
tag="div"
26+
circle
27+
strong
28+
secondary
29+
@click="playAllSongs(userCloudData)"
30+
>
2131
<template #icon>
2232
<n-icon size="32">
2333
<SvgIcon icon="play-arrow-rounded" />
@@ -82,19 +92,14 @@
8292
</template>
8393

8494
<script setup>
85-
import { storeToRefs } from "pinia";
86-
import { musicData, siteStatus, indexedDBData } from "@/stores";
95+
import { indexedDBData } from "@/stores";
8796
import { getUserCloud } from "@/api/cloud";
8897
import { fuzzySearch } from "@/utils/helper";
89-
import { fadePlayOrPause, initPlayer } from "@/utils/Player";
98+
import { playAllSongs } from "@/utils/Player";
9099
import debounce from "@/utils/debounce";
91100
import formatData from "@/utils/formatData";
92101
93-
const music = musicData();
94-
const status = siteStatus();
95102
const indexedDB = indexedDBData();
96-
const { playList, playSongData } = storeToRefs(music);
97-
const { playIndex, playMode, playHeartbeatMode } = storeToRefs(status);
98103
99104
// 云盘数据
100105
const userCloudSpace = ref([]);
@@ -160,31 +165,6 @@ const localSearch = debounce((val) => {
160165
searchData.value = result;
161166
}, 300);
162167
163-
// 播放歌单全部歌曲
164-
const playAllSongs = async () => {
165-
if (!userCloudData.value || !Object.keys(userCloudData.value).length) return false;
166-
// 关闭心动模式
167-
playHeartbeatMode.value = false;
168-
// 更改模式和歌单
169-
playMode.value = "normal";
170-
playList.value = userCloudData.value.slice();
171-
// 是否处于歌单内
172-
const songId = playSongData.value?.id;
173-
const existingIndex = userCloudData.value.findIndex((song) => song.id === songId);
174-
// 若不处于
175-
if (existingIndex === -1 || !songId) {
176-
playSongData.value = userCloudData.value[0];
177-
playIndex.value = 0;
178-
// 初始化播放器
179-
await initPlayer(true);
180-
} else {
181-
playSongData.value = userCloudData.value[existingIndex];
182-
playIndex.value = existingIndex;
183-
fadePlayOrPause();
184-
}
185-
$message.info("已开始播放", { showIcon: false });
186-
};
187-
188168
// 云盘扩容
189169
const goBuy = () => {
190170
window.open("https://music.163.com/#/store/product/detail?id=34001");

‎src/views/DailySongs.vue

+12-35
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,16 @@
1313
</div>
1414
<!-- 操作 -->
1515
<n-flex class="control">
16-
<n-button size="large" tag="div" round strong secondary @click="playAllSongs">
16+
<n-button
17+
:disabled="dailySongsData.data?.length === 0"
18+
:focusable="false"
19+
size="large"
20+
tag="div"
21+
round
22+
strong
23+
secondary
24+
@click="playAllSongs(dailySongsData.data)"
25+
>
1726
<template #icon>
1827
<n-icon>
1928
<SvgIcon icon="play-arrow-rounded" />
@@ -40,16 +49,12 @@
4049
<script setup>
4150
import { NIcon } from "naive-ui";
4251
import { storeToRefs } from "pinia";
43-
import { musicData, siteData, siteStatus } from "@/stores";
44-
import { fadePlayOrPause, initPlayer } from "@/utils/Player";
52+
import { siteData } from "@/stores";
53+
import { playAllSongs } from "@/utils/Player";
4554
import SvgIcon from "@/components/Global/SvgIcon";
4655

4756
const data = siteData();
48-
const music = musicData();
49-
const status = siteStatus();
5057
const { dailySongsData } = storeToRefs(data);
51-
const { playList, playSongData } = storeToRefs(music);
52-
const { playIndex, playMode, playHeartbeatMode } = storeToRefs(status);
5358

5459
const showTime = ref(false);
5560
const showTimeOut = ref(null);
@@ -85,34 +90,6 @@ const moreOptions = computed(() => [
8590
},
8691
]);
8792

88-
// 播放歌单全部歌曲
89-
const playAllSongs = async () => {
90-
if (!dailySongsData.value.data) return false;
91-
// 关闭心动模式
92-
playHeartbeatMode.value = false;
93-
// 更改模式和歌单
94-
playMode.value = "normal";
95-
playList.value = dailySongsData.value.data.slice();
96-
// 是否处于歌单内
97-
const songId = music.getPlaySongData?.id;
98-
const existingIndex = dailySongsData.value.data.findIndex((song) => song.id === songId);
99-
// 若不处于
100-
if (existingIndex === -1 || !songId) {
101-
console.log("不在歌单内");
102-
playSongData.value = dailySongsData.value.data[0];
103-
playIndex.value = 0;
104-
// 初始化播放器
105-
await initPlayer(true);
106-
} else {
107-
console.log("处于歌单内");
108-
playSongData.value = dailySongsData.value.data[existingIndex];
109-
playIndex.value = existingIndex;
110-
// 播放
111-
fadePlayOrPause();
112-
}
113-
$message.info("已开始播放", { showIcon: false });
114-
};
115-
11693
onMounted(() => {
11794
showTimeOut.value = setTimeout(() => {
11895
showTime.value = true;

‎src/views/List/album.vue

+9-37
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,14 @@
105105
<n-flex class="left">
106106
<n-button
107107
:disabled="albumData === 'empty'"
108+
:focusable="false"
108109
type="primary"
109110
class="play"
110111
tag="div"
111112
circle
112113
strong
113114
secondary
114-
@click="playAllSongs"
115+
@click="playAllSongs(albumData)"
115116
>
116117
<template #icon>
117118
<n-icon size="32">
@@ -120,6 +121,7 @@
120121
</template>
121122
</n-button>
122123
<n-button
124+
:focusable="false"
123125
class="like"
124126
size="large"
125127
tag="div"
@@ -138,7 +140,7 @@
138140
{{ isLikeOrDislike(albumId) ? "收藏专辑" : "取消收藏" }}
139141
</n-button>
140142
<n-dropdown :options="moreOptions" trigger="hover" placement="bottom-start">
141-
<n-button class="more" size="large" tag="div" circle strong secondary>
143+
<n-button :focusable="false" class="more" size="large" tag="div" circle strong secondary>
142144
<template #icon>
143145
<n-icon>
144146
<SvgIcon icon="format-list-bulleted" />
@@ -193,32 +195,30 @@
193195
</div>
194196
<div v-else class="title">
195197
<n-text class="key">参数不完整</n-text>
196-
<n-button class="back" strong secondary @click="router.go(-1)"> 返回上一页 </n-button>
198+
<n-button :focusable="false" class="back" strong secondary @click="router.go(-1)">
199+
返回上一页
200+
</n-button>
197201
</div>
198202
</template>
199203

200204
<script setup>
201205
import { NIcon } from "naive-ui";
202206
import { useRouter } from "vue-router";
203207
import { storeToRefs } from "pinia";
204-
import { musicData, siteData, siteStatus } from "@/stores";
208+
import { siteData } from "@/stores";
205209
import { getSongDetail } from "@/api/song";
206210
import { getAlbumDetail, likeAlbum } from "@/api/album";
207211
import { formatNumber, fuzzySearch } from "@/utils/helper";
208212
import { getTimestampTime } from "@/utils/timeTools";
209-
import { fadePlayOrPause, initPlayer } from "@/utils/Player";
213+
import { playAllSongs } from "@/utils/Player";
210214
import { isLogin } from "@/utils/auth";
211215
import debounce from "@/utils/debounce";
212216
import formatData from "@/utils/formatData";
213217
import SvgIcon from "@/components/Global/SvgIcon";
214218

215219
const router = useRouter();
216220
const data = siteData();
217-
const music = musicData();
218-
const status = siteStatus();
219221
const { userLikeData } = storeToRefs(data);
220-
const { playList, playSongData } = storeToRefs(music);
221-
const { playIndex, playMode, playHeartbeatMode } = storeToRefs(status);
222222

223223
// 专辑 ID
224224
const albumId = ref(router.currentRoute.value.query.id || null);
@@ -269,34 +269,6 @@ const getAlbumAllData = async (id, justDetail = false) => {
269269
albumData.value = formatData(songsDetail.songs, "song");
270270
};
271271

272-
// 播放专辑全部歌曲
273-
const playAllSongs = async () => {
274-
if (!albumData.value) return false;
275-
// 关闭心动模式
276-
playHeartbeatMode.value = false;
277-
// 更改模式和歌单
278-
playMode.value = "normal";
279-
playList.value = albumData.value.slice();
280-
// 是否处于专辑内
281-
const songId = playSongData.value?.id;
282-
const existingIndex = albumData.value.findIndex((song) => song.id === songId);
283-
// 若不处于
284-
if (existingIndex === -1 || !songId) {
285-
console.log("不在专辑内");
286-
playSongData.value = albumData.value[0];
287-
playIndex.value = 0;
288-
// 初始化播放器
289-
await initPlayer(true);
290-
} else {
291-
console.log("处于专辑内");
292-
playSongData.value = albumData.value[existingIndex];
293-
playIndex.value = existingIndex;
294-
// 播放
295-
fadePlayOrPause();
296-
}
297-
$message.info("已开始播放", { showIcon: false });
298-
};
299-
300272
// 歌曲模糊搜索
301273
const localSearch = debounce((val) => {
302274
const searchValue = val?.trim();

‎src/views/List/dj.vue

+9-37
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,14 @@
100100
<n-flex class="left">
101101
<n-button
102102
:disabled="djData === 'empty'"
103+
:focusable="false"
103104
type="primary"
104105
class="play"
105106
tag="div"
106107
circle
107108
strong
108109
secondary
109-
@click="playAllSongs"
110+
@click="playAllSongs(djData, 'dj')"
110111
>
111112
<template #icon>
112113
<n-icon size="32">
@@ -115,6 +116,7 @@
115116
</template>
116117
</n-button>
117118
<n-button
119+
:focusable="false"
118120
class="like"
119121
size="large"
120122
tag="div"
@@ -133,7 +135,7 @@
133135
{{ isLikeOrDislike(djId) ? "订阅电台" : "取消订阅" }}
134136
</n-button>
135137
<n-dropdown :options="moreOptions" trigger="hover" placement="bottom-start">
136-
<n-button class="more" size="large" tag="div" circle strong secondary>
138+
<n-button :focusable="false" class="more" size="large" tag="div" circle strong secondary>
137139
<template #icon>
138140
<n-icon>
139141
<SvgIcon icon="format-list-bulleted" />
@@ -197,33 +199,31 @@
197199
</div>
198200
<div v-else class="title">
199201
<n-text class="key">参数不完整</n-text>
200-
<n-button class="back" strong secondary @click="router.go(-1)"> 返回上一页 </n-button>
202+
<n-button :focusable="false" class="back" strong secondary @click="router.go(-1)">
203+
返回上一页
204+
</n-button>
201205
</div>
202206
</template>
203207

204208
<script setup>
205209
import { NIcon } from "naive-ui";
206210
import { useRouter } from "vue-router";
207211
import { storeToRefs } from "pinia";
208-
import { musicData, siteData, siteSettings, siteStatus } from "@/stores";
212+
import { siteData, siteSettings } from "@/stores";
209213
import { getDjDetail, getDjProgram, likeDj } from "@/api/dj";
210214
import { fuzzySearch } from "@/utils/helper";
211215
import { isLogin } from "@/utils/auth";
212216
import { getTimestampTime } from "@/utils/timeTools";
213-
import { fadePlayOrPause, initPlayer } from "@/utils/Player";
217+
import { playAllSongs } from "@/utils/Player";
214218
import debounce from "@/utils/debounce";
215219
import formatData from "@/utils/formatData";
216220
import SvgIcon from "@/components/Global/SvgIcon";
217221

218222
const router = useRouter();
219223
const data = siteData();
220-
const music = musicData();
221-
const status = siteStatus();
222224
const settings = siteSettings();
223225
const { userLikeData } = storeToRefs(data);
224226
const { loadSize } = storeToRefs(settings);
225-
const { playList, playSongData } = storeToRefs(music);
226-
const { playIndex, playMode, playHeartbeatMode } = storeToRefs(status);
227227

228228
// 电台数据
229229
const djId = ref(router.currentRoute.value.query.id);
@@ -290,34 +290,6 @@ const getDjProgramData = async (id, limit = loadSize.value, offset = 0) => {
290290
}
291291
};
292292

293-
// 播放电台全部节目
294-
const playAllSongs = async () => {
295-
if (!djData.value) return false;
296-
// 关闭心动模式
297-
playHeartbeatMode.value = false;
298-
// 更改模式和电台
299-
playMode.value = "dj";
300-
playList.value = djData.value.slice();
301-
// 是否处于电台内
302-
const songId = music.getPlaySongData?.id;
303-
const existingIndex = djData.value.findIndex((song) => song.id === songId);
304-
// 若不处于
305-
if (existingIndex === -1 || !songId) {
306-
console.log("不在电台内");
307-
playSongData.value = djData.value[0];
308-
playIndex.value = 0;
309-
// 初始化播放器
310-
await initPlayer(true);
311-
} else {
312-
console.log("处于电台内");
313-
playSongData.value = djData.value[existingIndex];
314-
playIndex.value = existingIndex;
315-
// 播放
316-
fadePlayOrPause();
317-
}
318-
$message.info("已开始播放", { showIcon: false });
319-
};
320-
321293
// 节目模糊搜索
322294
const localSearch = debounce((val) => {
323295
const searchValue = val?.trim();

‎src/views/List/playlist.vue

+18-37
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,14 @@
112112
<n-flex class="left">
113113
<n-button
114114
:disabled="playListData === null || playListData === 'empty' || loadingMsg !== null"
115+
:focusable="false"
115116
type="primary"
116117
class="play"
117118
tag="div"
118119
circle
119120
strong
120121
secondary
121-
@click="playAllSongs"
122+
@click="playAllSongs(playListData)"
122123
>
123124
<template #icon>
124125
<n-icon size="32">
@@ -128,6 +129,7 @@
128129
</n-button>
129130
<n-button
130131
v-if="!isUserPLayList"
132+
:focusable="false"
131133
class="like"
132134
size="large"
133135
tag="div"
@@ -149,6 +151,7 @@
149151
</n-button>
150152
<n-button
151153
v-else
154+
:focusable="false"
152155
class="like"
153156
size="large"
154157
tag="div"
@@ -165,7 +168,15 @@
165168
编辑歌单
166169
</n-button>
167170
<n-dropdown :options="moreOptions" trigger="hover" placement="bottom-start">
168-
<n-button class="more" size="large" tag="div" circle strong secondary>
171+
<n-button
172+
:focusable="false"
173+
class="more"
174+
size="large"
175+
tag="div"
176+
circle
177+
strong
178+
secondary
179+
>
169180
<template #icon>
170181
<n-icon>
171182
<SvgIcon icon="format-list-bulleted" />
@@ -218,15 +229,17 @@
218229
</div>
219230
<div v-else class="title">
220231
<n-text class="key">参数不完整</n-text>
221-
<n-button class="back" strong secondary @click="router.go(-1)"> 返回上一页 </n-button>
232+
<n-button :focusable="false" class="back" strong secondary @click="router.go(-1)">
233+
返回上一页
234+
</n-button>
222235
</div>
223236
</template>
224237

225238
<script setup>
226239
import { NIcon } from "naive-ui";
227240
import { useRouter } from "vue-router";
228241
import { storeToRefs } from "pinia";
229-
import { musicData, siteData, siteStatus } from "@/stores";
242+
import { siteData } from "@/stores";
230243
import {
231244
getPlayListDetail,
232245
getAllPlayList,
@@ -238,18 +251,14 @@ import { getSongDetail } from "@/api/song";
238251
import { formatNumber, fuzzySearch } from "@/utils/helper";
239252
import { isLogin } from "@/utils/auth";
240253
import { getTimestampTime } from "@/utils/timeTools";
241-
import { fadePlayOrPause, initPlayer } from "@/utils/Player";
254+
import { playAllSongs } from "@/utils/Player";
242255
import debounce from "@/utils/debounce";
243256
import formatData from "@/utils/formatData";
244257
import SvgIcon from "@/components/Global/SvgIcon";
245258

246259
const router = useRouter();
247260
const data = siteData();
248-
const music = musicData();
249-
const status = siteStatus();
250261
const { userLikeData, userData } = storeToRefs(data);
251-
const { playList, playSongData } = storeToRefs(music);
252-
const { playIndex, playMode, playHeartbeatMode } = storeToRefs(status);
253262

254263
// 歌单 ID
255264
const playlistId = ref(
@@ -385,34 +394,6 @@ const getBigPlayListData = async (id, count) => {
385394
loadingMsg.value = null;
386395
};
387396

388-
// 播放歌单全部歌曲
389-
const playAllSongs = async () => {
390-
if (!playListData.value) return false;
391-
// 关闭心动模式
392-
playHeartbeatMode.value = false;
393-
// 更改模式和歌单
394-
playMode.value = "normal";
395-
playList.value = playListData.value.slice();
396-
// 是否处于歌单内
397-
const songId = music.getPlaySongData?.id;
398-
const existingIndex = playListData.value.findIndex((song) => song.id === songId);
399-
// 若不处于
400-
if (existingIndex === -1 || !songId) {
401-
console.log("不在歌单内");
402-
playSongData.value = playListData.value[0];
403-
playIndex.value = 0;
404-
// 初始化播放器
405-
await initPlayer(true);
406-
} else {
407-
console.log("处于歌单内");
408-
playSongData.value = playListData.value[existingIndex];
409-
playIndex.value = existingIndex;
410-
// 播放
411-
fadePlayOrPause();
412-
}
413-
$message.info("已开始播放", { showIcon: false });
414-
};
415-
416397
// 歌曲模糊搜索
417398
const localSearch = debounce((val) => {
418399
const searchValue = val?.trim();

‎src/views/Local/albums.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
v-if="allAlbumData"
66
:style="{
77
height: `calc(100vh - ${
8-
Object.keys(music.playSongData)?.length && status.showPlayBar ? 380 : 300
8+
Object.keys(music.playSongData)?.length && status.showPlayBar ? 445 : 365
99
}px)`,
1010
}"
1111
class="local-album"

‎src/views/Local/artists.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
class="local-artists"
77
:style="{
88
height: `calc(100vh - ${
9-
Object.keys(music.playSongData)?.length && status.showPlayBar ? 380 : 300
9+
Object.keys(music.playSongData)?.length && status.showPlayBar ? 445 : 365
1010
}px)`,
1111
}"
1212
type="card"

‎src/views/Local/index.vue

+88-45
Original file line numberDiff line numberDiff line change
@@ -26,41 +26,68 @@
2626
GB
2727
</div>
2828
</n-flex>
29+
<!-- 功能区 -->
30+
<n-flex class="menu" justify="space-between">
31+
<n-flex class="left">
32+
<n-button
33+
:disabled="!localSongList?.length"
34+
:focusable="false"
35+
type="primary"
36+
class="play"
37+
tag="div"
38+
circle
39+
strong
40+
secondary
41+
@click="playAllSongs(localSongList)"
42+
>
43+
<template #icon>
44+
<n-icon size="32">
45+
<SvgIcon icon="play-arrow-rounded" />
46+
</n-icon>
47+
</template>
48+
</n-button>
49+
<!-- 目录管理 -->
50+
<n-button
51+
:focusable="false"
52+
class="local-path"
53+
tag="div"
54+
round
55+
strong
56+
secondary
57+
@click="localPathShow = true"
58+
>
59+
<template #icon>
60+
<n-icon>
61+
<SvgIcon icon="folder-cog" />
62+
</n-icon>
63+
</template>
64+
目录管理
65+
</n-button>
66+
</n-flex>
67+
<n-flex class="right">
68+
<!-- 模糊搜索 -->
69+
<n-input
70+
v-if="localSongList?.length"
71+
v-model:value="searchValue"
72+
:input-props="{ autoComplete: false }"
73+
class="search"
74+
placeholder="搜索"
75+
clearable
76+
@input="localSearch"
77+
>
78+
<template #prefix>
79+
<n-icon size="18">
80+
<SvgIcon icon="search-rounded" />
81+
</n-icon>
82+
</template>
83+
</n-input>
84+
</n-flex>
85+
</n-flex>
2986
<!-- 标签页 -->
3087
<n-tabs v-model:value="tabValue" class="tabs" type="segment" @update:value="tabChange">
3188
<n-tab name="local-songs"> 歌曲 </n-tab>
3289
<n-tab name="local-artists"> 歌手 </n-tab>
3390
<n-tab name="local-albums"> 专辑 </n-tab>
34-
<template #suffix>
35-
<!-- 模糊搜索 -->
36-
<div v-if="localSongList?.length" class="search">
37-
<n-input
38-
v-model:value="searchValue"
39-
:input-props="{ autoComplete: false }"
40-
class="local-search"
41-
placeholder="搜索"
42-
clearable
43-
@input="localSearch"
44-
>
45-
<template #prefix>
46-
<n-icon size="18">
47-
<SvgIcon icon="search-rounded" />
48-
</n-icon>
49-
</template>
50-
</n-input>
51-
</div>
52-
<!-- 目录管理 -->
53-
<div class="local-path">
54-
<n-button strong secondary @click="localPathShow = true">
55-
<template #icon>
56-
<n-icon>
57-
<SvgIcon icon="folder-cog" />
58-
</n-icon>
59-
</template>
60-
目录管理
61-
</n-button>
62-
</div>
63-
</template>
6491
</n-tabs>
6592
<!-- 路由页面 -->
6693
<Transition name="fade" mode="out-in">
@@ -172,6 +199,7 @@
172199
import { musicData, indexedDBData } from "@/stores";
173200
import { useRouter } from "vue-router";
174201
import { fuzzySearch } from "@/utils/helper";
202+
import { playAllSongs } from "@/utils/Player";
175203
import debounce from "@/utils/debounce";
176204

177205
const indexedDB = indexedDBData();
@@ -335,25 +363,40 @@ onBeforeMount(async () => {
335363
}
336364
}
337365
}
338-
.tabs {
339-
margin-bottom: 20px;
340-
.search {
341-
height: 100%;
342-
margin-right: 16px;
343-
.local-search {
344-
display: flex;
345-
align-items: center;
346-
height: 100%;
347-
border-radius: 6px;
366+
.menu {
367+
flex-wrap: nowrap;
368+
align-items: center;
369+
margin: 20px 0;
370+
.left {
371+
flex-wrap: nowrap;
372+
align-items: center;
373+
.play {
374+
--n-width: 46px;
375+
--n-height: 46px;
348376
}
349-
}
350-
.local-path {
351-
height: 100%;
352-
:deep(.n-button) {
377+
.local-path {
353378
--n-height: 100%;
354-
--n-border-radius: 6px;
379+
height: 40px;
355380
}
356381
}
382+
.right {
383+
.search {
384+
height: 40px;
385+
width: 130px;
386+
display: flex;
387+
align-items: center;
388+
border-radius: 40px;
389+
transition:
390+
width 0.3s,
391+
background-color 0.3s;
392+
&.n-input--focus {
393+
width: 200px;
394+
}
395+
}
396+
}
397+
}
398+
.tabs {
399+
margin-bottom: 20px;
357400
}
358401
}
359402
.local-list {

0 commit comments

Comments
 (0)
Please sign in to comment.