修复聊天信息聚合问题
This commit is contained in:
@@ -26,6 +26,7 @@ const menuX = ref(0)
|
|||||||
const menuY = ref(0)
|
const menuY = ref(0)
|
||||||
const topThreshold = 8
|
const topThreshold = 8
|
||||||
const bottomThreshold = 40
|
const bottomThreshold = 40
|
||||||
|
const scrollOverflowAllowance = 1
|
||||||
|
|
||||||
const groupedMessages = computed<GroupedTextMessage[]>(() => {
|
const groupedMessages = computed<GroupedTextMessage[]>(() => {
|
||||||
const groups = new Map<string, GroupedTextMessage>()
|
const groups = new Map<string, GroupedTextMessage>()
|
||||||
@@ -102,25 +103,29 @@ function handleKeydown(event: KeyboardEvent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleScroll() {
|
function loadOlderFromCurrentScroll(el: HTMLElement) {
|
||||||
closeMessageMenu()
|
|
||||||
const el = panelRef.value
|
|
||||||
if (
|
if (
|
||||||
!el ||
|
|
||||||
props.loadingOlder ||
|
props.loadingOlder ||
|
||||||
!props.hasMoreMessages ||
|
!props.hasMoreMessages ||
|
||||||
props.messages.length === 0 ||
|
groupedMessages.value.length === 0 ||
|
||||||
restoreScrollHeight != null
|
restoreScrollHeight != null
|
||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el.scrollTop <= topThreshold) {
|
restoreScrollHeight = el.scrollHeight
|
||||||
restoreScrollHeight = el.scrollHeight
|
restoreScrollTop = el.scrollTop
|
||||||
restoreScrollTop = el.scrollTop
|
restoreMessageCount = groupedMessages.value.length
|
||||||
restoreMessageCount = props.messages.length
|
emit('load-older')
|
||||||
emit('load-older')
|
}
|
||||||
|
|
||||||
|
function handleScroll() {
|
||||||
|
closeMessageMenu()
|
||||||
|
const el = panelRef.value
|
||||||
|
if (!el || el.scrollTop > topThreshold) {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
loadOlderFromCurrentScroll(el)
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeUpdate(() => {
|
onBeforeUpdate(() => {
|
||||||
@@ -138,6 +143,9 @@ onMounted(async () => {
|
|||||||
if (el) {
|
if (el) {
|
||||||
el.scrollTop = el.scrollHeight
|
el.scrollTop = el.scrollHeight
|
||||||
didInitialScroll = true
|
didInitialScroll = true
|
||||||
|
if (el.scrollHeight <= el.clientHeight + scrollOverflowAllowance) {
|
||||||
|
loadOlderFromCurrentScroll(el)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -153,7 +161,7 @@ onUpdated(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (restoreScrollHeight != null) {
|
if (restoreScrollHeight != null) {
|
||||||
if (props.messages.length > restoreMessageCount) {
|
if (groupedMessages.value.length > restoreMessageCount) {
|
||||||
el.scrollTop = el.scrollHeight - restoreScrollHeight + restoreScrollTop
|
el.scrollTop = el.scrollHeight - restoreScrollHeight + restoreScrollTop
|
||||||
clearRestoreState()
|
clearRestoreState()
|
||||||
return
|
return
|
||||||
@@ -167,6 +175,10 @@ onUpdated(() => {
|
|||||||
el.scrollTop = el.scrollHeight
|
el.scrollTop = el.scrollHeight
|
||||||
didInitialScroll = true
|
didInitialScroll = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (el.scrollHeight <= el.clientHeight + scrollOverflowAllowance) {
|
||||||
|
loadOlderFromCurrentScroll(el)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const chatHasMore = ref(true)
|
|||||||
const error = ref('')
|
const error = ref('')
|
||||||
const chatPageSize = 20
|
const chatPageSize = 20
|
||||||
const chatHistoryRef = ref<HTMLElement | null>(null)
|
const chatHistoryRef = ref<HTMLElement | null>(null)
|
||||||
|
const scrollOverflowAllowance = 1
|
||||||
type GroupedTextMessage = TextMessage & { mergedCount: number; mergedMessages: TextMessage[] }
|
type GroupedTextMessage = TextMessage & { mergedCount: number; mergedMessages: TextMessage[] }
|
||||||
type PendingDeleteAction =
|
type PendingDeleteAction =
|
||||||
| { kind: 'delete-message'; message: GroupedTextMessage }
|
| { kind: 'delete-message'; message: GroupedTextMessage }
|
||||||
@@ -186,24 +187,30 @@ async function loadInitialMessages() {
|
|||||||
const el = chatHistoryRef.value
|
const el = chatHistoryRef.value
|
||||||
if (el) {
|
if (el) {
|
||||||
el.scrollTop = el.scrollHeight
|
el.scrollTop = el.scrollHeight
|
||||||
|
await loadMoreUntilScrollable(el)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadOlderMessages() {
|
async function loadOlderMessages() {
|
||||||
|
const el = chatHistoryRef.value
|
||||||
|
await loadOlderMessagesFromCurrentScroll(el)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadOlderMessagesFromCurrentScroll(el: HTMLElement | null) {
|
||||||
if (chatLoadingOlder.value || !chatHasMore.value) {
|
if (chatLoadingOlder.value || !chatHasMore.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const el = chatHistoryRef.value
|
|
||||||
const previousScrollHeight = el?.scrollHeight ?? 0
|
const previousScrollHeight = el?.scrollHeight ?? 0
|
||||||
const previousScrollTop = el?.scrollTop ?? 0
|
const previousScrollTop = el?.scrollTop ?? 0
|
||||||
|
const previousGroupedMessageCount = groupedMessages.value.length
|
||||||
chatLoadingOlder.value = true
|
chatLoadingOlder.value = true
|
||||||
try {
|
try {
|
||||||
const response = await getTextMessages(chatPageSize, messages.value.length, props.nodeId)
|
const response = await getTextMessages(chatPageSize, messages.value.length, props.nodeId)
|
||||||
messages.value = mergeMessages(messages.value, toChronological(response.items))
|
messages.value = mergeMessages(messages.value, toChronological(response.items))
|
||||||
chatHasMore.value = response.items.length === chatPageSize
|
chatHasMore.value = response.items.length === chatPageSize
|
||||||
await nextTick()
|
await nextTick()
|
||||||
if (el) {
|
if (el && groupedMessages.value.length > previousGroupedMessageCount) {
|
||||||
el.scrollTop = el.scrollHeight - previousScrollHeight + previousScrollTop
|
el.scrollTop = el.scrollHeight - previousScrollHeight + previousScrollTop
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -213,6 +220,16 @@ async function loadOlderMessages() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadMoreUntilScrollable(el: HTMLElement) {
|
||||||
|
while (chatHasMore.value && el.scrollHeight <= el.clientHeight + scrollOverflowAllowance) {
|
||||||
|
const previousGroupedMessageCount = groupedMessages.value.length
|
||||||
|
await loadOlderMessagesFromCurrentScroll(el)
|
||||||
|
if (groupedMessages.value.length <= previousGroupedMessageCount) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function closeMessageMenu() {
|
function closeMessageMenu() {
|
||||||
menuMessage.value = null
|
menuMessage.value = null
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user