fix: Save draft message in Chat Form when adding System Prompt from new chat view
This commit is contained in:
parent
0fe25847ff
commit
16aa6fae0a
|
|
@ -12,7 +12,7 @@
|
||||||
onFileUpload?: (files: File[]) => void;
|
onFileUpload?: (files: File[]) => void;
|
||||||
onSend?: (message: string, files?: ChatUploadedFile[]) => Promise<boolean>;
|
onSend?: (message: string, files?: ChatUploadedFile[]) => Promise<boolean>;
|
||||||
onStop?: () => void;
|
onStop?: () => void;
|
||||||
onSystemPromptAdd?: () => void;
|
onSystemPromptAdd?: (draft: { message: string; files: ChatUploadedFile[] }) => void;
|
||||||
showHelperText?: boolean;
|
showHelperText?: boolean;
|
||||||
uploadedFiles?: ChatUploadedFile[];
|
uploadedFiles?: ChatUploadedFile[];
|
||||||
}
|
}
|
||||||
|
|
@ -32,8 +32,21 @@
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
let inputAreaRef: ChatFormInputArea | undefined = $state(undefined);
|
let inputAreaRef: ChatFormInputArea | undefined = $state(undefined);
|
||||||
let message = $state('');
|
let message = $state(initialMessage);
|
||||||
let previousIsLoading = $state(isLoading);
|
let previousIsLoading = $state(isLoading);
|
||||||
|
let previousInitialMessage = $state(initialMessage);
|
||||||
|
|
||||||
|
// Sync message when initialMessage prop changes (e.g., after draft restoration)
|
||||||
|
$effect(() => {
|
||||||
|
if (initialMessage !== previousInitialMessage) {
|
||||||
|
message = initialMessage;
|
||||||
|
previousInitialMessage = initialMessage;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleSystemPromptClick() {
|
||||||
|
onSystemPromptAdd?.({ message, files: uploadedFiles });
|
||||||
|
}
|
||||||
|
|
||||||
let hasLoadingAttachments = $derived(uploadedFiles.some((f) => f.isLoading));
|
let hasLoadingAttachments = $derived(uploadedFiles.some((f) => f.isLoading));
|
||||||
|
|
||||||
|
|
@ -101,7 +114,7 @@
|
||||||
onFilesAdd={handleFilesAdd}
|
onFilesAdd={handleFilesAdd}
|
||||||
{onStop}
|
{onStop}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
onSystemPromptClick={onSystemPromptAdd}
|
onSystemPromptClick={handleSystemPromptClick}
|
||||||
onUploadedFileRemove={handleUploadedFileRemove}
|
onUploadedFileRemove={handleUploadedFileRemove}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
onMcpPromptArgumentsChange?: (fileId: string, args: Record<string, string>) => void;
|
onMcpPromptArgumentsChange?: (fileId: string, args: Record<string, string>) => void;
|
||||||
onStop?: () => void;
|
onStop?: () => void;
|
||||||
onSubmit?: () => void;
|
onSubmit?: () => void;
|
||||||
onSystemPromptClick?: () => void;
|
onSystemPromptClick?: (draft: { message: string; files: ChatUploadedFile[] }) => void;
|
||||||
onUploadedFileRemove?: (fileId: string) => void;
|
onUploadedFileRemove?: (fileId: string) => void;
|
||||||
onUploadedFilesChange?: (files: ChatUploadedFile[]) => void;
|
onUploadedFilesChange?: (files: ChatUploadedFile[]) => void;
|
||||||
onValueChange?: (value: string) => void;
|
onValueChange?: (value: string) => void;
|
||||||
|
|
@ -422,7 +422,7 @@
|
||||||
onFileUpload={handleFileUpload}
|
onFileUpload={handleFileUpload}
|
||||||
onMicClick={handleMicClick}
|
onMicClick={handleMicClick}
|
||||||
{onStop}
|
{onStop}
|
||||||
{onSystemPromptClick}
|
onSystemPromptClick={() => onSystemPromptClick?.({ message: value, files: uploadedFiles })}
|
||||||
onMcpPromptClick={showMcpPromptButton ? () => (isPromptPickerOpen = true) : undefined}
|
onMcpPromptClick={showMcpPromptButton ? () => (isPromptPickerOpen = true) : undefined}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -400,7 +400,7 @@
|
||||||
onFileUpload={handleFileUpload}
|
onFileUpload={handleFileUpload}
|
||||||
onSend={handleSendMessage}
|
onSend={handleSendMessage}
|
||||||
onStop={() => chatStore.stopGeneration()}
|
onStop={() => chatStore.stopGeneration()}
|
||||||
onSystemPromptAdd={() => chatStore.addSystemPrompt()}
|
onSystemPromptAdd={handleSystemPromptAdd}
|
||||||
showHelperText={false}
|
showHelperText={false}
|
||||||
bind:uploadedFiles
|
bind:uploadedFiles
|
||||||
/>
|
/>
|
||||||
|
|
@ -460,7 +460,7 @@
|
||||||
onFileUpload={handleFileUpload}
|
onFileUpload={handleFileUpload}
|
||||||
onSend={handleSendMessage}
|
onSend={handleSendMessage}
|
||||||
onStop={() => chatStore.stopGeneration()}
|
onStop={() => chatStore.stopGeneration()}
|
||||||
onSystemPromptAdd={() => chatStore.addSystemPrompt()}
|
onSystemPromptAdd={handleSystemPromptAdd}
|
||||||
showHelperText={true}
|
showHelperText={true}
|
||||||
bind:uploadedFiles
|
bind:uploadedFiles
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,10 @@ class ChatStore {
|
||||||
private addFilesHandler: ((files: File[]) => void) | null = $state(null);
|
private addFilesHandler: ((files: File[]) => void) | null = $state(null);
|
||||||
pendingEditMessageId = $state<string | null>(null);
|
pendingEditMessageId = $state<string | null>(null);
|
||||||
|
|
||||||
|
// Draft preservation for navigation (e.g., when adding system prompt from welcome page)
|
||||||
|
private _pendingDraftMessage = $state<string>('');
|
||||||
|
private _pendingDraftFiles = $state<ChatUploadedFile[]>([]);
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
if (browser) {
|
if (browser) {
|
||||||
chatClient.setStoreCallbacks({
|
chatClient.setStoreCallbacks({
|
||||||
|
|
@ -219,6 +223,31 @@ class ChatStore {
|
||||||
this.pendingEditMessageId = null;
|
this.pendingEditMessageId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
savePendingDraft(message: string, files: ChatUploadedFile[]): void {
|
||||||
|
this._pendingDraftMessage = message;
|
||||||
|
this._pendingDraftFiles = [...files];
|
||||||
|
}
|
||||||
|
|
||||||
|
consumePendingDraft(): { message: string; files: ChatUploadedFile[] } | null {
|
||||||
|
if (!this._pendingDraftMessage && this._pendingDraftFiles.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const draft = {
|
||||||
|
message: this._pendingDraftMessage,
|
||||||
|
files: [...this._pendingDraftFiles]
|
||||||
|
};
|
||||||
|
|
||||||
|
this._pendingDraftMessage = '';
|
||||||
|
this._pendingDraftFiles = [];
|
||||||
|
|
||||||
|
return draft;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasPendingDraft(): boolean {
|
||||||
|
return Boolean(this._pendingDraftMessage) || this._pendingDraftFiles.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
getAllLoadingChats(): string[] {
|
getAllLoadingChats(): string[] {
|
||||||
return Array.from(this.chatLoadingStates.keys());
|
return Array.from(this.chatLoadingStates.keys());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue