mirror of
https://github.com/imsyy/SPlayer.git
synced 2025-11-25 03:14:57 +08:00
🐞 fix: 修复窗口 IPC 报错 & 歌单去重
This commit is contained in:
2
components.d.ts
vendored
2
components.d.ts
vendored
@@ -97,7 +97,6 @@ declare module 'vue' {
|
||||
NP: typeof import('naive-ui')['NP']
|
||||
NPopconfirm: typeof import('naive-ui')['NPopconfirm']
|
||||
NPopover: typeof import('naive-ui')['NPopover']
|
||||
NProgress: typeof import('naive-ui')['NProgress']
|
||||
NQrCode: typeof import('naive-ui')['NQrCode']
|
||||
NRadio: typeof import('naive-ui')['NRadio']
|
||||
NRadioGroup: typeof import('naive-ui')['NRadioGroup']
|
||||
@@ -107,7 +106,6 @@ declare module 'vue' {
|
||||
NSlider: typeof import('naive-ui')['NSlider']
|
||||
NSpin: typeof import('naive-ui')['NSpin']
|
||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||
NTab: typeof import('naive-ui')['NTab']
|
||||
NTabPane: typeof import('naive-ui')['NTabPane']
|
||||
NTabs: typeof import('naive-ui')['NTabs']
|
||||
NTag: typeof import('naive-ui')['NTag']
|
||||
|
||||
@@ -8,7 +8,6 @@ import mainWindow from "../windows/main-window";
|
||||
*/
|
||||
const initLyricIpc = (): void => {
|
||||
const store = useStore();
|
||||
const mainWin = mainWindow.getWin();
|
||||
|
||||
// 歌词窗口
|
||||
let lyricWin: BrowserWindow | null = null;
|
||||
@@ -58,6 +57,7 @@ const initLyricIpc = (): void => {
|
||||
|
||||
// 更新歌词窗口配置
|
||||
ipcMain.on("update-desktop-lyric-option", (_, option, callback: boolean = false) => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!option || !isWinAlive(lyricWin)) return;
|
||||
// 增量更新
|
||||
const prevOption = store.get("lyric.config");
|
||||
@@ -69,7 +69,9 @@ const initLyricIpc = (): void => {
|
||||
if (callback && isWinAlive(lyricWin)) {
|
||||
lyricWin.webContents.send("update-desktop-lyric-option", option);
|
||||
}
|
||||
mainWin?.webContents.send("update-desktop-lyric-option", option);
|
||||
if (isWinAlive(mainWin)) {
|
||||
mainWin?.webContents.send("update-desktop-lyric-option", option);
|
||||
}
|
||||
});
|
||||
|
||||
// 播放状态更改
|
||||
@@ -155,7 +157,8 @@ const initLyricIpc = (): void => {
|
||||
|
||||
// 请求歌词数据
|
||||
ipcMain.on("request-desktop-lyric-data", () => {
|
||||
if (!isWinAlive(lyricWin)) return;
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!isWinAlive(lyricWin) || !isWinAlive(mainWin)) return;
|
||||
// 触发窗口更新
|
||||
mainWin?.webContents.send("request-desktop-lyric-data");
|
||||
});
|
||||
@@ -171,14 +174,16 @@ const initLyricIpc = (): void => {
|
||||
|
||||
// 关闭桌面歌词
|
||||
ipcMain.on("closeDesktopLyric", () => {
|
||||
if (!isWinAlive(lyricWin)) return;
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!isWinAlive(lyricWin) || !isWinAlive(mainWin)) return;
|
||||
lyricWin.hide();
|
||||
mainWin?.webContents.send("closeDesktopLyric");
|
||||
});
|
||||
|
||||
// 锁定/解锁桌面歌词
|
||||
ipcMain.on("toogleDesktopLyricLock", (_, isLock: boolean, isTemp: boolean = false) => {
|
||||
if (!isWinAlive(lyricWin)) return;
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!isWinAlive(lyricWin) || !isWinAlive(mainWin)) return;
|
||||
// 是否穿透
|
||||
if (isLock) {
|
||||
lyricWin.setIgnoreMouseEvents(true, { forward: true });
|
||||
|
||||
@@ -7,13 +7,12 @@ import mainWindow from "../windows/main-window";
|
||||
* @returns void
|
||||
*/
|
||||
const initShortcutIpc = (): void => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
|
||||
// 快捷键是否被注册
|
||||
ipcMain.handle("is-shortcut-registered", (_, shortcut: string) => isShortcutRegistered(shortcut));
|
||||
|
||||
// 注册快捷键
|
||||
ipcMain.handle("register-all-shortcut", (_, allShortcuts: any): string[] | false => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin || !allShortcuts) return false;
|
||||
// 卸载所有快捷键
|
||||
unregisterShortcuts();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ipcMain, net, powerSaveBlocker, session } from "electron";
|
||||
import { app, ipcMain, net, powerSaveBlocker, session } from "electron";
|
||||
import { ipcLog } from "../logger";
|
||||
import { getFonts } from "font-list";
|
||||
import { useStore } from "../store";
|
||||
@@ -10,7 +10,6 @@ import mainWindow from "../windows/main-window";
|
||||
*/
|
||||
const initSystemIpc = (): void => {
|
||||
const store = useStore();
|
||||
const mainWin = mainWindow.getWin();
|
||||
|
||||
/** 阻止系统息屏 ID */
|
||||
let preventId: number | null = null;
|
||||
@@ -28,6 +27,11 @@ const initSystemIpc = (): void => {
|
||||
}
|
||||
});
|
||||
|
||||
// 退出应用
|
||||
ipcMain.on("quit-app", () => {
|
||||
app.exit();
|
||||
});
|
||||
|
||||
// 获取系统全部字体
|
||||
ipcMain.handle("get-all-fonts", async () => {
|
||||
try {
|
||||
@@ -41,13 +45,18 @@ const initSystemIpc = (): void => {
|
||||
|
||||
// 取消代理
|
||||
ipcMain.on("remove-proxy", () => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
store.set("proxy", "");
|
||||
mainWin?.webContents.session.setProxy({ proxyRules: "" });
|
||||
if (mainWin) {
|
||||
mainWin?.webContents.session.setProxy({ proxyRules: "" });
|
||||
}
|
||||
ipcLog.info("✅ Remove proxy successfully");
|
||||
});
|
||||
|
||||
// 配置网络代理
|
||||
ipcMain.on("set-proxy", (_, config) => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin) return;
|
||||
const proxyRules = `${config.protocol}://${config.server}:${config.port}`;
|
||||
store.set("proxy", proxyRules);
|
||||
mainWin?.webContents.session.setProxy({ proxyRules });
|
||||
|
||||
@@ -7,12 +7,13 @@ import lyricWindow from "../windows/lyric-window";
|
||||
*/
|
||||
const initTrayIpc = (): void => {
|
||||
const tray = getMainTray();
|
||||
const lyricWin = lyricWindow.getWin();
|
||||
|
||||
// 音乐播放状态更改
|
||||
ipcMain.on("play-status-change", (_, playStatus: boolean) => {
|
||||
const lyricWin = lyricWindow.getWin();
|
||||
tray?.setPlayState(playStatus ? "play" : "pause");
|
||||
lyricWin?.webContents.send("play-status-change", playStatus);
|
||||
if (!lyricWin) return;
|
||||
lyricWin.webContents.send("play-status-change", playStatus);
|
||||
});
|
||||
|
||||
// 音乐名称更改
|
||||
|
||||
@@ -3,10 +3,12 @@ import { checkUpdate, startDownloadUpdate } from "../update";
|
||||
import mainWindow from "../windows/main-window";
|
||||
|
||||
const initUpdateIpc = () => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
|
||||
// 检查更新
|
||||
ipcMain.on("check-update", (_event, showTip) => checkUpdate(mainWin!, showTip));
|
||||
ipcMain.on("check-update", (_event, showTip) => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin) return;
|
||||
checkUpdate(mainWin, showTip);
|
||||
});
|
||||
|
||||
// 开始下载更新
|
||||
ipcMain.on("start-download-update", () => startDownloadUpdate());
|
||||
|
||||
@@ -11,22 +11,24 @@ import loginWindow from "../windows/login-window";
|
||||
* @returns void
|
||||
*/
|
||||
const initWindowsIpc = (): void => {
|
||||
// 相关窗口
|
||||
const mainWin = mainWindow.getWin();
|
||||
const loadWin = loadWindow.getWin();
|
||||
// store
|
||||
const store = useStore();
|
||||
|
||||
// 当前窗口状态
|
||||
ipcMain.on("win-state", (event) => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin) return;
|
||||
event.returnValue = mainWin?.isMaximized();
|
||||
});
|
||||
|
||||
// 加载完成
|
||||
ipcMain.on("win-loaded", () => {
|
||||
const loadWin = loadWindow.getWin();
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (loadWin && !loadWin.isDestroyed()) loadWin.destroy();
|
||||
const isMaximized = store.get("window")?.maximized;
|
||||
if (isMaximized) mainWin?.maximize();
|
||||
if (!mainWin) return;
|
||||
mainWin?.show();
|
||||
mainWin?.focus();
|
||||
// 解决窗口不立即显示
|
||||
@@ -45,34 +47,37 @@ const initWindowsIpc = (): void => {
|
||||
|
||||
// 最小化
|
||||
ipcMain.on("win-min", (event) => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin) return;
|
||||
event.preventDefault();
|
||||
mainWin?.minimize();
|
||||
});
|
||||
|
||||
// 最大化
|
||||
ipcMain.on("win-max", () => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin) return;
|
||||
mainWin?.maximize();
|
||||
});
|
||||
|
||||
// 还原
|
||||
ipcMain.on("win-restore", () => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin) return;
|
||||
mainWin?.restore();
|
||||
});
|
||||
|
||||
// 关闭
|
||||
ipcMain.on("win-close", (event) => {
|
||||
event.preventDefault();
|
||||
mainWin?.close();
|
||||
app.quit();
|
||||
});
|
||||
|
||||
// 隐藏
|
||||
ipcMain.on("win-hide", () => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin) return;
|
||||
mainWin?.hide();
|
||||
});
|
||||
|
||||
// 显示
|
||||
ipcMain.on("win-show", () => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin) return;
|
||||
mainWin?.show();
|
||||
mainWin?.focus();
|
||||
});
|
||||
@@ -85,11 +90,15 @@ const initWindowsIpc = (): void => {
|
||||
|
||||
// 向主窗口发送事件
|
||||
ipcMain.on("send-to-mainWin", (_, eventName, ...args) => {
|
||||
mainWin?.webContents.send(eventName, ...args);
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin || mainWin.isDestroyed() || mainWin.webContents.isDestroyed()) return;
|
||||
mainWin.webContents.send(eventName, ...args);
|
||||
});
|
||||
|
||||
// 显示进度
|
||||
ipcMain.on("set-bar", (_event, val: number | "none" | "indeterminate" | "error" | "paused") => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin) return;
|
||||
switch (val) {
|
||||
case "none":
|
||||
mainWin?.setProgressBar(-1);
|
||||
@@ -115,6 +124,8 @@ const initWindowsIpc = (): void => {
|
||||
|
||||
// 开启控制台
|
||||
ipcMain.on("open-dev-tools", () => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin) return;
|
||||
mainWin?.webContents.openDevTools({
|
||||
title: "SPlayer DevTools",
|
||||
mode: isDev ? "right" : "detach",
|
||||
@@ -122,10 +133,16 @@ const initWindowsIpc = (): void => {
|
||||
});
|
||||
|
||||
// 开启登录窗口
|
||||
ipcMain.on("open-login-web", () => loginWindow.create(mainWin!));
|
||||
ipcMain.on("open-login-web", () => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin) return;
|
||||
loginWindow.create(mainWin);
|
||||
});
|
||||
|
||||
// 开启设置
|
||||
ipcMain.on("open-setting", (_, type) => {
|
||||
const mainWin = mainWindow.getWin();
|
||||
if (!mainWin) return;
|
||||
mainWin?.show();
|
||||
mainWin?.focus();
|
||||
mainWin?.webContents.send("openSetting", type);
|
||||
|
||||
@@ -28,9 +28,11 @@ class LyricWindow {
|
||||
});
|
||||
// 歌词窗口关闭
|
||||
this.win?.on("close", () => {
|
||||
this.win = null;
|
||||
const mainWin = mainWindow?.getWin();
|
||||
if (!mainWin || mainWin.isDestroyed() || mainWin.webContents.isDestroyed()) return;
|
||||
mainWin?.webContents.send("closeDesktopLyric");
|
||||
if (mainWin) {
|
||||
mainWin?.webContents.send("closeDesktopLyric");
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
@@ -79,7 +81,8 @@ class LyricWindow {
|
||||
* @returns BrowserWindow | null
|
||||
*/
|
||||
getWin(): BrowserWindow | null {
|
||||
return this.win;
|
||||
if (this.win && !this.win?.isDestroyed()) return this.win;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,6 +81,13 @@ class MainWindow {
|
||||
this.saveBounds();
|
||||
});
|
||||
}
|
||||
// 窗口关闭
|
||||
this.win?.on("close", (event) => {
|
||||
event.preventDefault();
|
||||
this.win?.show();
|
||||
this.win?.focus();
|
||||
this.win?.webContents.send("win-will-close");
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 创建窗口
|
||||
@@ -110,7 +117,10 @@ class MainWindow {
|
||||
* @returns BrowserWindow | null
|
||||
*/
|
||||
getWin(): BrowserWindow | null {
|
||||
return this.win;
|
||||
if (this.win && !this.win.isDestroyed()) {
|
||||
return this.win;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 显示主窗口
|
||||
|
||||
@@ -124,7 +124,7 @@ const hideOrClose = (action: "hide" | "exit") => {
|
||||
settingStore.closeAppMethod = action;
|
||||
}
|
||||
showCloseModal.value = false;
|
||||
window.electron.ipcRenderer.send(action === "hide" ? "win-hide" : "win-close");
|
||||
window.electron.ipcRenderer.send(action === "hide" ? "win-hide" : "quit-app");
|
||||
};
|
||||
|
||||
// 尝试关闭软件
|
||||
@@ -203,6 +203,9 @@ onMounted(() => {
|
||||
window.electron.ipcRenderer.on("win-state-change", (_event, value: boolean) => {
|
||||
isMax.value = value;
|
||||
});
|
||||
window.electron.ipcRenderer.on("win-will-close", () => {
|
||||
tryClose();
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -130,7 +130,7 @@ const isReadOver = useElementVisibility(readOverRef);
|
||||
|
||||
// 关闭软件
|
||||
const closeApp = () => {
|
||||
window.electron.ipcRenderer.send("win-close");
|
||||
window.electron.ipcRenderer.send("quit-app");
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ import { playlistDetail, playlistAllSongs } from "@/api/playlist";
|
||||
import { formatCoverList, formatSongsList } from "@/utils/format";
|
||||
import { coverLoaded, formatNumber, fuzzySearch, renderIcon } from "@/utils/helper";
|
||||
import { renderToolbar } from "@/utils/meta";
|
||||
import { debounce, isObject } from "lodash-es";
|
||||
import { debounce, isObject, uniqBy } from "lodash-es";
|
||||
import { useDataStore, useStatusStore } from "@/stores";
|
||||
import { openBatchList, openUpdatePlaylist } from "@/utils/modal";
|
||||
import { formatTimestamp } from "@/utils/time";
|
||||
@@ -302,7 +302,8 @@ const getPlaylistData = async (id: number, getList: boolean, refresh: boolean) =
|
||||
if (isLogin() === 1 && (playlistDetailData.value?.count as number) < 800) {
|
||||
const ids: number[] = detail.privileges.map((song: any) => song.id as number);
|
||||
const result = await songDetail(ids);
|
||||
playlistData.value = formatSongsList(result.songs);
|
||||
// 直接批量详情返回时也进行一次按 id 去重
|
||||
playlistData.value = uniqBy(formatSongsList(result.songs), "id");
|
||||
} else {
|
||||
await getPlaylistAllSongs(id, playlistDetailData.value.count || 0, refresh);
|
||||
}
|
||||
@@ -317,7 +318,8 @@ const loadLikedCache = () => {
|
||||
playlistDetailData.value = dataStore.likeSongsList.detail;
|
||||
}
|
||||
if (dataStore.likeSongsList.data.length) {
|
||||
playlistData.value = dataStore.likeSongsList.data;
|
||||
// 去重缓存中的歌曲,避免重复展示与后续重复拼接
|
||||
playlistData.value = uniqBy(dataStore.likeSongsList.data, "id");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -339,11 +341,13 @@ const getPlaylistAllSongs = async (
|
||||
const result = await playlistAllSongs(id, limit, offset);
|
||||
const songData = formatSongsList(result.songs);
|
||||
listData.push(...songData);
|
||||
if (!refresh) playlistData.value = playlistData.value.concat(songData);
|
||||
// 非刷新模式下,增量拼接时进行去重,避免与缓存或上一页数据重复
|
||||
if (!refresh) playlistData.value = uniqBy([...playlistData.value, ...songData], "id");
|
||||
// 更新数据
|
||||
offset += limit;
|
||||
} while (offset < count && isLikedPage.value);
|
||||
if (refresh) playlistData.value = listData;
|
||||
// 刷新模式下,统一以最终聚合数据为准,并进行去重
|
||||
if (refresh) playlistData.value = uniqBy(listData, "id");
|
||||
// 关闭加载
|
||||
loadingMsgShow(false);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user