fix: 修复快捷键异常占用 & 去除部分动画效果

This commit is contained in:
imsyy
2023-12-04 13:35:06 +08:00
parent 046b8f3a92
commit dd1081cfa2
20 changed files with 195 additions and 194 deletions

View File

@@ -1,6 +1,6 @@
import { join } from "path"; import { join } from "path";
import { app, protocol, shell, BrowserWindow, globalShortcut } from "electron"; import { app, protocol, shell, BrowserWindow, globalShortcut } from "electron";
import { optimizer, is } from "@electron-toolkit/utils"; import { platform, optimizer, is } from "@electron-toolkit/utils";
import { startNcmServer } from "@main/startNcmServer"; import { startNcmServer } from "@main/startNcmServer";
import { startMainServer } from "@main/startMainServer"; import { startMainServer } from "@main/startMainServer";
import { configureAutoUpdater } from "@main/utils/checkUpdates"; import { configureAutoUpdater } from "@main/utils/checkUpdates";
@@ -49,7 +49,7 @@ class MainProcess {
}); });
} }
// 检查上次程序 // 单例锁
async checkApp() { async checkApp() {
if (!app.requestSingleInstanceLock()) { if (!app.requestSingleInstanceLock()) {
log.error("已有一个程序正在运行,本次启动阻止"); log.error("已有一个程序正在运行,本次启动阻止");
@@ -164,7 +164,7 @@ class MainProcess {
// 创建主窗口 // 创建主窗口
this.createWindow(); this.createWindow();
// 检测更新 // 检测更新
configureAutoUpdater(process.platform); configureAutoUpdater();
// 创建系统信息 // 创建系统信息
createSystemInfo(this.mainWindow); createSystemInfo(this.mainWindow);
// 引入主 Ipc // 引入主 Ipc
@@ -173,7 +173,7 @@ class MainProcess {
createGlobalShortcut(this.mainWindow); createGlobalShortcut(this.mainWindow);
}); });
// 开发模式下默认通过 F12 打开或关闭 DevTools // 开发环境下 F12 打开控制台
app.on("browser-window-created", (_, window) => { app.on("browser-window-created", (_, window) => {
optimizer.watchWindowShortcuts(window); optimizer.watchWindowShortcuts(window);
}); });
@@ -196,7 +196,7 @@ class MainProcess {
// 当所有窗口都关闭时退出应用macOS 除外 // 当所有窗口都关闭时退出应用macOS 除外
app.on("window-all-closed", () => { app.on("window-all-closed", () => {
if (process.platform !== "darwin") { if (!platform.isMacOS) {
app.quit(); app.quit();
} }
}); });

View File

@@ -6,9 +6,19 @@ import { globalShortcut } from "electron";
*/ */
const createGlobalShortcut = (win) => { const createGlobalShortcut = (win) => {
// 刷新程序 // 刷新程序
globalShortcut.register("CommandOrControl+R", () => { globalShortcut.register("CmdOrCtrl+Shift+R", () => {
if (win && win.isFocused()) win?.reload(); if (win && win.isFocused()) win?.reload();
}); });
// 打开开发者工具
globalShortcut.register("CmdOrCtrl+Shift+I", () => {
if (win && win.isFocused()) {
win?.webContents.openDevTools({
mode: "right",
activate: true,
});
}
});
}; };
export default createGlobalShortcut; export default createGlobalShortcut;

View File

@@ -1,4 +1,5 @@
import { join } from "path"; import { join } from "path";
import { platform } from "@electron-toolkit/utils";
import { Tray, Menu, app, ipcMain, nativeImage, nativeTheme } from "electron"; import { Tray, Menu, app, ipcMain, nativeImage, nativeTheme } from "electron";
// 当前播放歌曲数据 // 当前播放歌曲数据
@@ -39,7 +40,7 @@ const createSystemInfo = (win) => {
mainTray.popUpContextMenu(Menu.buildFromTemplate(createTrayMenu(win))); mainTray.popUpContextMenu(Menu.buildFromTemplate(createTrayMenu(win)));
}); });
// linux 右键菜单 // linux 右键菜单
if (process.platform === "linux") { if (platform.isLinux) {
mainTray.setContextMenu(Menu.buildFromTemplate(createTrayMenu(win))); mainTray.setContextMenu(Menu.buildFromTemplate(createTrayMenu(win)));
} }
}; };
@@ -75,7 +76,7 @@ const createTrayMenu = (win) => {
{ {
label: "上一曲", label: "上一曲",
icon: createIcon("prev"), icon: createIcon("prev"),
accelerator: "CommandOrControl+Left", accelerator: "CmdOrCtrl+Left",
click: () => { click: () => {
win.webContents.send("playNextOrPrev", "prev"); win.webContents.send("playNextOrPrev", "prev");
}, },
@@ -83,7 +84,7 @@ const createTrayMenu = (win) => {
{ {
label: playSongState ? "暂停" : "播放", label: playSongState ? "暂停" : "播放",
icon: createIcon(playSongState ? "pause" : "play"), icon: createIcon(playSongState ? "pause" : "play"),
accelerator: "Space", accelerator: "CmdOrCtrl+Space",
click: () => { click: () => {
win.webContents.send("playOrPause"); win.webContents.send("playOrPause");
}, },
@@ -91,7 +92,7 @@ const createTrayMenu = (win) => {
{ {
label: "下一曲", label: "下一曲",
icon: createIcon("next"), icon: createIcon("next"),
accelerator: "CommandOrControl+Right", accelerator: "CmdOrCtrl+Right",
click: () => { click: () => {
win.webContents.send("playNextOrPrev", "next"); win.webContents.send("playNextOrPrev", "next");
}, },

View File

@@ -1,7 +1,7 @@
<template> <template>
<Provider> <Provider>
<!-- 主框架 --> <!-- 主框架 -->
<n-layout :class="['all-layout', status.showFullPlayer ? 'full-player' : null]"> <n-layout class="all-layout">
<!-- 导航栏 --> <!-- 导航栏 -->
<n-layout-header bordered> <n-layout-header bordered>
<MainNav /> <MainNav />
@@ -183,8 +183,5 @@ onUnmounted(() => {
padding: 24px; padding: 24px;
} }
} }
&.full-player {
transform: scale(0.95);
}
} }
</style> </style>

View File

@@ -35,12 +35,13 @@ import {
useNotification, useNotification,
} from "naive-ui"; } from "naive-ui";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { siteSettings, siteData } from "@/stores"; import { siteSettings, siteStatus } from "@/stores";
import themeColorData from "@/assets/themeColor.json"; import themeColorData from "@/assets/themeColor.json";
const data = siteData(); const status = siteStatus();
const osThemeRef = useOsTheme();
const settings = siteSettings(); const settings = siteSettings();
const osThemeRef = useOsTheme();
const { coverTheme } = storeToRefs(status);
const { themeType, themeAuto, themeTypeName, themeTypeData, themeAutoCover } = const { themeType, themeAuto, themeTypeName, themeTypeData, themeAutoCover } =
storeToRefs(settings); storeToRefs(settings);
@@ -63,23 +64,23 @@ const changeTheme = () => {
// 配置主题色 // 配置主题色
const changeThemeColor = (val, isCover = false) => { const changeThemeColor = (val, isCover = false) => {
const color = try {
// 获取主色数据
const mainColorData =
isCover && Object.keys(val)?.length isCover && Object.keys(val)?.length
? themeType.value === "dark" ? val[themeType.value]
? val.light.bg
: val.dark.bg
: val !== "custom" : val !== "custom"
? themeColorData[val] ? themeColorData[val]
: themeTypeData.value; : themeTypeData.value;
// 微调主题色 // 微调主题色
const primaryColor = isCover ? `rgb(${color})` : color.primaryColor; const primaryColor = isCover ? `rgb(${mainColorData.bg})` : mainColorData.primaryColor;
const primaryColorHover = isCover ? `rgba(${color}, 0.29)` : primaryColor + "29"; const primaryColorHover = isCover ? `rgba(${mainColorData.bg}, 0.29)` : primaryColor + "29";
const primaryColorPressed = isCover ? `rgba(${color}, 0.26)` : primaryColor + "26"; const primaryColorPressed = isCover ? `rgba(${mainColorData.bg}, 0.26)` : primaryColor + "26";
const primaryColorSuppl = isCover ? `rgba(${color}, 0.05)` : primaryColor + "05"; const primaryColorSuppl = isCover ? `rgba(${mainColorData.bg}, 0.05)` : primaryColor + "05";
// 自适应主题背景色 // 自适应主题背景色
const coverAutobgCover = isCover const coverAutobgCover = isCover
? themeType.value === "dark" ? themeType.value === "dark"
? val.dark.bg ? val.light.bg
: "239, 239, 239" : "239, 239, 239"
: null; : null;
// 更新主题覆盖 // 更新主题覆盖
@@ -91,34 +92,35 @@ const changeThemeColor = (val, isCover = false) => {
primaryColorHover, primaryColorHover,
primaryColorPressed, primaryColorPressed,
primaryColorSuppl, primaryColorSuppl,
textColor1: `rgba(${color}, 0.9)`, textColor1: `rgba(${mainColorData.bg}, 0.9)`,
textColor2: `rgba(${color}, 0.82)`, textColor2: `rgba(${mainColorData.bg}, 0.82)`,
textColor3: `rgba(${color}, 0.52)`, textColor3: `rgba(${mainColorData.bg}, 0.52)`,
bodyColor: `rgba(${val.dark.mainBg}, 0.52)`, bodyColor: `rgba(${val.dark.mainBg}, 0.52)`,
cardColor: `rgb(${coverAutobgCover})`, cardColor: `rgb(${coverAutobgCover})`,
tagColor: `rgb(${coverAutobgCover})`, tagColor: `rgb(${coverAutobgCover})`,
modalColor: `rgb(${coverAutobgCover})`, modalColor: `rgb(${coverAutobgCover})`,
popoverColor: `rgb(${coverAutobgCover})`, popoverColor: `rgb(${coverAutobgCover})`,
} }
: color, : mainColorData,
Icon: { color: isCover ? primaryColor : null }, Icon: { color: isCover ? primaryColor : null },
}; };
if (!isCover) themeTypeData.value = color; if (!isCover) themeTypeData.value = mainColorData;
// 更新全局颜色变量 // 更新全局颜色变量
setCssVariable("--main-color", primaryColor); setCssVariable("--main-color", primaryColor);
setCssVariable(
"--main-color-bg",
isCover ? `rgb(${val[themeType.value]?.bg})` : "rgb(16, 16, 20)",
);
setCssVariable("--main-second-color", primaryColorHover); setCssVariable("--main-second-color", primaryColorHover);
setCssVariable("--main-boxshadow-color", primaryColorPressed); setCssVariable("--main-boxshadow-color", primaryColorPressed);
setCssVariable("--main-boxshadow-hover-color", primaryColorSuppl); setCssVariable("--main-boxshadow-hover-color", primaryColorSuppl);
} catch (error) {
themeOverrides.value = {};
console.error("切换主题色出现错误:", error);
$message.error("切换主题色出现错误,已使用默认配置");
}
}; };
// 修改全局颜色 // 修改全局颜色
const setCssVariable = (name, value) => { const setCssVariable = (name, value) => {
document.documentElement.style.setProperty(name, value); // document.documentElement.style.setProperty(name, value);
// document.body.style.setProperty(name, value); document.body.style.setProperty(name, value);
}; };
// 挂载 naive 组件 // 挂载 naive 组件
@@ -148,8 +150,10 @@ watch(
() => { () => {
changeTheme(); changeTheme();
changeThemeColor( changeThemeColor(
themeAutoCover.value ? data.coverTheme : themeTypeName.value, themeAutoCover.value && Object.keys(coverTheme.value)?.length
themeAutoCover.value, ? coverTheme.value
: themeTypeName.value,
themeAutoCover.value && Object.keys(coverTheme.value)?.length,
); );
}, },
); );
@@ -170,9 +174,8 @@ watch(
(val) => changeThemeColor(val.label), (val) => changeThemeColor(val.label),
); );
watch( watch(
() => data.coverTheme, () => coverTheme.value,
(val) => { (val) => {
console.log(val);
if (themeAutoCover.value) changeThemeColor(val, themeAutoCover.value); if (themeAutoCover.value) changeThemeColor(val, themeAutoCover.value);
}, },
); );

View File

@@ -29,25 +29,28 @@
<!-- 搜索框 --> <!-- 搜索框 -->
<SearchInp /> <SearchInp />
<!-- GitHub --> <!-- GitHub -->
<n-button class="github" circle quaternary @click="openGithub"> <Transition name="fade" mode="out-in">
<n-button v-if="setting.showGithub" class="github" circle quaternary @click="openGithub">
<template #icon> <template #icon>
<n-icon size="20"> <n-icon size="20">
<SvgIcon icon="github" /> <SvgIcon icon="github" />
</n-icon> </n-icon>
</template> </template>
</n-button> </n-button>
</Transition>
<!-- 用户信息 --> <!-- 用户信息 -->
<userData /> <userData />
</nav> </nav>
</template> </template>
<script setup> <script setup>
import { siteStatus } from "@/stores"; import { siteStatus, siteSettings } from "@/stores";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import packageJson from "@/../package.json"; import packageJson from "@/../package.json";
const router = useRouter(); const router = useRouter();
const status = siteStatus(); const status = siteStatus();
const setting = siteSettings();
// 站点信息 // 站点信息
const siteName = import.meta.env.RENDERER_VITE_SITE_TITLE; const siteName = import.meta.env.RENDERER_VITE_SITE_TITLE;

View File

