feat(mobile): add screen stack navigation state to uiStore

This commit is contained in:
Jannis Braun
2026-03-17 15:28:36 +01:00
parent 8dda8b0b83
commit 8bd74ec608
+36 -3
View File
@@ -17,6 +17,11 @@ type ModalType =
| 'userProfile' | 'userProfile'
| null; | null;
interface MobileStackEntry {
screen: string;
params?: Record<string, string>;
}
interface Toast { interface Toast {
id: string; id: string;
message: string; message: string;
@@ -59,6 +64,13 @@ interface UIState {
setPipCollapsed: (collapsed: boolean) => void; setPipCollapsed: (collapsed: boolean) => void;
floatingPanelHeight: number; floatingPanelHeight: number;
setFloatingPanelHeight: (height: number) => void; setFloatingPanelHeight: (height: number) => void;
// Mobile navigation
mobileScreen: 'spaces' | 'dms' | 'you';
mobileStack: MobileStackEntry[];
setMobileTab: (tab: 'spaces' | 'dms' | 'you') => void;
pushMobileScreen: (screen: string, params?: Record<string, string>) => void;
popMobileScreen: () => void;
} }
export const useUIStore = create<UIState>()( export const useUIStore = create<UIState>()(
@@ -89,9 +101,9 @@ export const useUIStore = create<UIState>()(
if (isMobile) { if (isMobile) {
set({ isMobile, sidebarOpen: false, memberListOpen: false }); set({ isMobile, sidebarOpen: false, memberListOpen: false });
} else { } else {
// On desktop transition, restore sidebarOpen but leave memberListOpen // On desktop transition: restore sidebar, clear mobile nav state
// at its persisted/toggled value — don't override user preference // memberListOpen is NOT reset here — it keeps its persisted/toggled value
set({ isMobile, sidebarOpen: true }); set({ isMobile, sidebarOpen: true, mobileScreen: 'spaces' as const, mobileStack: [] });
} }
}, },
@@ -130,6 +142,27 @@ export const useUIStore = create<UIState>()(
setPipCollapsed: (collapsed) => set({ pipCollapsed: collapsed }), setPipCollapsed: (collapsed) => set({ pipCollapsed: collapsed }),
floatingPanelHeight: 140, floatingPanelHeight: 140,
setFloatingPanelHeight: (height) => set({ floatingPanelHeight: height }), setFloatingPanelHeight: (height) => set({ floatingPanelHeight: height }),
mobileScreen: 'spaces',
mobileStack: [],
setMobileTab: (tab) => set({ mobileScreen: tab, mobileStack: [] }),
pushMobileScreen: (screen, params) => {
set((state) => ({
mobileStack: [...state.mobileStack, { screen, params }],
}));
// Sync with browser history so hardware back button works
history.pushState({ mobileScreen: screen }, '');
},
popMobileScreen: () => {
const state = get();
if (state.mobileStack.length === 0) return;
set({ mobileStack: state.mobileStack.slice(0, -1) });
// Note: do NOT call history.back() here if triggered by popstate event.
// The MobileShell popstate handler manages this — see Task 5.
},
}), }),
{ {
name: 'backspace-ui-settings', name: 'backspace-ui-settings',