diff --git a/src/views/components/AddTaskModal.jsx b/src/views/components/AddTaskModal.jsx index 500f7a9..930192e 100644 --- a/src/views/components/AddTaskModal.jsx +++ b/src/views/components/AddTaskModal.jsx @@ -161,6 +161,10 @@ const TaskInput = ({ initialMode, isModalOpen, onChoreUpdate, onClose }) => { // Picker edits made on a voice task card, applied once after the reparse // that follows landing the spoken text in the smart input const pendingVoiceOverridesRef = useRef(null) + // True while the current assignees came from an @mention in the text, so a + // reparse without mentions only resets what a mention set — never a + // selection made directly in the assignee picker + const assigneesFromMentionRef = useRef(false) const [priority, setPriority] = useState(0) const [dueDate, setDueDate] = useState(null) const [description, setDescription] = useState(null) @@ -510,14 +514,18 @@ const TaskInput = ({ initialMode, isModalOpen, onChoreUpdate, onClose }) => { // @Anyone was used - set empty assignees (anyone can do the task) setIsAnyoneTask(true) setAssignees([]) + assigneesFromMentionRef.current = true } else if (assigneesResult.result && assigneesResult.result.length > 0) { setIsAnyoneTask(false) const parsedAssignees = assigneesResult.result.map(assignee => ({ userId: assignee.userId, })) setAssignees(parsedAssignees) - } else { - // Only assign to current user if no @ mentions found and userProfile exists + assigneesFromMentionRef.current = true + } else if (assigneesFromMentionRef.current) { + // The @mention that set the current assignees was deleted — fall back + // to the implicit self default. Picker selections stay untouched. + assigneesFromMentionRef.current = false setIsAnyoneTask(false) if (userProfile?.id) { setAssignees([ @@ -622,6 +630,7 @@ const TaskInput = ({ initialMode, isModalOpen, onChoreUpdate, onClose }) => { if ('assignees' in overrides || 'isAnyone' in overrides) { setIsAnyoneTask(!!overrides.isAnyone) setAssignees(overrides.assignees || []) + assigneesFromMentionRef.current = false } if ('dueDate' in overrides) { if (overrides.dueDate) { @@ -849,6 +858,7 @@ const TaskInput = ({ initialMode, isModalOpen, onChoreUpdate, onClose }) => { setHasSubTasks(false) setLabelsV2([]) setAssignees([]) + assigneesFromMentionRef.current = false setProjectId(getInitialProject()) setDeadlineOffset(-1) setRequireApproval(false) @@ -1351,7 +1361,9 @@ const TaskInput = ({ initialMode, isModalOpen, onChoreUpdate, onClose }) => { onAssignStrategyChange={setAssignStrategy} hasDueDate={!!dueDate} hasMultipleAssignees={assignees.length > 1} - hasAssignees={assignees.length > 0} + // Empty assignees still implicitly assigns the current user at + // create time; only an "Anyone" task truly has no assignee + hasAssignees={!isAnyoneTask} isPrivate={isPrivate} onIsPrivateChange={setIsPrivate} /> diff --git a/src/views/components/SmartTaskTitleInput.jsx b/src/views/components/SmartTaskTitleInput.jsx index 4b38458..b67714c 100644 --- a/src/views/components/SmartTaskTitleInput.jsx +++ b/src/views/components/SmartTaskTitleInput.jsx @@ -118,6 +118,7 @@ const SmartTaskTitleInput = ({ const newCursorPosition = cursorPosition - lastWord.length + suggestionValue.length + 1 + setCursorPosition(newCursorPosition) titleInputRef.current.setSelectionRange( newCursorPosition, newCursorPosition, @@ -373,18 +374,10 @@ const SmartTaskTitleInput = ({ const suggestionValue = suggestions[suggestionTrigger].display ? suggestion[suggestions[suggestionTrigger].display] : suggestion - const newValue = `${value.slice(0, cursorPosition)}${suggestionValue}${value.slice(cursorPosition)}` - - onChange(newValue) + // Same insertion path as keyboard selection: replace the partial + // word typed after the trigger instead of inserting alongside it titleInputRef?.current?.focus() - - setCursorPosition(cursorPosition + suggestion.length) - titleInputRef.current.value = newValue - titleInputRef.current.setSelectionRange( - cursorPosition + suggestionValue.length, - cursorPosition + suggestionValue.length, - ) - setShowSuggestions(false) + selectSuggestionText(suggestionValue) }} onCreateSuggestion={name => { selectSuggestionText(name)