mirror of
https://github.com/atdunbg/Nekosonic-Music.git
synced 2026-08-06 03:44:18 +08:00
feat: v0.6.0 - 亮色主题、封面主色、发现页重做、漫游页重做、减少推荐、列表风格统一
新功能: - 亮色主题:新增浅色外观模式,7种主题色各有对应亮色变体 - 封面主色背景:漫游抽屉自动提取封面主色,PlayerBar跟随继承 - 发现页重做:多类型搜索(歌曲/歌手/专辑)+搜索建议+搜索历史 - 漫游页重做:进入即播放,布局改为封面+歌名+播放/下一首/减少推荐 - 减少推荐:FM模式下可标记不推荐歌曲或歌手 - 列表风格统一:播放指示器跳动动画+hover播放图标+图标统一使用Lucide 修复: - 专辑页艺术家过多时窗口缩小竖排,改为自动换行 - FM播放时退出登录后首页仍可点击下一首 - 本地音乐播放时缓冲进度条未重置 - 亮色主题下多处文字不可见 - 退出FM模式时状态未正确清理 - 暗色模式下关闭抽屉时PlayerBar闪烁亮色(改用opacity过渡) - player.ts tickInterval双变量状态不同步,统一为clearTick/setTick 变更: - 移除播放列表按钮数字角标 - 主页卡片标题固定白色不随主题变化 - 全项目空catch块格式统一 - 清理冗余注释和代码
This commit is contained in:
+47
-10
@@ -1,11 +1,12 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref, watch } from 'vue';
|
||||
import { ref, watch, computed } from 'vue';
|
||||
|
||||
export type AudioQuality = 'standard' | 'higher' | 'exhigh' | 'lossless' | 'hires';
|
||||
export type ThemeName = 'blue' | 'green' | 'rose' | 'violet' | 'orange' | 'cyan' | 'pink';
|
||||
export type ThemeColor = 'blue' | 'green' | 'rose' | 'violet' | 'orange' | 'cyan' | 'pink';
|
||||
export type Appearance = 'dark' | 'light';
|
||||
export type CloseAction = 'ask' | 'minimize' | 'exit';
|
||||
|
||||
export const themeLabels: Record<ThemeName, string> = {
|
||||
export const themeLabels: Record<ThemeColor, string> = {
|
||||
blue: '天蓝',
|
||||
green: '翠绿',
|
||||
rose: '玫红',
|
||||
@@ -15,7 +16,7 @@ export const themeLabels: Record<ThemeName, string> = {
|
||||
pink: '粉色',
|
||||
};
|
||||
|
||||
export const themeColors: Record<ThemeName, string> = {
|
||||
export const themeColors: Record<ThemeColor, string> = {
|
||||
blue: '#3b82f6',
|
||||
green: '#22c55e',
|
||||
rose: '#f43f5e',
|
||||
@@ -25,6 +26,11 @@ export const themeColors: Record<ThemeName, string> = {
|
||||
pink: '#ec4899',
|
||||
};
|
||||
|
||||
export const appearanceLabels: Record<Appearance, string> = {
|
||||
dark: '深色',
|
||||
light: '浅色',
|
||||
};
|
||||
|
||||
export const qualityLabels: Record<AudioQuality, string> = {
|
||||
standard: '标准',
|
||||
higher: '较高',
|
||||
@@ -60,7 +66,8 @@ export const defaultShortcuts: Record<string, ShortcutBinding> = {
|
||||
interface SettingsData {
|
||||
audioQuality: AudioQuality;
|
||||
downloadPath: string;
|
||||
theme: ThemeName;
|
||||
theme: ThemeColor;
|
||||
appearance: Appearance;
|
||||
closeAction: CloseAction;
|
||||
shortcuts: Record<string, ShortcutBinding>;
|
||||
outputDevice: string | null;
|
||||
@@ -73,22 +80,38 @@ function loadSettings(): SettingsData {
|
||||
if (raw) {
|
||||
const parsed = JSON.parse(raw);
|
||||
const theme = parsed.theme || parsed.accentColor || 'blue';
|
||||
const validThemes: ThemeName[] = ['blue', 'green', 'rose', 'violet', 'orange', 'cyan', 'pink'];
|
||||
const validThemes: ThemeColor[] = ['blue', 'green', 'rose', 'violet', 'orange', 'cyan', 'pink'];
|
||||
const validAppearances: Appearance[] = ['dark', 'light'];
|
||||
const appearance = validAppearances.includes(parsed.appearance) ? parsed.appearance : 'dark';
|
||||
if (parsed.theme && parsed.theme.startsWith('light-')) {
|
||||
return {
|
||||
audioQuality: parsed.audioQuality || 'standard',
|
||||
downloadPath: parsed.downloadPath || '',
|
||||
theme: validThemes.includes(parsed.theme.slice(6)) ? parsed.theme.slice(6) : 'blue',
|
||||
appearance: 'light',
|
||||
closeAction: parsed.closeAction || 'ask',
|
||||
shortcuts: { ...defaultShortcuts, ...(parsed.shortcuts || {}) },
|
||||
outputDevice: parsed.outputDevice || null,
|
||||
volume: typeof parsed.volume === 'number' ? parsed.volume : 100,
|
||||
};
|
||||
}
|
||||
return {
|
||||
audioQuality: parsed.audioQuality || 'standard',
|
||||
downloadPath: parsed.downloadPath || '',
|
||||
theme: validThemes.includes(theme) ? theme : 'blue',
|
||||
appearance,
|
||||
closeAction: parsed.closeAction || 'ask',
|
||||
shortcuts: { ...defaultShortcuts, ...(parsed.shortcuts || {}) },
|
||||
outputDevice: parsed.outputDevice || null,
|
||||
volume: typeof parsed.volume === 'number' ? parsed.volume : 100,
|
||||
};
|
||||
}
|
||||
} catch {}
|
||||
} catch { /* 忽略 */ }
|
||||
return {
|
||||
audioQuality: 'standard',
|
||||
downloadPath: '',
|
||||
theme: 'blue',
|
||||
appearance: 'dark',
|
||||
closeAction: 'ask',
|
||||
shortcuts: { ...defaultShortcuts },
|
||||
outputDevice: null,
|
||||
@@ -101,12 +124,17 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
|
||||
const audioQuality = ref<AudioQuality>(saved.audioQuality);
|
||||
const downloadPath = ref<string>(saved.downloadPath);
|
||||
const theme = ref<ThemeName>(saved.theme);
|
||||
const theme = ref<ThemeColor>(saved.theme);
|
||||
const appearance = ref<Appearance>(saved.appearance);
|
||||
const closeAction = ref<CloseAction>(saved.closeAction || 'ask');
|
||||
const shortcuts = ref<Record<string, ShortcutBinding>>(saved.shortcuts);
|
||||
const outputDevice = ref<string | null>(saved.outputDevice);
|
||||
const volume = ref<number>(saved.volume);
|
||||
|
||||
const dataTheme = computed(() =>
|
||||
appearance.value === 'light' ? `light-${theme.value}` : theme.value
|
||||
);
|
||||
|
||||
function setAudioQuality(q: AudioQuality) {
|
||||
audioQuality.value = q;
|
||||
}
|
||||
@@ -115,10 +143,14 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
downloadPath.value = p;
|
||||
}
|
||||
|
||||
function setTheme(t: ThemeName) {
|
||||
function setTheme(t: ThemeColor) {
|
||||
theme.value = t;
|
||||
}
|
||||
|
||||
function setAppearance(a: Appearance) {
|
||||
appearance.value = a;
|
||||
}
|
||||
|
||||
function setCloseAction(a: CloseAction) {
|
||||
closeAction.value = a;
|
||||
}
|
||||
@@ -139,17 +171,19 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
audioQuality.value = 'standard';
|
||||
downloadPath.value = '';
|
||||
theme.value = 'blue';
|
||||
appearance.value = 'dark';
|
||||
closeAction.value = 'ask';
|
||||
shortcuts.value = { ...defaultShortcuts };
|
||||
outputDevice.value = null;
|
||||
volume.value = 100;
|
||||
}
|
||||
|
||||
watch([audioQuality, downloadPath, theme, closeAction, shortcuts, outputDevice, volume], () => {
|
||||
watch([audioQuality, downloadPath, theme, appearance, closeAction, shortcuts, outputDevice, volume], () => {
|
||||
const data: SettingsData = {
|
||||
audioQuality: audioQuality.value,
|
||||
downloadPath: downloadPath.value,
|
||||
theme: theme.value,
|
||||
appearance: appearance.value,
|
||||
closeAction: closeAction.value,
|
||||
shortcuts: shortcuts.value,
|
||||
outputDevice: outputDevice.value,
|
||||
@@ -162,6 +196,8 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
audioQuality,
|
||||
downloadPath,
|
||||
theme,
|
||||
appearance,
|
||||
dataTheme,
|
||||
closeAction,
|
||||
shortcuts,
|
||||
outputDevice,
|
||||
@@ -169,6 +205,7 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
setAudioQuality,
|
||||
setDownloadPath,
|
||||
setTheme,
|
||||
setAppearance,
|
||||
setCloseAction,
|
||||
setOutputDevice,
|
||||
setShortcut,
|
||||
|
||||
Reference in New Issue
Block a user