feat: 移除无关文件

This commit is contained in:
duanshuwen
2025-10-19 19:11:11 +08:00
parent c9ff2021fd
commit a2507ba1df
18 changed files with 9 additions and 364 deletions

View File

@@ -1,9 +0,0 @@
import { exposeThemeContext } from "./theme/theme-context";
import { exposeWindowContext } from "./window/window-context";
import { exposeRecordingContext } from "./recording/recording-context";
export default function exposeContexts() {
exposeWindowContext();
exposeThemeContext();
exposeRecordingContext();
}

View File

@@ -1,6 +0,0 @@
import { BrowserWindow } from "electron";
import { addWindowEventListeners } from "./window/window-listeners";
export default function registerListeners(mainWindow: BrowserWindow) {
addWindowEventListeners(mainWindow);
}

View File

@@ -1,5 +0,0 @@
// 自动化录制相关的 IPC 通道
export const RUN_RECORDING_SCRIPT_CHANNEL = "run-recording-script";
export const RUN_RECORDING_SCRIPT_SAVE_CHANNEL = "run-recording-script-save";
export const RUN_RECORDING_SCRIPT_EDIT_CHANNEL = "run-recording-script-edit";

View File

@@ -1,35 +0,0 @@
import {
RUN_RECORDING_SCRIPT_CHANNEL,
RUN_RECORDING_SCRIPT_SAVE_CHANNEL,
RUN_RECORDING_SCRIPT_EDIT_CHANNEL,
} from "./recording-channels";
import { contextBridge, ipcRenderer } from "electron";
export function exposeRecordingContext() {
contextBridge.exposeInMainWorld("recording", {
// 运行录制脚本
runRecordingScript: () => ipcRenderer.invoke(RUN_RECORDING_SCRIPT_CHANNEL),
// 监听录制脚本输出(保存)
onRecordingSave: (callback: (payload: unknown) => void) => {
ipcRenderer.on(RUN_RECORDING_SCRIPT_SAVE_CHANNEL, (_event, payload) => {
try {
callback(payload);
} catch (err) {
console.error("onRecordingSave callback error:", err);
}
});
},
// 监听录制脚本输出(编辑)
onRecordingEdit: (callback: (payload: unknown) => void) => {
ipcRenderer.on(RUN_RECORDING_SCRIPT_EDIT_CHANNEL, (_event, payload) => {
try {
callback(payload);
} catch (err) {
console.error("onRecordingEdit callback error:", err);
}
});
},
});
}

View File

@@ -1,81 +0,0 @@
import { BrowserWindow, ipcMain, app } from "electron";
import { spawn } from "child_process";
import path from "path";
import { RUN_RECORDING_SCRIPT_CHANNEL } from "./recording-channels";
export function addRecordingEventListeners(mainWindow: BrowserWindow) {
// 监听运行录制脚本的请求
ipcMain.handle(RUN_RECORDING_SCRIPT_CHANNEL, async () => {
try {
console.log('🎬 主进程:开始执行录制脚本');
const basePath = app.isPackaged ? process.resourcesPath : app.getAppPath();
const scriptPath = app.isPackaged
? path.join(basePath, 'automation', 'recording-automation.js')
: path.join(basePath, 'src', 'automation', 'recording-automation.js');
// 启动录制脚本
const recordingProcess = spawn('node', [scriptPath], {
stdio: ['pipe', 'pipe', 'pipe'],
detached: false
});
let stdout = '';
let stderr = '';
// 监听标准输出
recordingProcess.stdout.on('data', (data) => {
const message = data.toString();
stdout += message;
console.log('录制脚本输出:', message);
// 发送输出到渲染进程
mainWindow.webContents.send(RECORDING_CHANNELS.RECORDING_SCRIPT_RESULT, {
type: 'stdout',
message: message
});
});
// 监听错误输出
recordingProcess.stderr.on('data', (data) => {
const message = data.toString();
stderr += message;
console.error('录制脚本错误:', message);
// 发送错误到渲染进程
mainWindow.webContents.send(RECORDING_CHANNELS.RECORDING_SCRIPT_ERROR, {
type: 'stderr',
message: message
});
});
// 监听进程退出
recordingProcess.on('close', (code) => {
console.log(`录制脚本退出,退出码: ${code}`);
mainWindow.webContents.send(RECORDING_CHANNELS.RECORDING_SCRIPT_RESULT, {
type: 'exit',
code: code,
stdout: stdout,
stderr: stderr
});
});
// 监听进程错误
recordingProcess.on('error', (error) => {
console.error('录制脚本启动失败:', error);
mainWindow.webContents.send(RECORDING_CHANNELS.RECORDING_SCRIPT_ERROR, {
type: 'error',
message: error.message
});
});
return { success: true, message: '录制脚本已启动' };
} catch (error) {
console.error('执行录制脚本失败:', error);
return { success: false, error: (error as Error).message };
}
});
}

