mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
buildMessageAnnotationEntries() is reachable on the render path via
currentFeedbackPayload (useMemo) -> getCurrentFeedbackPayload ->
buildFullAnnotationsOutput. It called saveCurrentMessageState(), which
writes React state (setCachedMessageAnnotationCounts) with a fresh Map
each call, so React's Object.is bail-out never fires. In multi-message
mode (annotateSource === 'message' && recentMessages.length > 1) this is
an infinite re-render — React throws #301 and the page renders blank.
This broke /plannotator-last on Pi for any conversation with 2+ assistant
messages.
Switch the render-path read to getMessageStatesWithCurrent(), which
returns the same merged states (cached + live current message) without
the setState side effect. Cache persistence still happens in event
handlers (handleSelectMessage). Exported feedback is unchanged.
Root cause introduced in 1fa60522. Reported and diagnosed by @emmaneugene.
Closes #949
This commit is contained in:
@@ -896,7 +896,14 @@ const App: React.FC = () => {
|
||||
|
||||
const buildMessageAnnotationEntries = React.useCallback((): MessageAnnotationEntry[] => {
|
||||
if (annotateSource !== 'message' || recentMessages.length === 0) return [];
|
||||
const states = saveCurrentMessageState();
|
||||
// Must be a PURE read: this runs on the render path via
|
||||
// currentFeedbackPayload (useMemo) -> getCurrentFeedbackPayload ->
|
||||
// buildFullAnnotationsOutput. saveCurrentMessageState() writes React state
|
||||
// (setCachedMessageAnnotationCounts), which during render is an infinite
|
||||
// re-render loop in multi-message mode (#949). getMessageStatesWithCurrent
|
||||
// returns the same merged data without the setState side effect; the cache
|
||||
// persistence happens in event handlers (handleSelectMessage) instead.
|
||||
const states = getMessageStatesWithCurrent();
|
||||
return recentMessages.map((msg) => {
|
||||
const state = states.get(msg.messageId) ?? createEmptyMessageState(msg);
|
||||
const linkedDocs: Map<string, LinkedDocAnnotationEntry> = new Map();
|
||||
@@ -917,7 +924,7 @@ const App: React.FC = () => {
|
||||
codeAnnotations: state.codeAnnotations,
|
||||
};
|
||||
});
|
||||
}, [annotateSource, recentMessages, saveCurrentMessageState]);
|
||||
}, [annotateSource, recentMessages, getMessageStatesWithCurrent]);
|
||||
|
||||
const activeMessageAnnotationCounts = React.useMemo(() => {
|
||||
const counts = new Map(cachedMessageAnnotationCounts);
|
||||
|
||||
Reference in New Issue
Block a user