From 35259b5d2939b029b9f80f8cdd43eb1edcc0cfd1 Mon Sep 17 00:00:00 2001 From: Neko Ayaka Date: Tue, 7 Oct 2025 23:06:19 +0800 Subject: [PATCH] feat(stage-tamagotchi): put injecta into good use to prevent global variable --- apps/stage-tamagotchi/src/main/index.ts | 55 +++++++++++-------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/apps/stage-tamagotchi/src/main/index.ts b/apps/stage-tamagotchi/src/main/index.ts index 81dae915a..311b6651f 100644 --- a/apps/stage-tamagotchi/src/main/index.ts +++ b/apps/stage-tamagotchi/src/main/index.ts @@ -6,7 +6,9 @@ import { platform } from 'node:process' import { electronApp, optimizer } from '@electron-toolkit/utils' import { Format, LogLevel, setGlobalFormat, setGlobalLogLevel, useLogg } from '@guiiai/logg' +import { injecta } from '@proj-airi/injecta' import { app, Menu, nativeImage, Tray } from 'electron' +import { noop, once } from 'es-toolkit' import { isMacOS } from 'std-env' import icon from '../../resources/icon.png?asset' @@ -14,6 +16,7 @@ import macOSTrayIcon from '../../resources/tray-icon-macos.png?asset' import { openDebugger, setupDebugger } from './app/debugger' import { emitAppBeforeQuit, emitAppReady, emitAppWindowAllClosed, onAppBeforeQuit } from './libs/bootkit/lifecycle' +import { setupInlayWindow } from './windows/inlay' import { setupMainWindow } from './windows/main' import { setupSettingsWindow } from './windows/settings' import { toggleWindowShow } from './windows/shared/window' @@ -27,31 +30,26 @@ const log = useLogg('main').useGlobalConfig() app.dock?.setIcon(icon) electronApp.setAppUserModelId('ai.moeru.airi') -let mainWindow: BrowserWindow | null = null -let appTray: Tray | null = null +function setupTray(params: { mainWindow: BrowserWindow }): void { + once(() => { + const appTray = new Tray(nativeImage.createFromPath(macOSTrayIcon).resize({ width: 16 })) + onAppBeforeQuit(() => appTray.destroy()) -function setupTray(): void { - if (appTray) { - return - } + const contextMenu = Menu.buildFromTemplate([ + { label: 'Show', click: () => toggleWindowShow(params.mainWindow) }, + { label: 'Inlay', click: () => setupInlayWindow() }, + { type: 'separator' }, + { label: 'Settings', click: () => setupSettingsWindow() }, + { type: 'separator' }, + { label: 'Quit', click: () => app.quit() }, + ]) - appTray = new Tray(nativeImage.createFromPath(macOSTrayIcon).resize({ width: 16 })) - - const contextMenu = Menu.buildFromTemplate([ - { label: 'Show Window', click: () => toggleWindowShow(mainWindow) }, - { type: 'separator' }, - { label: 'Settings', click: () => setupSettingsWindow() }, - { type: 'separator' }, - { label: 'Quit', click: () => app.quit() }, - ]) - - appTray.setContextMenu(contextMenu) - appTray.setToolTip('Project AIRI') - appTray.addListener('click', () => toggleWindowShow(mainWindow)) - // On macOS, there's a special double-click event - if (isMacOS) { - appTray.addListener('double-click', () => toggleWindowShow(mainWindow)) - } + appTray.setContextMenu(contextMenu) + appTray.setToolTip('Project AIRI') + appTray.addListener('click', () => toggleWindowShow(params.mainWindow)) + // On macOS, there's a special double-click event + isMacOS && appTray.addListener('double-click', () => toggleWindowShow(params.mainWindow)) + })() } async function setupProjectAIRIServerRuntime() { @@ -91,8 +89,10 @@ async function setupProjectAIRIServerRuntime() { app.whenReady().then(async () => { await setupProjectAIRIServerRuntime() - mainWindow = await setupMainWindow() - setupTray() + injecta.provide('mainWindow', async () => await setupMainWindow()) + injecta.provide<{ mainWindow: BrowserWindow }>('tray', { dependsOn: { mainWindow: 'mainWindow' }, build: async ({ dependsOn }) => setupTray({ mainWindow: dependsOn.mainWindow }) }) + injecta.invoke({ dependsOn: { mainWindow: 'mainWindow', tray: 'tray' }, callback: noop }) + injecta.start() // Lifecycle emitAppReady() @@ -122,9 +122,4 @@ app.on('window-all-closed', () => { // Clean up server and intervals when app quits app.on('before-quit', async () => { emitAppBeforeQuit() - - if (appTray) { - appTray.destroy() - appTray = null - } })