View File

@@ -1,5 +0,0 @@
export const THEME_MODE_CURRENT_CHANNEL = "theme-mode:current";
export const THEME_MODE_TOGGLE_CHANNEL = "theme-mode:toggle";
export const THEME_MODE_DARK_CHANNEL = "theme-mode:dark";
export const THEME_MODE_LIGHT_CHANNEL = "theme-mode:light";
export const THEME_MODE_SYSTEM_CHANNEL = "theme-mode:system";

View File

@@ -1,19 +0,0 @@
import {
THEME_MODE_CURRENT_CHANNEL,
THEME_MODE_DARK_CHANNEL,
THEME_MODE_LIGHT_CHANNEL,
THEME_MODE_SYSTEM_CHANNEL,
THEME_MODE_TOGGLE_CHANNEL,
} from "./theme-channels";
import { contextBridge, ipcRenderer } from "electron";
export function exposeThemeContext() {
contextBridge.exposeInMainWorld("themeMode", {
current: () => ipcRenderer.invoke(THEME_MODE_CURRENT_CHANNEL),
toggle: () => ipcRenderer.invoke(THEME_MODE_TOGGLE_CHANNEL),
dark: () => ipcRenderer.invoke(THEME_MODE_DARK_CHANNEL),
light: () => ipcRenderer.invoke(THEME_MODE_LIGHT_CHANNEL),
system: () => ipcRenderer.invoke(THEME_MODE_SYSTEM_CHANNEL),
});
}

View File

@@ -1,37 +0,0 @@
import { nativeTheme } from "electron";
import { ipcMain } from "electron";
import {
THEME_MODE_CURRENT_CHANNEL,
THEME_MODE_DARK_CHANNEL,
THEME_MODE_LIGHT_CHANNEL,
THEME_MODE_SYSTEM_CHANNEL,
THEME_MODE_TOGGLE_CHANNEL,
} from "./theme-channels";
export function addThemeEventListeners() {
ipcMain.handle(THEME_MODE_CURRENT_CHANNEL, () => nativeTheme.themeSource);
ipcMain.handle(THEME_MODE_TOGGLE_CHANNEL, () => {
if (nativeTheme.shouldUseDarkColors) {
nativeTheme.themeSource = "light";
} else {
nativeTheme.themeSource = "dark";
}
return nativeTheme.shouldUseDarkColors;
});
ipcMain.handle(
THEME_MODE_DARK_CHANNEL,
() => (nativeTheme.themeSource = "dark")
);
ipcMain.handle(
THEME_MODE_LIGHT_CHANNEL,
() => (nativeTheme.themeSource = "light")
);
ipcMain.handle(THEME_MODE_SYSTEM_CHANNEL, () => {
nativeTheme.themeSource = "system";
return nativeTheme.shouldUseDarkColors;
});
}

View File

@@ -1,3 +0,0 @@
export const WIN_MINIMIZE_CHANNEL = "window:minimize";
export const WIN_MAXIMIZE_CHANNEL = "window:maximize";
export const WIN_CLOSE_CHANNEL = "window:close";

View File

@@ -1,14 +0,0 @@
import {
WIN_MINIMIZE_CHANNEL,
WIN_MAXIMIZE_CHANNEL,
WIN_CLOSE_CHANNEL
} from "./window-channels";
import { contextBridge, ipcRenderer } from "electron";
export function exposeWindowContext() {
contextBridge.exposeInMainWorld("electronWindow", {
minimize: () => ipcRenderer.invoke(WIN_MINIMIZE_CHANNEL),
maximize: () => ipcRenderer.invoke(WIN_MAXIMIZE_CHANNEL),
close: () => ipcRenderer.invoke(WIN_CLOSE_CHANNEL)
});
}

View File

@@ -1,24 +0,0 @@
import { BrowserWindow, ipcMain } from "electron";
import {
WIN_CLOSE_CHANNEL,
WIN_MAXIMIZE_CHANNEL,
WIN_MINIMIZE_CHANNEL
} from "./window-channels";
export function addWindowEventListeners(mainWindow: BrowserWindow) {
ipcMain.handle(WIN_MINIMIZE_CHANNEL, () => {
mainWindow.minimize();
});
ipcMain.handle(WIN_MAXIMIZE_CHANNEL, () => {
if (mainWindow.isMaximized()) {
mainWindow.unmaximize();
} else {
mainWindow.maximize();
}
});
ipcMain.handle(WIN_CLOSE_CHANNEL, () => {
mainWindow.close();
});
}

