Skip to content

Commit a7d5793

Browse files
committed
feat(stage-tamagotchi): support to auto fade out & resize for caption window
1 parent a753eca commit a7d5793

File tree

3 files changed

+47
-8
lines changed

3 files changed

+47
-8
lines changed

apps/stage-tamagotchi/src/main/windows/caption/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import icon from '../../../../resources/icon.png?asset'
1515
import { captionGetIsFollowingWindow, captionIsFollowingWindowChanged } from '../../../shared/eventa'
1616
import { baseUrl, getElectronMainDirname, load, withHashRoute } from '../../libs/electron/location'
1717
import { createReusableWindow } from '../../libs/electron/window-manager'
18+
import { setupBaseWindowElectronInvokes } from '../main/rpc/index.electron'
1819
import { mapForBreakpoints, resolutionBreakpoints, widthFrom } from '../shared/display'
1920
import { createConfig } from '../shared/persistence'
2021
import { transparentWindowConfig } from '../shared/window'
@@ -255,6 +256,8 @@ export function setupCaptionWindowManager(params: { mainWindow: BrowserWindow })
255256
const { context } = createContext(ipcMain, window)
256257
eventaContext = context
257258

259+
setupBaseWindowElectronInvokes({ context, window })
260+
258261
const cfg = getConfig()
259262
const saved = cfg?.matrices?.[matrixHash]?.bounds
260263

apps/stage-tamagotchi/src/main/windows/main/rpc/index.electron.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ import { createWidgetsService } from '../../../services/airi/widgets'
1313
import { createAppService, createAutoUpdaterService, createScreenService, createWindowService } from '../../../services/electron'
1414
import { toggleWindowShow } from '../../shared'
1515

16+
export function setupBaseWindowElectronInvokes(params: {
17+
context: ReturnType<typeof createContext>['context']
18+
window: BrowserWindow
19+
}) {
20+
createScreenService({ context: params.context, window: params.window })
21+
createWindowService({ context: params.context, window: params.window })
22+
createAppService({ context: params.context, window: params.window })
23+
}
24+
1625
export function setupMainWindowElectronInvokes(params: {
1726
window: BrowserWindow
1827
settingsWindow: () => Promise<BrowserWindow>
@@ -28,11 +37,9 @@ export function setupMainWindowElectronInvokes(params: {
2837

2938
const { context } = createContext(ipcMain, params.window)
3039

31-
createScreenService({ context, window: params.window })
32-
createWindowService({ context, window: params.window })
40+
setupBaseWindowElectronInvokes({ context, window: params.window })
3341
createWidgetsService({ context, widgetsManager: params.widgetsManager, window: params.window })
3442
createAutoUpdaterService({ context, window: params.window, service: params.autoUpdater })
35-
createAppService({ context, window: params.window })
3643

3744
defineInvokeHandler(context, electronOpenMainDevtools, () => params.window.webContents.openDevTools({ mode: 'detach' }))
3845
defineInvokeHandler(context, electronOpenSettings, async () => toggleWindowShow(await params.settingsWindow()))

apps/stage-tamagotchi/src/renderer/pages/caption.vue

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
<script setup lang="ts">
22
import { defineInvoke } from '@moeru/eventa'
3-
import { useBroadcastChannel } from '@vueuse/core'
4-
import { onMounted, ref, watch } from 'vue'
3+
import { refDebounced, useBroadcastChannel } from '@vueuse/core'
4+
import { computed, onMounted, ref, watch } from 'vue'
55
66
import { captionGetIsFollowingWindow, captionIsFollowingWindowChanged } from '../../shared/eventa'
7-
import { useElectronEventaContext } from '../composables/electron-vueuse'
7+
import { useElectronEventaContext, useElectronMouseAroundWindowBorder, useElectronMouseInWindow } from '../composables/electron-vueuse'
88
99
const attached = ref(true)
1010
const speakerText = ref('')
1111
const assistantText = ref('')
12+
const { isOutside: isOutsideWindow } = useElectronMouseInWindow()
13+
const isOutsideWindowFor250Ms = refDebounced(isOutsideWindow, 250)
14+
const shouldFadeOnCursorWithin = computed(() => !isOutsideWindowFor250Ms.value)
15+
const { isNearAnyBorder: isAroundWindowBorder } = useElectronMouseAroundWindowBorder({ threshold: 30 })
16+
const isAroundWindowBorderFor250Ms = refDebounced(isAroundWindowBorder, 250)
1217
1318
// Broadcast channel for captions
1419
type CaptionChannelEvent
@@ -51,8 +56,14 @@ onMounted(async () => {
5156
</script>
5257

5358
<template>
54-
<div class="pointer-events-none h-full w-full flex items-end justify-center">
55-
<div class="pointer-events-auto relative select-none rounded-xl px-3 py-2">
59+
<div class="pointer-events-none relative h-full w-full flex items-end justify-center">
60+
<div
61+
:class="[
62+
shouldFadeOnCursorWithin ? 'op-0' : 'op-100',
63+
'pointer-events-auto relative select-none rounded-xl px-3 py-2',
64+
'transition-opacity duration-250 ease-in-out',
65+
]"
66+
>
5667
<div
5768
v-show="!attached"
5869
class="[-webkit-app-region:drag] absolute left-1/2 h-[14px] w-[36px] border border-[rgba(125,125,125,0.35)] rounded-[10px] bg-[rgba(125,125,125,0.28)] backdrop-blur-[6px] -top-2 -translate-x-1/2"
@@ -77,6 +88,24 @@ onMounted(async () => {
7788
</div>
7889
</div>
7990
</div>
91+
92+
<Transition
93+
enter-active-class="transition-opacity duration-250 ease-in-out"
94+
enter-from-class="opacity-50"
95+
enter-to-class="opacity-100"
96+
leave-active-class="transition-opacity duration-250 ease-in-out"
97+
leave-from-class="opacity-100"
98+
leave-to-class="opacity-50"
99+
>
100+
<div v-if="isAroundWindowBorderFor250Ms" class="pointer-events-none absolute left-0 top-0 z-999 h-full w-full">
101+
<div
102+
:class="[
103+
'b-primary/50',
104+
'h-full w-full animate-flash animate-duration-3s animate-count-infinite b-4 rounded-2xl',
105+
]"
106+
/>
107+
</div>
108+
</Transition>
80109
</div>
81110
</template>
82111

0 commit comments

Comments
 (0)