From 5657a02a9fdc5e0486b61ffb8801661004e12a3b Mon Sep 17 00:00:00 2001 From: Toby <2287769986@qq.com> Date: Sat, 7 Jun 2025 11:08:15 +0800 Subject: [PATCH 1/5] Squashed commit of the following: commit 979628248edffccae385404363ff8c90101668f3 Author: Toby <2287769986@qq.com> Date: Fri Jun 6 20:44:55 2025 +0800 fix: lock-screen commit f3da30fc81f4ad4d995800ab8b599d5fd3cb2d57 Merge: 7cd1d0ae 3b18b067 Author: Toby <2287769986@qq.com> Date: Fri Jun 6 18:13:29 2025 +0800 Merge branch 'main' into feat-lock-screen-logout commit 7cd1d0ae0a699cdd786759c75d749156b0dfcafc Author: Toby <2287769986@qq.com> Date: Fri May 30 11:13:45 2025 +0800 fix: default signin page commit 9bfa89ba20c7f5253017580800935632db24fa39 Author: Toby <2287769986@qq.com> Date: Thu May 29 21:14:43 2025 +0800 fix: bug commit 02e73a8d3b23943f2a7aaae7cd30042600edb8c3 Author: Toby <2287769986@qq.com> Date: Thu May 29 20:58:37 2025 +0800 fix: bug commit ecfd936cc4028184300ac2ecc6ff5777228574f2 Author: Toby <2287769986@qq.com> Date: Thu May 29 20:37:50 2025 +0800 fix: send lock-screen commit 181a69f3880f2d778f0cddcf1b397a0443f4a1c5 Author: Toby <2287769986@qq.com> Date: Thu May 29 15:43:52 2025 +0800 fix: lock-screen logout --- src/ambient.d.ts | 1 + src/main/engine.ts | 4 +++ src/main/main.ts | 11 +++++++-- src/preload/preload.ts | 6 +++++ src/renderer/components/main-viewer.tsx | 33 +++++++++++++++++++++++-- 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/ambient.d.ts b/src/ambient.d.ts index 092f1432..9dcda143 100644 --- a/src/ambient.d.ts +++ b/src/ambient.d.ts @@ -192,6 +192,7 @@ declare global { themePath: string; uncacheTypes(ver: RunnableVersion): Promise; unwatchElectronTypes(): Promise; + onLockScreen: (cb: () => void) => void; }; } } diff --git a/src/main/engine.ts b/src/main/engine.ts index c85ae380..457a98de 100644 --- a/src/main/engine.ts +++ b/src/main/engine.ts @@ -125,4 +125,8 @@ export class TachybaseEngine { ipcMainManager.send(IpcEvents.ENGINE_STATUS_CHANGED, ['stopped']); } } + + sendChildMessage(message: string) { + this.child?.stdin.write(message); + } } diff --git a/src/main/main.ts b/src/main/main.ts index 9a4a8d24..113e0e78 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -4,6 +4,7 @@ import { IpcMainEvent, app, nativeTheme, + powerMonitor, systemPreferences, } from 'electron'; @@ -69,11 +70,17 @@ export async function onReady() { // Do this after setting everything up to ensure that // any IPC listeners are set up before they're used mainIsReady(); - await getOrCreateMainWindow(); + const mainWindow = await getOrCreateMainWindow(); - new TachybaseEngine(); + const engine = new TachybaseEngine(); processCommandLine(argv); + + powerMonitor.on('lock-screen', () => { + engine.sendChildMessage('lock-screen'); + mainWindow.webContents.send('lock-screen'); + }); + return mainWindow; } /** diff --git a/src/preload/preload.ts b/src/preload/preload.ts index baa0e6d3..f5723137 100644 --- a/src/preload/preload.ts +++ b/src/preload/preload.ts @@ -268,6 +268,12 @@ export async function setupFiddleGlobal() { async unwatchElectronTypes() { await ipcRenderer.invoke(IpcEvents.UNWATCH_ELECTRON_TYPES); }, + onLockScreen: (callback: () => void) => { + ipcRenderer.on('lock-screen', () => { + console.log('[preload] 转发 lock-screen 到渲染进程'); + callback(); + }); + }, }); } diff --git a/src/renderer/components/main-viewer.tsx b/src/renderer/components/main-viewer.tsx index 43e64839..74ccd4df 100644 --- a/src/renderer/components/main-viewer.tsx +++ b/src/renderer/components/main-viewer.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { Spinner } from '@blueprintjs/core'; import { observer } from 'mobx-react-lite'; @@ -6,6 +6,35 @@ import { observer } from 'mobx-react-lite'; import { AppState } from '../state'; export const MainViewer = observer(({ appState }: { appState: AppState }) => { + useEffect(() => { + const handler = () => { + console.log('[系统事件] 收到 lock-screen, 跳转到 /signin'); + const webview = document.getElementById( + 'mainView', + ) as Electron.WebviewTag; + if (webview) { + if (appState.enginePort) { + webview.src = `${appState.enginePort}/signin`; + webview.executeJavaScript(` + localStorage.removeItem('TACHYBASE_TOKEN'); + `); + } else { + console.warn('⚠️ appState.enginePort is null!'); + } + } else { + console.warn('⚠️ webview not found!'); + } + }; + + window.ElectronFiddle?.onLockScreen(handler); + + // 可选:组件卸载时清理监听器(如果支持) + return () => { + // 假设支持取消监听,如: + // window.ElectronFiddle?.offLockScreen(handler); + }; + }, [appState.enginePort]); + console.log('🚀 ~ MainViewer ~ appState:', appState.enginePort); if ( (appState.engineStatus === 'ready' || appState.engineStatus === 'remote') && @@ -14,7 +43,7 @@ export const MainViewer = observer(({ appState }: { appState: AppState }) => { return ( ); From 9431642f0390039bec4abff90d58c16d2294dcf6 Mon Sep 17 00:00:00 2001 From: Toby <2287769986@qq.com> Date: Sat, 7 Jun 2025 11:45:00 +0800 Subject: [PATCH 2/5] feat: lock screen event --- src/ambient.d.ts | 10 ++++++++- src/main/engine.ts | 4 ---- src/main/main.ts | 3 +-- src/preload/preload.ts | 18 ++++++++++++---- src/renderer/components/main-viewer.tsx | 28 ++++++++++--------------- 5 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/ambient.d.ts b/src/ambient.d.ts index 9dcda143..07a23186 100644 --- a/src/ambient.d.ts +++ b/src/ambient.d.ts @@ -1,3 +1,4 @@ +import { IpcRendererEvent } from 'electron'; import * as MonacoType from 'monaco-editor'; import { @@ -192,7 +193,14 @@ declare global { themePath: string; uncacheTypes(ver: RunnableVersion): Promise; unwatchElectronTypes(): Promise; - onLockScreen: (cb: () => void) => void; + addIpcRenderListener: ( + channel: string, + cb: (channel: string) => void, + ) => void; + removeIpcRenderListener: ( + channel: string, + cb: (channel: string) => void, + ) => void; }; } } diff --git a/src/main/engine.ts b/src/main/engine.ts index 457a98de..c85ae380 100644 --- a/src/main/engine.ts +++ b/src/main/engine.ts @@ -125,8 +125,4 @@ export class TachybaseEngine { ipcMainManager.send(IpcEvents.ENGINE_STATUS_CHANGED, ['stopped']); } } - - sendChildMessage(message: string) { - this.child?.stdin.write(message); - } } diff --git a/src/main/main.ts b/src/main/main.ts index 113e0e78..32365f6c 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -72,12 +72,11 @@ export async function onReady() { mainIsReady(); const mainWindow = await getOrCreateMainWindow(); - const engine = new TachybaseEngine(); + new TachybaseEngine(); processCommandLine(argv); powerMonitor.on('lock-screen', () => { - engine.sendChildMessage('lock-screen'); mainWindow.webContents.send('lock-screen'); }); return mainWindow; diff --git a/src/preload/preload.ts b/src/preload/preload.ts index f5723137..e25f8a6f 100644 --- a/src/preload/preload.ts +++ b/src/preload/preload.ts @@ -268,10 +268,20 @@ export async function setupFiddleGlobal() { async unwatchElectronTypes() { await ipcRenderer.invoke(IpcEvents.UNWATCH_ELECTRON_TYPES); }, - onLockScreen: (callback: () => void) => { - ipcRenderer.on('lock-screen', () => { - console.log('[preload] 转发 lock-screen 到渲染进程'); - callback(); + addIpcRenderListener: ( + channel: string, + callback: (channel: string) => void, + ) => { + ipcRenderer.on(channel, () => { + callback(channel); + }); + }, + removeIpcRenderListener: ( + channel: string, + callback: (channel: string) => void, + ) => { + ipcRenderer.off(channel, () => { + callback(channel); }); }, }); diff --git a/src/renderer/components/main-viewer.tsx b/src/renderer/components/main-viewer.tsx index 74ccd4df..0b720856 100644 --- a/src/renderer/components/main-viewer.tsx +++ b/src/renderer/components/main-viewer.tsx @@ -7,33 +7,27 @@ import { AppState } from '../state'; export const MainViewer = observer(({ appState }: { appState: AppState }) => { useEffect(() => { - const handler = () => { - console.log('[系统事件] 收到 lock-screen, 跳转到 /signin'); + const lockScreenChannel = 'lock-screen'; + const handler = (channel: string) => { const webview = document.getElementById( 'mainView', ) as Electron.WebviewTag; if (webview) { - if (appState.enginePort) { - webview.src = `${appState.enginePort}/signin`; - webview.executeJavaScript(` - localStorage.removeItem('TACHYBASE_TOKEN'); - `); - } else { - console.warn('⚠️ appState.enginePort is null!'); - } + webview.executeJavaScript(` + window.postMessage('${channel}', '*'); + `); } else { console.warn('⚠️ webview not found!'); } }; - - window.ElectronFiddle?.onLockScreen(handler); - - // 可选:组件卸载时清理监听器(如果支持) + window.ElectronFiddle?.addIpcRenderListener(lockScreenChannel, handler); return () => { - // 假设支持取消监听,如: - // window.ElectronFiddle?.offLockScreen(handler); + window.ElectronFiddle?.removeIpcRenderListener( + lockScreenChannel, + handler, + ); }; - }, [appState.enginePort]); + }, []); console.log('🚀 ~ MainViewer ~ appState:', appState.enginePort); if ( From e21d103822386640a9d90456adfe2ee9936dc032 Mon Sep 17 00:00:00 2001 From: Toby <2287769986@qq.com> Date: Sat, 7 Jun 2025 12:02:56 +0800 Subject: [PATCH 3/5] fix: appState.enginePort --- src/renderer/components/main-viewer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/components/main-viewer.tsx b/src/renderer/components/main-viewer.tsx index 0b720856..feb1c70b 100644 --- a/src/renderer/components/main-viewer.tsx +++ b/src/renderer/components/main-viewer.tsx @@ -37,7 +37,7 @@ export const MainViewer = observer(({ appState }: { appState: AppState }) => { return ( ); From 07bf357e1807360b449cfd425b5c985db747fa98 Mon Sep 17 00:00:00 2001 From: sealday Date: Sat, 7 Jun 2025 12:39:24 +0800 Subject: [PATCH 4/5] refactor: use a similar approach as before --- src/ambient.d.ts | 12 ++++-------- src/interfaces.ts | 1 + src/ipc-events.ts | 2 ++ src/main/main.ts | 14 ++++++++++---- src/preload/preload.ts | 1 + src/renderer/components/main-viewer.tsx | 25 ++++++++++--------------- 6 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/ambient.d.ts b/src/ambient.d.ts index 07a23186..b8e113a6 100644 --- a/src/ambient.d.ts +++ b/src/ambient.d.ts @@ -59,6 +59,10 @@ declare global { type: 'engine-status-changed', listener: (status: string, port: string) => void, ): void; + addEventListener( + type: 'power-monitor', + listener: (event: string) => void, + ): void; addEventListener( type: 'engine-stdout', listener: (data: string) => void, @@ -193,14 +197,6 @@ declare global { themePath: string; uncacheTypes(ver: RunnableVersion): Promise; unwatchElectronTypes(): Promise; - addIpcRenderListener: ( - channel: string, - cb: (channel: string) => void, - ) => void; - removeIpcRenderListener: ( - channel: string, - cb: (channel: string) => void, - ) => void; }; } } diff --git a/src/interfaces.ts b/src/interfaces.ts index a4388c76..7eda5b6c 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -193,6 +193,7 @@ export type FiddleEvent = | 'open-settings' | 'open-template' | 'package-fiddle' + | 'power-monitor' | 'redo-in-editor' | 'run-fiddle' | 'save-fiddle-gist' diff --git a/src/ipc-events.ts b/src/ipc-events.ts index 3e76fbb7..d3bf4a20 100644 --- a/src/ipc-events.ts +++ b/src/ipc-events.ts @@ -82,6 +82,7 @@ export enum IpcEvents { ENGINE_STDOUT = 'ENGINE_STDOUT', ENGINE_STDERR = 'ENGINE_STDERR', GET_ENGINE_STATUS = 'GET_ENGINE_STATUS', + POWER_MONITOR = 'POWER_MONITOR', } export const ipcMainEvents = [ @@ -136,6 +137,7 @@ export const ipcMainEvents = [ IpcEvents.ENGINE_STDOUT, IpcEvents.ENGINE_STDERR, IpcEvents.GET_ENGINE_STATUS, + IpcEvents.POWER_MONITOR, ]; export const WEBCONTENTS_READY_FOR_IPC_SIGNAL = diff --git a/src/main/main.ts b/src/main/main.ts index 32365f6c..709612f3 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -61,6 +61,7 @@ export async function onReady() { setupThemes(); setupIsDevMode(); setupNpm(); + setupPowerMonitor(); const knownVersions = await setupVersions(); setupGetProjectName(); setupGetUsername(); @@ -70,16 +71,21 @@ export async function onReady() { // Do this after setting everything up to ensure that // any IPC listeners are set up before they're used mainIsReady(); - const mainWindow = await getOrCreateMainWindow(); + await getOrCreateMainWindow(); new TachybaseEngine(); processCommandLine(argv); +} + +const POWER_MONITOR_EVENTS = ['lock-screen', 'unlock-screen']; - powerMonitor.on('lock-screen', () => { - mainWindow.webContents.send('lock-screen'); +export function setupPowerMonitor() { + POWER_MONITOR_EVENTS.forEach((event) => { + powerMonitor.on(event as any, () => { + ipcMainManager.send(IpcEvents.POWER_MONITOR, [event]); + }); }); - return mainWindow; } /** diff --git a/src/preload/preload.ts b/src/preload/preload.ts index e25f8a6f..8beed48c 100644 --- a/src/preload/preload.ts +++ b/src/preload/preload.ts @@ -59,6 +59,7 @@ const channelMapping: Record = { 'engine-started': IpcEvents.ENGINE_STARTED, 'engine-stdout': IpcEvents.ENGINE_STDOUT, 'engine-stderr': IpcEvents.ENGINE_STDERR, + 'power-monitor': IpcEvents.POWER_MONITOR, } as const; async function preload() { diff --git a/src/renderer/components/main-viewer.tsx b/src/renderer/components/main-viewer.tsx index feb1c70b..c893827e 100644 --- a/src/renderer/components/main-viewer.tsx +++ b/src/renderer/components/main-viewer.tsx @@ -1,41 +1,36 @@ import React, { useEffect } from 'react'; import { Spinner } from '@blueprintjs/core'; +import type { WebviewTag } from 'electron'; import { observer } from 'mobx-react-lite'; import { AppState } from '../state'; export const MainViewer = observer(({ appState }: { appState: AppState }) => { + const ref = React.useRef(null); useEffect(() => { - const lockScreenChannel = 'lock-screen'; - const handler = (channel: string) => { - const webview = document.getElementById( - 'mainView', - ) as Electron.WebviewTag; - if (webview) { - webview.executeJavaScript(` - window.postMessage('${channel}', '*'); + window.ElectronFiddle.addEventListener('power-monitor', (event: string) => { + if (ref.current) { + ref.current.executeJavaScript(` + window.postMessage('${event}', '*'); `); } else { console.warn('⚠️ webview not found!'); } - }; - window.ElectronFiddle?.addIpcRenderListener(lockScreenChannel, handler); + }); + return () => { - window.ElectronFiddle?.removeIpcRenderListener( - lockScreenChannel, - handler, - ); + window.ElectronFiddle.removeAllListeners('power-monitor'); }; }, []); - console.log('🚀 ~ MainViewer ~ appState:', appState.enginePort); if ( (appState.engineStatus === 'ready' || appState.engineStatus === 'remote') && appState.enginePort ) { return ( Date: Sat, 7 Jun 2025 12:40:18 +0800 Subject: [PATCH 5/5] chore: clean codes --- src/preload/preload.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/preload/preload.ts b/src/preload/preload.ts index 8beed48c..d20263e4 100644 --- a/src/preload/preload.ts +++ b/src/preload/preload.ts @@ -269,22 +269,6 @@ export async function setupFiddleGlobal() { async unwatchElectronTypes() { await ipcRenderer.invoke(IpcEvents.UNWATCH_ELECTRON_TYPES); }, - addIpcRenderListener: ( - channel: string, - callback: (channel: string) => void, - ) => { - ipcRenderer.on(channel, () => { - callback(channel); - }); - }, - removeIpcRenderListener: ( - channel: string, - callback: (channel: string) => void, - ) => { - ipcRenderer.off(channel, () => { - callback(channel); - }); - }, }); }