feat: 移除无关文件
This commit is contained in:
@@ -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();
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import { BrowserWindow } from "electron";
|
|
||||||
import { addWindowEventListeners } from "./window/window-listeners";
|
|
||||||
|
|
||||||
export default function registerListeners(mainWindow: BrowserWindow) {
|
|
||||||
addWindowEventListeners(mainWindow);
|
|
||||||
}
|
|
||||||
@@ -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";
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -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 };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -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";
|
|
||||||
@@ -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),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -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";
|
|
||||||
@@ -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)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
@@ -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) {
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
import exposeContexts from "./helpers/ipc/context-exposer";
|
|
||||||
|
|
||||||
exposeContexts();
|
|
||||||
|
|||||||
30
src/types.d.ts
vendored
30
src/types.d.ts
vendored
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user