fix(deferred): close frontend UI/UX tails from the hygiene sweep
- player YB2: keepalive pagehide beacon (api.saveProgressBeacon) so the resume position isn't lost on F5/close within 5s of the last checkpoint (mirrors Plex). - player YB4: bound consecutive unplayable items in auto-advance so an auto-advancing/loop=all queue can't spin over a run of dead videos. - downloads B6 (client): localise structured quota/edit errors centrally in api.req() via localizeDetail() + Intl.NumberFormat (fixes HU/DE + decimal sep); + 3-locale download error strings. - channels FB1: focusChannelToken bump so re-clicking the same channel re-seeds the search box; FB2: syncSubs invalidates feed/feed-count (set can change now). - config CB2: reseed the ConfigPanel draft on a key-set dataVersion + explicit post-save token, so a mid-edit refetch can't clobber an in-progress edit. - config AB3 (UI): a blank allow_empty field stores "" instead of resetting. - admin SB2/SC2: confirm + success toast on demo-whitelist remove and deny-invite (+ trilingual strings); SC1: disable only the acted-on row (pendingId), not all; SB3: pause the 1s scheduler countdown ticker while the tab is hidden. - messages CT4: only invalidate conversations/unread when the incoming-message count actually changed, not on every 20s poll; MB3 (client): react to the live unread ping (onUnread → invalidate); MC3: extract e2ee installKey (setup/unlock); CC2: hoist POLL_MS to messaging.ts; MB4: document the reload-scoped socket.
This commit is contained in:
parent
4e80e2b39b
commit
f0198f2e0a
19 changed files with 302 additions and 45 deletions
|
|
@ -48,6 +48,7 @@ export default function Channels({
|
|||
onFilterByTag,
|
||||
onFocusChannel,
|
||||
focusChannelName,
|
||||
focusChannelToken,
|
||||
statusFilter,
|
||||
setStatusFilter,
|
||||
view,
|
||||
|
|
@ -61,6 +62,9 @@ export default function Channels({
|
|||
onFilterByTag: (tagId: number, name: string) => void;
|
||||
onFocusChannel: (name: string) => void;
|
||||
focusChannelName: string | null;
|
||||
// Bumped every time a focus-channel intent is (re-)issued, so re-clicking the same channel
|
||||
// re-seeds the search box even when the name is unchanged.
|
||||
focusChannelToken: number;
|
||||
statusFilter: ChannelStatusFilter;
|
||||
setStatusFilter: (f: ChannelStatusFilter) => void;
|
||||
// The active tab lives in App so navigation intents that target the subscriptions table
|
||||
|
|
@ -92,6 +96,10 @@ export default function Channels({
|
|||
qc.invalidateQueries({ queryKey: ["channels"] });
|
||||
qc.invalidateQueries({ queryKey: ["tags"] });
|
||||
qc.invalidateQueries({ queryKey: ["my-status"] });
|
||||
// FB2: syncing subscriptions can change the feed immediately — newly-followed channels may
|
||||
// already have videos in the shared catalog, so refresh the feed too (not just the manager).
|
||||
qc.invalidateQueries({ queryKey: ["feed"] });
|
||||
qc.invalidateQueries({ queryKey: ["feed-count"] });
|
||||
};
|
||||
|
||||
const userTags = (tagsQuery.data ?? []).filter((t) => !t.system);
|
||||
|
|
@ -189,7 +197,8 @@ export default function Channels({
|
|||
// A focus-channel intent (header "without full history" / tag manager) seeds the search box.
|
||||
useEffect(() => {
|
||||
if (focusChannelName) setSearch(focusChannelName);
|
||||
}, [focusChannelName]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [focusChannelToken]);
|
||||
// The header's reset intent clears the search + tag chips (skip the initial mount).
|
||||
const resetRef = useRef(filtersResetToken);
|
||||
useEffect(() => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue