History

fix: improve business logic in prompt editor and fix cursor bugs in Plan mode (#867)

Noah Gregory committed 8 months ago

Commit f63cda21 parent b60a34e2 files · +50 −20Browse files

Unified · Split

2 files
  1. apps/web/src/components/ChatView.tsx +32 −9
  2. apps/web/src/components/ComposerPromptEditor.tsx +18 −11
apps/web/src/components/ChatView.tsx+32−9
@@ -633,23 +633,46 @@ export default function ChatView({ threadId }: ChatViewProps) { · 632 unmodified lines
633 pendingUserInputs.length > 0 ||633 pendingUserInputs.length > 0 ||
634 (showPlanFollowUpPrompt && activeProposedPlan !== null);634 (showPlanFollowUpPrompt && activeProposedPlan !== null);
635 const composerFooterHasWideActions = showPlanFollowUpPrompt || activePendingProgress !== null;635 const composerFooterHasWideActions = showPlanFollowUpPrompt || activePendingProgress !== null;
636 const lastSyncedPendingInputRef = useRef<{
637 requestId: string | null;
638 questionId: string | null;
639 } | null>(null);
636 useEffect(() => {640 useEffect(() => {
637 if (!activePendingProgress) {641 const nextCustomAnswer = activePendingProgress?.customAnswer;
642 if (typeof nextCustomAnswer !== "string") {
643 lastSyncedPendingInputRef.current = null;
638 return;644 return;
639 }645 }
640 promptRef.current = activePendingProgress.customAnswer;646 const nextRequestId = activePendingUserInput?.requestId ?? null;
641 setComposerCursor(activePendingProgress.customAnswer.length);647 const nextQuestionId = activePendingProgress?.activeQuestion?.id ?? null;
648 const questionChanged =
649 lastSyncedPendingInputRef.current?.requestId !== nextRequestId ||
650 lastSyncedPendingInputRef.current?.questionId !== nextQuestionId;
651 const textChangedExternally = promptRef.current !== nextCustomAnswer;
652
653 lastSyncedPendingInputRef.current = {
654 requestId: nextRequestId,
655 questionId: nextQuestionId,
656 };
657
658 if (!questionChanged && !textChangedExternally) {
659 return;
660 }
661
662 promptRef.current = nextCustomAnswer;
663 setComposerCursor(nextCustomAnswer.length);
642 setComposerTrigger(664 setComposerTrigger(
643 detectComposerTrigger(665 detectComposerTrigger(
644 activePendingProgress.customAnswer,666 nextCustomAnswer,
645 expandCollapsedComposerCursor(667 expandCollapsedComposerCursor(nextCustomAnswer, nextCustomAnswer.length),
646 activePendingProgress.customAnswer,
647 activePendingProgress.customAnswer.length,
648 ),
649 ),668 ),
650 );669 );
651 setComposerHighlightedItemId(null);670 setComposerHighlightedItemId(null);
652 }, [activePendingProgress, activePendingUserInput?.requestId]);671 }, [
672 activePendingProgress?.customAnswer,
673 activePendingUserInput?.requestId,
674 activePendingProgress?.activeQuestion?.id,
675 ]);
653 useEffect(() => {676 useEffect(() => {
654 attachmentPreviewHandoffByMessageIdRef.current = attachmentPreviewHandoffByMessageId;677 attachmentPreviewHandoffByMessageIdRef.current = attachmentPreviewHandoffByMessageId;
655 }, [attachmentPreviewHandoffByMessageId]);678 }, [attachmentPreviewHandoffByMessageId]);
apps/web/src/components/ComposerPromptEditor.tsx+18−11
@@ -629,6 +629,7 @@ function ComposerPromptEditorInner({ · 628 unmodified lines
629 const [editor] = useLexicalComposerContext();629 const [editor] = useLexicalComposerContext();
630 const onChangeRef = useRef(onChange);630 const onChangeRef = useRef(onChange);
631 const snapshotRef = useRef({ value, cursor: clampCursor(value, cursor) });631 const snapshotRef = useRef({ value, cursor: clampCursor(value, cursor) });
632 const isApplyingControlledUpdateRef = useRef(false);
632 633
633 useEffect(() => {634 useEffect(() => {
634 onChangeRef.current = onChange;635 onChangeRef.current = onChange;
@@ -645,21 +646,26 @@ function ComposerPromptEditorInner({ · 10 unmodified lines
645 return;646 return;
646 }647 }
647 648
648 if (previousSnapshot.value !== value) {
649 editor.update(() => {
650 $setComposerEditorPrompt(value);
651 });
652 }
653
654 snapshotRef.current = { value, cursor: normalizedCursor };649 snapshotRef.current = { value, cursor: normalizedCursor };
655 650
656 const rootElement = editor.getRootElement();651 const rootElement = editor.getRootElement();
657 if (!rootElement || document.activeElement !== rootElement) {652 const isFocused = Boolean(rootElement && document.activeElement === rootElement);
653 if (previousSnapshot.value === value && !isFocused) {
658 return;654 return;
659 }655 }
660 656
657 isApplyingControlledUpdateRef.current = true;
661 editor.update(() => {658 editor.update(() => {
662 $setSelectionAtComposerOffset(normalizedCursor);659 const valueChanged = previousSnapshot.value !== value;
660 if (previousSnapshot.value !== value) {
661 $setComposerEditorPrompt(value);
662 }
663 if (valueChanged || isFocused) {
664 $setSelectionAtComposerOffset(normalizedCursor);
665 }
666 });
667 queueMicrotask(() => {
668 isApplyingControlledUpdateRef.current = false;
663 });669 });
664 }, [cursor, editor, value]);670 }, [cursor, editor, value]);
665 671
@@ -705,9 +711,7 @@ function ComposerPromptEditorInner({ · 39 unmodified lines
705 focus: () => {711 focus: () => {
706 focusAt(snapshotRef.current.cursor);712 focusAt(snapshotRef.current.cursor);
707 },713 },
708 focusAt: (nextCursor: number) => {714 focusAt,
709 focusAt(nextCursor);
710 },
711 focusAtEnd: () => {715 focusAtEnd: () => {
712 focusAt(snapshotRef.current.value.length);716 focusAt(snapshotRef.current.value.length);
713 },717 },
@@ -728,6 +732,9 @@ function ComposerPromptEditorInner({ · 14 unmodified lines
728 if (previousSnapshot.value === nextValue && previousSnapshot.cursor === nextCursor) {732 if (previousSnapshot.value === nextValue && previousSnapshot.cursor === nextCursor) {
729 return;733 return;
730 }734 }
735 if (isApplyingControlledUpdateRef.current) {
736 return;
737 }
731 snapshotRef.current = {738 snapshotRef.current = {
732 value: nextValue,739 value: nextValue,
733 cursor: nextCursor,740 cursor: nextCursor,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t