feat: drag and drop in contextual prompts

This commit is contained in:
legao 2023-07-14 18:08:03 +08:00
parent b51f7f9a25
commit fb98050d9f

View File

@ -42,6 +42,20 @@ import { ModelConfigList } from "./model-config";
import { FileName, Path } from "../constant";
import { BUILTIN_MASK_STORE } from "../masks";
import { nanoid } from "nanoid";
import {
DragDropContext,
Droppable,
Draggable,
OnDragEndResponder,
} from "@hello-pangea/dnd";
// drag and drop helper function
function reorder<T>(list: T[], startIndex: number, endIndex: number): T[] {
const result = [...list];
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
}
export function MaskAvatar(props: { mask: Mask }) {
return props.mask.avatar !== DEFAULT_MASK_AVATAR ? (
@ -192,6 +206,7 @@ export function MaskConfig(props: {
}
function ContextPromptItem(props: {
index: number;
prompt: ChatMessage;
update: (prompt: ChatMessage) => void;
remove: () => void;
@ -199,7 +214,14 @@ function ContextPromptItem(props: {
const [focusingInput, setFocusingInput] = useState(false);
return (
<div className={chatStyle["context-prompt-row"]}>
<Draggable draggableId={props.prompt.id} index={props.index}>
{(provided) => (
<div
className={chatStyle["context-prompt-row"]}
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
{!focusingInput && (
<Select
value={props.prompt.role}
@ -246,6 +268,8 @@ function ContextPromptItem(props: {
/>
)}
</div>
)}
</Draggable>
);
}
@ -267,17 +291,41 @@ export function ContextPrompts(props: {
props.updateContext((context) => (context[i] = prompt));
};
const onDragEnd: OnDragEndResponder = (result) => {
if (!result.destination) {
return;
}
const newContext = reorder(
context,
result.source.index,
result.destination.index,
);
props.updateContext((context) => {
context.splice(0, context.length, ...newContext);
});
};
return (
<>
<div className={chatStyle["context-prompt"]} style={{ marginBottom: 20 }}>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="context-prompt-list">
{(provided) => (
<div ref={provided.innerRef} {...provided.droppableProps}>
{context.map((c, i) => (
<ContextPromptItem
key={i}
index={i}
key={c.id}
prompt={c}
update={(prompt) => updateContextPrompt(i, prompt)}
remove={() => removeContextPrompt(i)}
/>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
<div className={chatStyle["context-prompt-row"]}>
<IconButton