mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 23:56:42 +08:00
fix message ui
This commit is contained in:
@@ -41,8 +41,10 @@ const chatContainer = ref<HTMLDivElement>()
|
|||||||
// 滚动到底部
|
// 滚动到底部
|
||||||
function scrollMessageToEnd() {
|
function scrollMessageToEnd() {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (chatContainer.value)
|
if (chatContainer.value) {
|
||||||
chatContainer.value.scrollTop = chatContainer.value.scrollHeight
|
const scrollDiv = chatContainer.value.$el
|
||||||
|
scrollDiv.scrollTop = scrollDiv.scrollHeight
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,6 +335,7 @@ onMounted(() => {
|
|||||||
single-line
|
single-line
|
||||||
clearable
|
clearable
|
||||||
density="compact"
|
density="compact"
|
||||||
|
:disabled="sendButtonDisabled"
|
||||||
@keydown.enter="sendMessage"
|
@keydown.enter="sendMessage"
|
||||||
>
|
>
|
||||||
<template #append>
|
<template #append>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import MessageCard from '@/components/cards/MessageCard.vue'
|
|
||||||
import type { Message } from '@/api/types'
|
import type { Message } from '@/api/types'
|
||||||
|
import MessageCard from '@/components/cards/MessageCard.vue'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
|
|
||||||
// 定义事件
|
// 定义事件
|
||||||
@@ -9,10 +9,18 @@ const emit = defineEmits(['scroll'])
|
|||||||
|
|
||||||
// 消息列表
|
// 消息列表
|
||||||
const messages = ref<Message[]>([])
|
const messages = ref<Message[]>([])
|
||||||
|
// 当前页数据
|
||||||
|
const currData = ref<Message[]>([])
|
||||||
|
|
||||||
// 是否完成加载
|
// 是否完成加载
|
||||||
const isLoaded = ref(false)
|
const isLoaded = ref(false)
|
||||||
|
|
||||||
|
// 是否加载中
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 当前页码
|
||||||
|
const page = ref(1)
|
||||||
|
|
||||||
// SSE持续获取消息
|
// SSE持续获取消息
|
||||||
function startSSEMessager() {
|
function startSSEMessager() {
|
||||||
const token = store.state.auth.token
|
const token = store.state.auth.token
|
||||||
@@ -38,13 +46,36 @@ function startSSEMessager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 调用API加载存量消息
|
// 调用API加载存量消息
|
||||||
async function loadMessages() {
|
async function loadMessages({ done }: { done: any }) {
|
||||||
|
// 如果正在加载中,直接返回
|
||||||
|
if (loading.value) {
|
||||||
|
done('ok')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 设置加载中
|
||||||
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
messages.value = await api.get('message/web')
|
currData.value = await api.get('message/web', {
|
||||||
if (messages.value.length > 0) {
|
params: {
|
||||||
isLoaded.value = true
|
page: page.value,
|
||||||
|
size: 20,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if (currData.value.length > 0) {
|
||||||
|
// 合并数据
|
||||||
|
messages.value = [...currData.value, ...messages.value]
|
||||||
|
// 页码+1
|
||||||
|
page.value++
|
||||||
|
// 加载完成
|
||||||
|
done('ok')
|
||||||
|
// 滚动到底部
|
||||||
emit('scroll')
|
emit('scroll')
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
done('ok')
|
||||||
|
}
|
||||||
|
loading.value = false
|
||||||
|
isLoaded.value = true
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
@@ -52,50 +83,65 @@ async function loadMessages() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 加载存量消息
|
|
||||||
loadMessages()
|
|
||||||
// 监听新消息
|
// 监听新消息
|
||||||
startSSEMessager()
|
startSSEMessager()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<VInfiniteScroll
|
||||||
v-if="!isLoaded"
|
mode="intersect"
|
||||||
class="mt-5 w-full text-center flex flex-col items-center"
|
side="start"
|
||||||
|
:items="messages"
|
||||||
|
class="overflow-hidden"
|
||||||
|
@load="loadMessages"
|
||||||
>
|
>
|
||||||
<VProgressCircular
|
<template #loading>
|
||||||
size="48"
|
<VProgressCircular
|
||||||
indeterminate
|
v-if="loading"
|
||||||
color="primary"
|
indeterminate
|
||||||
/>
|
size="48"
|
||||||
<span class="mt-3">正在刷新 ...</span>
|
class="mb-5"
|
||||||
</div>
|
color="primary"
|
||||||
<div
|
/>
|
||||||
v-if="messages.length === 0 && isLoaded"
|
</template>
|
||||||
class="w-full text-center flex flex-col items-center"
|
<div>
|
||||||
>
|
<VRow
|
||||||
<span class="mb-3">当前没有消息</span>
|
v-for="(msg, index) in messages"
|
||||||
</div>
|
:key="index"
|
||||||
<div>
|
:class="{
|
||||||
<VRow
|
'justify-end': msg.action === 0,
|
||||||
v-for="(msg, index) in messages"
|
'justify-start': msg.action === 1,
|
||||||
:key="index"
|
}"
|
||||||
:class="{
|
|
||||||
'justify-end': msg.action === 0,
|
|
||||||
'justify-start': msg.action === 1,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<VCol
|
|
||||||
cols="10"
|
|
||||||
lg="6"
|
|
||||||
xl="4"
|
|
||||||
style="position: relative;"
|
|
||||||
>
|
>
|
||||||
<MessageCard
|
<VCol
|
||||||
:message="msg"
|
cols="10"
|
||||||
/>
|
lg="6"
|
||||||
</VCol>
|
xl="4"
|
||||||
</VRow>
|
style="position: relative;"
|
||||||
</div>
|
>
|
||||||
|
<MessageCard
|
||||||
|
:message="msg"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="!isLoaded"
|
||||||
|
class="mt-5 w-full text-center flex flex-col items-center"
|
||||||
|
>
|
||||||
|
<VProgressCircular
|
||||||
|
size="48"
|
||||||
|
indeterminate
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
<span class="mt-3">正在刷新 ...</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="messages.length === 0 && isLoaded"
|
||||||
|
class="w-full text-center flex flex-col items-center"
|
||||||
|
>
|
||||||
|
<span class="mb-3">当前没有消息</span>
|
||||||
|
</div>
|
||||||
|
</VInfiniteScroll>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user