From 30a647096dbbb9383300f8852156313fe20dfcc3 Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Mon, 18 Nov 2024 12:13:24 +0100 Subject: [PATCH] fix: add 'Generate summary' button Signed-off-by: Maksim Sukharev --- .../MessagesGroup/Message/Message.vue | 47 ++++++++++++++----- src/services/messagesService.ts | 16 +++++++ src/stores/chatExtras.js | 34 ++++++++++++++ src/types/index.ts | 2 + 4 files changed, 88 insertions(+), 11 deletions(-) diff --git a/src/components/MessagesList/MessagesGroup/Message/Message.vue b/src/components/MessagesList/MessagesGroup/Message/Message.vue index aa8b7894540..999689b72d6 100644 --- a/src/components/MessagesList/MessagesGroup/Message/Message.vue +++ b/src/components/MessagesList/MessagesGroup/Message/Message.vue @@ -60,8 +60,8 @@ :title="t('spreed', 'Show or collapse system messages')" @click="toggleCombinedSystemMessage"> @@ -82,6 +82,13 @@ class="message-unread-marker">
{{ t('spreed', 'Unread messages') }} + + + {{ t('spreed', 'Generate summary') }} +
@@ -90,8 +97,9 @@ diff --git a/src/services/messagesService.ts b/src/services/messagesService.ts index 2387efb8a5f..1650f1834ba 100644 --- a/src/services/messagesService.ts +++ b/src/services/messagesService.ts @@ -26,6 +26,8 @@ import type { receiveMessagesResponse, setReadMarkerParams, setReadMarkerResponse, + summarizeChatParams, + summarizeChatResponse, } from '../types/index.ts' type ReceiveMessagesPayload = Partial & { token: string } @@ -209,6 +211,19 @@ const setConversationUnread = async function(token: string, options?: object): m return axios.delete(generateOcsUrl('apps/spreed/api/v1/chat/{token}/read', { token }, options), options) } +/** + * Request chat summary from a given message + * + * @param token The conversation token + * @param fromMessageId The last read message to start from + * @param options object destructured + */ +const summarizeChat = async function(token: string, fromMessageId: summarizeChatParams['fromMessageId'], options?: object): summarizeChatResponse { + return axios.post(generateOcsUrl('apps/spreed/api/v1/chat/{token}/summarize', { token }, options), { + fromMessageId, + } as summarizeChatParams, options) +} + export { fetchMessages, lookForNewMessages, @@ -220,4 +235,5 @@ export { postRichObjectToConversation, updateLastReadMessage, setConversationUnread, + summarizeChat, } diff --git a/src/stores/chatExtras.js b/src/stores/chatExtras.js index d2c097145c7..e022fd6c61c 100644 --- a/src/stores/chatExtras.js +++ b/src/stores/chatExtras.js @@ -11,6 +11,7 @@ import { generateUrl, getBaseUrl } from '@nextcloud/router' import BrowserStorage from '../services/BrowserStorage.js' import { getUpcomingEvents } from '../services/conversationsService.js' import { EventBus } from '../services/EventBus.ts' +import { summarizeChat } from '../services/messagesService.ts' import { getUserAbsence } from '../services/participantsService.js' import { parseSpecialSymbols, parseMentions } from '../utils/textParse.ts' @@ -41,6 +42,7 @@ export const useChatExtrasStore = defineStore('chatExtras', { chatEditInput: {}, tasksCount: 0, tasksDoneCount: 0, + chatSummary: {}, }), getters: { @@ -61,6 +63,14 @@ export const useChatExtrasStore = defineStore('chatExtras', { getNextEvent: (state) => (token) => { return state.upcomingEvents[token]?.[0] }, + + getChatSummaryTaskQueue: (state) => (token) => { + return Object.values(Object(state.chatSummary[token])) + }, + + hasChatSummaryTaskRequested: (state) => (token) => { + return state.chatSummary[token] !== undefined + }, }, actions: { @@ -246,6 +256,30 @@ export const useChatExtrasStore = defineStore('chatExtras', { setTasksCounters({ tasksCount, tasksDoneCount }) { this.tasksCount = tasksCount this.tasksDoneCount = tasksDoneCount + }, + + async requestChatSummary(token, fromMessageId) { + try { + const response = await summarizeChat(token, fromMessageId) + if (!response.data) { + console.warn('No messages found to summarize:', { token, fromMessageId }) + return + } + const task = response.data.ocs.data + + if (!this.chatSummary[token]) { + Vue.set(this.chatSummary, token, {}) + } + Vue.set(this.chatSummary[token], fromMessageId, { + ...task, + fromMessageId, + }) + if (task.nextOffset && task.nextOffset !== fromMessageId) { + await this.requestChatSummary(token, task.nextOffset) + } + } catch (error) { + console.error('Error while requesting a summary:', error) + } } }, }) diff --git a/src/types/index.ts b/src/types/index.ts index b4a16c22169..8e2a819c8fa 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -96,6 +96,8 @@ export type postRichObjectResponse = ApiResponse['requestBody']['content']['application/json'] export type setReadMarkerResponse = ApiResponse export type markUnreadResponse = ApiResponse +export type summarizeChatParams = operations['chat-summarize-chat']['requestBody']['content']['application/json'] +export type summarizeChatResponse = ApiResponse // Avatars export type setFileAvatarResponse = ApiResponse