From 7619b091da471b81948160d2dbfbe08f77ea42ed Mon Sep 17 00:00:00 2001
From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com>
Date: Tue, 17 Mar 2026 15:49:36 +0100
Subject: [PATCH] feat(mobile): route user profile to pushed screen instead of
popout
---
.../web/src/components/layout/MobileShell.tsx | 27 ++++++++++---------
packages/web/src/stores/uiStore.ts | 14 +++++++---
2 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/packages/web/src/components/layout/MobileShell.tsx b/packages/web/src/components/layout/MobileShell.tsx
index 13825df3..d050f588 100644
--- a/packages/web/src/components/layout/MobileShell.tsx
+++ b/packages/web/src/components/layout/MobileShell.tsx
@@ -6,23 +6,17 @@ import { MobileScreenStack } from './MobileScreenStack';
import { MobileBottomNav } from './MobileBottomNav';
import { useSwipeGesture } from '../../hooks/useSwipeGesture';
-// Screen components — imported as they are created in subsequent tasks.
-// Inline placeholders are used until the real components exist.
-const PlaceholderScreen = ({ label }: { label: string }) => (
-
- {label}
-
-);
-
import { MobileSpacesScreen } from './MobileSpacesScreen';
-import { FriendsPage } from '../chat/FriendsPage';
-// These will be replaced with real imports as each task is completed:
import { MobileDmsScreen } from './MobileDmsScreen';
import { MobileYouScreen } from './MobileYouScreen';
import { MobileChatScreen } from './MobileChatScreen';
import { MobileSettingsScreen } from './MobileSettingsScreen';
import { MobileVoiceMiniBar } from './MobileVoiceMiniBar';
import { MobileVoiceFullScreen } from './MobileVoiceFullScreen';
+import { MemberSidebar } from './MemberSidebar';
+import { FriendsPage } from '../chat/FriendsPage';
+import { ExplorePage } from '../chat/ExplorePage';
+import { UserProfileModal } from '../modals/UserProfileModal';
const screenMap: Record) => React.ReactNode> = {
'channel-chat': (params) => ,
@@ -33,10 +27,17 @@ const screenMap: Record) => React.React
'settings-privacy': () => ,
'settings-connections': () => ,
'settings-instance': () => ,
- 'members': () => ,
+ 'members': () => ,
'voice-full': () => ,
- 'explore': () => ,
- 'user-profile': () => ,
+ 'explore': () => ,
+ 'user-profile': (params) => {
+ // Open the user profile modal with the userId from params
+ if (params?.userId) {
+ // Set modalData so UserProfileModal can read it
+ useUIStore.getState().openModal('userProfile', { userId: params.userId });
+ }
+ return ;
+ },
};
export function MobileShell() {
diff --git a/packages/web/src/stores/uiStore.ts b/packages/web/src/stores/uiStore.ts
index ba4721dd..3f872a5e 100644
--- a/packages/web/src/stores/uiStore.ts
+++ b/packages/web/src/stores/uiStore.ts
@@ -112,9 +112,17 @@ export const useUIStore = create()(
openImagePreview: (url) => set({ activeModal: 'imagePreview', imagePreviewUrl: url }),
closeImagePreview: () => set({ activeModal: null, imagePreviewUrl: null }),
- openUserProfile: (user, position) => set({
- userProfilePopout: { user, position }
- }),
+ openUserProfile: (user, position) => {
+ if (get().isMobile) {
+ // On mobile, push a full-screen user profile instead of a positioned popout
+ set((state) => ({
+ mobileStack: [...state.mobileStack, { screen: 'user-profile', params: { userId: user.id } }],
+ }));
+ history.pushState({ mobileScreen: 'user-profile' }, '');
+ } else {
+ set({ userProfilePopout: { user, position } });
+ }
+ },
closeUserProfile: () => set({
userProfilePopout: { user: null, position: null }
}),