feat(mobile): admin reach + post-mount routing + RegistrationPanel modals → Modal

MobileInstancePanel gains Registration and Federation entries (parity with
desktop's six sub-tabs). MobileShell registers the matching screenMap
wrappers; the Federation entry surfaces the live approval-count badge via
a new uiStore slot and a wrapper that forwards FederationPanel's
onApprovalCountChange.

MobileShell's deep-link reconstruction now reacts to post-mount pathname
changes (was [] / mount-only) with an idempotency guard that skips the
push when the topmost stack entry already represents the new URL —
prevents the pushMobileScreen → history.pushState → location-effect
double-push.

RegistrationPanel's four portaled modals (CreateInvite, EditInvite,
ReinstateInvite, Redemptions) now render through the shared <Modal>
with mobileStyle="fullscreen", portaled to document.body to escape the
parent settings dialog's backdrop-filter containing block. Desktop
appearance preserved (same maxWidth, same sticky action bar).
This commit is contained in:
Jannis Braun
2026-05-05 23:23:37 +02:00
parent 69cd2dc537
commit e2d938e6c0
6 changed files with 638 additions and 514 deletions
+9
View File
@@ -72,6 +72,12 @@ interface UIState {
setMobileTab: (tab: 'spaces' | 'dms' | 'you') => void;
pushMobileScreen: (screen: string, params?: Record<string, string>) => void;
popMobileScreen: () => void;
// Federation approval-count badge (surfaced by MobileInstancePanel; kept fresh
// by the FederationPanel via `onApprovalCountChange` whenever an admin
// approves/denies a request from inside the panel)
federationApprovalCount: number;
setFederationApprovalCount: (count: number) => void;
}
export const useUIStore = create<UIState>()(
@@ -172,6 +178,9 @@ export const useUIStore = create<UIState>()(
// Note: do NOT call history.back() here if triggered by popstate event.
// The MobileShell popstate handler manages this — see Task 5.
},
federationApprovalCount: 0,
setFederationApprovalCount: (count) => set({ federationApprovalCount: count }),
}),
{
name: 'backspace-ui-settings',