Chatroom rename feature
pull/532/head^2
Alex 9 months ago committed by GitHub
commit 64a8857884
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -53,6 +53,15 @@ def get_single_conversation():
conversation = conversations_collection.find_one({"_id": ObjectId(conversation_id)})
return jsonify(conversation['queries'])
@user.route("/api/update_conversation_name", methods=["POST"])
def update_conversation_name():
# update data for a conversation
data = request.get_json()
id = data["id"]
name = data["name"]
conversations_collection.update_one({"_id": ObjectId(id)},{"$set":{"name":name}})
return {"status": "ok"}
@user.route("/api/feedback", methods=["POST"])
def api_feedback():

@ -4,7 +4,7 @@
export default function About() {
return (
<div className="mx-5 grid min-h-screen md:mx-36">
<article className="place-items-left mx-auto my-auto flex w-full max-w-6xl flex-col gap-6 rounded-3xl bg-gray-100 p-6 mt-20 text-jet lg:p-10 xl:p-16">
<article className="place-items-left mx-auto my-auto mt-20 flex w-full max-w-6xl flex-col gap-6 rounded-3xl bg-gray-100 p-6 text-jet lg:p-10 xl:p-16">
<div className="flex items-center">
<p className="mr-2 text-3xl">About DocsGPT</p>
<p className="text-[21px]">🦖</p>

@ -18,9 +18,7 @@ export default function App() {
<div
className={`transition-all duration-200 ${
!isMobile
? `ml-0 ${
!navOpen ? '-mt-5 md:mx-auto lg:mx-auto' : 'md:ml-72'
}`
? `ml-0 ${!navOpen ? '-mt-5 md:mx-auto lg:mx-auto' : 'md:ml-72'}`
: 'ml-0 md:ml-16'
}`}
>

@ -32,6 +32,7 @@ import { useMediaQuery, useOutsideAlerter } from './hooks';
import Upload from './upload/Upload';
import { Doc, getConversations } from './preferences/preferenceApi';
import SelectDocsModal from './preferences/SelectDocsModal';
import ConversationTile from './conversation/ConversationTile';
interface NavigationProps {
navOpen: boolean;
@ -68,16 +69,20 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
useEffect(() => {
if (!conversations) {
getConversations()
.then((fetchedConversations) => {
dispatch(setConversations(fetchedConversations));
})
.catch((error) => {
console.error('Failed to fetch conversations: ', error);
});
fetchConversations();
}
}, [conversations, dispatch]);
async function fetchConversations() {
return await getConversations()
.then((fetchedConversations) => {
dispatch(setConversations(fetchedConversations));
})
.catch((error) => {
console.error('Failed to fetch conversations: ', error);
});
}
const handleDeleteConversation = (id: string) => {
fetch(`${apiHost}/api/delete_conversation?id=${id}`, {
method: 'POST',
@ -89,6 +94,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
) as HTMLElement;
const parentElement = imageElement.parentNode as HTMLElement;
parentElement.parentNode?.removeChild(parentElement);
fetchConversations();
})
.catch((error) => console.error(error));
};
@ -126,6 +132,29 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
);
});
};
async function updateConversationName(updatedConversation: {
name: string;
id: string;
}) {
await fetch(`${apiHost}/api/update_conversation_name`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(updatedConversation),
})
.then((response) => response.json())
.then((data) => {
if (data) {
navigate('/');
fetchConversations();
}
})
.catch((err) => {
console.error(err);
});
}
useOutsideAlerter(
navRef,
() => {
@ -210,41 +239,17 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
</NavLink>
<div className="conversations-container max-h-[25rem] overflow-y-auto">
{conversations
? conversations.map((conversation) => {
return (
<div
key={conversation.id}
onClick={() => {
handleConversationClick(conversation.id);
}}
className={`my-auto mx-4 mt-4 flex h-12 cursor-pointer items-center justify-between gap-4 rounded-3xl hover:bg-gray-100 ${
conversationId === conversation.id ? 'bg-gray-100' : ''
}`}
>
<div className="flex gap-4">
<img src={Message} className="ml-2 w-5"></img>
<p className="my-auto text-eerie-black">
{conversation.name.length > 45
? conversation.name.substring(0, 45) + '...'
: conversation.name}
</p>
</div>
{conversationId === conversation.id ? (
<img
src={Exit}
alt="Exit"
className="mr-4 h-3 w-3 cursor-pointer hover:opacity-50"
id={`img-${conversation.id}`}
onClick={(event) => {
event.stopPropagation();
handleDeleteConversation(conversation.id);
}}
/>
) : null}
</div>
);
})
? conversations.map((conversation, index) => (
<ConversationTile
key={index}
conversation={conversation}
selectConversation={(id) => handleConversationClick(id)}
onDeleteConversation={(id) => handleDeleteConversation(id)}
onSave={(conversation) =>
updateConversationName(conversation)
}
/>
))
: null}
</div>

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="11" viewBox="0 0 14 11" fill="none">
<path d="M4.95919 10.1906C4.84318 10.1902 4.72847 10.166 4.62222 10.1194C4.51596 10.0729 4.42041 10.0049 4.34152 9.91985L0.229353 5.54538C0.0756344 5.38157 -0.00671208 5.1634 0.000428491 4.93886C0.00756906 4.71433 0.103612 4.50183 0.267428 4.34812C0.431245 4.1944 0.649417 4.11205 0.873948 4.11919C1.09848 4.12633 1.31098 4.22238 1.4647 4.38619L4.95073 8.10068L12.0666 0.316329C12.1389 0.226405 12.2287 0.152193 12.3306 0.0982513C12.4326 0.0443098 12.5445 0.0117775 12.6594 0.00265255C12.7744 -0.00647237 12.89 0.00800286 12.9992 0.045189C13.1084 0.082375 13.2088 0.141487 13.2943 0.218894C13.3798 0.296301 13.4485 0.390369 13.4964 0.49532C13.5442 0.600272 13.57 0.713891 13.5723 0.829198C13.5746 0.944506 13.5534 1.05907 13.5098 1.16585C13.4662 1.27263 13.4012 1.36937 13.3189 1.45014L5.58533 9.91139C5.50718 9.998 5.41197 10.0675 5.30567 10.1156C5.19938 10.1636 5.0843 10.1892 4.96766 10.1906H4.95919Z" fill="#747474"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -1,3 +1,3 @@
<svg width="14" height="10" viewBox="0 0 14 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.7617 1.34847L5.14891 9.76785C5.0739 9.84143 4.98476 9.89982 4.88661 9.93965C4.78847 9.97949 4.68324 10 4.57697 10C4.4707 10 4.36547 9.97949 4.26732 9.93965C4.16917 9.89982 4.08004 9.84143 4.00502 9.76785L0.236908 6.08437C0.161799 6.01095 0.102219 5.92378 0.0615703 5.82785C0.0209216 5.73192 1.11921e-09 5.6291 0 5.52527C-1.11921e-09 5.42143 0.0209216 5.31862 0.0615703 5.22269C0.102219 5.12676 0.161799 5.03959 0.236908 4.96617C0.312017 4.89275 0.401184 4.83451 0.499319 4.79477C0.597453 4.75503 0.702634 4.73458 0.808854 4.73458C0.915074 4.73458 1.02025 4.75503 1.11839 4.79477C1.21652 4.83451 1.30569 4.89275 1.3808 4.96617L4.57764 8.09121L12.6192 0.231586C12.7709 0.083304 12.9766 0 13.1911 0C13.4057 0 13.6114 0.083304 13.7631 0.231586C13.9148 0.379869 14 0.580983 14 0.790686C14 1.00039 13.9148 1.2015 13.7631 1.34978L13.7617 1.34847Z" fill="#13A10E"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="11" viewBox="0 0 14 11" fill="none">
<path d="M4.95919 10.1906C4.84318 10.1902 4.72847 10.166 4.62222 10.1194C4.51596 10.0729 4.42041 10.0049 4.34152 9.91985L0.229353 5.54538C0.0756344 5.38157 -0.00671208 5.1634 0.000428491 4.93886C0.00756906 4.71433 0.103612 4.50183 0.267428 4.34812C0.431245 4.1944 0.649417 4.11205 0.873948 4.11919C1.09848 4.12633 1.31098 4.22238 1.4647 4.38619L4.95073 8.10068L12.0666 0.316329C12.1389 0.226405 12.2287 0.152193 12.3306 0.0982513C12.4326 0.0443098 12.5445 0.0117775 12.6594 0.00265255C12.7744 -0.00647237 12.89 0.00800286 12.9992 0.045189C13.1084 0.082375 13.2088 0.141487 13.2943 0.218894C13.3798 0.296301 13.4485 0.390369 13.4964 0.49532C13.5442 0.600272 13.57 0.713891 13.5723 0.829198C13.5746 0.944506 13.5534 1.05907 13.5098 1.16585C13.4662 1.27263 13.4012 1.36937 13.3189 1.45014L5.58533 9.91139C5.50718 9.998 5.41197 10.0675 5.30567 10.1156C5.19938 10.1636 5.0843 10.1892 4.96766 10.1906H4.95919Z" fill="#747474"/>
</svg>

Before

Width:  |  Height:  |  Size: 974 B

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="15" viewBox="0 0 16 15" fill="none">
<path d="M10.0588 2.74568L12.5294 5.15732M8.41176 14H15M1.82353 10.7845L1 14L4.29412 13.1961L13.8355 3.88237C14.1443 3.58087 14.3178 3.172 14.3178 2.74568C14.3178 2.31936 14.1443 1.9105 13.8355 1.609L13.6939 1.47073C13.385 1.16932 12.9662 1 12.5294 1C12.0927 1 11.6738 1.16932 11.3649 1.47073L1.82353 10.7845Z" stroke="#747474" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 500 B

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="15" viewBox="0 0 12 15" fill="none">
<path d="M0.857143 13.3333C0.857143 13.7754 1.03775 14.1993 1.35925 14.5118C1.68074 14.8244 2.11677 15 2.57143 15H9.42857C9.88323 15 10.3193 14.8244 10.6408 14.5118C10.9622 14.1993 11.1429 13.7754 11.1429 13.3333V3.33333H0.857143V13.3333ZM2.57143 5H9.42857V13.3333H2.57143V5ZM9 0.833333L8.14286 0H3.85714L3 0.833333H0V2.5H12V0.833333H9Z" fill="#747474"/>
</svg>

After

Width:  |  Height:  |  Size: 459 B

@ -0,0 +1,128 @@
import { useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import Edit from '../assets/edit.svg';
import Exit from '../assets/exit.svg';
import Message from '../assets/message.svg';
import CheckMark from '../assets/checkmark.svg';
import Trash from '../assets/trash.svg';
import { selectConversationId } from '../preferences/preferenceSlice';
import { useOutsideAlerter } from '../hooks';
interface ConversationProps {
name: string;
id: string;
}
interface ConversationTileProps {
conversation: ConversationProps;
selectConversation: (arg1: string) => void;
onDeleteConversation: (arg1: string) => void;
onSave: ({ name, id }: ConversationProps) => void;
}
export default function ConversationTile({
conversation,
selectConversation,
onDeleteConversation,
onSave,
}: ConversationTileProps) {
const conversationId = useSelector(selectConversationId);
const tileRef = useRef<HTMLInputElement>(null);
const [isEdit, setIsEdit] = useState(false);
const [conversationName, setConversationsName] = useState('');
useOutsideAlerter(
tileRef,
() =>
handleSaveConversation({
id: conversationId || conversation.id,
name: conversationName,
}),
[conversationName],
);
useEffect(() => {
setConversationsName(conversation.name);
}, [conversation.name]);
function handleEditConversation() {
setIsEdit(true);
}
function handleSaveConversation(changedConversation: ConversationProps) {
if (changedConversation.name.trim().length) {
onSave(changedConversation);
setIsEdit(false);
} else {
onClear();
}
}
function onClear() {
setConversationsName(conversation.name);
setIsEdit(false);
}
return (
<div
ref={tileRef}
onClick={() => {
selectConversation(conversation.id);
}}
className={`my-auto mx-4 mt-4 flex h-12 cursor-pointer items-center justify-between gap-4 rounded-3xl hover:bg-gray-100 ${
conversationId === conversation.id ? 'bg-gray-100' : ''
}`}
>
<div
className={`flex ${
conversationId === conversation.id ? 'w-[75%]' : 'w-[95%]'
} gap-4`}
>
<img src={Message} className="ml-2 w-5"></img>
{isEdit ? (
<input
autoFocus
type="text"
className="h-6 w-full px-1 text-sm font-normal leading-6 outline-[#0075FF] focus:outline-1"
value={conversationName}
onChange={(e) => setConversationsName(e.target.value)}
/>
) : (
<p className="my-auto overflow-hidden overflow-ellipsis whitespace-nowrap text-sm font-normal leading-6 text-eerie-black">
{conversationName}
</p>
)}
</div>
{conversationId === conversation.id ? (
<div className="flex">
<img
src={isEdit ? CheckMark : Edit}
alt="Edit"
className="mr-2 h-4 w-4 cursor-pointer hover:opacity-50"
id={`img-${conversation.id}`}
onClick={(event) => {
event.stopPropagation();
isEdit
? handleSaveConversation({
id: conversationId,
name: conversationName,
})
: handleEditConversation();
}}
/>
<img
src={isEdit ? Exit : Trash}
alt="Exit"
className={`mr-4 ${
isEdit ? 'h-3 w-3' : 'h-4 w-4'
}mt-px cursor-pointer hover:opacity-50`}
id={`img-${conversation.id}`}
onClick={(event) => {
event.stopPropagation();
isEdit ? onClear() : onDeleteConversation(conversation.id);
}}
/>
</div>
) : null}
</div>
);
}
Loading…
Cancel
Save