fix(stage-tamagotchi): let tray menu close caption overlay (#1316)

Co-authored-by: stablegenius49 <185121704+stablegenius49@users.noreply.github.com>
This commit is contained in:
Stable Genius
2026-03-12 23:11:37 +08:00
committed by GitHub
co-authored by stablegenius49
parent 28db2f6e2a
commit 0d1dc34bd8
11 changed files with 65 additions and 1 deletions
+9 -1
View File
@@ -177,7 +177,14 @@ export function setupTray(params: {
{ type: 'separator' },
{ label: params.i18n.t('tamagotchi.electron.tray.menu.labels.label.open_inlay'), click: () => setupInlayWindow({ i18n: params.i18n, serverChannel: params.serverChannel }) },
{ label: params.i18n.t('tamagotchi.electron.tray.menu.labels.label.open_widgets'), click: () => params.widgetsWindow.getWindow().then(window => toggleWindowShow(window)) },
{ label: params.i18n.t('tamagotchi.electron.tray.menu.labels.label.open_caption'), click: () => params.captionWindow.getWindow().then(window => toggleWindowShow(window)) },
{
label: params.i18n.t(params.captionWindow.isVisible()
? 'tamagotchi.electron.tray.menu.labels.label.close_caption'
: 'tamagotchi.electron.tray.menu.labels.label.open_caption'),
click: () => {
void params.captionWindow.toggleVisibility().then(() => rebuildContextMenu())
},
},
{
type: 'submenu',
label: params.i18n.t('tamagotchi.electron.tray.menu.labels.label.caption_overlay'),
@@ -202,6 +209,7 @@ export function setupTray(params: {
params.mainWindow.on('resize', rebuildContextMenu)
params.mainWindow.on('move', rebuildContextMenu)
params.captionWindow.onVisibilityChanged(rebuildContextMenu)
rebuildContextMenu()
@@ -264,6 +264,18 @@ export function setupCaptionWindowManager(params: {
}
let eventaContext: ReturnType<typeof createContext>['context'] | undefined
let currentWindow: BrowserWindow | undefined
const visibilityListeners = new Set<() => void>()
const emitVisibilityChanged = () => {
for (const listener of visibilityListeners) {
try {
listener()
}
catch {
}
}
}
const reusable = createReusableWindow(async () => {
// TODO: once we refactored eventa to support window-namespaced contexts,
@@ -272,6 +284,7 @@ export function setupCaptionWindowManager(params: {
ipcMain.setMaxListeners(0)
const window = createCaptionWindow()
currentWindow = window
const { context } = createContext(ipcMain, window)
eventaContext = context
@@ -304,6 +317,8 @@ export function setupCaptionWindowManager(params: {
window.on('resize', persistBounds)
window.on('move', persistBounds)
window.on('show', emitVisibilityChanged)
window.on('hide', emitVisibilityChanged)
await load(window, withHashRoute(baseUrl(resolve(getElectronMainDirname(), '..', 'renderer')), '/caption'))
@@ -327,7 +342,11 @@ export function setupCaptionWindowManager(params: {
catch {
}
if (currentWindow === window) {
currentWindow = undefined
}
eventaContext = undefined
emitVisibilityChanged()
})
return window
@@ -396,11 +415,39 @@ export function setupCaptionWindowManager(params: {
updateConfig(config)
}
function isVisible(): boolean {
return Boolean(currentWindow && !currentWindow.isDestroyed() && currentWindow.isVisible())
}
async function toggleVisibility() {
if (isVisible()) {
currentWindow?.hide()
return
}
const window = await reusable.getWindow()
if (window.isMinimized()) {
window.restore()
}
window.show()
window.focus()
}
function onVisibilityChanged(listener: () => void): () => void {
visibilityListeners.add(listener)
return () => {
visibilityListeners.delete(listener)
}
}
return {
getWindow,
setFollowWindow,
toggleFollowWindow,
getIsFollowingWindow,
resetToSide,
isVisible,
toggleVisibility,
onVisibilityChanged,
}
}
@@ -18,6 +18,7 @@ menu:
open_inlay: Open Inlay...
open_widgets: Open Widgets...
open_caption: Open Caption...
close_caption: Close Caption...
caption_overlay: Caption Overlay
follow_window: Follow window
reset_position: Reset position
@@ -18,6 +18,7 @@ menu:
open_inlay: Open Inlay...
open_widgets: Open Widgets...
open_caption: Open Caption...
close_caption: Cerrar subtítulos...
caption_overlay: Caption Overlay
follow_window: Follow window
reset_position: Reset position
@@ -18,6 +18,7 @@ menu:
open_inlay: Ouvrir l'incrustation...
open_widgets: Ouvrir les widgets...
open_caption: Ouvrir le sous-titrage...
close_caption: Fermer le sous-titrage...
caption_overlay: Superposition des sous-titres
follow_window: Suivre la fenêtre
reset_position: Réinitialiser la position
@@ -18,6 +18,7 @@ menu:
open_inlay: Open Inlay...
open_widgets: Open Widgets...
open_caption: Open Caption...
close_caption: 字幕を閉じる...
caption_overlay: Caption Overlay
follow_window: Follow window
reset_position: Reset position
@@ -18,6 +18,7 @@ menu:
open_inlay: 인레이 열기...
open_widgets: 위젯 열기...
open_caption: 자막 열기...
close_caption: 자막 닫기...
caption_overlay: 자막 오버레이
follow_window: 창 따라가기
reset_position: 위치 초기화
@@ -18,6 +18,7 @@ menu:
open_inlay: Open Inlay...
open_widgets: Open Widgets...
open_caption: Open Caption...
close_caption: Закрыть субтитры...
caption_overlay: Caption Overlay
follow_window: Follow window
reset_position: Reset position
@@ -18,6 +18,7 @@ menu:
open_inlay: Mở khảm...
open_widgets: Mở tiện ích...
open_caption: Mở phụ đề...
close_caption: Đóng phụ đề...
caption_overlay: Lớp phủ phụ đề
follow_window: Theo cửa sổ
reset_position: Đặt lại vị trí
@@ -18,6 +18,7 @@ menu:
open_inlay: 打开内嵌...
open_widgets: 打开小部件...
open_caption: 打开字幕...
close_caption: 关闭字幕...
caption_overlay: 字幕覆盖
follow_window: 跟随窗口
reset_position: 重置位置
@@ -18,6 +18,7 @@ menu:
open_inlay: 開啟內嵌……
open_widgets: 開啟套件……
open_caption: 開啟字幕……
close_caption: 關閉字幕……
caption_overlay: 字幕浮水印
follow_window: 跟隨視窗
reset_position: 重置位置