feat(stage-tamagotchi): background window for beat-sync

This commit is contained in:
Makito
2025-11-29 00:18:05 +09:00
parent e891678d27
commit 8e499a880a
6 changed files with 97 additions and 7 deletions
@@ -23,12 +23,28 @@ export default defineConfig({
plugins: [externalizeDepsPlugin()],
},
preload: {
build: {
lib: {
entry: {
'index': resolve(join(import.meta.dirname, 'src', 'preload', 'index.ts')),
'beat-sync': resolve(join(import.meta.dirname, 'src', 'preload', 'beat-sync.ts')),
},
},
},
plugins: [externalizeDepsPlugin()],
},
renderer: {
// Thanks to [@Maqsyo](https://github.com/Maqsyo)
// https://github.com/alex8088/electron-vite/issues/99#issuecomment-1862671727
base: './',
build: {
rolldownOptions: {
input: {
'main': resolve(join(import.meta.dirname, 'src', 'renderer', 'index.html')),
'beat-sync': resolve(join(import.meta.dirname, 'src', 'renderer', 'beat-sync.html')),
},
},
},
optimizeDeps: {
exclude: [
// Internal Packages
+18 -4
View File
@@ -4,7 +4,7 @@ import type { WidgetsWindowManager } from './windows/widgets'
import { env, platform } from 'node:process'
import { electronApp, optimizer } from '@electron-toolkit/utils'
import { electronApp, is, optimizer } from '@electron-toolkit/utils'
import { Format, LogLevel, setGlobalFormat, setGlobalLogLevel, useLogg } from '@guiiai/logg'
import { app, ipcMain, Menu, nativeImage, Tray } from 'electron'
import { noop, once } from 'es-toolkit'
@@ -18,6 +18,7 @@ import { openDebugger, setupDebugger } from './app/debugger'
import { emitAppBeforeQuit, emitAppReady, emitAppWindowAllClosed, onAppBeforeQuit } from './libs/bootkit/lifecycle'
import { setElectronMainDirname } from './libs/electron/location'
import { setupChannelServer } from './services/airi/channel-server'
import { setupBeatSyncBackgroundWindow } from './windows/beat-sync'
import { setupCaptionWindowManager } from './windows/caption'
import { setupChatWindowReusableFunc } from './windows/chat'
import { setupInlayWindow } from './windows/inlay'
@@ -73,6 +74,7 @@ function setupTray(params: {
settingsWindow: () => Promise<BrowserWindow>
captionWindow: ReturnType<typeof setupCaptionWindowManager>
widgetsWindow: WidgetsWindowManager
beatSyncBackgroundWindow: BrowserWindow
}): void {
once(() => {
const trayImage = nativeImage.createFromPath(isMacOS ? macOSTrayIcon : icon).resize({ width: 16 })
@@ -97,6 +99,13 @@ function setupTray(params: {
]),
},
{ type: 'separator' },
...is.dev || env.MAIN_APP_DEBUG || env.APP_DEBUG
? [
{ type: 'header', label: 'DevTools' },
{ label: 'Troubleshoot BeatSync...', click: () => params.beatSyncBackgroundWindow.webContents.openDevTools() },
{ type: 'separator' },
] as const // :(
: [],
{ label: 'Quit', click: () => app.quit() },
])
@@ -118,12 +127,17 @@ app.whenReady().then(async () => {
const widgetsManager = injeca.provide('windows:widgets', { build: () => setupWidgetsWindowManager() })
const noticeWindow = injeca.provide('windows:notice', { build: () => setupNoticeWindowManager() })
// This is a background window
const beatSyncBackgroundWindow = injeca.provide('windows:beat-sync', {
build: () => setupBeatSyncBackgroundWindow(),
})
const settingsWindow = injeca.provide('windows:settings', {
dependsOn: { widgetsManager },
dependsOn: { widgetsManager, beatSyncBackgroundWindow },
build: ({ dependsOn }) => setupSettingsWindowReusableFunc(dependsOn),
})
const mainWindow = injeca.provide('windows:main', {
dependsOn: { settingsWindow, chatWindow, widgetsManager, noticeWindow },
dependsOn: { settingsWindow, chatWindow, widgetsManager, noticeWindow, beatSyncBackgroundWindow },
build: async ({ dependsOn }) => setupMainWindow(dependsOn),
})
const captionWindow = injeca.provide('windows:caption', {
@@ -131,7 +145,7 @@ app.whenReady().then(async () => {
build: async ({ dependsOn }) => setupCaptionWindowManager(dependsOn),
})
const tray = injeca.provide('app:tray', {
dependsOn: { mainWindow, settingsWindow, captionWindow, widgetsWindow: widgetsManager },
dependsOn: { mainWindow, settingsWindow, captionWindow, widgetsWindow: widgetsManager, beatSyncBackgroundWindow },
build: async ({ dependsOn }) => setupTray(dependsOn),
})
injeca.invoke({
@@ -15,12 +15,21 @@ export function getElectronMainDirname() {
return electronMainDirname
}
export function baseUrl(parentOfIndexHtml: string) {
export function baseUrl(parentOfIndexHtml: string, filename?: string) {
if (is.dev && env.ELECTRON_RENDERER_URL) {
return { url: env.ELECTRON_RENDERER_URL }
if (!filename) {
return { url: env.ELECTRON_RENDERER_URL }
}
const url = new URL(env.ELECTRON_RENDERER_URL)
const paths = url.pathname.split('/')
paths.pop()
paths.push(filename)
url.pathname = paths.join('/')
return { url: url.toString() }
}
else {
return { file: join(parentOfIndexHtml, 'index.html') }
return { file: join(parentOfIndexHtml, filename ?? 'index.html') }
}
}
@@ -0,0 +1,18 @@
import { dirname, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { BrowserWindow } from 'electron'
import { baseUrl, getElectronMainDirname, load } from '../../libs/electron/location'
export async function setupBeatSyncBackgroundWindow() {
const window = new BrowserWindow({
show: false,
webPreferences: {
preload: join(dirname(fileURLToPath(import.meta.url)), '../preload/beat-sync.mjs'),
sandbox: false,
},
})
await load(window, baseUrl(resolve(getElectronMainDirname(), '..', 'renderer'), 'beat-sync.html'))
return window
}
@@ -0,0 +1,2 @@
// eslint-disable-next-line no-console
console.log('beat-sync preload')
@@ -0,0 +1,31 @@
<!-- This is intended to be a background window -->
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>BeatSync - AIRI</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, viewport-fit=cover" />
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-family: sans-serif;
font-size: 16px;
}
</style>
</head>
<body>
<div class="center">Open the DevTools to troubleshoot BeatSync</div>
</body>
</html>