diff --git a/src/components/chat/Conversation.jsx b/src/components/chat/Conversation.jsx index 0fd7e06..8abdabb 100644 --- a/src/components/chat/Conversation.jsx +++ b/src/components/chat/Conversation.jsx @@ -1,19 +1,21 @@ import { useEffect, useRef, useState } from "react"; import ConversationBubble from "./ConversationBubble"; -import { FileImageFill, FileTextFill, Paperclip, Send, StopCircleFill } from 'react-bootstrap-icons'; +import { CheckCircle, FileImageFill, FileTextFill, Paperclip, Send, StopCircleFill, XCircle } from 'react-bootstrap-icons'; import useIDB from "../../utils/idb"; import { isModelLoaded, loadModel } from '../../utils/workers/worker' import { getCompletionFunctions } from "../../utils/workers"; import { setClient as setAwsClient } from "../../utils/workers/aws-worker"; import { setClient as setOpenaiClient } from "../../utils/workers/openai-worker"; -export default function Conversation({ uid, client, updateClient }) { +export default function Conversation({ uid, title, updateTitle, client, updateClient }) { const [conversation, setConversation] = useState([]); const [message, setMessage] = useState(''); const [pending_message, setPendingMessage] = useState(''); const [hide_pending, setHidePending] = useState(true); const [upload_file, setUploadFile] = useState(null); + const [edit_title, toggleEditTitle] = useState(false); + const [edited_title, setEditedTitle] = useState(title); const chat_functions = useRef(getCompletionFunctions()); const idb = useIDB(); @@ -108,6 +110,13 @@ export default function Conversation({ uid, client, updateClient }) { setPendingMessage(''); setHidePending(true); } + + function submitUpdateTitle() { + if(edited_title && edited_title !== title) { + updateTitle(edited_title); + } + toggleEditTitle(false); + } useEffect(()=>{ uid && getConversationByUid(); @@ -123,7 +132,11 @@ export default function Conversation({ uid, client, updateClient }) { }, [conversation, pending_message]) useEffect(()=>{ - if(!chat_functions.current) return; + setEditedTitle(title); + }, [title]) + + useEffect(()=>{ + if(!chat_functions.current || !uid) return; const platform = chat_functions.current.platform if(platform) { @@ -139,13 +152,24 @@ export default function Conversation({ uid, client, updateClient }) { })() } // eslint-disable-next-line - }, [client]) + }, [uid]) return (
{ uid ? <> +
+ { + edit_title ? +
{evt.preventDefault(); submitUpdateTitle()}}> + setEditedTitle(evt.target.value)} /> + + {setEditedTitle(title); toggleEditTitle(false)}} /> + : +
toggleEditTitle(true)}>{ title }
+ } +
{ conversation.map(({role, content}, idx) => { return ( diff --git a/src/components/chat/index.jsx b/src/components/chat/index.jsx index a6a3116..288007e 100644 --- a/src/components/chat/index.jsx +++ b/src/components/chat/index.jsx @@ -40,6 +40,20 @@ export default function Chat() { resetRequestDelete(); } + async function updateTitle(title) { + await idb.updateOne("chat-history", {title}, [{uid: chat.uid}]) + + selectChat({ + ...chat, title: title + }) + + let history_cp = [...history]; + history_cp[ + history_cp.findIndex(e=>e.uid === chat.uid) + ].title = title; + setHistory(history_cp); + } + useEffect(()=>{ if(dialogRef.current) { if(showConfirm) dialogRef.current.showModal(); @@ -58,7 +72,11 @@ export default function Chat() { setHistory={setHistory} history={history} deleteHistory={requestDelete} /> - +
Delete {conv_to_delete && conv_to_delete.title}? diff --git a/src/styles/chat.css b/src/styles/chat.css index 428a338..7a056eb 100644 --- a/src/styles/chat.css +++ b/src/styles/chat.css @@ -111,9 +111,10 @@ background-repeat: no-repeat; background-size: cover; + --title-bar-height: 40px; --send-input-height: 60px; --elem-size: 40px; - --bubbles-height: calc(100% - var(--send-input-height) - 10px); + --bubbles-height: calc(100% - var(--send-input-height) - var(--title-bar-height) - 10px); } .chat > .conversation-main::before { @@ -142,6 +143,39 @@ background-image: none; } +.chat > .conversation-main > .title-bar { + background-color: var(--normal-bg-color); + width: 100%; + height: var(--title-bar-height); + padding: 0px 15px; + align-content: center; + font-size: 15px; + font-weight: bold; + color: rgb(50, 50, 50); + + --elem-height: calc(var(--title-bar-height) - 14px); +} + +.chat > .conversation-main > .title-bar > form { + display: flex; +} + +.chat > .conversation-main > .title-bar .edit-title { + border: none; + background-color: transparent; + border-bottom: 1px solid gray; + padding: 0px 5px; + width: 100%; + font-size: 15px; + height: var(--elem-height); +} + +.chat > .conversation-main > .title-bar .btn { + height: var(--elem-height); + width: var(--elem-height); + margin-left: 15px; +} + .chat > .conversation-main > .bubbles { height: var(--bubbles-height); width: 100%; @@ -149,7 +183,7 @@ margin-bottom: 10px; position: absolute; left: 0; - top: 0; + top: var(--title-bar-height); padding: 20px 10px; }