chat attachment is now related to single message

This commit is contained in:
josc146 2023-11-05 21:05:06 +08:00
parent 64826b9af7
commit 37dda4333d
2 changed files with 59 additions and 29 deletions

View File

@ -91,6 +91,7 @@ const MoreUtilsButton: FC<{ uuid: string, setEditing: (editing: boolean) => void
onClick={() => { onClick={() => {
commonStore.conversationOrder.splice(commonStore.conversationOrder.indexOf(uuid), 1); commonStore.conversationOrder.splice(commonStore.conversationOrder.indexOf(uuid), 1);
delete commonStore.conversation[uuid]; delete commonStore.conversation[uuid];
commonStore.setAttachment(uuid, null);
}} /> }} />
</MenuPopover> </MenuPopover>
</Menu>; </Menu>;
@ -157,7 +158,21 @@ const ChatMessageItem: FC<{
)} )}
> >
{!editing ? {!editing ?
<MarkdownRender>{messageItem.content}</MarkdownRender> : <div className="flex flex-col">
<MarkdownRender>{messageItem.content}</MarkdownRender>
{uuid in commonStore.attachments &&
<div className="flex grow">
<div className="grow" />
<ToolTipButton className="whitespace-nowrap"
text={
commonStore.attachments[uuid][0].name.replace(
new RegExp('(^[^\\.]{5})[^\\.]+'), '$1...')
}
desc={`${commonStore.attachments[uuid][0].name} (${bytesToReadable(commonStore.attachments[uuid][0].size)})`}
size="small" shape="circular" appearance="secondary" />
</div>
}
</div> :
<Textarea ref={textareaRef} <Textarea ref={textareaRef}
className="grow" className="grow"
style={{ minWidth: 0 }} style={{ minWidth: 0 }}
@ -275,6 +290,11 @@ const ChatPanel: FC = observer(() => {
commonStore.setConversation(commonStore.conversation); commonStore.setConversation(commonStore.conversation);
commonStore.conversationOrder.push(newId); commonStore.conversationOrder.push(newId);
commonStore.setConversationOrder(commonStore.conversationOrder); commonStore.setConversationOrder(commonStore.conversationOrder);
if (commonStore.currentTempAttachment) {
commonStore.setAttachment(newId, [commonStore.currentTempAttachment]);
commonStore.setCurrentTempAttachment(null);
}
} }
let startIndex = startUuid ? commonStore.conversationOrder.indexOf(startUuid) : 0; let startIndex = startUuid ? commonStore.conversationOrder.indexOf(startUuid) : 0;
@ -282,20 +302,21 @@ const ChatPanel: FC = observer(() => {
let targetRange = commonStore.conversationOrder.slice(startIndex, endIndex); let targetRange = commonStore.conversationOrder.slice(startIndex, endIndex);
const messages: ConversationMessage[] = []; const messages: ConversationMessage[] = [];
if (commonStore.attachmentContent) {
messages.push({
role: 'user',
content: t('The content of file') + ` "${commonStore.attachmentName}" `
+ t('is as follows. When replying to me, consider the file content and respond accordingly:')
+ '\n\n' + commonStore.attachmentContent
});
messages.push({ role: 'user', content: t('What\'s the file name') });
messages.push({ role: 'assistant', content: t('The file name is: ') + commonStore.attachmentName });
}
targetRange.forEach((uuid, index) => { targetRange.forEach((uuid, index) => {
if (uuid === welcomeUuid) if (uuid === welcomeUuid)
return; return;
const messageItem = commonStore.conversation[uuid]; const messageItem = commonStore.conversation[uuid];
if (uuid in commonStore.attachments) {
const attachment = commonStore.attachments[uuid][0];
messages.push({
role: 'user',
content: t('The content of file') + ` "${attachment.name}" `
+ t('is as follows. When replying to me, consider the file content and respond accordingly:')
+ '\n\n' + attachment.content
});
messages.push({ role: 'user', content: t('What\'s the file name') });
messages.push({ role: 'assistant', content: t('The file name is: ') + attachment.name });
}
if (messageItem.done && messageItem.type === MessageType.Normal && messageItem.sender === userName) { if (messageItem.done && messageItem.type === MessageType.Normal && messageItem.sender === userName) {
messages.push({ role: 'user', content: messageItem.content }); messages.push({ role: 'user', content: messageItem.content });
} else if (messageItem.done && messageItem.type === MessageType.Normal && messageItem.sender === botName) { } else if (messageItem.done && messageItem.type === MessageType.Normal && messageItem.sender === botName) {
@ -433,7 +454,7 @@ const ChatPanel: FC = observer(() => {
onKeyDown={handleKeyDownOrClick} onKeyDown={handleKeyDownOrClick}
/> />
<div className="absolute right-2 bottom-2"> <div className="absolute right-2 bottom-2">
{!commonStore.attachmentContent ? {!commonStore.currentTempAttachment ?
<ToolTipButton <ToolTipButton
desc={commonStore.attachmentUploading ? desc={commonStore.attachmentUploading ?
t('Uploading Attachment') : t('Uploading Attachment') :
@ -477,9 +498,12 @@ const ChatPanel: FC = observer(() => {
attachmentContent = pages[0].page_content; attachmentContent = pages[0].page_content;
else else
attachmentContent = pages.map((p, i) => `Page ${i + 1}:\n${p.page_content}`).join('\n\n'); attachmentContent = pages.map((p, i) => `Page ${i + 1}:\n${p.page_content}`).join('\n\n');
commonStore.setAttachmentName(attachmentName!); commonStore.setCurrentTempAttachment(
commonStore.setAttachmentSize(blob.size); {
commonStore.setAttachmentContent(attachmentContent); name: attachmentName!,
size: blob.size,
content: attachmentContent
});
} else { } else {
toast(r.statusText + '\n' + (await r.text()), { toast(r.statusText + '\n' + (await r.text()), {
type: 'error' type: 'error'
@ -499,18 +523,16 @@ const ChatPanel: FC = observer(() => {
<div> <div>
<ToolTipButton <ToolTipButton
text={ text={
commonStore.attachmentName.replace( commonStore.currentTempAttachment.name.replace(
new RegExp('(^[^\\.]{5})[^\\.]+'), '$1...') new RegExp('(^[^\\.]{5})[^\\.]+'), '$1...')
} }
desc={`${commonStore.attachmentName} (${bytesToReadable(commonStore.attachmentSize)})`} desc={`${commonStore.currentTempAttachment.name} (${bytesToReadable(commonStore.currentTempAttachment.size)})`}
size="small" shape="circular" appearance="secondary" /> size="small" shape="circular" appearance="secondary" />
<ToolTipButton desc={t('Remove Attachment')} <ToolTipButton desc={t('Remove Attachment')}
icon={<Dismiss16Regular />} icon={<Dismiss16Regular />}
size="small" shape="circular" appearance="subtle" size="small" shape="circular" appearance="subtle"
onClick={() => { onClick={() => {
commonStore.setAttachmentName(''); commonStore.setCurrentTempAttachment(null);
commonStore.setAttachmentSize(0);
commonStore.setAttachmentContent('');
}} /> }} />
</div> </div>
} }

View File

@ -31,6 +31,12 @@ export type Status = {
device_name: string; device_name: string;
} }
export type Attachment = {
name: string;
size: number;
content: string;
}
export type Platform = 'windows' | 'darwin' | 'linux'; export type Platform = 'windows' | 'darwin' | 'linux';
class CommonStore { class CommonStore {
@ -53,9 +59,8 @@ class CommonStore {
conversationOrder: string[] = []; conversationOrder: string[] = [];
activePreset: Preset | null = null; activePreset: Preset | null = null;
attachmentUploading: boolean = false; attachmentUploading: boolean = false;
attachmentName: string = ''; attachments: { [uuid: string]: Attachment[] } = {};
attachmentSize: number = 0; currentTempAttachment: Attachment | null = null;
attachmentContent: string = '';
// completion // completion
completionPreset: CompletionPreset | null = null; completionPreset: CompletionPreset | null = null;
completionGenerating: boolean = false; completionGenerating: boolean = false;
@ -332,16 +337,19 @@ class CommonStore {
this.attachmentUploading = value; this.attachmentUploading = value;
} }
setAttachmentName(value: string) { setAttachments(value: { [uuid: string]: Attachment[] }) {
this.attachmentName = value; this.attachments = value;
} }
setAttachmentSize(value: number) { setAttachment(uuid: string, value: Attachment[] | null) {
this.attachmentSize = value; if (value === null)
delete this.attachments[uuid];
else
this.attachments[uuid] = value;
} }
setAttachmentContent(value: string) { setCurrentTempAttachment(value: Attachment | null) {
this.attachmentContent = value; this.currentTempAttachment = value;
} }
} }