Skip to content

Commit ebb7ce2

Browse files
committed
refac
1 parent 9a6bf78 commit ebb7ce2

4 files changed

Lines changed: 73 additions & 10 deletions

File tree

src/lib/components/chat/Chat.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2814,7 +2814,7 @@
28142814
</div>
28152815
</div>
28162816

2817-
<div class=" pb-2 z-10">
2817+
<div class=" pb-2 {dragged ? 'z-0' : 'z-10'}">
28182818
<MessageInput
28192819
bind:this={messageInput}
28202820
{history}

src/lib/components/chat/MessageInput.svelte

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import { uploadFile } from '$lib/apis/files';
5656
import { generateAutoCompletion } from '$lib/apis';
5757
import { deleteFileById } from '$lib/apis/files';
58+
import { getChatById } from '$lib/apis/chats';
5859
import { getSessionUser } from '$lib/apis/auths';
5960
import { getTools } from '$lib/apis/tools';
6061
@@ -806,8 +807,11 @@
806807
const onDragOver = (e: DragEvent) => {
807808
e.preventDefault();
808809
809-
// Check if a file is being dragged.
810-
if (e.dataTransfer?.types?.includes('Files')) {
810+
// Check if a file or a sidebar chat item is being dragged.
811+
if (
812+
e.dataTransfer?.types?.includes('Files') ||
813+
e.dataTransfer?.types?.includes('text/plain')
814+
) {
811815
dragged = true;
812816
} else {
813817
dragged = false;
@@ -825,6 +829,35 @@
825829
e.preventDefault();
826830
console.log(e);
827831
832+
// Check if the dropped data is a sidebar chat item
833+
const textData = e.dataTransfer?.getData('text/plain');
834+
if (textData) {
835+
try {
836+
const data = JSON.parse(textData);
837+
if (data.type === 'chat' && data.id) {
838+
// Fetch the chat to get its title, then add as a reference chat
839+
const chat = await getChatById(localStorage.token, data.id);
840+
if (chat) {
841+
const chatItem = {
842+
type: 'chat',
843+
id: chat.id,
844+
name: chat.title,
845+
collection_name: '',
846+
status: 'processed'
847+
};
848+
if (!files.find((f) => f.id === chatItem.id)) {
849+
files = [...files, chatItem];
850+
}
851+
}
852+
dragged = false;
853+
e.stopPropagation();
854+
return;
855+
}
856+
} catch (_) {
857+
// Not valid JSON — fall through to file handling
858+
}
859+
}
860+
828861
if (e.dataTransfer?.files) {
829862
const inputFiles = Array.from(e.dataTransfer?.files);
830863
if (inputFiles && inputFiles.length > 0) {
@@ -1022,8 +1055,8 @@
10221055
10231056
dropzoneElement = document.getElementById('chat-pane');
10241057
if (dropzoneElement) {
1025-
dropzoneElement.addEventListener('dragover', onDragOver);
1026-
dropzoneElement.addEventListener('drop', onDrop);
1058+
dropzoneElement.addEventListener('dragover', onDragOver, true);
1059+
dropzoneElement.addEventListener('drop', onDrop, true);
10271060
dropzoneElement.addEventListener('dragleave', onDragLeave);
10281061
}
10291062
@@ -1041,8 +1074,8 @@
10411074
window.removeEventListener('blur', onBlur);
10421075
10431076
if (dropzoneElement) {
1044-
dropzoneElement.removeEventListener('dragover', onDragOver);
1045-
dropzoneElement.removeEventListener('drop', onDrop);
1077+
dropzoneElement.removeEventListener('dragover', onDragOver, true);
1078+
dropzoneElement.removeEventListener('drop', onDrop, true);
10461079
dropzoneElement.removeEventListener('dragleave', onDragLeave);
10471080
}
10481081
};

src/lib/components/common/DragGhost.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
<div
3131
bind:this={popupElement}
32-
class="fixed top-0 left-0 w-screen h-[100dvh] z-50 touch-none pointer-events-none"
32+
class="fixed top-0 left-0 w-screen h-[100dvh] z-[99999] touch-none pointer-events-none"
3333
>
3434
<div class=" absolute text-white z-99999" style="top: {y + 10}px; left: {x + 10}px;">
3535
<slot></slot>

src/lib/components/common/RichTextInput.svelte

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -801,8 +801,8 @@
801801
if (!editor || !editor.view || editor.isDestroyed) {
802802
return false;
803803
}
804-
// default logic
805-
return from !== to;
804+
// Only show when editor is focused and text is selected
805+
return view.hasFocus() && from !== to;
806806
}
807807
}),
808808
FloatingMenu.configure({
@@ -905,6 +905,24 @@
905905
},
906906
editorProps: {
907907
attributes: { id },
908+
handleDrop: (view, event) => {
909+
// Intercept sidebar chat item drops to prevent ProseMirror
910+
// from inserting the raw JSON as text. The actual handling
911+
// (adding as Reference Chat) is done by MessageInput's onDrop.
912+
const textData = event.dataTransfer?.getData('text/plain');
913+
if (textData) {
914+
try {
915+
const data = JSON.parse(textData);
916+
if (data.type === 'chat' && data.id) {
917+
// Swallow the drop — let the parent handler deal with it
918+
return true;
919+
}
920+
} catch (_) {
921+
// Not JSON, let ProseMirror handle normally
922+
}
923+
}
924+
return false;
925+
},
908926
handlePaste: (view, event) => {
909927
// Force plain-text pasting when richText === false
910928
if (!richText) {
@@ -1170,6 +1188,18 @@
11701188
}
11711189
},
11721190
onSelectionUpdate: onSelectionUpdate,
1191+
onBlur: () => {
1192+
// Force-hide floating menus when editor loses focus.
1193+
// shouldShow alone isn't enough because it only runs on transactions.
1194+
if (bubbleMenuElement) {
1195+
bubbleMenuElement.style.visibility = 'hidden';
1196+
bubbleMenuElement.style.opacity = '0';
1197+
}
1198+
if (floatingMenuElement) {
1199+
floatingMenuElement.style.visibility = 'hidden';
1200+
floatingMenuElement.style.opacity = '0';
1201+
}
1202+
},
11731203
enableInputRules: richText,
11741204
enablePasteRules: richText
11751205
});

0 commit comments

Comments
 (0)