@@ -4,8 +4,8 @@
<div <div
v-if="showFullPlayer" v-if="showFullPlayer"
:style="{ :style="{
'--cover-main-color': `rgb(${coverTheme?.dark?.shadeTwo})` || '#efefef', '--cover-main-color': `rgb(${coverTheme?.light?.shadeTwo})` || '#efefef',
'--cover-second-color': `rgba(${coverTheme?.dark?.shadeTwo}, 0.14)` || '#efefef14', '--cover-second-color': `rgba(${coverTheme?.light?.shadeTwo}, 0.14)` || '#efefef14',
'--cover-bg': coverBackground, '--cover-bg': coverBackground,
cursor: playerControlShow ? 'auto' : 'none', cursor: playerControlShow ? 'auto' : 'none',
}" }"
@@ -183,20 +183,24 @@
<script setup> <script setup>
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { musicData, siteStatus, siteSettings, siteData } from "@/stores"; import { musicData, siteStatus, siteSettings } from "@/stores";
import screenfull from "screenfull"; import screenfull from "screenfull";
import throttle from "@/utils/throttle"; import throttle from "@/utils/throttle";
const router = useRouter(); const router = useRouter();
const data = siteData();
const music = musicData(); const music = musicData();
const status = siteStatus(); const status = siteStatus();
const settings = siteSettings(); const settings = siteSettings();
const { playList, playSongLyric } = storeToRefs(music); const { playList, playSongLyric } = storeToRefs(music);
const { playerBackgroundType, showYrc } = storeToRefs(settings); const { playerBackgroundType, showYrc } = storeToRefs(settings);
const { coverTheme, coverBackground } = storeToRefs(data); const {
const { playerControlShow, controlTimeOut, showFullPlayer, playUseOtherSource } = playerControlShow,
storeToRefs(status); controlTimeOut,
showFullPlayer,
playUseOtherSource,
coverTheme,
coverBackground,
} = storeToRefs(status);
// 全屏状态 // 全屏状态
const screenfullStatus = ref(false); const screenfullStatus = ref(false);

