diff --git a/new-client/src/app/bootstrap/signaling.ts b/new-client/src/app/bootstrap/signaling.ts index 6dbf940..c866853 100644 --- a/new-client/src/app/bootstrap/signaling.ts +++ b/new-client/src/app/bootstrap/signaling.ts @@ -4,6 +4,7 @@ import { useClients } from '@shared/composables/use-clients' import { useEventBus } from '@shared/composables/use-event-bus.ts' import { useSignaling } from '@shared/composables/use-signaling' import { watch, watchEffect } from 'vue' +import { queryClient } from '../plugins/tanstack-query' export default function () { const { authorized } = useAuth() @@ -33,8 +34,9 @@ export default function () { removeClient(socketId) }) - socket.on('disconnect', () => { + socket.on('disconnect', async () => { clearClients() + await queryClient.resetQueries() }) socket.on('chat:new-message', (message: ChatMessage) => { diff --git a/new-client/src/app/plugins/tanstack-query.ts b/new-client/src/app/plugins/tanstack-query.ts index ea934de..f7cf4ec 100644 --- a/new-client/src/app/plugins/tanstack-query.ts +++ b/new-client/src/app/plugins/tanstack-query.ts @@ -1,8 +1,18 @@ import type { FunctionPlugin } from 'vue' -import { VueQueryPlugin } from '@tanstack/vue-query' +import { QueryClient, VueQueryPlugin } from '@tanstack/vue-query' + +export const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, +}) export default { install(app) { - app.use(VueQueryPlugin, {}) + app.use(VueQueryPlugin, { + queryClient, + }) }, } as FunctionPlugin diff --git a/new-client/src/widgets/chat/composables/use-chat-scroll.ts b/new-client/src/widgets/chat/composables/use-chat-scroll.ts index b8da78c..490f057 100644 --- a/new-client/src/widgets/chat/composables/use-chat-scroll.ts +++ b/new-client/src/widgets/chat/composables/use-chat-scroll.ts @@ -35,7 +35,7 @@ export function useChatScroll(target: TemplateRef, options?: MaybeR getArrivedState() }, { childList: true, - // subtree: true, + subtree: true, }) useEventListener(el, 'scroll', () => { diff --git a/new-client/src/widgets/chat/composables/use-chat.ts b/new-client/src/widgets/chat/composables/use-chat.ts index bc34fed..8657dfe 100644 --- a/new-client/src/widgets/chat/composables/use-chat.ts +++ b/new-client/src/widgets/chat/composables/use-chat.ts @@ -1,16 +1,21 @@ import type { ChatMessage } from '@shared/api/generated-chad-api.ts' import { useSignaling } from '@shared/composables/use-signaling' import { createGlobalState } from '@vueuse/core' -import { shallowRef, triggerRef, watch } from 'vue' +import { computed, shallowRef, triggerRef, watch } from 'vue' import { qChatMessages } from '../api/qChatMessages.ts' +export interface MessageGroup { + senderUsername: string + messages: ChatMessage[] +} + export const useChat = createGlobalState(() => { const { data: messages, hasNextPage: hasMoreMessages, fetchNextPage, isFetching } = qChatMessages() const { socket, connected } = useSignaling() const feedItems = shallowRef([]) - watch(connected, (isConnected) => { + watch(connected, async (isConnected) => { if (!isConnected) return @@ -20,5 +25,17 @@ export const useChat = createGlobalState(() => { }) }) - return { messages, feedItems, hasMoreMessages, fetchNextPage, isFetching } + const messageGroups = computed(() => { + const all = [...(messages.value ?? []), ...feedItems.value] + return all.reduce((groups, msg) => { + const last = groups.at(-1) + if (last?.senderUsername === msg.senderUsername) + last.messages.push(msg) + else + groups.push({ senderUsername: msg.senderUsername, messages: [msg] }) + return groups + }, [] as MessageGroup[]) + }) + + return { messageGroups, hasMoreMessages, fetchNextPage, isFetching } }) diff --git a/new-client/src/widgets/chat/ui/ChatMessage.vue b/new-client/src/widgets/chat/ui/ChatMessage.vue index b4a6393..b43b886 100644 --- a/new-client/src/widgets/chat/ui/ChatMessage.vue +++ b/new-client/src/widgets/chat/ui/ChatMessage.vue @@ -1,30 +1,25 @@