Просмотр исходного кода

WIP: 使用会话标题作为浏览器标题

samien 2 месяцев назад
Родитель
Сommit
f5f5105a3d
3 измененных файлов с 27 добавлено и 2 удалено
  1. 1 1
      index.html
  2. 18 1
      src/client/App.vue
  3. 8 0
      tests/e2e/workspace.spec.ts

+ 1 - 1
index.html

@@ -8,7 +8,7 @@
     <link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32.png" />
     <link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32.png" />
     <link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-touch-icon.png" />
     <link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-touch-icon.png" />
     <link rel="manifest" href="/manifest.webmanifest" />
     <link rel="manifest" href="/manifest.webmanifest" />
-    <title>夭夭 Web</title>
+    <title>夭夭</title>
   </head>
   </head>
   <body>
   <body>
     <div id="app"></div>
     <div id="app"></div>

+ 18 - 1
src/client/App.vue

@@ -1,12 +1,27 @@
 <script setup lang="ts">
 <script setup lang="ts">
-import { onMounted, watch } from 'vue'
+import { computed, onMounted, watch } from 'vue'
+import { useRoute } from 'vue-router'
 import LoadingScreen from '@/components/app/LoadingScreen.vue'
 import LoadingScreen from '@/components/app/LoadingScreen.vue'
 import LoginView from '@/views/LoginView.vue'
 import LoginView from '@/views/LoginView.vue'
 import { useAuthStore } from '@/stores/auth'
 import { useAuthStore } from '@/stores/auth'
+import { useChatStore } from '@/stores/chat'
+import { useGroupsStore } from '@/stores/groups'
 import { useThemeStore } from '@/stores/theme'
 import { useThemeStore } from '@/stores/theme'
 
 
 const auth = useAuthStore()
 const auth = useAuthStore()
+const chat = useChatStore()
+const groups = useGroupsStore()
 const theme = useThemeStore()
 const theme = useThemeStore()
+const route = useRoute()
+
+const pageTitle = computed(() => {
+  const name = route.path.startsWith('/groups')
+    ? groups.selectedRoom?.name || '群聊'
+    : route.path.startsWith('/files')
+      ? '文件库'
+      : chat.activeSession?.title || '对话'
+  return `${name} · 夭夭`
+})
 
 
 watch(() => theme.resolvedTheme, value => {
 watch(() => theme.resolvedTheme, value => {
   document.documentElement.classList.toggle('dark', value === 'dark')
   document.documentElement.classList.toggle('dark', value === 'dark')
@@ -14,6 +29,8 @@ watch(() => theme.resolvedTheme, value => {
   document.querySelector('meta[name="theme-color"]')?.setAttribute('content', value === 'dark' ? '#181817' : '#f8f8f6')
   document.querySelector('meta[name="theme-color"]')?.setAttribute('content', value === 'dark' ? '#181817' : '#f8f8f6')
 }, { immediate: true })
 }, { immediate: true })
 
 
+watch(pageTitle, value => { document.title = value }, { immediate: true })
+
 onMounted(() => auth.bootstrap())
 onMounted(() => auth.bootstrap())
 </script>
 </script>
 
 

+ 8 - 0
tests/e2e/workspace.spec.ts

@@ -95,6 +95,14 @@ test('navigates every 9119 workspace without blank transitions', async ({ page }
   expect(consoleErrors).toEqual([])
   expect(consoleErrors).toEqual([])
 })
 })
 
 
+test('uses the active session or group title in the browser title', async ({ page }) => {
+  await page.goto('/chat/session-demo?profile=yaoyao')
+  await expect(page).toHaveTitle('夭夭 Web 验收会话 · 夭夭')
+
+  await page.goto('/groups/group-demo')
+  await expect(page).toHaveTitle('设计与工程协作 · 夭夭')
+})
+
 test('edits every protocol v3 Agent setting with one inspector close control', async ({ page }) => {
 test('edits every protocol v3 Agent setting with one inspector close control', async ({ page }) => {
   await page.getByRole('button', { name: '群聊' }).click()
   await page.getByRole('button', { name: '群聊' }).click()
   await expect(page.getByRole('heading', { name: '设计与工程协作' })).toBeVisible()
   await expect(page.getByRole('heading', { name: '设计与工程协作' })).toBeVisible()