feat: 新增主进程功能
This commit is contained in:
@@ -5,6 +5,7 @@ export enum IPC_EVENTS {
|
||||
WINDOW_MINIMIZE = 'window-minimize',
|
||||
WINDOW_MAXIMIZE = 'window-maximize',
|
||||
WINDOW_CLOSE = 'window-close',
|
||||
IS_WINDOW_MAXIMIZED = 'is-window-maximized',
|
||||
APP_SET_FRAMELESS = 'app:set-frameless',
|
||||
TAB_CREATE = 'tab:create',
|
||||
TAB_LIST = 'tab:list',
|
||||
@@ -27,12 +28,29 @@ export enum IPC_EVENTS {
|
||||
CUSTOM_EVENT ='custom:event',
|
||||
TIME_UPDATE = 'time:update',
|
||||
RENDERER_IS_READY = 'renderer-ready',
|
||||
SHOW_CONTEXT_MENU = 'show-context-menu',
|
||||
START_A_DIALOGUE = 'start-a-dialogue',
|
||||
|
||||
// 打开窗口
|
||||
OPEN_WINDOW = 'open-window',
|
||||
|
||||
// 发送日志
|
||||
LOG_DEBUG = 'log-debug',
|
||||
LOG_INFO = 'log-info',
|
||||
LOG_WARN = 'log-warn',
|
||||
LOG_ERROR = 'log-error',
|
||||
|
||||
// 设置
|
||||
CONFIG_UPDATED = 'config-updated',
|
||||
SET_CONFIG = 'set-config',
|
||||
GET_CONFIG = 'get-config',
|
||||
UPDATE_CONFIG = 'update-config',
|
||||
|
||||
// 主题
|
||||
SET_THEME_MODE = 'set-theme-mode',
|
||||
GET_THEME_MODE = 'get-theme-mode',
|
||||
IS_DARK_THEME = 'is-dark-theme',
|
||||
THEME_MODE_UPDATED = 'theme-mode-updated',
|
||||
}
|
||||
|
||||
export const MAIN_WIN_SIZE = {
|
||||
@@ -42,7 +60,48 @@ export const MAIN_WIN_SIZE = {
|
||||
minHeight: 900,
|
||||
} as const
|
||||
|
||||
export enum WINDOW_NAMES {
|
||||
MAIN = 'main',
|
||||
SETTING = 'setting',
|
||||
DIALOG = 'dialog',
|
||||
}
|
||||
|
||||
export enum CONFIG_KEYS {
|
||||
THEME_MODE = 'themeMode',
|
||||
PRIMARY_COLOR = 'primaryColor',
|
||||
LANGUAGE = 'language',
|
||||
FONT_SIZE = 'fontSize',
|
||||
MINIMIZE_TO_TRAY = 'minimizeToTray',
|
||||
PROVIDER = 'provider',
|
||||
DEFAULT_MODEL = 'defaultModel',
|
||||
}
|
||||
|
||||
export enum MENU_IDS {
|
||||
CONVERSATION_ITEM = 'conversation-item',
|
||||
CONVERSATION_LIST = 'conversation-list',
|
||||
MESSAGE_ITEM = 'message-item',
|
||||
}
|
||||
|
||||
export enum CONVERSATION_ITEM_MENU_IDS {
|
||||
PIN = 'pin',
|
||||
RENAME = 'rename',
|
||||
DEL = 'del',
|
||||
}
|
||||
|
||||
export enum CONVERSATION_LIST_MENU_IDS {
|
||||
NEW_CONVERSATION = 'newConversation',
|
||||
SORT_BY = 'sortBy',
|
||||
SORT_BY_CREATE_TIME = 'sortByCreateTime',
|
||||
SORT_BY_UPDATE_TIME = 'sortByUpdateTime',
|
||||
SORT_BY_NAME = 'sortByName',
|
||||
SORT_BY_MODEL = 'sortByModel',
|
||||
SORT_ASCENDING = 'sortAscending',
|
||||
SORT_DESCENDING = 'sortDescending',
|
||||
BATCH_OPERATIONS = 'batchOperations',
|
||||
}
|
||||
|
||||
export enum MESSAGE_ITEM_MENU_IDS {
|
||||
COPY = 'copy',
|
||||
DELETE = 'delete',
|
||||
SELECT = 'select',
|
||||
}
|
||||
|
||||
38
src/common/types.ts
Normal file
38
src/common/types.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { WINDOW_NAMES, CONFIG_KEYS } from './constants';
|
||||
|
||||
export type WindowNames = `${WINDOW_NAMES}`;
|
||||
export type ConfigKeys = `${CONFIG_KEYS}`;
|
||||
|
||||
export interface IConfig {
|
||||
// 主题模式配置
|
||||
[CONFIG_KEYS.THEME_MODE]: ThemeMode;
|
||||
// 高亮色
|
||||
[CONFIG_KEYS.PRIMARY_COLOR]: string;
|
||||
// 语言
|
||||
[CONFIG_KEYS.LANGUAGE]: 'zh' | 'en';
|
||||
// 字体大小
|
||||
[CONFIG_KEYS.FONT_SIZE]: number;
|
||||
// 关闭时最小化到托盘
|
||||
[CONFIG_KEYS.MINIMIZE_TO_TRAY]: boolean;
|
||||
// provider 配置 JSON
|
||||
[CONFIG_KEYS.PROVIDER]?: string;
|
||||
// 默认模型
|
||||
[CONFIG_KEYS.DEFAULT_MODEL]?: string | null;
|
||||
}
|
||||
|
||||
export interface Provider {
|
||||
id: number;
|
||||
name: string;
|
||||
visible?: boolean;
|
||||
title?: string;
|
||||
type?: 'OpenAI';
|
||||
openAISetting?: string;
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
models: string[];
|
||||
}
|
||||
|
||||
export interface OpenAISetting {
|
||||
baseURL?: string;
|
||||
apiKey?: string;
|
||||
}
|
||||
94
src/common/utils.ts
Normal file
94
src/common/utils.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import type { OpenAISetting } from './types'
|
||||
import { encode, decode } from 'js-base64'
|
||||
/**
|
||||
* 防抖函数
|
||||
* @param fn 需要执行的函数
|
||||
* @param delay 延迟时间(毫秒)
|
||||
* @returns 防抖处理后的函数
|
||||
*/
|
||||
export function debounce<T extends (...args: any[]) => any>(fn: T, delay: number): (...args: Parameters<T>) => void {
|
||||
let timer: NodeJS.Timeout | null = null;
|
||||
return function (this: any, ...args: Parameters<T>) {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
timer = setTimeout(() => {
|
||||
fn.apply(this, args);
|
||||
}, delay);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 节流函数
|
||||
* @param fn 需要执行的函数
|
||||
* @param interval 间隔时间(毫秒)
|
||||
* @returns 节流处理后的函数
|
||||
*/
|
||||
export function throttle<T extends (...args: any[]) => any>(fn: T, interval: number): (...args: Parameters<T>) => void {
|
||||
let lastTime = 0;
|
||||
return function (this: any, ...args: Parameters<T>) {
|
||||
const now = Date.now();
|
||||
if (now - lastTime >= interval) {
|
||||
fn.apply(this, args);
|
||||
lastTime = now;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function cloneDeep<T>(obj: T): T {
|
||||
if (obj === null || typeof obj !== 'object') {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
return obj.map(item => cloneDeep(item)) as T;
|
||||
}
|
||||
|
||||
const clone = Object.assign({}, obj);
|
||||
for (const key in clone) {
|
||||
if (Object.prototype.hasOwnProperty.call(clone, key)) {
|
||||
clone[key] = cloneDeep(clone[key]);
|
||||
}
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
export function simpleCloneDeep<T>(obj: T): T {
|
||||
try {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
} catch (error) {
|
||||
console.error('simpleCloneDeep failed:', error);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
export function stringifyOpenAISetting(setting: OpenAISetting) {
|
||||
try {
|
||||
return encode(JSON.stringify(setting));
|
||||
} catch (error) {
|
||||
console.error('stringifyOpenAISetting failed:', error);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
export function parseOpenAISetting(setting: string): OpenAISetting {
|
||||
try {
|
||||
return JSON.parse(decode(setting));
|
||||
} catch (error) {
|
||||
console.error('parseOpenAISetting failed:', error);
|
||||
return {} as OpenAISetting;
|
||||
}
|
||||
}
|
||||
|
||||
export function uniqueByKey<T extends Record<string, any>>(arr: T[], key: keyof T): T[] {
|
||||
const seen = new Map<any, boolean>();
|
||||
|
||||
return arr.filter(item => {
|
||||
const keyValue = item[key];
|
||||
if (seen.has(keyValue)) {
|
||||
return false;
|
||||
}
|
||||
seen.set(keyValue, true);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user