App.vue 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. <script setup lang="ts">
  2. import { computed, onMounted, watch } from 'vue'
  3. import { useRoute } from 'vue-router'
  4. import LoadingScreen from '@/components/app/LoadingScreen.vue'
  5. import LoginView from '@/views/LoginView.vue'
  6. import { useAuthStore } from '@/stores/auth'
  7. import { useChatStore } from '@/stores/chat'
  8. import { useGroupsStore } from '@/stores/groups'
  9. import { useThemeStore } from '@/stores/theme'
  10. const auth = useAuthStore()
  11. const chat = useChatStore()
  12. const groups = useGroupsStore()
  13. const theme = useThemeStore()
  14. const route = useRoute()
  15. const pageTitle = computed(() => {
  16. const name = route.path.startsWith('/groups')
  17. ? groups.selectedRoom?.name || '团队'
  18. : route.path.startsWith('/files')
  19. ? '文件库'
  20. : chat.activeSession?.title || '对话'
  21. return `${name} · 夭夭`
  22. })
  23. watch(() => theme.resolvedTheme, value => {
  24. document.documentElement.classList.toggle('dark', value === 'dark')
  25. document.documentElement.dataset.theme = value
  26. document.querySelector('meta[name="theme-color"]')?.setAttribute('content', value === 'dark' ? '#181817' : '#f8f8f6')
  27. }, { immediate: true })
  28. watch(pageTitle, value => { document.title = value }, { immediate: true })
  29. watch(() => auth.isAuthenticated, authenticated => {
  30. if (authenticated) void chat.connect().catch(() => undefined)
  31. })
  32. onMounted(() => auth.bootstrap())
  33. </script>
  34. <template>
  35. <LoadingScreen v-if="auth.status === 'checking'" />
  36. <LoginView v-else-if="!auth.isAuthenticated" />
  37. <RouterView v-else />
  38. </template>