parent
06f41c3758
commit
c98a2a3cb8
|
@ -8,6 +8,7 @@ import { useChat } from './hooks/useChat'
|
|||
import { fetchChatAPI } from '@/api'
|
||||
import { HoverButton, SvgIcon } from '@/components/common'
|
||||
import { useHistoryStore } from '@/store'
|
||||
import { useBasicLayout } from '@/hooks/useBasicLayout'
|
||||
|
||||
let controller = new AbortController()
|
||||
|
||||
|
@ -15,6 +16,8 @@ const ms = useMessage()
|
|||
|
||||
const historyStore = useHistoryStore()
|
||||
|
||||
const { isMobile } = useBasicLayout()
|
||||
|
||||
let messageReactive: MessageReactive | null = null
|
||||
|
||||
const scrollRef = ref<HTMLDivElement>()
|
||||
|
@ -30,6 +33,12 @@ const heartbeat = computed(() => historyStore.heartbeat)
|
|||
const list = computed<Chat.Chat[]>(() => historyStore.getCurrentChat)
|
||||
const chatList = computed<Chat.Chat[]>(() => list.value.filter(item => (!item.reversal && !item.error)))
|
||||
|
||||
const footerMobileStyle = computed(() => {
|
||||
if (isMobile.value)
|
||||
return ['pl-2', 'pt-2', 'pb-6', 'fixed', 'bottom-0', 'left-0', 'right-0', 'z-30']
|
||||
return []
|
||||
})
|
||||
|
||||
async function handleSubmit() {
|
||||
if (loading.value)
|
||||
return
|
||||
|
@ -143,7 +152,11 @@ watch(
|
|||
<Layout>
|
||||
<div class="flex flex-col h-full">
|
||||
<main class="flex-1 overflow-hidden">
|
||||
<div ref="scrollRef" class="h-full p-4 overflow-hidden overflow-y-auto">
|
||||
<div
|
||||
ref="scrollRef"
|
||||
class="h-full p-4 overflow-hidden overflow-y-auto"
|
||||
:class="[{ 'p-2': isMobile }]"
|
||||
>
|
||||
<template v-if="!list.length">
|
||||
<div class="flex items-center justify-center mt-4 text-center text-neutral-300">
|
||||
<SvgIcon icon="ri:bubble-chart-fill" class="mr-2 text-3xl" />
|
||||
|
@ -153,21 +166,32 @@ watch(
|
|||
<template v-else>
|
||||
<div>
|
||||
<Message
|
||||
v-for="(item, index) of list" :key="index" :date-time="item.dateTime" :message="item.message"
|
||||
:reversal="item.reversal" :error="item.error"
|
||||
v-for="(item, index) of list"
|
||||
:key="index"
|
||||
:date-time="item.dateTime"
|
||||
:message="item.message"
|
||||
:reversal="item.reversal"
|
||||
:error="item.error"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</main>
|
||||
<footer class="p-4">
|
||||
<footer
|
||||
class="p-4"
|
||||
:class="footerMobileStyle"
|
||||
>
|
||||
<div class="flex items-center justify-between space-x-2">
|
||||
<HoverButton tooltip="Clear conversations">
|
||||
<span class="text-xl text-[#4f555e]" @click="handleClear">
|
||||
<SvgIcon icon="ri:delete-bin-line" />
|
||||
</span>
|
||||
</HoverButton>
|
||||
<NInput v-model:value="prompt" placeholder="Type a message..." @keypress="handleEnter" />
|
||||
<NInput
|
||||
v-model:value="prompt"
|
||||
placeholder="Type a message..."
|
||||
@keypress="handleEnter"
|
||||
/>
|
||||
<NButton type="primary" :disabled="loading" @click="handleSubmit">
|
||||
<template #icon>
|
||||
<SvgIcon icon="ri:send-plane-fill" />
|
||||
|
|
|
@ -22,13 +22,14 @@ const getContainerClass = computed(() => {
|
|||
return [
|
||||
'h-full',
|
||||
{ 'pt-14': isMobile.value },
|
||||
{ 'pb-[70px]': isMobile.value },
|
||||
{ 'pl-[260px]': !isMobile.value && !collapsed.value },
|
||||
]
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-screen p-4" :class="[{ 'p-0': isMobile }]">
|
||||
<div class="h-screen" :class="[isMobile ? 'p-0' : 'p-4']">
|
||||
<div class="h-full overflow-hidden" :class="getMobileClass">
|
||||
<NLayout class="z-40 transition" :class="getContainerClass" has-sider>
|
||||
<Sider />
|
||||
|
|
|
@ -23,7 +23,7 @@ function handleUpdateCollapsed() {
|
|||
|
||||
<template>
|
||||
<header class="fixed top-0 left-0 right-0 z-50 border-b bg-white/80 backdrop-blur">
|
||||
<div class="relative flex items-center justify-between px-4 h-14">
|
||||
<div class="relative flex items-center justify-between h-14">
|
||||
<button class="flex items-center justify-center w-11 h-11" @click="handleUpdateCollapsed">
|
||||
<SvgIcon v-if="collapsed" class="text-2xl" icon="ri:align-justify" />
|
||||
<SvgIcon v-else class="text-2xl" icon="ri:align-right" />
|
||||
|
|
|
@ -29,7 +29,10 @@ watch(
|
|||
(val) => {
|
||||
appStore.setSiderCollapsed(val)
|
||||
},
|
||||
{ flush: 'post' },
|
||||
{
|
||||
immediate: true,
|
||||
flush: 'post',
|
||||
},
|
||||
)
|
||||
</script>
|
||||
|
||||
|
@ -42,6 +45,7 @@ watch(
|
|||
collapse-mode="transform"
|
||||
position="absolute"
|
||||
bordered
|
||||
style="z-index: 50;"
|
||||
@update-collapsed="handleUpdateCollapsed"
|
||||
>
|
||||
<div class="flex flex-col h-full" :class="[{ 'pt-14': isMobile }]">
|
||||
|
@ -63,4 +67,7 @@ watch(
|
|||
</footer>
|
||||
</div>
|
||||
</NLayoutSider>
|
||||
<template v-if="isMobile">
|
||||
<div v-show="!collapsed" class="absolute inset-0 z-40 bg-black/40" @click="handleUpdateCollapsed" />
|
||||
</template>
|
||||
</template>
|
||||
|
|
Loading…
Reference in New Issue