View File

@@ -1,19 +0,0 @@
import type { i18n } from "i18next";
const languageLocalStorageKey = "lang";
export function setAppLanguage(lang: string, i18n: i18n) {
localStorage.setItem(languageLocalStorageKey, lang);
i18n.changeLanguage(lang);
document.documentElement.lang = lang;
}
export function updateAppLanguage(i18n: i18n) {
const localLang = localStorage.getItem(languageLocalStorageKey);
if (!localLang) {
return;
}
i18n.changeLanguage(localLang);
document.documentElement.lang = localLang;
}

View File

@@ -1,59 +0,0 @@
import { ThemeMode } from "@types/theme-mode";
const THEME_KEY = "theme";
export interface ThemePreferences {
system: ThemeMode;
local: ThemeMode | null;
}
export async function getCurrentTheme(): Promise<ThemePreferences> {
const currentTheme = await window.themeMode.current();
const localTheme = localStorage.getItem(THEME_KEY) as ThemeMode | null;
return {
system: currentTheme,
local: localTheme,
};
}
export async function setTheme(newTheme: ThemeMode) {
switch (newTheme) {
case "dark":
await window.themeMode.dark();
updateDocumentTheme(true);
break;
case "light":
await window.themeMode.light();
updateDocumentTheme(false);
break;
case "system": {
const isDarkMode = await window.themeMode.system();
updateDocumentTheme(isDarkMode);
break;
}
}
localStorage.setItem(THEME_KEY, newTheme);
}
export async function syncThemeWithLocal() {
const { local } = await getCurrentTheme();
if (!local) {
setTheme("system");
return;
}
await setTheme(local);
}
function updateDocumentTheme(isDarkMode: boolean) {
if (!isDarkMode) {
document.documentElement.classList.remove("dark");
} else {
document.documentElement.classList.add("dark");
}
}

View File

@@ -1,11 +0,0 @@
export async function minimizeWindow() {
await window.electronWindow.minimize();
}
export async function maximizeWindow() {
await window.electronWindow.maximize();
}
export async function closeWindow() {
await window.electronWindow.close();
}

View File

@@ -1,5 +1,4 @@
import { app, BrowserWindow } from "electron"; import { app, BrowserWindow, ipcMain } from "electron";
import registerListeners from "./helpers/ipc/listeners-register";
import path from "node:path"; import path from "node:path";
// import started from "electron-squirrel-startup"; // import started from "electron-squirrel-startup";
@@ -24,8 +23,9 @@ const createWindow = () => {
}, },
}); });
// 注册 IPC 事件监听器(包括录制功能) ipcMain.on('open-baidu', () => {
registerListeners(mainWindow); mainWindow.loadURL("https://www.baidu.com")
})
// and load the index.html of the app. // and load the index.html of the app.
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) { if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {

View File

@@ -1,3 +0,0 @@
import exposeContexts from "./helpers/ipc/context-exposer";
exposeContexts();

30
src/types.d.ts vendored
View File

@@ -1,30 +0,0 @@
// This allows TypeScript to pick up the magic constants that's auto-generated by Forge's Vite
// plugin that tells the Electron app where to look for the Vite-bundled app code (depending on
// whether you're running in development or production).
// Preload types
interface ThemeModeContext {
toggle: () => Promise<boolean>;
dark: () => Promise<void>;
light: () => Promise<void>;
system: () => Promise<boolean>;
current: () => Promise<"dark" | "light" | "system">;
}
interface ElectronWindow {
minimize: () => Promise<void>;
maximize: () => Promise<void>;
close: () => Promise<void>;
}
interface RecordingContext {
runRecordingScript: () => Promise<unknown>;
onRecordingSave: (callback: (payload: unknown) => void) => void;
onRecordingEdit: (callback: (payload: unknown) => void) => void;
}
declare interface Window {
themeMode: ThemeModeContext;
electronWindow: ElectronWindow;
recording: RecordingContext;
}

View File

@@ -4,6 +4,7 @@
<div class="bg-white p-6"> <div class="bg-white p-6">
<button <button
class="bg-blue-300 hover:bg-blue-500 text-white px-4 py-2 rounded mr-2" class="bg-blue-300 hover:bg-blue-500 text-white px-4 py-2 rounded mr-2"
@click="openBaidu"
> >
打开百度 打开百度
</button> </button>
@@ -12,5 +13,9 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
const { ipcRenderer } = require("electron")
const openBaidu = async () => {
ipcRenderer.send('open-baidu')
};
</script> </script>