feat: 添加桌面歌词锁定

This commit is contained in:
imsyy
2025-11-07 17:38:49 +08:00
parent 8f69b56378
commit 8ec91e1392
8 changed files with 65 additions and 28 deletions

5
components.d.ts vendored
View File

@@ -61,8 +61,11 @@ declare module 'vue' {
NDrawerContent: typeof import('naive-ui')['NDrawerContent']
NDropdown: typeof import('naive-ui')['NDropdown']
NDynamicTags: typeof import('naive-ui')['NDynamicTags']
NEllipsis: typeof import('naive-ui')['NEllipsis']
NEmpty: typeof import('naive-ui')['NEmpty']
NFlex: typeof import('naive-ui')['NFlex']
NFloatButton: typeof import('naive-ui')['NFloatButton']
NFloatButtonGroup: typeof import('naive-ui')['NFloatButtonGroup']
NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem']
NFormItemGi: typeof import('naive-ui')['NFormItemGi']
@@ -70,6 +73,7 @@ declare module 'vue' {
NGlobalStyle: typeof import('naive-ui')['NGlobalStyle']
NGrid: typeof import('naive-ui')['NGrid']
NH1: typeof import('naive-ui')['NH1']
NH2: typeof import('naive-ui')['NH2']
NH3: typeof import('naive-ui')['NH3']
NIcon: typeof import('naive-ui')['NIcon']
NImage: typeof import('naive-ui')['NImage']
@@ -100,6 +104,7 @@ declare module 'vue' {
NSelect: typeof import('naive-ui')['NSelect']
NSkeleton: typeof import('naive-ui')['NSkeleton']
NSlider: typeof import('naive-ui')['NSlider']
NSpin: typeof import('naive-ui')['NSpin']
NSwitch: typeof import('naive-ui')['NSwitch']
NTabPane: typeof import('naive-ui')['NTabPane']
NTabs: typeof import('naive-ui')['NTabs']

View File

@@ -195,6 +195,10 @@ const initLyricIpc = (): void => {
} else {
lyricWin.setIgnoreMouseEvents(false);
}
store.set("lyric.config", { ...store.get("lyric.config"), isLock });
// 触发窗口更新
const config = store.get("lyric.config");
mainWin?.webContents.send("update-desktop-lyric-option", config);
});
};

View File

@@ -118,6 +118,13 @@ const initWindowsIpc = (): void => {
// 开启登录窗口
ipcMain.on("open-login-web", () => loginWindow.create(mainWin!));
// 开启设置
ipcMain.on("open-setting", (_, type) => {
mainWin?.show();
mainWin?.focus();
mainWin?.webContents.send("openSetting", type);
});
};
export default initWindowsIpc;

View File

@@ -43,7 +43,7 @@ export const useStore = () => {
x: screenData.workAreaSize.width / 2 - 400,
y: screenData.workAreaSize.height - 90,
width: 800,
height: 152,
height: 136,
config: defaultLyricConfig,
},
proxy: "",

View File

