fix(dashboard): stop the planning textarea from reverting to the persisted description on every keystroke
The "restore description from localStorage" branch ran inside an effect whose deps included handleStartPlanning, and that callback regenerated on every change to initialPlan. So every keystroke would re-fire the effect, hit the same `getPlanningDescription` value, and overwrite what the user just typed. Guard the restore with a one-shot ref so it only runs the first time the modal opens, and reset the ref when the modal closes so a future re-open still picks up an updated persisted value. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -96,6 +96,7 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat
|
||||
// which would skip auto-start on the second (committed) render. Refs are
|
||||
// re-initialized on each render, ensuring the auto-start effect runs correctly.
|
||||
const hasAutoStartedRef = useRef(false);
|
||||
const hasLoadedPersistedRef = useRef(false);
|
||||
const [streamingOutput, setStreamingOutput] = useState<string>("");
|
||||
const [showThinking, setShowThinking] = useState(true);
|
||||
const [isReconnecting, setIsReconnecting] = useState(false);
|
||||
@@ -369,14 +370,24 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat
|
||||
handleStartPlanning(initialPlanProp);
|
||||
}, 0);
|
||||
return () => clearTimeout(timer);
|
||||
} else if (isOpen && !initialPlanProp && !hasAutoStartedRef.current && view.type === "initial") {
|
||||
// Check localStorage for persisted description when no prop provided
|
||||
} else if (
|
||||
isOpen &&
|
||||
!initialPlanProp &&
|
||||
!hasAutoStartedRef.current &&
|
||||
!hasLoadedPersistedRef.current &&
|
||||
view.type === "initial"
|
||||
) {
|
||||
// Restore the persisted description from localStorage on first open only.
|
||||
// Without the ref this effect re-fires on every keystroke (handleStart-
|
||||
// Planning depends on initialPlan), and each fire would clobber what
|
||||
// the user just typed back to the persisted value.
|
||||
hasLoadedPersistedRef.current = true;
|
||||
const persisted = getPlanningDescription(projectId);
|
||||
if (persisted) {
|
||||
setInitialPlan(persisted);
|
||||
}
|
||||
}
|
||||
}, [isOpen, initialPlanProp, view.type, handleStartPlanning]);
|
||||
}, [isOpen, initialPlanProp, view.type, handleStartPlanning, projectId]);
|
||||
|
||||
// Resume a persisted background session
|
||||
useEffect(() => {
|
||||
@@ -435,6 +446,7 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat
|
||||
useEffect(() => {
|
||||
if (!isOpen) {
|
||||
hasAutoStartedRef.current = false;
|
||||
hasLoadedPersistedRef.current = false;
|
||||
setIsReconnecting(false);
|
||||
setIsRetrying(false);
|
||||
setLockSessionId(null);
|
||||
|
||||
Reference in New Issue
Block a user