From 6d1c06dc7951327d2497f498d0518b367413c108 Mon Sep 17 00:00:00 2001 From: jordan-ae Date: Thu, 19 Dec 2024 15:48:24 +0100 Subject: [PATCH 1/3] feat: update title change --- src/people/hiveChat/index.tsx | 50 ++++++++++++++++++++++++++++++++++- src/services/index.ts | 33 +++++++++++++++++++++++ src/store/chat.ts | 10 +++++++ 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/people/hiveChat/index.tsx b/src/people/hiveChat/index.tsx index 38fd8b8a..98948b8e 100644 --- a/src/people/hiveChat/index.tsx +++ b/src/people/hiveChat/index.tsx @@ -8,6 +8,7 @@ import { SOCKET_MSG } from 'config/socket'; import styled from 'styled-components'; import { EuiLoadingSpinner } from '@elastic/eui'; import MaterialIcon from '@material/react-material-icon'; +import { chatHistoryStore } from 'store/chat.ts'; import { renderMarkdown } from '../utils/RenderMarkdown.tsx'; interface RouteParams { @@ -169,6 +170,7 @@ export const HiveChatView: React.FC = observer(() => { const [title, setTitle] = useState('Talk to Hive - Chat'); const history = useHistory(); const socketRef = useRef(null); + const [isUpdatingTitle, setIsUpdatingTitle] = useState(false); const handleBackClick = () => { history.push(`/workspace/${uuid}`); @@ -192,6 +194,33 @@ export const HiveChatView: React.FC = observer(() => { } }, [chat, chatId, ui]); + const updateChatTitle = async (chatId: string, uuid: string, newTitle: string, setIsUpdatingTitle: (status: boolean) => void): Promise => { + if (!chatId || !uuid || !newTitle.trim()) return; + + setIsUpdatingTitle(true); + try { + console.log(newTitle); + chatHistoryStore.updateChatTitle(chatId, newTitle); + ui.setToasts([ + { + title: 'Success', + text: 'Chat Title Updated', + }, + ]); + } catch (error) { + console.error('Error updating chat title:', error); + ui.setToasts([ + { + title: 'Error', + color: 'danger', + text: 'Failed to update chat title', + }, + ]); + } finally { + setIsUpdatingTitle(false); + } + }; + useEffect(() => { const initializeChat = async () => { setLoading(true); @@ -210,6 +239,21 @@ export const HiveChatView: React.FC = observer(() => { initializeChat(); }, [chatId, chat]); + let debounceUpdateTitle: ReturnType; + const handleTitleChange = (chatId: string, uuid: string, title: string, setIsUpdatingTitle: (status: boolean) => void) => { + clearTimeout(debounceUpdateTitle); + + debounceUpdateTitle = setTimeout(() => { + updateChatTitle(chatId, uuid, title, setIsUpdatingTitle); + }, 500); + }; + + const onTitleChange = (event: React.ChangeEvent) => { + const newTitle = event.target.value; + setTitle(newTitle); + handleTitleChange(chatId, uuid, newTitle, setIsUpdatingTitle); + }; + useEffect(() => { const socket = createSocketInstance(); socketRef.current = socket; @@ -365,8 +409,12 @@ export const HiveChatView: React.FC = observer(() => { /> ) => setTitle(e.target.value)} + onChange={onTitleChange} placeholder="Enter chat title..." + disabled={isUpdatingTitle} + style={{ + cursor: isUpdatingTitle ? 'not-allowed' : 'text', + }} /> diff --git a/src/services/index.ts b/src/services/index.ts index 1990ec42..b198111a 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -113,6 +113,39 @@ export class ChatService { } } + async updateChatTitle(chat_id: string, title: string): Promise { + try { + if (!uiStore.meInfo) return undefined; + const info = uiStore.meInfo; + + const response = await fetch(`${TribesURL}/hivechat/${chat_id}`, { + method: 'PUT', + mode: 'cors', + headers: { + 'x-jwt': info.tribe_jwt, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ title }), + }); + + if (!response.ok) { + console.log(response) + throw new Error(`HTTP error! status: ${response.text}`); + } + + const result = await response.json(); + + if (!result.success) { + throw new Error('Invalid chat title update response'); + } + + return result.data; + } catch (error) { + console.error('Error updating chat title:', error); + throw error; + } + } + async sendMessage( chat_id: string, message: string, diff --git a/src/store/chat.ts b/src/store/chat.ts index 8f97d5e1..cf3fdbbb 100644 --- a/src/store/chat.ts +++ b/src/store/chat.ts @@ -120,6 +120,16 @@ export class ChatHistoryStore implements ChatStore { return chat; } + async updateChatTitle(chat_id: string, newTitle: string): Promise { + try { + await chatService.updateChatTitle(chat_id, newTitle); + this.updateChat(chat_id, { title: newTitle }); + } catch (error) { + console.error('Error updating chat title in store:', error); + throw error; + } + } + async loadChatHistory(chat_id: string): Promise { try { const messages = await chatService.getChatHistory(chat_id); From bf6b8716ad66ed89dd5641f56b955c0b1c313350 Mon Sep 17 00:00:00 2001 From: jordan-ae Date: Thu, 19 Dec 2024 16:29:20 +0100 Subject: [PATCH 2/3] chore: clean up prettier --- src/people/hiveChat/index.tsx | 27 ++++++++++++++++++--------- src/services/index.ts | 5 ++--- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/people/hiveChat/index.tsx b/src/people/hiveChat/index.tsx index 98948b8e..155460a4 100644 --- a/src/people/hiveChat/index.tsx +++ b/src/people/hiveChat/index.tsx @@ -194,18 +194,22 @@ export const HiveChatView: React.FC = observer(() => { } }, [chat, chatId, ui]); - const updateChatTitle = async (chatId: string, uuid: string, newTitle: string, setIsUpdatingTitle: (status: boolean) => void): Promise => { + const updateChatTitle = async ( + chatId: string, + uuid: string, + newTitle: string, + setIsUpdatingTitle: (status: boolean) => void + ): Promise => { if (!chatId || !uuid || !newTitle.trim()) return; - + setIsUpdatingTitle(true); try { - console.log(newTitle); chatHistoryStore.updateChatTitle(chatId, newTitle); ui.setToasts([ { title: 'Success', - text: 'Chat Title Updated', - }, + text: 'Chat Title Updated' + } ]); } catch (error) { console.error('Error updating chat title:', error); @@ -213,8 +217,8 @@ export const HiveChatView: React.FC = observer(() => { { title: 'Error', color: 'danger', - text: 'Failed to update chat title', - }, + text: 'Failed to update chat title' + } ]); } finally { setIsUpdatingTitle(false); @@ -240,7 +244,12 @@ export const HiveChatView: React.FC = observer(() => { }, [chatId, chat]); let debounceUpdateTitle: ReturnType; - const handleTitleChange = (chatId: string, uuid: string, title: string, setIsUpdatingTitle: (status: boolean) => void) => { + const handleTitleChange = ( + chatId: string, + uuid: string, + title: string, + setIsUpdatingTitle: (status: boolean) => void + ) => { clearTimeout(debounceUpdateTitle); debounceUpdateTitle = setTimeout(() => { @@ -413,7 +422,7 @@ export const HiveChatView: React.FC = observer(() => { placeholder="Enter chat title..." disabled={isUpdatingTitle} style={{ - cursor: isUpdatingTitle ? 'not-allowed' : 'text', + cursor: isUpdatingTitle ? 'not-allowed' : 'text' }} /> diff --git a/src/services/index.ts b/src/services/index.ts index b198111a..94146366 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -118,18 +118,17 @@ export class ChatService { if (!uiStore.meInfo) return undefined; const info = uiStore.meInfo; - const response = await fetch(`${TribesURL}/hivechat/${chat_id}`, { + const response = await fetch(`${TribesURL}/hivechat/${chat_id}`, { method: 'PUT', mode: 'cors', headers: { 'x-jwt': info.tribe_jwt, 'Content-Type': 'application/json' }, - body: JSON.stringify({ title }), + body: JSON.stringify({ title }) }); if (!response.ok) { - console.log(response) throw new Error(`HTTP error! status: ${response.text}`); } From 70dd1c6acf9e71d70e94d952452ea302ab2a020e Mon Sep 17 00:00:00 2001 From: jordan-ae Date: Thu, 19 Dec 2024 20:12:28 +0100 Subject: [PATCH 3/3] chore: refetch title --- src/people/hiveChat/index.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/people/hiveChat/index.tsx b/src/people/hiveChat/index.tsx index 155460a4..d6f30e9a 100644 --- a/src/people/hiveChat/index.tsx +++ b/src/people/hiveChat/index.tsx @@ -179,6 +179,10 @@ export const HiveChatView: React.FC = observer(() => { const refreshChatHistory = useCallback(async () => { try { await chat.loadChatHistory(chatId); + const selectedChat = chat.getChat(chatId); + if (selectedChat?.title) { + setTitle(selectedChat.title); + } if (chatHistoryRef.current) { chatHistoryRef.current.scrollTop = chatHistoryRef.current.scrollHeight; }