diff --git a/apps/frontend/auto-imports.d.ts b/apps/frontend/auto-imports.d.ts index 6192ef841..40adc8659 100644 --- a/apps/frontend/auto-imports.d.ts +++ b/apps/frontend/auto-imports.d.ts @@ -31,7 +31,7 @@ declare global { const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable'] const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise'] const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn'] - const createWebsocketV2Context: typeof import('./src/composables/useWebsocket')['createWebsocketV2Context'] + const createWebsocketV2Context: typeof import('./src/composables/useWebsocketV2')['createWebsocketV2Context'] const customRef: typeof import('vue')['customRef'] const debouncedRef: typeof import('@vueuse/core')['debouncedRef'] const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch'] @@ -307,6 +307,7 @@ declare global { const useWebWorker: typeof import('@vueuse/core')['useWebWorker'] const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn'] const useWebsocket: typeof import('./src/composables/useWebsocket')['useWebsocket'] + const useWebsocketV2: typeof import('./src/composables/useWebsocketV2')['useWebsocketV2'] const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus'] const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll'] const useWindowSize: typeof import('@vueuse/core')['useWindowSize'] @@ -338,6 +339,9 @@ declare global { // @ts-ignore export type { ClientSendEventFn, ClientCreateWsMessageFn } from './src/composables/useWebsocket' import('./src/composables/useWebsocket') + // @ts-ignore + export type { WsEventHandler, WsRegisterEventHandler } from './src/composables/useWebsocketV2' + import('./src/composables/useWebsocketV2') } // for vue template auto import @@ -365,7 +369,7 @@ declare module 'vue' { readonly createSharedComposable: UnwrapRef readonly createTemplatePromise: UnwrapRef readonly createUnrefFn: UnwrapRef - readonly createWebsocketV2Context: UnwrapRef + readonly createWebsocketV2Context: UnwrapRef readonly customRef: UnwrapRef readonly debouncedRef: UnwrapRef readonly debouncedWatch: UnwrapRef @@ -616,6 +620,7 @@ declare module 'vue' { readonly useWebWorker: UnwrapRef readonly useWebWorkerFn: UnwrapRef readonly useWebsocket: UnwrapRef + readonly useWebsocketV2: UnwrapRef readonly useWindowFocus: UnwrapRef readonly useWindowScroll: UnwrapRef readonly useWindowSize: UnwrapRef diff --git a/apps/frontend/components.d.ts b/apps/frontend/components.d.ts index 19e61ca98..62707a7ca 100644 --- a/apps/frontend/components.d.ts +++ b/apps/frontend/components.d.ts @@ -9,23 +9,32 @@ export {} declare module 'vue' { export interface GlobalComponents { AlertCard: typeof import('./src/components/ui/AlertCard.vue')['default'] + ChatGroup: typeof import('./src/components/ui/ChatGroup.vue')['default'] ChatSelector: typeof import('./src/components/ChatSelector.vue')['default'] CheckboxGroup: typeof import('./src/components/ui/CheckboxGroup.vue')['default'] + ComposeMessage: typeof import('./src/components/ui/ComposeMessage.vue')['default'] Dialog: typeof import('./src/components/ui/Dialog.vue')['default'] DropdownMenu: typeof import('./src/components/ui/DropdownMenu.vue')['default'] + ForwardMessage: typeof import('./src/components/ui/ForwardMessage.vue')['default'] HighlightText: typeof import('./src/components/ui/HighlightText.vue')['default'] IconButton: typeof import('./src/components/ui/IconButton.vue')['default'] + ImageMessage: typeof import('./src/components/ui/ImageMessage.vue')['default'] LoadingButton: typeof import('./src/components/ui/LoadingButton.vue')['default'] + MessageItem: typeof import('./src/components/ui/MessageItem.vue')['default'] Pagination: typeof import('./src/components/ui/Pagination.vue')['default'] ProgressBar: typeof import('./src/components/ui/ProgressBar.vue')['default'] RadioGroup: typeof import('./src/components/ui/RadioGroup.vue')['default'] + RefMessage: typeof import('./src/components/ui/RefMessage.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] SearchSelect: typeof import('./src/components/ui/SearchSelect.vue')['default'] SelectDropdown: typeof import('./src/components/ui/SelectDropdown.vue')['default'] + Settings: typeof import('./src/components/ui/Settings.vue')['default'] + SlotButton: typeof import('./src/components/ui/SlotButton.vue')['default'] StatusBadge: typeof import('./src/components/ui/StatusBadge.vue')['default'] StepIndicator: typeof import('./src/components/ui/StepIndicator.vue')['default'] Switch: typeof import('./src/components/ui/Switch.vue')['default'] + TextMessage: typeof import('./src/components/ui/TextMessage.vue')['default'] ThemeToggle: typeof import('./src/components/ThemeToggle.vue')['default'] } } diff --git a/apps/frontend/src/App.vue b/apps/frontend/src/App.vue index 2017feb9b..6621dc017 100644 --- a/apps/frontend/src/App.vue +++ b/apps/frontend/src/App.vue @@ -8,7 +8,9 @@ import DefaultLayout from './layouts/default.vue'
- +
diff --git a/apps/frontend/src/components/ChatSelector.vue b/apps/frontend/src/components/ChatSelector.vue index 587d0b5b9..04ca960bc 100644 --- a/apps/frontend/src/components/ChatSelector.vue +++ b/apps/frontend/src/components/ChatSelector.vue @@ -105,7 +105,7 @@ watch([selectedType, searchQuery], () => { @@ -118,20 +118,20 @@ watch([selectedType, searchQuery], () => { :key="chat.id" class="relative w-full flex active:scale-98 cursor-pointer items-center border rounded-lg p-4 text-left transition-all duration-300 space-x-3 hover:shadow-md hover:-translate-y-0.5" :class="{ - 'border-blue-500 bg-blue-50 dark:bg-blue-900/20 shadow-md scale-102': isSelected(chat.id), - 'border-gray-200 dark:border-gray-700 hover:border-blue-300 dark:hover:border-blue-600': !isSelected(chat.id), + 'border-primary bg-primary/10 shadow-md scale-102': isSelected(chat.id), + 'border-secondary hover:border-primary': !isSelected(chat.id), }" @click="toggleSelection(chat.id)" >
-

+

{{ chat.title }} - +

-

+

{{ chat.subtitle }}

@@ -148,7 +148,7 @@ watch([selectedType, searchQuery], () => { /> -
+
No chats found
diff --git a/apps/frontend/src/components/ui/ChatGroup.vue b/apps/frontend/src/components/ui/ChatGroup.vue new file mode 100644 index 000000000..55091556f --- /dev/null +++ b/apps/frontend/src/components/ui/ChatGroup.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/apps/frontend/src/components/ui/ComposeMessage.vue b/apps/frontend/src/components/ui/ComposeMessage.vue new file mode 100644 index 000000000..378e4da16 --- /dev/null +++ b/apps/frontend/src/components/ui/ComposeMessage.vue @@ -0,0 +1,24 @@ + + + diff --git a/apps/frontend/src/components/ui/Dialog.vue b/apps/frontend/src/components/ui/Dialog.vue index a3e8f29a4..60927c32c 100644 --- a/apps/frontend/src/components/ui/Dialog.vue +++ b/apps/frontend/src/components/ui/Dialog.vue @@ -13,6 +13,7 @@ const emit = defineEmits<{ const dialogRef = ref(null) const contentRef = ref(null) +const isVisible = ref(false) const isOpen = computed({ get: () => props.modelValue, @@ -39,7 +40,7 @@ function closeWithAnimation() { contentRef.value.classList.add('dialog-content-leave') setTimeout(() => { isOpen.value = false - }, 200) + }, 100) } else { isOpen.value = false @@ -60,6 +61,7 @@ function enableScroll() { watch(isOpen, (value) => { if (value) { + isVisible.value = true disableScroll() // 打开时重置动画类 if (contentRef.value) { @@ -67,6 +69,9 @@ watch(isOpen, (value) => { } } else { + setTimeout(() => { + isVisible.value = false + }, 100) enableScroll() } }) @@ -83,74 +88,64 @@ onUnmounted(() => { diff --git a/apps/frontend/src/pages/[...all].vue b/apps/frontend/src/pages/[...all].vue index 9ece676ac..7988da764 100644 --- a/apps/frontend/src/pages/[...all].vue +++ b/apps/frontend/src/pages/[...all].vue @@ -1,19 +1,19 @@