View File

@@ -171,7 +171,7 @@
<!-- 播放暂停 --> <!-- 播放暂停 -->
<n-button <n-button
:loading="playLoading" :loading="playLoading"
:keyboard="false" tag="div"
type="primary" type="primary"
class="play-control" class="play-control"
strong strong

View File

@@ -3,7 +3,10 @@
<div <div
class="private-fm" class="private-fm"
:style="{ :style="{
color: playMode === 'fm' && settings.themeAutoCover ? 'var(--main-color)' : '#efefef', '--color':
playMode === 'fm' && settings.themeAutoCover && Object.keys(coverTheme)?.length
? `rgb(${coverTheme.dark.bg})`
: '#efefef',
}" }"
> >
<!-- 背景 --> <!-- 背景 -->
@@ -68,7 +71,7 @@
<!-- 播放暂停 --> <!-- 播放暂停 -->
<n-button <n-button
:loading="playLoading" :loading="playLoading"
:class="{ 'play-control': true, isFm: playMode === 'fm' && settings.themeAutoCover }" class="play-control"
color="#efefef" color="#efefef"
type="primary" type="primary"
strong strong
@@ -134,7 +137,7 @@ const status = siteStatus();
const settings = siteSettings(); const settings = siteSettings();
const router = useRouter(); const router = useRouter();
const { privateFmSong, playMode } = storeToRefs(music); const { privateFmSong, playMode } = storeToRefs(music);
const { playLoading, playState } = storeToRefs(status); const { playLoading, playState, coverTheme } = storeToRefs(status);
// 播放暂停 // 播放暂停
const fmPlayOrPause = () => { const fmPlayOrPause = () => {
@@ -240,6 +243,7 @@ onBeforeMount(async () => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;
color: var(--color);
.info { .info {
.name { .name {
display: -webkit-box; display: -webkit-box;
@@ -256,6 +260,7 @@ onBeforeMount(async () => {
align-items: center; align-items: center;
.n-icon { .n-icon {
margin-right: 4px; margin-right: 4px;
color: var(--color);
} }
.all-ar { .all-ar {
display: -webkit-box; display: -webkit-box;
@@ -292,6 +297,7 @@ onBeforeMount(async () => {
align-items: center; align-items: center;
.n-icon { .n-icon {
margin-right: 4px; margin-right: 4px;
color: var(--color);
} }
.al { .al {
display: -webkit-box; display: -webkit-box;
@@ -315,9 +321,11 @@ onBeforeMount(async () => {
align-items: center; align-items: center;
height: 46px; height: 46px;
margin-top: auto; margin-top: auto;
color: var(--color);
.play-control { .play-control {
--n-width: 46px; --n-width: 46px;
--n-height: 46px; --n-height: 46px;
color: var(--color);
margin-right: 12px; margin-right: 12px;
transition: transition:
background-color 0.3s, background-color 0.3s,
@@ -331,9 +339,6 @@ onBeforeMount(async () => {
&:active { &:active {
transform: scale(1); transform: scale(1);
} }
&.isFm {
color: var(--main-color);
}
} }
.play-other { .play-other {
margin-right: 12px; margin-right: 12px;
@@ -355,6 +360,7 @@ onBeforeMount(async () => {
position: absolute; position: absolute;
right: 0; right: 0;
bottom: 0; bottom: 0;
color: var(--color);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-end; align-items: flex-end;

View File

@@ -2,21 +2,21 @@
<template> <template>
<div class="title-bar"> <div class="title-bar">
<n-divider vertical /> <n-divider vertical />
<n-button class="bar-icon" quaternary circle @click="windowMin"> <n-button class="bar-icon" tag="div" quaternary circle @click="windowMin">
<template #icon> <template #icon>
<n-icon :depth="2"> <n-icon :depth="2">
<SvgIcon icon="window-minimize" /> <SvgIcon icon="window-minimize" />
</n-icon> </n-icon>
</template> </template>
</n-button> </n-button>
<n-button class="bar-icon" quaternary circle @click="maxOrRestore"> <n-button class="bar-icon" tag="div" quaternary circle @click="maxOrRestore">
<template #icon> <template #icon>
<n-icon :depth="2"> <n-icon :depth="2">
<SvgIcon :icon="defaultWindowState ? 'window-restore' : 'window-maximize'" /> <SvgIcon :icon="defaultWindowState ? 'window-restore' : 'window-maximize'" />
</n-icon> </n-icon>
</template> </template>
</n-button> </n-button>
<n-button class="bar-icon" quaternary circle @click="openCloseTip"> <n-button class="bar-icon" tag="div" quaternary circle @click="openCloseTip">
<template #icon> <template #icon>
<n-icon :depth="2"> <n-icon :depth="2">
<SvgIcon icon="window-close" /> <SvgIcon icon="window-close" />

View File

@@ -46,9 +46,6 @@ const useSiteDataStore = defineStore("siteData", {
catList: [], // 普通分类 catList: [], // 普通分类
hqCatList: [], // 精品分类 hqCatList: [], // 精品分类
}, },
// 封面主题
coverTheme: {},
coverBackground: null,
}; };
}, },
getters: { getters: {

View File

@@ -10,6 +10,7 @@ const useSiteSettingsStore = defineStore("siteSettings", {
showTaskbarProgress: false, // 显示歌曲任务栏进度 showTaskbarProgress: false, // 显示歌曲任务栏进度
searchHistory: true, // 搜索历史 searchHistory: true, // 搜索历史
autoSignIn: true, // 自动签到 autoSignIn: true, // 自动签到
showGithub: true,
// 主题部分 // 主题部分
themeType: "dark", themeType: "dark",
themeAuto: false, themeAuto: false,

View File

@@ -25,6 +25,9 @@ const useSiteStatusStore = defineStore("siteStatus", {
playSeek: 0, playSeek: 0,
// 是否下一首 // 是否下一首
hasNextSong: false, hasNextSong: false,
// 封面主题
coverTheme: {},
coverBackground: null,
}; };
}, },
getters: {}, getters: {},

View File

@@ -12,7 +12,6 @@ body,
height: 100vh; height: 100vh;
font-family: "HarmonyOS_Regular", sans-serif !important; font-family: "HarmonyOS_Regular", sans-serif !important;
overflow: hidden; overflow: hidden;
background-color: var(--main-color-bg) !important;
} }
// n-text // n-text
@@ -169,12 +168,3 @@ body,
backdrop-filter: blur(16px); backdrop-filter: blur(16px);
} }
} }
// n-switch
.n-switch {
&.n-switch--active {
.n-switch__rail {
background-color: var(--main-second-color);
}
}
}

View File

@@ -1,5 +1,5 @@
import { Howl, Howler } from "howler"; import { Howl, Howler } from "howler";
import { musicData, siteStatus, siteSettings, siteData } from "@/stores"; import { musicData, siteStatus, siteSettings } from "@/stores";
import { getSongUrl, getSongLyric, songScrobble } from "@/api/song"; import { getSongUrl, getSongLyric, songScrobble } from "@/api/song";
import { checkPlatform, getLocalCoverData } from "@/utils/helper"; import { checkPlatform, getLocalCoverData } from "@/utils/helper";
import { decode as base642Buffer } from "@/utils/base64"; import { decode as base642Buffer } from "@/utils/base64";
@@ -673,17 +673,17 @@ const initMediaSession = async (data, islocal, cover) => {
* @returns {string} - 主要颜色的RGB十六进制表示 * @returns {string} - 主要颜色的RGB十六进制表示
*/ */
const getColorMainColor = async (islocal, cover) => { const getColorMainColor = async (islocal, cover) => {
const data = siteData(); const status = siteStatus();
try { try {
// 获取封面图像的URL // 获取封面图像的URL
if (!cover) return (data.coverColor = {}); if (!cover) return (status.coverColor = {});
const colorUrl = islocal ? cover : cover.s; const colorUrl = islocal ? cover : cover.s;
// 获取渐变色背景 // 获取渐变色背景
const gradientColor = await getCoverGradient(colorUrl); const gradientColor = await getCoverGradient(colorUrl);
data.coverBackground = gradientColor; status.coverBackground = gradientColor;
} catch (error) { } catch (error) {
console.error("封面颜色获取失败:", error); console.error("封面颜色获取失败:", error);
data.coverColor = {}; status.coverColor = {};
} }
}; };

View File

@@ -4,7 +4,7 @@ import {
Hct, Hct,
Score, Score,
} from "@material/material-color-utilities"; } from "@material/material-color-utilities";
import { siteData, siteSettings } from "@/stores"; import { siteSettings, siteStatus } from "@/stores";
import { getGradientFromPalette, argb2Rgb, rgb2Argb } from "@/utils/color-utils"; import { getGradientFromPalette, argb2Rgb, rgb2Argb } from "@/utils/color-utils";
import { chunk } from "@/utils/helper"; import { chunk } from "@/utils/helper";
import ColorThief from "colorthief"; import ColorThief from "colorthief";
@@ -45,7 +45,7 @@ export const getCoverGradient = (coverSrc) => {
*/ */
const calcAccentColor = (dom) => { const calcAccentColor = (dom) => {
// pinia // pinia
const data = siteData(); const status = siteStatus();
const settings = siteSettings(); const settings = siteSettings();
// 创建一个用于提取颜色的 canvas // 创建一个用于提取颜色的 canvas
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
@@ -77,11 +77,11 @@ const calcAccentColor = (dom) => {
const top = ranked[0]; const top = ranked[0];
const theme = themeFromSourceColor(top); const theme = themeFromSourceColor(top);
// 错误 error, 中性 neutral, 中性的变体 neutralVariant, 主要的 primary, 二次 secondary, 三级 tertiary // 错误 error, 中性 neutral, 中性的变体 neutralVariant, 主要的 primary, 二次 secondary, 三级 tertiary
const variant = window.accentColorVariant ?? "secondary"; const variant = "secondary";
// 更新主题色 // 更新主题色
data.coverTheme = { status.coverTheme = {
light: { dark: {
light: getAccentColor(theme.schemes.dark[variant]), dark: getAccentColor(theme.schemes.dark[variant]),
primary: getAccentColor( primary: getAccentColor(
Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 100).toInt(), Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 100).toInt(),
), ),
@@ -94,9 +94,12 @@ const calcAccentColor = (dom) => {
bg: getAccentColor( bg: getAccentColor(
Hct.from(theme.palettes.secondary.hue, theme.palettes.secondary.chroma, 90).toInt(), Hct.from(theme.palettes.secondary.hue, theme.palettes.secondary.chroma, 90).toInt(),
), ),
mainBg: getAccentColor(
Hct.from(theme.palettes.secondary.hue, theme.palettes.secondary.chroma, 10).toInt(),
),
}, },
dark: { light: {
dark: getAccentColor(theme.schemes.dark[variant]), light: getAccentColor(theme.schemes.light[variant]),
primary: getAccentColor( primary: getAccentColor(
Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 20).toInt(), Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 20).toInt(),
), ),
@@ -110,13 +113,13 @@ const calcAccentColor = (dom) => {
Hct.from(theme.palettes.secondary.hue, theme.palettes.secondary.chroma, 20).toInt(), Hct.from(theme.palettes.secondary.hue, theme.palettes.secondary.chroma, 20).toInt(),
), ),
mainBg: getAccentColor( mainBg: getAccentColor(
Hct.from(theme.palettes.secondary.hue, theme.palettes.secondary.chroma, 10).toInt(), Hct.from(theme.palettes.secondary.hue, theme.palettes.secondary.chroma, 100).toInt(),
), ),
}, },
}; };
// 尝试更新主题色 // 尝试更新主题色
if (typeof $changeThemeColor !== "undefined" && settings.themeAutoCover) { if (typeof $changeThemeColor !== "undefined" && settings.themeAutoCover) {
$changeThemeColor(data.coverTheme, settings.themeAutoCover); $changeThemeColor(status.coverTheme, settings.themeAutoCover);
} }
}; };
@@ -125,17 +128,18 @@ const calcAccentColor = (dom) => {
*/ */
const useGreyAccentColor = () => { const useGreyAccentColor = () => {
// pinia // pinia
const data = siteData(); const status = siteStatus();
data.coverTheme = { status.coverTheme = {
light: { dark: {
light: getAccentColor(rgb2Argb(120, 120, 120)), dark: getAccentColor(rgb2Argb(120, 120, 120)),
primary: getAccentColor(rgb2Argb(250, 250, 250)), primary: getAccentColor(rgb2Argb(250, 250, 250)),
shade: getAccentColor(rgb2Argb(40, 40, 40)), shade: getAccentColor(rgb2Argb(40, 40, 40)),
shadeTwo: getAccentColor(rgb2Argb(20, 20, 20)), shadeTwo: getAccentColor(rgb2Argb(20, 20, 20)),
bg: getAccentColor(rgb2Argb(190, 190, 190)), bg: getAccentColor(rgb2Argb(190, 190, 190)),
mainBg: getAccentColor(rgb2Argb(11, 11, 11)),
}, },
dark: { light: {
dark: getAccentColor(rgb2Argb(150, 150, 150)), light: getAccentColor(rgb2Argb(150, 150, 150)),
primary: getAccentColor(rgb2Argb(10, 10, 10)), primary: getAccentColor(rgb2Argb(10, 10, 10)),
shade: getAccentColor(rgb2Argb(210, 210, 210)), shade: getAccentColor(rgb2Argb(210, 210, 210)),
shadeTwo: getAccentColor(rgb2Argb(255, 255, 255)), shadeTwo: getAccentColor(rgb2Argb(255, 255, 255)),

View File

@@ -51,21 +51,8 @@ watch(
font-weight: bold; font-weight: bold;
} }
.tabs { .tabs {
position: sticky;
top: 20px;
margin-bottom: 20px; margin-bottom: 20px;
z-index: 2; z-index: 2;
&::after {
content: "";
position: absolute;
top: -20px;
left: -25px;
width: calc(100% + 50px);
height: calc(100% + 40px);
background-color: var(--n-color);
backdrop-filter: blur(40px);
z-index: -1;
}
} }
} }
</style> </style>

View File

@@ -275,6 +275,7 @@ onMounted(() => {
} }
} }
.tag { .tag {
background-color: var(--n-action-color);
transition: transition:
transform 0.3s, transform 0.3s,
background-color 0.3s, background-color 0.3s,

View File

@@ -2,8 +2,6 @@
<template> <template>
<div class="search"> <div class="search">
<template v-if="searchKeywords"> <template v-if="searchKeywords">
<!-- 固定 -->
<div class="fixed">
<div class="title"> <div class="title">
<n-text class="key">{{ searchKeywords }}</n-text> <n-text class="key">{{ searchKeywords }}</n-text>
<n-text depth="3">的相关搜索</n-text> <n-text depth="3">的相关搜索</n-text>
@@ -16,7 +14,6 @@
<n-tab name="sea-playlists"> 歌单 </n-tab> <n-tab name="sea-playlists"> 歌单 </n-tab>
<n-tab name="sea-videos"> 视频 </n-tab> <n-tab name="sea-videos"> 视频 </n-tab>
</n-tabs> </n-tabs>
</div>
<!-- 路由页面 --> <!-- 路由页面 -->
<router-view v-slot="{ Component }"> <router-view v-slot="{ Component }">
<keep-alive> <keep-alive>
@@ -69,23 +66,6 @@ watch(
<style lang="scss" scoped> <style lang="scss" scoped>
.search { .search {
.fixed {
position: sticky;
top: 34px;
background-color: var(--n-color);
z-index: 2;
&::after {
content: "";
position: absolute;
bottom: -20px;
left: -25px;
width: calc(100% + 50px);
height: calc(100% + 54px);
background-color: var(--n-color);
backdrop-filter: blur(40px);
z-index: -1;
}
.title { .title {
margin: 10px 0; margin: 10px 0;
font-size: 22px; font-size: 22px;
@@ -101,6 +81,5 @@ watch(
.tabs { .tabs {
margin-bottom: 20px; margin-bottom: 20px;
} }
}
} }
</style> </style>

View File

@@ -1,6 +1,6 @@
<!-- 全局设置 --> <!-- 全局设置 -->
<template> <template>
<div class="setting"> <div :class="{ setting: true, 'use-cover': themeAutoCover }">
<n-h1 class="title"> <n-h1 class="title">
<n-text>全局设置</n-text> <n-text>全局设置</n-text>
<n-text class="version" depth="3">v&nbsp;{{ packageJson.version }}</n-text> <n-text class="version" depth="3">v&nbsp;{{ packageJson.version }}</n-text>
@@ -24,7 +24,7 @@
ref="setScrollRef" ref="setScrollRef"
:style="{ :style="{
height: `calc(100vh - ${ height: `calc(100vh - ${
Object.keys(music.getPlaySongData)?.length && status.showPlayBar ? 328 : 248 Object.keys(music.getPlaySongData)?.length && showPlayBar ? 328 : 248
}px)`, }px)`,
}" }"
class="all-set" class="all-set"
@@ -92,6 +92,7 @@
<n-switch <n-switch
v-model:value="themeAutoCover" v-model:value="themeAutoCover"
:round="false" :round="false"
:disabled="Object.keys(coverTheme)?.length === 0"
@update:value="themeAutoCoverChange" @update:value="themeAutoCoverChange"
/> />
</n-card> </n-card>
@@ -386,6 +387,10 @@
<!-- 其他 --> <!-- 其他 -->
<div class="set-type"> <div class="set-type">
<n-h3 prefix="bar"> 其他 </n-h3> <n-h3 prefix="bar"> 其他 </n-h3>
<n-card class="set-item">
<div class="name">是否显示 GitHub 仓库按钮</div>
<n-switch v-model:value="showGithub" :round="false" />
</n-card>
<n-card class="set-item"> <n-card class="set-item">
<div class="name"> <div class="name">
默认加载数量 默认加载数量
@@ -426,15 +431,15 @@
<script setup> <script setup>
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { useOsTheme } from "naive-ui"; import { useOsTheme } from "naive-ui";
import { siteSettings, siteStatus, musicData, siteData } from "@/stores"; import { siteSettings, siteStatus, musicData } from "@/stores";
import { checkPlatform } from "@/utils/helper"; import { checkPlatform } from "@/utils/helper";
import debounce from "@/utils/debounce"; import debounce from "@/utils/debounce";
import packageJson from "@/../package.json"; import packageJson from "@/../package.json";
const music = musicData(); const music = musicData();
const status = siteStatus(); const status = siteStatus();
const data = siteData();
const settings = siteSettings(); const settings = siteSettings();
const { showPlayBar, coverTheme } = storeToRefs(status);
const { const {
themeType, themeType,
themeTypeName, themeTypeName,
@@ -464,6 +469,7 @@ const {
bottomLyricShow, bottomLyricShow,
downloadPath, downloadPath,
memorySeek, memorySeek,
showGithub,
} = storeToRefs(settings); } = storeToRefs(settings);
// 标签页数据 // 标签页数据
@@ -515,9 +521,9 @@ const songLevelData = {
// 封面自动跟随变化 // 封面自动跟随变化
const themeAutoCoverChange = (val) => { const themeAutoCoverChange = (val) => {
typeof $changeThemeColor !== "undefined" && val if ($changeThemeColor !== "undefined" && Object.keys(coverTheme.value)?.length) {
? $changeThemeColor(data.coverTheme, val) $changeThemeColor(val ? coverTheme.value : themeTypeName.value, val);
: $changeThemeColor(themeTypeName.value, val); }
}; };
// 标签页切换 // 标签页切换
@@ -635,5 +641,14 @@ const resetApp = () => {
} }
} }
} }
&.use-cover {
.n-switch {
&.n-switch--active {
:deep(.n-switch__rail) {
background-color: var(--main-second-color);
}
}
}
}
} }
</style> </style>