refactored chat into separate chat_view and chat_message_list

This commit is contained in:
Henry Jameson 2026-07-07 20:44:13 +03:00
commit 55917125a8
12 changed files with 127 additions and 96 deletions

View file

@ -0,0 +1,76 @@
import { throttle, orderBy, uniqueId } from 'lodash'
import { mapState as mapPiniaState } from 'pinia'
import { mapGetters, mapState } from 'vuex'
import ChatMessage from 'src/components/chat_message/chat_message.vue'
const ChatMessageList = {
components: {
ChatMessage,
},
props: {
messages: Array,
},
data() {
return {
hoveredMessageChainId: undefined,
}
},
computed: {
chatItems() {
const messages = orderBy(this.messages, ['pending', 'id'], ['asc', 'asc'])
return messages.reduceRight((acc, message, index) => {
const date = new Date(message.created_at)
const olderMessage = messages[index - 1]
const newerMessage = messages[index + 1]
const newerItem = acc[acc.length - 1]
const diff = message.created_at - (olderMessage?.created_at || 0)
const MAX_DIFF = 1000 * 60 // 5 minutes
const chatItem = {
type: 'message',
data: message,
date,
id: message.id,
isTail: true,
isHead: true,
}
if (newerItem == null) {
chatItem.messageChainId = uniqueId()
} else {
if (newerItem.type === 'date') {
chatItem.messageChainId = uniqueId()
} else if (newerItem.type === 'message') {
if (newerItem.data.account_id !== message.account_id) {
chatItem.messageChainId = uniqueId()
} else {
chatItem.messageChainId = newerItem.messageChainId
chatItem.isTail = false
newerItem.isHead = false
}
}
}
if (diff > MAX_DIFF || !olderMessage) {
return [...acc, chatItem, {
type: 'date',
date,
id: date.getTime().toString(),
}]
} else {
return [...acc, chatItem]
}
}, []).reverse()
}
},
methods: {
onMessageHover({ isHovered, messageChainId }) {
this.hoveredMessageChainId = isHovered ? messageChainId : undefined
},
}
}
export default ChatMessageList

View file

@ -0,0 +1,7 @@
.ChatMessageList {
padding: 0 0.8em;
height: 100%;
display: flex;
flex-direction: column;
justify-content: end;
}

View file

@ -0,0 +1,14 @@
<template>
<div class="ChatMessageList">
<ChatMessage
v-for="chatItem in chatItems"
:key="chatItem.id"
:chat-item="chatItem"
:hovered-message-chain="chatItem.messageChainId === hoveredMessageChainId"
@hover="onMessageHover"
/>
</div>
</template>
<script src="./chat_message_list.js"></script>
<style src="./chat_message_list.scss" lang="scss" />