110 lines
3.0 KiB
Vue
110 lines
3.0 KiB
Vue
<script setup lang="ts">
|
|
import { computed, defineAsyncComponent, onMounted, watch } from 'vue'
|
|
import { useDesktopSession } from './composables/useDesktopSession'
|
|
import LoginView from './views/LoginView.vue'
|
|
|
|
const DesktopShell = defineAsyncComponent(() => import('./components/DesktopShell.vue'))
|
|
const SettingsWindow = defineAsyncComponent(() => import('./views/SettingsWindow.vue'))
|
|
|
|
const { isAuthenticated, syncRuntimeSession } = useDesktopSession()
|
|
type RendererWindowMode = 'auto' | 'login' | 'main' | 'settings'
|
|
|
|
interface WindowModeBridge {
|
|
setWindowMode?: (
|
|
mode: 'login' | 'main',
|
|
request?: { source?: 'auth-state' | 'login' | 'logout'; animate?: boolean },
|
|
) => Promise<unknown>
|
|
}
|
|
|
|
function resolveRendererWindowMode(): RendererWindowMode {
|
|
const mode = new URLSearchParams(window.location.search).get('window')
|
|
return mode === 'login' || mode === 'main' || mode === 'settings' ? mode : 'auto'
|
|
}
|
|
|
|
function getModeBridge(): WindowModeBridge | undefined {
|
|
return (
|
|
globalThis as unknown as {
|
|
desktopBridge?: { app?: WindowModeBridge }
|
|
}
|
|
).desktopBridge?.app
|
|
}
|
|
|
|
function syncWindowMode(authenticated: boolean): void {
|
|
void getModeBridge()
|
|
?.setWindowMode?.(authenticated ? 'main' : 'login', { source: 'auth-state' })
|
|
.catch((err) => {
|
|
console.warn('[desktop-app] window mode sync failed', {
|
|
authenticated,
|
|
message: err instanceof Error ? err.message : String(err),
|
|
})
|
|
})
|
|
}
|
|
|
|
const rendererWindowMode = resolveRendererWindowMode()
|
|
document.documentElement.dataset.windowMode = rendererWindowMode
|
|
document.documentElement.dataset.platform = navigator.platform.toLowerCase().includes('mac')
|
|
? 'darwin'
|
|
: 'win32'
|
|
const usesAutomaticWindowMode = rendererWindowMode === 'auto'
|
|
const showsSettingsSurface = rendererWindowMode === 'settings'
|
|
const showsMainSurface = computed(
|
|
() => rendererWindowMode === 'main' || (rendererWindowMode === 'auto' && isAuthenticated.value),
|
|
)
|
|
|
|
if (usesAutomaticWindowMode) {
|
|
syncWindowMode(isAuthenticated.value)
|
|
watch(isAuthenticated, (next) => syncWindowMode(next))
|
|
}
|
|
|
|
if (rendererWindowMode === 'main') {
|
|
if (!isAuthenticated.value) {
|
|
syncWindowMode(false)
|
|
}
|
|
watch(isAuthenticated, (next) => {
|
|
if (!next) {
|
|
syncWindowMode(false)
|
|
}
|
|
})
|
|
}
|
|
|
|
if (rendererWindowMode === 'login') {
|
|
if (isAuthenticated.value) {
|
|
syncWindowMode(true)
|
|
}
|
|
watch(isAuthenticated, (next) => {
|
|
if (next) {
|
|
syncWindowMode(true)
|
|
}
|
|
})
|
|
}
|
|
|
|
onMounted(() => {
|
|
if (rendererWindowMode !== 'login') {
|
|
void syncRuntimeSession().catch((err) => {
|
|
console.warn('[desktop-app] runtime session sync failed', {
|
|
message: err instanceof Error ? err.message : String(err),
|
|
})
|
|
})
|
|
}
|
|
if (usesAutomaticWindowMode) {
|
|
syncWindowMode(isAuthenticated.value)
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<SettingsWindow v-if="showsSettingsSurface" />
|
|
<DesktopShell v-else-if="showsMainSurface" />
|
|
<LoginView v-else />
|
|
</template>
|
|
|
|
<style>
|
|
html,
|
|
body,
|
|
#app {
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow: hidden;
|
|
}
|
|
</style>
|