diff --git a/components.d.ts b/components.d.ts
index 05a460bd3..d9247dcfe 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -29,6 +29,7 @@ declare module 'vue' {
copy: typeof import('./src/components/Global/Provider copy.vue')['default']
CopyLyrics: typeof import('./src/components/Modal/CopyLyrics.vue')['default']
CoverList: typeof import('./src/components/List/CoverList.vue')['default']
+ CoverManager: typeof import('./src/components/Modal/Setting/CoverManager.vue')['default']
CoverMenu: typeof import('./src/components/Menu/CoverMenu.vue')['default']
CreatePlaylist: typeof import('./src/components/Modal/CreatePlaylist.vue')['default']
CustomCode: typeof import('./src/components/Modal/Setting/CustomCode.vue')['default']
@@ -161,6 +162,7 @@ declare module 'vue' {
PlayerSlider: typeof import('./src/components/Player/PlayerComponents/PlayerSlider.vue')['default']
PlayerSpectrum: typeof import('./src/components/Player/PlayerComponents/PlayerSpectrum.vue')['default']
PlaylistAdd: typeof import('./src/components/Modal/PlaylistAdd.vue')['default']
+ PlaylistPageManager: typeof import('./src/components/Modal/Setting/PlaylistPageManager.vue')['default']
PlaySetting: typeof import('./src/components/Setting/old/PlaySetting.vue')['default']
Provider: typeof import('./src/components/Global/Provider.vue')['default']
ProxyConfig: typeof import('./src/components/Setting/components/ProxyConfig.vue')['default']
diff --git a/electron/main/ipc/ipc-file.ts b/electron/main/ipc/ipc-file.ts
index 649fc2f15..332dec0c0 100644
--- a/electron/main/ipc/ipc-file.ts
+++ b/electron/main/ipc/ipc-file.ts
@@ -156,6 +156,12 @@ const initFileIpc = (): void => {
size: (size / (1024 * 1024)).toFixed(2),
path: fullPath,
quality: format.bitrate ?? 0,
+ replayGain: {
+ trackGain: common.replaygain_track_gain?.ratio,
+ trackPeak: common.replaygain_track_peak?.ratio,
+ albumGain: common.replaygain_album_gain?.ratio,
+ albumPeak: common.replaygain_album_peak?.ratio,
+ },
};
} catch (err) {
ipcLog.warn(`⚠️ Failed to parse file: ${fullPath}`, err);
@@ -193,6 +199,12 @@ const initFileIpc = (): void => {
format,
// md5
md5: await getFileMD5(filePath),
+ replayGain: {
+ trackGain: common.replaygain_track_gain?.ratio,
+ trackPeak: common.replaygain_track_peak?.ratio,
+ albumGain: common.replaygain_album_gain?.ratio,
+ albumPeak: common.replaygain_album_peak?.ratio,
+ },
};
} catch (error) {
ipcLog.error("❌ Error fetching music metadata:", error);
@@ -636,9 +648,26 @@ const initFileIpc = (): void => {
Id3v2Settings.defaultVersion = 3;
songFile.tag.title = songData?.name || "未知曲目";
- songFile.tag.album = songData?.album?.name || "未知专辑";
- songFile.tag.performers = songData?.artists?.map((ar: any) => ar.name) || ["未知艺术家"];
- songFile.tag.albumArtists = songData?.artists?.map((ar: any) => ar.name) || ["未知艺术家"];
+ songFile.tag.album =
+ (typeof songData?.album === "string" ? songData.album : songData?.album?.name) || "未知专辑";
+ // 处理歌手信息(兼容字符串和数组格式)
+ const getArtistNames = (artists: any): string[] => {
+ if (Array.isArray(artists)) {
+ return artists
+ .map((ar: any) => (typeof ar === "string" ? ar : ar?.name || ""))
+ .filter((name) => name && name.trim().length > 0);
+ }
+ if (typeof artists === "string" && artists.trim().length > 0) {
+ return [artists];
+ }
+ return [];
+ };
+
+ const artistNames = getArtistNames(songData?.artists);
+ const finalArtists = artistNames.length > 0 ? artistNames : ["未知艺术家"];
+
+ songFile.tag.performers = finalArtists;
+ songFile.tag.albumArtists = finalArtists;
if (lyric && downloadLyric) songFile.tag.lyrics = lyric;
if (songCover && downloadCover) songFile.tag.pictures = [songCover];
// 保存元信息
diff --git a/src/components/Card/SongCard.vue b/src/components/Card/SongCard.vue
index 49ac0ead1..5dc66e46b 100644
--- a/src/components/Card/SongCard.vue
+++ b/src/components/Card/SongCard.vue
@@ -40,12 +40,12 @@
class="name-text"
>
{{
- settingStore.hideLyricBrackets
+ settingStore.hideBracketedContent
? removeBrackets(song?.name)
: song?.name || "未知曲目"
}}
@@ -120,14 +120,22 @@
class="ar"
@click="openJumpArtist(song.artists, ar.id)"
>
- {{ ar.name }}
+ {{
+ settingStore.hideBracketedContent ? removeBrackets(ar.name) : ar.name
+ }}
电台节目
- {{ song.artists || "未知艺术家" }}
+
+ {{
+ settingStore.hideBracketedContent
+ ? removeBrackets(song.artists)
+ : song.artists || "未知艺术家"
+ }}
+
@@ -236,7 +244,7 @@ const qualityColor = computed(() => {
const albumName = computed(() => {
const album = song.value.album;
const name = isObject(album) ? album.name : album;
- return (settingStore.hideLyricBrackets ? removeBrackets(name) : name) || "未知专辑";
+ return (settingStore.hideBracketedContent ? removeBrackets(name) : name) || "未知专辑";
});
// 加载本地歌曲封面
diff --git a/src/components/Card/SongDataCard.vue b/src/components/Card/SongDataCard.vue
index 2760a1560..bd8bcec9f 100644
--- a/src/components/Card/SongDataCard.vue
+++ b/src/components/Card/SongDataCard.vue
@@ -19,12 +19,20 @@
- {{ ar.name }}
+ {{
+ settingStore.hideBracketedContent ? removeBrackets(ar.name) : ar.name
+ }}
- {{ data.artists || "未知艺术家" }}
+
+ {{
+ settingStore.hideBracketedContent
+ ? removeBrackets(data.artists)
+ : data.artists || "未知艺术家"
+ }}
+
@@ -47,6 +55,10 @@
import type { SongType } from "@/types/main";
import { coverLoaded } from "@/utils/helper";
import { isObject } from "lodash-es";
+import { removeBrackets } from "@/utils/format";
+import { useSettingStore } from "@/stores";
+
+const settingStore = useSettingStore();
defineProps<{
data: SongType | null;
diff --git a/src/components/Card/SongListCard.vue b/src/components/Card/SongListCard.vue
index 242954eee..cedff1a32 100644
--- a/src/components/Card/SongListCard.vue
+++ b/src/components/Card/SongListCard.vue
@@ -7,7 +7,7 @@
-
+
@@ -65,6 +65,7 @@ const props = defineProps<{
loading?: boolean;
height?: number;
cover?: string;
+ hiddenCover?: boolean;
}>();
// 列表前三首
diff --git a/src/components/List/ArtistList.vue b/src/components/List/ArtistList.vue
index 3da9aed85..a382393ed 100644
--- a/src/components/List/ArtistList.vue
+++ b/src/components/List/ArtistList.vue
@@ -5,7 +5,7 @@
-
+
-
{{ item.name }}
+
{{
+ settingStore.hideBracketedContent ? removeBrackets(item.name) : item.name
+ }}
@@ -49,8 +51,8 @@
-
-
+
+
@@ -66,6 +68,8 @@
diff --git a/src/components/Modal/Setting/PlaylistPageManager.vue b/src/components/Modal/Setting/PlaylistPageManager.vue
new file mode 100644
index 000000000..6941ea286
--- /dev/null
+++ b/src/components/Modal/Setting/PlaylistPageManager.vue
@@ -0,0 +1,63 @@
+
+
+
+
+ {{ item.label }}
+ updateSetting(item.key, val)"
+ />
+
+
+
+
+
+
+
+
diff --git a/src/components/Player/FullPlayerMobile.vue b/src/components/Player/FullPlayerMobile.vue
index a3ac9b423..dbb73a2e9 100644
--- a/src/components/Player/FullPlayerMobile.vue
+++ b/src/components/Player/FullPlayerMobile.vue
@@ -129,7 +129,7 @@
{{
- settingStore.hideLyricBrackets
+ settingStore.hideBracketedContent
? removeBrackets(musicStore.playSong.name)
: musicStore.playSong.name
}}
diff --git a/src/components/Player/MainPlayer.vue b/src/components/Player/MainPlayer.vue
index 207eb94ec..739214797 100644
--- a/src/components/Player/MainPlayer.vue
+++ b/src/components/Player/MainPlayer.vue
@@ -16,6 +16,7 @@
- {{ item.name }}
+ {{
+ settingStore.hideBracketedContent ? removeBrackets(item.name) : item.name
+ }}
-
- {{ musicStore.playSong.artists || "未知艺术家" }}
+
+ {{
+ settingStore.hideBracketedContent
+ ? removeBrackets(musicStore.playSong.artists)
+ : musicStore.playSong.artists || "未知艺术家"
+ }}
diff --git a/src/components/Player/PlayerComponents/PersonalFM.vue b/src/components/Player/PlayerComponents/PersonalFM.vue
index 6e8c97bd6..493d7da12 100644
--- a/src/components/Player/PlayerComponents/PersonalFM.vue
+++ b/src/components/Player/PlayerComponents/PersonalFM.vue
@@ -3,6 +3,7 @@
-
+
{{ musicStore.personalFMSong?.name || "未知曲目" }}
@@ -37,6 +41,13 @@
-
-
@@ -78,12 +82,13 @@
diff --git a/src/views/Like/artists.vue b/src/views/Like/artists.vue
index 6e26c165f..beb0a9e96 100644
--- a/src/views/Like/artists.vue
+++ b/src/views/Like/artists.vue
@@ -1,11 +1,16 @@
diff --git a/src/views/Like/playlists.vue b/src/views/Like/playlists.vue
index dc2326df1..edd9cb53f 100644
--- a/src/views/Like/playlists.vue
+++ b/src/views/Like/playlists.vue
@@ -14,15 +14,22 @@
-
+
diff --git a/src/views/Like/videos.vue b/src/views/Like/videos.vue
index a4db18ce1..673567bf5 100644
--- a/src/views/Like/videos.vue
+++ b/src/views/Like/videos.vue
@@ -5,12 +5,14 @@
:loading="true"
cols="2 600:2 800:3 900:4 1200:5 1400:6"
type="video"
+ :hiddenCover="settingStore.hiddenCovers.like"
/>
diff --git a/src/views/Radio/hot.vue b/src/views/Radio/hot.vue
index 5c67e4bbc..f28c489ec 100644
--- a/src/views/Radio/hot.vue
+++ b/src/views/Radio/hot.vue
@@ -45,14 +45,24 @@
热门推荐
-
+
{{ item.name }}
-
+
@@ -63,6 +73,7 @@ import type { CoverType } from "@/types/main";
import { radioCatList, radioToplist, radioTypes } from "@/api/radio";
import { getCacheData } from "@/utils/cache";
import { formatCoverList } from "@/utils/format";
+import { useSettingStore } from "@/stores";
interface RadioType {
id: number;
@@ -71,6 +82,7 @@ interface RadioType {
}
const router = useRouter();
+const settingStore = useSettingStore();
// 栅格折叠
const gridCollapsed = ref
(true);
diff --git a/src/views/Radio/type.vue b/src/views/Radio/type.vue
index 3082a3655..aabd83cdf 100644
--- a/src/views/Radio/type.vue
+++ b/src/views/Radio/type.vue
@@ -13,10 +13,20 @@
-
+
-
+
@@ -26,8 +36,10 @@
import { radioCatHot, radioCatRecommend } from "@/api/radio";
import type { CoverType } from "@/types/main";
import { formatCoverList } from "@/utils/format";
+import { useSettingStore } from "@/stores";
const router = useRouter();
+const settingStore = useSettingStore();
// 播客数据
const radioId = ref
(Number(router.currentRoute.value.query.id as string));
diff --git a/src/views/Search/videos.vue b/src/views/Search/videos.vue
index 0b07f884e..cb64365b6 100644
--- a/src/views/Search/videos.vue
+++ b/src/views/Search/videos.vue
@@ -8,6 +8,7 @@
:loadMore="hasMore"
cols="2 600:2 800:3 900:4 1200:5 1400:6"
type="video"
+ :hiddenCover="settingStore.hiddenCovers.video"
@loadMore="loadMore"
/>
();
+const settingStore = useSettingStore();
+
// 搜索数据
const hasMore = ref(true);
const loading = ref(true);
diff --git a/src/views/Song/wiki.vue b/src/views/Song/wiki.vue
index deb318f4a..7eedb9764 100644
--- a/src/views/Song/wiki.vue
+++ b/src/views/Song/wiki.vue
@@ -22,7 +22,11 @@
/>
-
{{ currentSong.name }}
+
{{
+ settingStore.hideBracketedContent
+ ? removeBrackets(currentSong.name)
+ : currentSong.name
+ }}
@@ -47,9 +59,17 @@
class="text-hidden"
@click="$router.push({ name: 'album', query: { id: currentSong.album.id } })"
>
- {{ currentSong.album.name }}
+ {{
+ settingStore.hideBracketedContent
+ ? removeBrackets(currentSong.album.name)
+ : currentSong.album.name
+ }}
- {{ currentSong.album }}
+ {{
+ settingStore.hideBracketedContent
+ ? removeBrackets(currentSong.album)
+ : currentSong.album
+ }}
@@ -277,11 +297,13 @@ import {
songSheetPreview,
songFirstListenInfo,
} from "@/api/song";
-import { formatSongsList } from "@/utils/format";
+import { formatSongsList, removeBrackets } from "@/utils/format";
+import { useSettingStore } from "@/stores";
import dayjs from "dayjs";
const route = useRoute();
const player = usePlayerController();
+const settingStore = useSettingStore();
const loading = ref(true);
const currentSongId = ref(0);
diff --git a/src/views/Streaming/layout.vue b/src/views/Streaming/layout.vue
index 64dfbcbf6..46ec27969 100644
--- a/src/views/Streaming/layout.vue
+++ b/src/views/Streaming/layout.vue
@@ -251,7 +251,7 @@ const moreOptions = computed(() => [
label: "流媒体设置",
key: "setting",
props: {
- onClick: () => openSetting("streaming"),
+ onClick: () => openSetting("network"),
},
icon: renderIcon("Settings"),
},
diff --git a/src/views/Video.vue b/src/views/Video.vue
index edba7241e..fedc9bd76 100644
--- a/src/views/Video.vue
+++ b/src/views/Video.vue
@@ -46,7 +46,12 @@
})
"
>
-
+
{{ artistData?.name || "未知歌手" }}
@@ -119,6 +124,7 @@
:type="videoType === 'mv' ? 1 : 5"
:loadMore="commentHasMore"
:res-id="videoId"
+ :hiddenCover="settingStore.hiddenCovers.videoDetail"
@loadMore="loadMoreComment"
/>
@@ -127,7 +133,7 @@