2025-01-01 02:25:18 +08:00
|
|
|
|
import { electronAPI } from '@electron-toolkit/preload';
|
|
|
|
|
|
import { contextBridge, ipcRenderer } from 'electron';
|
|
|
|
|
|
|
|
|
|
|
|
// Custom APIs for renderer
|
|
|
|
|
|
const api = {
|
|
|
|
|
|
minimize: () => ipcRenderer.send('minimize-window'),
|
|
|
|
|
|
maximize: () => ipcRenderer.send('maximize-window'),
|
|
|
|
|
|
close: () => ipcRenderer.send('close-window'),
|
|
|
|
|
|
dragStart: (data) => ipcRenderer.send('drag-start', data),
|
|
|
|
|
|
miniTray: () => ipcRenderer.send('mini-tray'),
|
2025-04-01 23:22:26 +08:00
|
|
|
|
miniWindow: () => ipcRenderer.send('mini-window'),
|
|
|
|
|
|
restore: () => ipcRenderer.send('restore-window'),
|
2025-01-01 02:25:18 +08:00
|
|
|
|
restart: () => ipcRenderer.send('restart'),
|
2025-04-01 23:22:26 +08:00
|
|
|
|
resizeWindow: (width, height) => ipcRenderer.send('resize-window', width, height),
|
|
|
|
|
|
resizeMiniWindow: (showPlaylist) => ipcRenderer.send('resize-mini-window', showPlaylist),
|
2025-01-01 02:25:18 +08:00
|
|
|
|
openLyric: () => ipcRenderer.send('open-lyric'),
|
|
|
|
|
|
sendLyric: (data) => ipcRenderer.send('send-lyric', data),
|
2025-03-31 23:05:19 +08:00
|
|
|
|
sendSong: (data) => ipcRenderer.send('update-current-song', data),
|
2025-04-22 23:39:08 +08:00
|
|
|
|
unblockMusic: (id, data, enabledSources) => ipcRenderer.invoke('unblock-music', id, data, enabledSources),
|
2025-03-08 19:00:50 +08:00
|
|
|
|
// 歌词窗口关闭事件
|
|
|
|
|
|
onLyricWindowClosed: (callback: () => void) => {
|
|
|
|
|
|
ipcRenderer.on('lyric-window-closed', () => callback());
|
|
|
|
|
|
},
|
2025-01-17 00:02:57 +08:00
|
|
|
|
// 更新相关
|
|
|
|
|
|
startDownload: (url: string) => ipcRenderer.send('start-download', url),
|
|
|
|
|
|
onDownloadProgress: (callback: (progress: number, status: string) => void) => {
|
|
|
|
|
|
ipcRenderer.on('download-progress', (_event, progress, status) => callback(progress, status));
|
|
|
|
|
|
},
|
|
|
|
|
|
onDownloadComplete: (callback: (success: boolean, filePath: string) => void) => {
|
|
|
|
|
|
ipcRenderer.on('download-complete', (_event, success, filePath) => callback(success, filePath));
|
|
|
|
|
|
},
|
2025-03-22 10:30:57 +08:00
|
|
|
|
// 语言相关
|
|
|
|
|
|
onLanguageChanged: (callback: (locale: string) => void) => {
|
|
|
|
|
|
ipcRenderer.on('language-changed', (_event, locale) => {
|
|
|
|
|
|
callback(locale);
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
2025-01-17 00:02:57 +08:00
|
|
|
|
removeDownloadListeners: () => {
|
|
|
|
|
|
ipcRenderer.removeAllListeners('download-progress');
|
|
|
|
|
|
ipcRenderer.removeAllListeners('download-complete');
|
|
|
|
|
|
},
|
2025-01-12 20:59:36 +08:00
|
|
|
|
// 歌词缓存相关
|
|
|
|
|
|
invoke: (channel: string, ...args: any[]) => {
|
2025-01-17 22:45:59 +08:00
|
|
|
|
const validChannels = [
|
|
|
|
|
|
'get-lyrics',
|
|
|
|
|
|
'clear-lyrics-cache',
|
|
|
|
|
|
'get-system-fonts',
|
|
|
|
|
|
'get-cached-lyric',
|
|
|
|
|
|
'cache-lyric',
|
2025-04-12 23:16:12 +08:00
|
|
|
|
'clear-lyric-cache',
|
|
|
|
|
|
// 统计相关
|
|
|
|
|
|
'record-visit',
|
|
|
|
|
|
'record-play',
|
|
|
|
|
|
'get-stats-summary'
|
2025-01-17 22:45:59 +08:00
|
|
|
|
];
|
2025-01-12 20:59:36 +08:00
|
|
|
|
if (validChannels.includes(channel)) {
|
|
|
|
|
|
return ipcRenderer.invoke(channel, ...args);
|
|
|
|
|
|
}
|
2025-01-17 22:45:59 +08:00
|
|
|
|
return Promise.reject(new Error(`未授权的 IPC 通道: ${channel}`));
|
2025-01-12 20:59:36 +08:00
|
|
|
|
}
|
2025-01-01 02:25:18 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-04-12 23:16:12 +08:00
|
|
|
|
// 创建带类型的ipcRenderer对象,暴露给渲染进程
|
|
|
|
|
|
const ipc = {
|
|
|
|
|
|
// 发送消息到主进程(无返回值)
|
|
|
|
|
|
send: (channel: string, ...args: any[]) => {
|
|
|
|
|
|
ipcRenderer.send(channel, ...args);
|
|
|
|
|
|
},
|
|
|
|
|
|
// 调用主进程方法(有返回值)
|
|
|
|
|
|
invoke: (channel: string, ...args: any[]) => {
|
|
|
|
|
|
return ipcRenderer.invoke(channel, ...args);
|
|
|
|
|
|
},
|
|
|
|
|
|
// 监听主进程消息
|
|
|
|
|
|
on: (channel: string, listener: (...args: any[]) => void) => {
|
|
|
|
|
|
ipcRenderer.on(channel, (_, ...args) => listener(...args));
|
|
|
|
|
|
return () => {
|
|
|
|
|
|
ipcRenderer.removeListener(channel, listener);
|
|
|
|
|
|
};
|
|
|
|
|
|
},
|
|
|
|
|
|
// 移除所有监听器
|
|
|
|
|
|
removeAllListeners: (channel: string) => {
|
|
|
|
|
|
ipcRenderer.removeAllListeners(channel);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-01-01 02:25:18 +08:00
|
|
|
|
// Use `contextBridge` APIs to expose Electron APIs to
|
|
|
|
|
|
// renderer only if context isolation is enabled, otherwise
|
|
|
|
|
|
// just add to the DOM global.
|
|
|
|
|
|
if (process.contextIsolated) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
contextBridge.exposeInMainWorld('electron', electronAPI);
|
|
|
|
|
|
contextBridge.exposeInMainWorld('api', api);
|
2025-04-12 23:16:12 +08:00
|
|
|
|
contextBridge.exposeInMainWorld('ipcRenderer', ipc);
|
2025-01-01 02:25:18 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error(error);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// @ts-ignore (define in dts)
|
|
|
|
|
|
window.electron = electronAPI;
|
|
|
|
|
|
// @ts-ignore (define in dts)
|
|
|
|
|
|
window.api = api;
|
2025-04-12 23:16:12 +08:00
|
|
|
|
// @ts-ignore (define in dts)
|
|
|
|
|
|
window.ipcRenderer = ipc;
|
2025-01-01 02:25:18 +08:00
|
|
|
|
}
|