fix: restore proposals + attribution on coediting enter (PUC-7) — registry onDidChange subscribers
Task 4 gated every surface on CoeditingRegistry but only wired ThreadController/EditorProposalController to registry.onDidChange for restore-on-enter — ProposalController.renderAll and AttributionController.loadAll were never called on the enter transition, so a document's FIRST enter with pre-existing sidecar proposals/attribution showed threads but not proposal decorations/CodeLens or committed author-coloring until a later edit happened to fire them (a gap Task 4's own report flagged as known and unfixed). Both controllers now subscribe to registry.onDidChange in their constructors and call renderAll/loadAll on entry only (both already self-gate on isCoediting; exit stays hide-only, mirroring ThreadController). Construction order in extension.ts (attribution before proposals before EditorProposalController) keeps the same-tick read order correct. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -77,6 +77,21 @@ export class AttributionController implements vscode.Disposable {
|
||||
vscode.workspace.onDidChangeTextDocument((e) => this.onDidChange(e)),
|
||||
vscode.workspace.onDidSaveTextDocument((d) => this.onDidSave(d)),
|
||||
vscode.window.onDidChangeActiveTextEditor(() => this.renderActive()),
|
||||
// PUC-7 restore-on-enter: `loadAll` is the only path that (re)populates
|
||||
// s.spans/s.orphans from the sidecar — without this, a document's FIRST
|
||||
// entry into coediting (registry.enter(), extension.ts) never runs it,
|
||||
// so pre-existing committed authorship never surfaces until the next
|
||||
// edit. Mirrors ThreadController's own registry subscription; `loadAll`
|
||||
// already gates on isCoediting, and exit intentionally does nothing here
|
||||
// (no data to wipe — EditorProposalController's own gate clears the
|
||||
// decorations that read spansFor). Registered before ProposalController/
|
||||
// EditorProposalController (construction order in extension.ts) so their
|
||||
// renders see fresh spans on the same enter transition.
|
||||
this.registry.onDidChange(({ uri, coediting }) => {
|
||||
if (!coediting) return;
|
||||
const doc = vscode.workspace.textDocuments.find((d) => d.uri.toString() === uri);
|
||||
if (doc) this.loadAll(doc);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,23 @@ export class ProposalController implements vscode.Disposable {
|
||||
this.disposables.push(this.onDidChangeProposalsEmitter);
|
||||
this.disposables.push(
|
||||
vscode.workspace.onDidChangeTextDocument((e) => this.onDidChange(e)),
|
||||
// PUC-7 restore-on-enter (mirrors ThreadController/AttributionController):
|
||||
// `renderAll` is the only path that recomputes state.live/unresolved AND
|
||||
// fires onDidChangeProposals — the event EditorProposalController listens
|
||||
// to for optimistic-apply (decorations/CodeLens). Without this, a FIRST
|
||||
// entry into coediting (registry.enter()) never fires it, so pre-existing
|
||||
// pending proposals stay un-applied/undecorated until the next edit.
|
||||
// `renderAll` already gates on isCoediting; exit intentionally does
|
||||
// nothing here (it clears only the live/unresolved recompute, not the
|
||||
// persisted artifact — EditorProposalController's own gate hides the
|
||||
// decorations). Registered after AttributionController's own subscription
|
||||
// (construction order in extension.ts) so decorateCommitted's spansFor
|
||||
// read sees fresh attribution on the same enter transition.
|
||||
this.registry.onDidChange(({ uri, coediting }) => {
|
||||
if (!coediting) return;
|
||||
const doc = vscode.workspace.textDocuments.find((d) => d.uri.toString() === uri);
|
||||
if (doc) this.renderAll(doc);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user