-
Notifications
You must be signed in to change notification settings - Fork 343
[front] fix: stop sticky human mention re-inserting in the composer #32281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -253,6 +253,17 @@ export interface InputBarContainerProps { | |
| isSelectableSpacesLoading?: boolean; | ||
| onSelectedSpaceIdsChange?: (spaceIds: string[]) => Promise<string[] | null>; | ||
| stickyMentions?: RichMention[]; | ||
| /** | ||
| * @cc [owner:frankaloia,label:react] sticky-human-mentions-prefill-once-per-source | ||
| * Sticky human mentions MUST be prefilled into the composer at most once per | ||
| * (conversation, source message). `stickyMentionsSourceId` identifies that source — the sId of | ||
| * the current user's last message the mentions derive from. Callers MUST set it so the prefill | ||
| * re-arms only when the user sends a new message (new source id) or switches conversation, not | ||
| * on unrelated conversation updates (streaming, other participants' messages). Re-inserting on | ||
| * every update re-adds the mention to the empty composer and prevents the user from dismissing | ||
| * it. | ||
| */ | ||
| stickyMentionsSourceId?: string | null; | ||
| user: UserType | null; | ||
| } | ||
|
|
||
|
|
@@ -278,6 +289,7 @@ const InputBarContainer = ({ | |
| selectedAgent, | ||
| pendingInputText, | ||
| stickyMentions, | ||
| stickyMentionsSourceId, | ||
| actions, | ||
| disableAutoFocus, | ||
| disableUserMentions, | ||
|
|
@@ -853,6 +865,11 @@ const InputBarContainer = ({ | |
| selectedSingleAgentRef.current = selectedSingleAgent; | ||
| // Skip auto-save (especially clearDraft on empty) until initial content is restored. | ||
| const hasCompletedInitialContentRestoreRef = useRef(false); | ||
| // Tracks the (conversation, source message) for which sticky human mentions were last | ||
| // prefilled, so we insert them once per source rather than on every re-render. Without this, | ||
| // streaming updates and other participants' messages would keep re-inserting the mention into | ||
| // the empty composer, and the user could not dismiss it. | ||
| const appliedStickyMentionKeyRef = useRef<string | null>(null); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new |
||
|
|
||
| const saveCurrentDraftWithSelectedSpaces = useCallback( | ||
| (spaceIds: string[]) => { | ||
|
|
@@ -1387,7 +1404,6 @@ const InputBarContainer = ({ | |
|
|
||
| // Restore draft text when switching conversations (including new conversations). | ||
| // Agent selection is handled by useHandleMention. | ||
| // biome-ignore lint/correctness/useExhaustiveDependencies: ignored using `--suppress` | ||
| useEffect(() => { | ||
| hasCompletedInitialContentRestoreRef.current = false; | ||
|
|
||
|
|
@@ -1421,10 +1437,19 @@ const InputBarContainer = ({ | |
| return; | ||
| } | ||
|
|
||
| // No draft — insert sticky user mentions into the editor | ||
| // No draft — insert sticky user mentions into the editor, but only once per source message. | ||
| // The effect re-runs on every conversation update (streaming, other participants' messages), | ||
| // so without this key it would keep re-inserting the mention into the empty composer and the | ||
| // user could never dismiss it. The key changes when the current user sends a new message (new | ||
| // source id) or switches conversation, which is exactly when we want to re-prefill. | ||
| const stickyUserMentions = stickyMentions?.filter(isRichUserMention) ?? []; | ||
| if (stickyUserMentions.length > 0) { | ||
| const stickyMentionKey = `${conversation?.sId ?? "new"}::${stickyMentionsSourceId ?? ""}`; | ||
| if ( | ||
| stickyUserMentions.length > 0 && | ||
| appliedStickyMentionKeyRef.current !== stickyMentionKey | ||
| ) { | ||
| editorService.resetWithMentions(stickyUserMentions, disableAutoFocus); | ||
| appliedStickyMentionKeyRef.current = stickyMentionKey; | ||
| } | ||
|
|
||
| hasCompletedInitialContentRestoreRef.current = true; | ||
|
|
@@ -1436,6 +1461,7 @@ const InputBarContainer = ({ | |
| editorService, | ||
| getDraft, | ||
| stickyMentions, | ||
| stickyMentionsSourceId, | ||
| disableAutoFocus, | ||
| ]); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new
sticky-human-mentions-prefill-once-per-sourcecontract onInputBarContainerProps.stickyMentionsSourceIdconflicts with the pre-existing optimistic-message lifecycle:lastUserMessagechanges fromplaceholder-user-message-*to a server ID for the same send (ConversationViewer.tsx:1296). If acknowledgment occurs while the initial prefill remains, the ref keeps the placeholder key; dismissing the mention and receiving another update then reinserts it without a new message.