fix(channels): re-hydrate per-account manager state once the account is pinned

The provider tree mounts above <App>, which pins this tab's account only after /api/me
resolves — so on a genuinely fresh tab (empty sessionStorage) the manager's sort, filters,
view and layout initialised from an unknown account and stayed at defaults until a second
reload. Make the active account reactive (a subscribable store + useActiveAccountId via
useSyncExternalStore; setActiveAccount/clearActiveAccount notify) and re-read the stored
value when the account transitions null→id, via a shared useAccountRehydrate hook. A
markDirty guard (called by each owning setter) prevents clobbering a value the user changed
in the brief pre-pin window; the effect is keyed on the account id only, so the user's own
writes can't loop it. useSortState, useFilterState and ChannelsProvider (view/layout) all
adopt it. Affects sort identically — this was a long-standing caveat, not new to R13.
This commit is contained in:
2026-08-14 02:37:28 +02:00
parent ca9dd54923
commit b57e4fb9bc
9 changed files with 160 additions and 27 deletions
+7 -1
View File
@@ -1,5 +1,6 @@
import { useCallback, useState } from "react";
import { getAccountRaw, setAccountRaw } from "./storage";
import { useAccountRehydrate } from "./useAccountRehydrate";
import { hydrateSort, type SortOption, type SortState } from "./columnSort";
// The per-account persisted sort state, hydrated + healed against the current options — the plumbing
@@ -13,12 +14,17 @@ export function useSortState(
const [sort, setSort] = useState<SortState>(() =>
hydrateSort(getAccountRaw(storageBase), options, fallback),
);
// When the account is pinned after mount (first load), re-read the stored sort for that account.
const markDirty = useAccountRehydrate(() =>
setSort(hydrateSort(getAccountRaw(storageBase), options, fallback)),
);
const set = useCallback(
(next: SortState) => {
markDirty();
setSort(next);
setAccountRaw(storageBase, JSON.stringify(next));
},
[storageBase],
[storageBase, markDirty],
);
return [sort, set];
}