fix(ui): close review findings from the switch-and-scroll integration
- Markdown DOM cache: key includes a content-length fingerprint so an edited or reverted part re-materializing under the same id cannot restore stale DOM, memoization uses scalar identities instead of the part object (store reducers recreate part objects on unrelated updates, which re-ran the async render pipeline for identical content), and a probe with a mismatched locale/directory no longer destroys the entry it failed to claim. - Sidebar bootstrap: the layout-level sync owner only knows known directories, so expanded projects bootstrapped serialized at background priority. The visible collection now publishes a second, expansion- aware demand owner, restoring concurrent hydration for expanded projects and worktree groups. - Settings: local changes still sitting in the debounce buffer are not yet tracked as mutations, so a settings GET racing the debounce window briefly reverted them; reconciled results now reapply the pending buffer.
This commit is contained in:
@@ -1884,12 +1884,22 @@ export const syncDesktopSettings = async (): Promise<void> => {
|
||||
// Each step is wrapped in try/catch so a failure in one side-effect (e.g.
|
||||
// a TypeError from writing to a contextBridge-protected global) doesn't
|
||||
// prevent server settings from reaching the Zustand store.
|
||||
// Local changes sitting in the debounce buffer are not yet tracked as
|
||||
// mutations (record() only stores while a request is in flight), so a GET
|
||||
// racing the debounce window would briefly revert them. Reapply the
|
||||
// pending buffer over every reconciled result.
|
||||
const overlayPendingChanges = (settings: DesktopSettings): DesktopSettings => {
|
||||
if (!_pendingSettingsChanges || !_pendingSettingsContext) return settings;
|
||||
if (!isSettingsRuntimeContextCurrent(_pendingSettingsContext)) return settings;
|
||||
return { ...settings, ..._pendingSettingsChanges };
|
||||
};
|
||||
|
||||
const applySettings = async (loadedSettings: DesktopSettings) => {
|
||||
if (!isSettingsRuntimeContextCurrent(context)) return;
|
||||
let settings = _settingsMutationTracker.reconcile(loadedSettings, operation);
|
||||
let settings = overlayPendingChanges(_settingsMutationTracker.reconcile(loadedSettings, operation));
|
||||
await waitForHydration();
|
||||
if (!isSettingsRuntimeContextCurrent(context)) return;
|
||||
settings = _settingsMutationTracker.reconcile(loadedSettings, operation);
|
||||
settings = overlayPendingChanges(_settingsMutationTracker.reconcile(loadedSettings, operation));
|
||||
const shouldPersistCraftGoalMigration = settings.draftStartersCraftGoalAdded !== true
|
||||
|| settings.draftStartersScheduleTaskAdded !== true;
|
||||
// `autoSaveEnabled` is new to the settings backend. Until the server has a
|
||||
|
||||
Reference in New Issue
Block a user