Skip to content

Commit 3ff0710

Browse files
committed
add renaming
1 parent d813da8 commit 3ff0710

File tree

4 files changed

+55
-7
lines changed

4 files changed

+55
-7
lines changed

tools/server/webui/src/components/ChatScreen.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,10 @@ function ChatInput({
378378
<div className="flex flex-row gap-2 ml-2">
379379
<label
380380
htmlFor="file-upload"
381-
className="btn w-8 h-8 p-0 rounded-full"
381+
className={classNames({
382+
'btn w-8 h-8 p-0 rounded-full': true,
383+
'btn-disabled': isGenerating,
384+
})}
382385
>
383386
<PaperClipIcon className="h-5 w-5" />
384387
</label>

tools/server/webui/src/components/Sidebar.tsx

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import { classNames } from '../utils/misc';
33
import { Conversation } from '../utils/types';
44
import StorageUtils from '../utils/storage';
55
import { useNavigate, useParams } from 'react-router';
6-
import { EllipsisVerticalIcon, XMarkIcon } from '@heroicons/react/24/outline';
6+
import {
7+
ArrowDownTrayIcon,
8+
EllipsisVerticalIcon,
9+
PencilIcon,
10+
TrashIcon,
11+
XMarkIcon,
12+
} from '@heroicons/react/24/outline';
713
import { BtnWithTooltips } from '../utils/common';
814
import { useAppContext } from '../utils/app.context';
915
import toast from 'react-hot-toast';
@@ -106,6 +112,19 @@ export default function Sidebar() {
106112
document.body.removeChild(a);
107113
URL.revokeObjectURL(url);
108114
}}
115+
onRename={() => {
116+
if (isGenerating(conv.id)) {
117+
toast.error('Cannot rename conversation while generating');
118+
return;
119+
}
120+
const newName = window.prompt(
121+
'Enter new name for the conversation',
122+
conv.name
123+
);
124+
if (newName && newName.trim().length > 0) {
125+
StorageUtils.updateConversationName(conv.id, newName);
126+
}
127+
}}
109128
/>
110129
))}
111130
<div className="text-center text-xs opacity-40 mt-auto mx-4">
@@ -123,17 +142,19 @@ function ConversationItem({
123142
onSelect,
124143
onDelete,
125144
onDownload,
145+
onRename,
126146
}: {
127147
conv: Conversation;
128148
isCurrConv: boolean;
129149
onSelect: () => void;
130150
onDelete: () => void;
131151
onDownload: () => void;
152+
onRename: () => void;
132153
}) {
133154
return (
134155
<div
135156
className={classNames({
136-
'group flex flex-row btn btn-ghost justify-start items-center font-normal':
157+
'group flex flex-row btn btn-ghost justify-start items-center font-normal pr-2':
137158
true,
138159
'btn-soft': isCurrConv,
139160
})}
@@ -160,13 +181,25 @@ function ConversationItem({
160181
{/* dropdown menu */}
161182
<ul
162183
tabIndex={0}
163-
className="dropdown-content menu bg-base-100 rounded-box z-[1] w-32 p-2 shadow"
184+
className="dropdown-content menu bg-base-100 rounded-box z-[1] p-2 shadow"
164185
>
186+
<li onClick={onRename}>
187+
<a>
188+
<PencilIcon className="w-4 h-4" />
189+
Rename
190+
</a>
191+
</li>
165192
<li onClick={onDownload}>
166-
<a>Download</a>
193+
<a>
194+
<ArrowDownTrayIcon className="w-4 h-4" />
195+
Download
196+
</a>
167197
</li>
168198
<li className="text-error" onClick={onDelete}>
169-
<a>Delete</a>
199+
<a>
200+
<TrashIcon className="w-4 h-4" />
201+
Delete
202+
</a>
170203
</li>
171204
</ul>
172205
</div>

tools/server/webui/src/components/useChatExtraContext.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export function useChatExtraContext(): ChatExtraContextApi {
5959
mimeType.startsWith('video/') ||
6060
mimeType.startsWith('audio/')
6161
) {
62-
toast.error('Video files are not supported yet.');
62+
toast.error('Video and audio files are not supported yet.');
6363
break;
6464
} else if (mimeType.startsWith('application/pdf')) {
6565
toast.error('PDF files are not supported yet.');
@@ -100,6 +100,8 @@ export function useChatExtraContext(): ChatExtraContextApi {
100100

101101
// WARN: vibe code below
102102
// This code is a heuristic to determine if a string is likely not binary.
103+
// It is necessary because input file can have various mime types which we don't have time to investigate.
104+
// For example, a python file can be text/plain, application/x-python, etc.
103105
export function isLikelyNotBinary(str: string): boolean {
104106
const options = {
105107
prefixLength: 1024 * 10, // Check the first 10KB of the string

tools/server/webui/src/utils/storage.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ const StorageUtils = {
116116
});
117117
return conv;
118118
},
119+
/**
120+
* update the name of a conversation
121+
*/
122+
async updateConversationName(convId: string, name: string): Promise<void> {
123+
await db.conversations.update(convId, {
124+
name,
125+
lastModified: Date.now(),
126+
});
127+
dispatchConversationChange(convId);
128+
},
119129
/**
120130
* if convId does not exist, throw an error
121131
*/

0 commit comments

Comments
 (0)