fix(ui): a page's sub-tab is remembered per browser tab, not forever
Settings, Configuration, Statistics and Users kept the last sub-tab in localStorage, so every fresh tab opened Configuration on "Plex" as if that were its home. useTabPersistedState keeps it in sessionStorage (account-scoped): a reload and a trip to another page keep it, a new tab starts on the first sub-tab. The pre-selects (a Review link, the Google-link return) write the same store; a value an older build left in localStorage is cleared on first read.
This commit is contained in:
@@ -42,6 +42,8 @@ export const LS = {
|
||||
channelDiscoveryCardSize: "siftlode.channelDiscoveryCardSize",
|
||||
channelsTable: "siftlode.channelsTable",
|
||||
channelDiscoveryTable: "siftlode.channelDiscoveryTable",
|
||||
// A page's sub-tab: sessionStorage, per browser tab (useTabPersistedState), like adminUsersTab and
|
||||
// statsTab below.
|
||||
settingsTab: "siftlode.settingsTab",
|
||||
configTab: "siftlode.configTab",
|
||||
auditTable: "siftlode.auditTable",
|
||||
@@ -174,6 +176,61 @@ export function useAccountPersistedState(
|
||||
return [value, set];
|
||||
}
|
||||
|
||||
// --- a page's sub-tab, per browser tab ---------------------------------------------------------
|
||||
|
||||
// Which sub-tab a page was left on (Settings, Configuration, Statistics, Users) is kept for THIS browser
|
||||
// tab only — sessionStorage, account-scoped: it survives a reload and a trip to another page, and a new
|
||||
// tab opens the page on its first sub-tab (the owner, E31: a position remembered forever in
|
||||
// localStorage made Configuration open on "Plex" in every fresh tab, as if that were its home).
|
||||
|
||||
/** The sub-tab stored for this browser tab, or null. */
|
||||
function getTabRaw(base: string): string | null {
|
||||
const k = accountKey(base);
|
||||
try {
|
||||
return k ? sessionStorage.getItem(k) : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Pre-select a page's sub-tab before navigating there (a "Review" link, the Google-link return). */
|
||||
export function setTabRaw(base: string, value: string): void {
|
||||
const k = accountKey(base);
|
||||
if (!k) return;
|
||||
try {
|
||||
sessionStorage.setItem(k, value);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
/** `useAccountPersistedState` for a page's sub-tab, kept per browser tab (see above). */
|
||||
export function useTabPersistedState(
|
||||
base: string,
|
||||
fallback = "",
|
||||
): [string, (value: string) => void] {
|
||||
const [value, setValue] = useState<string>(() => {
|
||||
// Before E31 the position lived in localStorage; a value left there would never be read again.
|
||||
const old = accountKey(base);
|
||||
if (old) {
|
||||
try {
|
||||
localStorage.removeItem(old);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
return getTabRaw(base) ?? fallback;
|
||||
});
|
||||
const set = useCallback(
|
||||
(next: string) => {
|
||||
setValue(next);
|
||||
setTabRaw(base, next);
|
||||
},
|
||||
[base],
|
||||
);
|
||||
return [value, set];
|
||||
}
|
||||
|
||||
/** A per-account persisted JSON OBJECT: `patch(partial)` merges + saves, unknown/missing keys fall
|
||||
* back to `defaults` (via readAccountMerged) so adding a field later is safe. Used for bundles of
|
||||
* related per-account settings (e.g. the Plex player prefs: volume, offsets, seek steps, sub style). */
|
||||
|
||||
Reference in New Issue
Block a user