87 lines
4.4 KiB
JavaScript
87 lines
4.4 KiB
JavaScript
/**
|
||
* preload.js — contextBridge 暴露给渲染进程的安全 IPC API
|
||
*/
|
||
'use strict';
|
||
|
||
const { contextBridge, ipcRenderer } = require('electron');
|
||
|
||
contextBridge.exposeInMainWorld('api', {
|
||
// 数据查询(列表不含图片数据,图片走 getImage 按需拉)。
|
||
// limit 留空 → 主进程用配置里的 displayLimit(默认 300),改设置后下次拉就生效。
|
||
list: (query, limit) => ipcRenderer.invoke('clips:list', { query: query || '', limit: limit || 0 }),
|
||
getImage: (id) => ipcRenderer.invoke('clips:get-image', { id }),
|
||
count: () => ipcRenderer.invoke('clips:count'),
|
||
|
||
// 操作
|
||
movetop: (id) => ipcRenderer.invoke('clips:movetop', { id }),
|
||
remove: (id) => ipcRenderer.invoke('clips:delete', { id }),
|
||
hide: () => ipcRenderer.invoke('window:hide'),
|
||
openSettings: () => ipcRenderer.invoke('settings:open'),
|
||
|
||
// 窗口置顶
|
||
toggleAlwaysOnTop: (on) => ipcRenderer.invoke('window:toggle-always-on-top', { on }),
|
||
getAlwaysOnTop: () => ipcRenderer.invoke('window:get-always-on-top'),
|
||
|
||
// 应用图标(标题栏左上角小图标):返回 PNG data URL,喂给 <img src>。
|
||
// 主进程会缓存 .ico→PNG 的转换结果,每个窗口首次调用一次即可。
|
||
getAppIcon: () => ipcRenderer.invoke('app:get-icon'),
|
||
|
||
// 订阅
|
||
subscribe: () => ipcRenderer.invoke('clips:subscribe'),
|
||
onAdded: (cb) => {
|
||
const handler = (_e, clip) => cb(clip);
|
||
ipcRenderer.on('clips:added', handler);
|
||
return () => ipcRenderer.removeListener('clips:added', handler);
|
||
},
|
||
onRefresh: (cb) => {
|
||
const handler = () => cb();
|
||
ipcRenderer.on('clips:refresh', handler);
|
||
return () => ipcRenderer.removeListener('clips:refresh', handler);
|
||
},
|
||
});
|
||
|
||
contextBridge.exposeInMainWorld('favoritesApi', {
|
||
add: (clipId) => ipcRenderer.invoke('favorites:add', { clipId }),
|
||
remove: (favId) => ipcRenderer.invoke('favorites:remove', { favId }),
|
||
// 收藏 Tab 的复制:写收藏自身存的内容(favId 与历史 id 不同库,不能走 movetop)
|
||
copy: (favId) => ipcRenderer.invoke('favorites:copy', { favId }),
|
||
list: (query, limit) => ipcRenderer.invoke('favorites:list', { query: query || '', limit: limit || 0 }),
|
||
getImage: (favId) => ipcRenderer.invoke('favorites:get-image', { favId }),
|
||
count: () => ipcRenderer.invoke('favorites:count'),
|
||
subscribe: () => ipcRenderer.invoke('favorites:subscribe'),
|
||
onChanged: (cb) => {
|
||
const handler = () => cb();
|
||
ipcRenderer.on('favorites:changed', handler);
|
||
return () => ipcRenderer.removeListener('favorites:changed', handler);
|
||
},
|
||
});
|
||
|
||
contextBridge.exposeInMainWorld('settingsApi', {
|
||
get: () => ipcRenderer.invoke('settings:get'),
|
||
set: (key, value) => ipcRenderer.invoke('settings:set', { key, value }),
|
||
clearHistory: () => ipcRenderer.invoke('settings:clear-history'),
|
||
openDir: () => ipcRenderer.invoke('settings:open-dir'),
|
||
chooseDir: () => ipcRenderer.invoke('settings:choose-dir'),
|
||
// 外链交给系统浏览器(关于页)。scheme 白名单在主进程卡,渲染进程只管递 URL
|
||
openExternal: (url) => ipcRenderer.invoke('settings:open-external', { url }),
|
||
// 设置窗口订阅 displayLimit 变更,主进程设置被改后给所有窗口推一条刷新通知
|
||
onDisplayLimitChanged: (cb) => {
|
||
const handler = (_e, payload) => cb(payload);
|
||
ipcRenderer.on('settings:display-limit-changed', handler);
|
||
return () => ipcRenderer.removeListener('settings:display-limit-changed', handler);
|
||
},
|
||
});
|
||
|
||
contextBridge.exposeInMainWorld('themeApi', {
|
||
get: () => ipcRenderer.invoke('theme:get'),
|
||
set: (theme) => ipcRenderer.invoke('theme:set', { theme }),
|
||
setAccent: (accent) => ipcRenderer.invoke('theme:set-accent', { accent }),
|
||
setFollowSystem: (followSystem)=> ipcRenderer.invoke('theme:set-follow-system', { followSystem }),
|
||
// 必须先订阅,主进程才会把 theme:system-changed 发过来
|
||
subscribe: () => ipcRenderer.invoke('theme:subscribe'),
|
||
onSystemChanged: (cb) => {
|
||
const handler = (_e, payload) => cb(payload);
|
||
ipcRenderer.on('theme:system-changed', handler);
|
||
return () => ipcRenderer.removeListener('theme:system-changed', handler);
|
||
},
|
||
}); |