@@ -10,6 +10,7 @@ import {
import { isWin, appName } from "../utils/config";
import { join } from "path";
import { trayLog } from "../logger";
import { useStore } from "../store";
import lyricWindow from "../windows/lyric-window";
// 播放模式
@@ -48,10 +49,7 @@ const trayIcon = (filename: string) => {
};
// 托盘菜单
const createTrayMenu = (
win: BrowserWindow,
lyricWin: BrowserWindow | null,
): MenuItemConstructorOptions[] => {
const createTrayMenu = (win: BrowserWindow): MenuItemConstructorOptions[] => {
// 区分明暗图标
const showIcon = (iconName: string) => {
const isDark = nativeTheme.shouldUseDarkColors;
@@ -146,11 +144,16 @@ const createTrayMenu = (
id: "toogleDesktopLyricLock",
label: `${desktopLyricLock ? "解锁" : "锁定"}桌面歌词`,
icon: showIcon(desktopLyricLock ? "lock" : "unlock"),
visible: desktopLyricShow && lyricWin !== null,
visible: desktopLyricShow,
click: () => {
if (lyricWin) {
lyricWin.webContents.send("toogleDesktopLyricLock", !desktopLyricLock);
}
const store = useStore();
// 更新锁定状态
store.set("lyric.config", { ...store.get("lyric.config"), isLock: !desktopLyricLock });
// 触发窗口更新
const config = store.get("lyric.config");
const lyricWin = lyricWindow.getWin();
if (!lyricWin) return;
lyricWin.webContents.send("update-desktop-lyric-option", config);
},
},
{
@@ -187,7 +190,6 @@ const createTrayMenu = (
class CreateTray implements MainTray {
// 窗口
private _win: BrowserWindow;
private _lyricWin: BrowserWindow | null;
// 托盘
private _tray: Tray;
// 菜单
@@ -202,9 +204,8 @@ class CreateTray implements MainTray {
});
// 初始化数据
this._win = win;
this._lyricWin = lyricWindow.getWin();
this._tray = new Tray(icon);
this._menu = createTrayMenu(this._win, this._lyricWin);
this._menu = createTrayMenu(this._win);
this._contextMenu = Menu.buildFromTemplate(this._menu);
// 初始化事件
this.initTrayMenu();
@@ -213,7 +214,7 @@ class CreateTray implements MainTray {
}
// 托盘菜单
private initTrayMenu() {
this._menu = createTrayMenu(this._win, this._lyricWin);
this._menu = createTrayMenu(this._win);
this._contextMenu = Menu.buildFromTemplate(this._menu);
this._tray.setContextMenu(this._contextMenu);
}

View File

@@ -58,7 +58,7 @@ class LyricWindow {
movable: true,
show: false,
// 不在任务栏显示
// skipTaskbar: true,
skipTaskbar: true,
// 窗口不能最小化
minimizable: false,
// 窗口不能最大化

View File

@@ -1,10 +1,11 @@
import { isElectron } from "./env";
import { openUpdateApp } from "./modal";
import { openSetting, openUpdateApp } from "./modal";
import { useMusicStore, useDataStore, useStatusStore } from "@/stores";
import { toLikeSong } from "./auth";
import player from "./player";
import { cloneDeep } from "lodash-es";
import { getPlayerInfo } from "./player-utils/song";
import { SettingType } from "@/types/main";
// 关闭更新状态
const closeUpdateStatus = () => {
@@ -38,6 +39,8 @@ const initIpc = () => {
const musicStore = useMusicStore();
await toLikeSong(musicStore.playSong, !dataStore.isLikeSong(musicStore.playSong.id));
});
// 开启设置
window.electron.ipcRenderer.on("openSetting", (_, type: SettingType) => openSetting(type));
// 桌面歌词开关
window.electron.ipcRenderer.on("toogleDesktopLyric", () => player.toggleDesktopLyric());
window.electron.ipcRenderer.on("closeDesktopLyric", () => player.toggleDesktopLyric());

View File

@@ -32,14 +32,15 @@
</div>
</n-flex>
<n-flex :wrap="false" align="center" justify="flex-end" size="small" @pointerdown.stop>
<div class="menu-btn" title="设置">
<div class="menu-btn" title="设置" @click.stop="sendToMain('open-setting', 'lyrics')">
<SvgIcon name="Settings" />
</div>
<div class="menu-btn" title="锁定">
<SvgIcon name="Lock" />
</div>
<div class="menu-btn" title="解锁">
<SvgIcon name="LockOpen" />
<div
class="menu-btn lock-btn"
:title="lyricConfig.isLock ? '解锁' : '锁定'"
@click.stop="toggleLyricLock"
>
<SvgIcon :name="lyricConfig.isLock ? 'LockOpen' : 'Lock'" />
</div>
<div class="menu-btn" title="关闭" @click.stop="sendToMain('closeDesktopLyric')">
<SvgIcon name="Close" />
@@ -247,7 +248,7 @@ const { height: winHeight } = useWindowSize();
* 线性映射并取整,范围 20-96
*/
const computedFontSize = computed(() => {
const h = Number(winHeight?.value ?? 0);
const h = dragState.isDragging ? dragState.winHeight : Math.round(Number(winHeight?.value ?? 0));
const minH = 140;
const maxH = 360;
const minF = 20;
@@ -259,7 +260,7 @@ const computedFontSize = computed(() => {
});
// 监听字体大小变化,同步更新窗口高度
watch(
watchThrottled(
computedFontSize,
(size) => {
if (!Number.isFinite(size)) return;
@@ -268,7 +269,7 @@ watch(
const next = { fontSize: size };
window.electron.ipcRenderer.send("update-desktop-lyric-option", next, true);
},
{ immediate: true },
{ immediate: true, throttle: 100 },
);
/**
@@ -286,12 +287,12 @@ const fontSizeToHeight = (size: number) => {
return Math.round(minH + ratio * (maxH - minH));
};
// 防抖推送窗口高度更新,避免频繁抖动
const pushWindowHeight = useDebounceFn((nextHeight: number) => {
// 推送窗口高度更新
const pushWindowHeight = (nextHeight: number) => {
if (!Number.isFinite(nextHeight)) return;
if (dragState.isDragging) return;
window.electron.ipcRenderer.send("update-window-height", nextHeight);
}, 100);
};
// 监听配置中的字体大小变化,同步更新窗口高度
watch(
@@ -313,6 +314,12 @@ const sendToMainWin = (eventName: string, ...args: any[]) => {
window.electron.ipcRenderer.send("send-to-main", eventName, ...args);
};
// 切换桌面歌词锁定状态
const toggleLyricLock = () => {
sendToMain("toogleDesktopLyricLock", !lyricConfig.isLock);
lyricConfig.isLock = !lyricConfig.isLock;
};
onMounted(() => {
// 接收歌词数据
window.electron.ipcRenderer.on("update-desktop-lyric-data", (_event, data: LyricData) => {
@@ -323,10 +330,17 @@ onMounted(() => {
// 根据文字大小改变一次高度
const height = fontSizeToHeight(config.fontSize);
if (height) pushWindowHeight(height);
// 是否锁定
sendToMain("toogleDesktopLyricLock", config.isLock);
});
// 请求歌词数据及配置
window.electron.ipcRenderer.send("request-desktop-lyric-data");
window.electron.ipcRenderer.invoke("request-desktop-lyric-option");
// 鼠标移入
document.addEventListener("mouseenter", () => {
console.log("进入");
});
});
</script>
@@ -383,6 +397,9 @@ onMounted(() => {
.n-icon {
font-size: 24px;
}
&.lock-btn {
pointer-events: auto;
}
&:hover {
background-color: rgba(255, 255, 255, 0.3);
}
@@ -430,7 +447,7 @@ onMounted(() => {
}
}
&.locked {
pointer-events: none;
// pointer-events: none;
cursor: default;
.header {
opacity: 0;