about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/state/models/navigation.ts19
-rw-r--r--src/state/models/session.ts5
-rw-r--r--src/view/lib/icons.tsx32
-rw-r--r--src/view/routes.ts2
-rw-r--r--src/view/screens/Menu.tsx246
-rw-r--r--src/view/shell/mobile/MainMenu.tsx354
-rw-r--r--src/view/shell/mobile/index.tsx21
7 files changed, 300 insertions, 379 deletions
diff --git a/src/state/models/navigation.ts b/src/state/models/navigation.ts
index 6eb13a62a..93aab9d4f 100644
--- a/src/state/models/navigation.ts
+++ b/src/state/models/navigation.ts
@@ -17,8 +17,11 @@ export type HistoryPtr = [number, number]
 
 export class NavigationTabModel {
   id = genId()
-  history: HistoryItem[] = [{url: '/', ts: Date.now(), id: genId()}]
-  index = 0
+  history: HistoryItem[] = [
+    {url: '/menu', ts: Date.now(), id: genId()},
+    {url: '/', ts: Date.now(), id: genId()},
+  ]
+  index = 1
   isNewTab = false
 
   constructor() {
@@ -107,9 +110,15 @@ export class NavigationTabModel {
     }
   }
 
-  goBackToZero() {
-    if (this.canGoBack) {
-      this.index = 0
+  resetTo(path: string) {
+    if (this.index >= 1 && this.history[1]?.url === path) {
+      // fall back in history to target
+      if (this.index > 1) {
+        this.index = 1
+      }
+    } else {
+      this.history = [this.history[0], {url: path, ts: Date.now(), id: genId()}]
+      this.index = 1
     }
   }
 
diff --git a/src/state/models/session.ts b/src/state/models/session.ts
index 069e3db32..1537d1316 100644
--- a/src/state/models/session.ts
+++ b/src/state/models/session.ts
@@ -138,7 +138,10 @@ export class SessionModel {
   }
 
   async connect(): Promise<void> {
-    this._connectPromise ??= this._connect()
+    if (this._connectPromise) {
+      return this._connectPromise
+    }
+    this._connectPromise = this._connect()
     await this._connectPromise
     this._connectPromise = undefined
   }
diff --git a/src/view/lib/icons.tsx b/src/view/lib/icons.tsx
index 7e3313597..31869810d 100644
--- a/src/view/lib/icons.tsx
+++ b/src/view/lib/icons.tsx
@@ -166,6 +166,38 @@ export function BellIconSolid({
   )
 }
 
+export function CogIcon({
+  style,
+  size,
+  strokeWidth = 1.5,
+}: {
+  style?: StyleProp<ViewStyle>
+  size?: string | number
+  strokeWidth: number
+}) {
+  return (
+    <Svg
+      fill="none"
+      viewBox="0 0 24 24"
+      width={size || 32}
+      height={size || 32}
+      strokeWidth={strokeWidth}
+      stroke="currentColor"
+      style={style}>
+      <Path
+        strokeLinecap="round"
+        strokeLinejoin="round"
+        d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z"
+      />
+      <Path
+        strokeLinecap="round"
+        strokeLinejoin="round"
+        d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
+      />
+    </Svg>
+  )
+}
+
 // Copyright (c) 2020 Refactoring UI Inc.
 // https://github.com/tailwindlabs/heroicons/blob/master/LICENSE
 export function UserGroupIcon({
diff --git a/src/view/routes.ts b/src/view/routes.ts
index 272a1b096..e662e2cca 100644
--- a/src/view/routes.ts
+++ b/src/view/routes.ts
@@ -1,6 +1,7 @@
 import React, {MutableRefObject} from 'react'
 import {FlatList} from 'react-native'
 import {IconProp} from '@fortawesome/fontawesome-svg-core'
+import {Menu} from './screens/Menu'
 import {Home} from './screens/Home'
 import {Contacts} from './screens/Contacts'
 import {Search} from './screens/Search'
@@ -33,6 +34,7 @@ export type MatchResult = {
 
 const r = (pattern: string) => new RegExp('^' + pattern + '([?]|$)', 'i')
 export const routes: Route[] = [
+  [Menu, 'Menu', 'bars', r('/menu')],
   [Home, 'Home', 'house', r('/')],
   [Contacts, 'Contacts', ['far', 'circle-user'], r('/contacts')],
   [Search, 'Search', 'magnifying-glass', r('/search')],
diff --git a/src/view/screens/Menu.tsx b/src/view/screens/Menu.tsx
new file mode 100644
index 000000000..d226ea02b
--- /dev/null
+++ b/src/view/screens/Menu.tsx
@@ -0,0 +1,246 @@
+import React, {useEffect} from 'react'
+import {
+  StyleProp,
+  StyleSheet,
+  Text,
+  TouchableOpacity,
+  View,
+  ViewStyle,
+} from 'react-native'
+import {colors} from '../lib/styles'
+import {ScreenParams} from '../routes'
+import {useStores} from '../../state'
+import {
+  HomeIcon,
+  UserGroupIcon,
+  BellIcon,
+  CogIcon,
+  MagnifyingGlassIcon,
+} from '../lib/icons'
+import {UserAvatar} from '../com/util/UserAvatar'
+import {ViewHeader} from '../com/util/ViewHeader'
+import {CreateSceneModel} from '../../state/models/shell-ui'
+
+export const Menu = ({navIdx, visible}: ScreenParams) => {
+  const store = useStores()
+
+  useEffect(() => {
+    if (visible) {
+      store.nav.setTitle(navIdx, 'Menu')
+      // trigger a refresh in case memberships have changed recently
+      store.me.refreshMemberships()
+    }
+  }, [store, visible])
+
+  // events
+  // =
+
+  const onNavigate = (url: string) => {
+    store.nav.navigate(url)
+  }
+  const onPressCreateScene = () => {
+    store.shell.openModal(new CreateSceneModel())
+  }
+
+  // rendering
+  // =
+
+  const MenuItem = ({
+    icon,
+    label,
+    count,
+    url,
+    bold,
+    onPress,
+  }: {
+    icon: JSX.Element
+    label: string
+    count?: number
+    url?: string
+    bold?: boolean
+    onPress?: () => void
+  }) => (
+    <TouchableOpacity
+      style={styles.menuItem}
+      onPress={onPress ? onPress : () => onNavigate(url || '/')}>
+      <View style={[styles.menuItemIconWrapper]}>
+        {icon}
+        {count ? (
+          <View style={styles.menuItemCount}>
+            <Text style={styles.menuItemCountLabel}>{count}</Text>
+          </View>
+        ) : undefined}
+      </View>
+      <Text
+        style={[
+          styles.menuItemLabel,
+          bold ? styles.menuItemLabelBold : undefined,
+        ]}
+        numberOfLines={1}>
+        {label}
+      </Text>
+    </TouchableOpacity>
+  )
+
+  /*TODO <MenuItem icon={['far', 'compass']} label="Discover" url="/" />*/
+  return (
+    <View style={styles.view}>
+      <ViewHeader title="Bluesky" subtitle="Private Beta" />
+      <TouchableOpacity
+        style={styles.searchBtn}
+        onPress={() => onNavigate('/search')}>
+        <MagnifyingGlassIcon
+          style={{color: colors.gray5} as StyleProp<ViewStyle>}
+          size={21}
+        />
+        <Text style={styles.searchBtnLabel}>Search</Text>
+      </TouchableOpacity>
+      <View style={styles.section}>
+        <MenuItem
+          icon={
+            <UserAvatar
+              size={24}
+              displayName={store.me.displayName}
+              handle={store.me.handle}
+            />
+          }
+          label={store.me.displayName || store.me.handle}
+          bold
+          url={`/profile/${store.me.handle}`}
+        />
+        <MenuItem
+          icon={
+            <HomeIcon
+              style={{color: colors.gray5} as StyleProp<ViewStyle>}
+              size="24"
+            />
+          }
+          label="Home"
+          url="/"
+        />
+        <MenuItem
+          icon={
+            <BellIcon
+              style={{color: colors.gray5} as StyleProp<ViewStyle>}
+              size="24"
+            />
+          }
+          label="Notifications"
+          url="/notifications"
+          count={store.me.notificationCount}
+        />
+        <MenuItem
+          icon={
+            <CogIcon
+              style={{color: colors.gray6} as StyleProp<ViewStyle>}
+              size="24"
+              strokeWidth={2}
+            />
+          }
+          label="Settings"
+          url="/settings"
+          count={store.me.notificationCount}
+        />
+      </View>
+      <View style={styles.section}>
+        <Text style={styles.heading}>Scenes</Text>
+        <MenuItem
+          icon={
+            <UserGroupIcon
+              style={{color: colors.gray6} as StyleProp<ViewStyle>}
+              size="24"
+            />
+          }
+          label="Create a scene"
+          onPress={onPressCreateScene}
+        />
+        {store.me.memberships
+          ? store.me.memberships.memberships.map((membership, i) => (
+              <MenuItem
+                key={i}
+                icon={
+                  <UserAvatar
+                    size={24}
+                    displayName={membership.displayName}
+                    handle={membership.handle}
+                  />
+                }
+                label={membership.displayName || membership.handle}
+                url={`/profile/${membership.handle}`}
+              />
+            ))
+          : undefined}
+      </View>
+    </View>
+  )
+}
+
+const styles = StyleSheet.create({
+  view: {
+    flex: 1,
+    backgroundColor: colors.white,
+  },
+  section: {
+    paddingHorizontal: 10,
+    paddingTop: 10,
+    paddingBottom: 10,
+    borderBottomWidth: 1,
+    borderBottomColor: colors.gray1,
+  },
+  heading: {
+    fontSize: 16,
+    fontWeight: 'bold',
+    paddingVertical: 8,
+    paddingHorizontal: 4,
+  },
+
+  searchBtn: {
+    flexDirection: 'row',
+    backgroundColor: colors.gray1,
+    borderRadius: 8,
+    margin: 10,
+    marginBottom: 0,
+    paddingVertical: 10,
+    paddingHorizontal: 12,
+  },
+  searchBtnLabel: {
+    marginLeft: 8,
+    fontSize: 18,
+    color: colors.gray6,
+  },
+
+  menuItem: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    paddingVertical: 8,
+    paddingHorizontal: 2,
+  },
+  menuItemIconWrapper: {
+    width: 30,
+    height: 30,
+    alignItems: 'center',
+    justifyContent: 'center',
+    marginRight: 10,
+  },
+  menuItemLabel: {
+    fontSize: 17,
+    color: colors.gray7,
+  },
+  menuItemLabelBold: {
+    fontWeight: 'bold',
+  },
+  menuItemCount: {
+    position: 'absolute',
+    right: -6,
+    top: -2,
+    backgroundColor: colors.red3,
+    paddingHorizontal: 4,
+    paddingBottom: 1,
+    borderRadius: 6,
+  },
+  menuItemCountLabel: {
+    fontSize: 12,
+    fontWeight: 'bold',
+    color: colors.white,
+  },
+})
diff --git a/src/view/shell/mobile/MainMenu.tsx b/src/view/shell/mobile/MainMenu.tsx
deleted file mode 100644
index 8a7264612..000000000
--- a/src/view/shell/mobile/MainMenu.tsx
+++ /dev/null
@@ -1,354 +0,0 @@
-import React, {useEffect} from 'react'
-import {observer} from 'mobx-react-lite'
-import {
-  StyleSheet,
-  SafeAreaView,
-  Text,
-  TouchableOpacity,
-  TouchableWithoutFeedback,
-  View,
-} from 'react-native'
-import Animated, {
-  useSharedValue,
-  useAnimatedStyle,
-  withTiming,
-  interpolate,
-} from 'react-native-reanimated'
-import {IconProp} from '@fortawesome/fontawesome-svg-core'
-import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
-import _chunk from 'lodash.chunk'
-import {HomeIcon, UserGroupIcon, BellIcon} from '../../lib/icons'
-import {UserAvatar} from '../../com/util/UserAvatar'
-import {useStores} from '../../../state'
-import {CreateSceneModel} from '../../../state/models/shell-ui'
-import {s, colors} from '../../lib/styles'
-
-export const MainMenu = observer(
-  ({
-    active,
-    insetBottom,
-    onClose,
-  }: {
-    active: boolean
-    insetBottom: number
-    onClose: () => void
-  }) => {
-    const store = useStores()
-    const initInterp = useSharedValue<number>(0)
-
-    useEffect(() => {
-      if (active) {
-        // trigger a refresh in case memberships have changed recently
-        store.me.refreshMemberships()
-      }
-    }, [active])
-    useEffect(() => {
-      if (active) {
-        initInterp.value = withTiming(1, {duration: 150})
-      } else {
-        initInterp.value = 0
-      }
-    }, [initInterp, active])
-    const wrapperAnimStyle = useAnimatedStyle(() => ({
-      opacity: interpolate(initInterp.value, [0, 1.0], [0, 1.0]),
-    }))
-    const menuItemsAnimStyle = useAnimatedStyle(() => ({
-      top: interpolate(initInterp.value, [0, 1.0], [15, 0]),
-    }))
-
-    // events
-    // =
-
-    const onNavigate = (url: string) => {
-      store.nav.navigate(url)
-      onClose()
-    }
-    const onPressCreateScene = () => {
-      store.shell.openModal(new CreateSceneModel())
-      onClose()
-    }
-
-    // rendering
-    // =
-
-    const MenuItemBlank = () => (
-      <View style={[styles.menuItem, styles.menuItemMargin]} />
-    )
-
-    const MenuItem = ({
-      icon,
-      label,
-      count,
-      url,
-      onPress,
-    }: {
-      icon: IconProp
-      label: string
-      count?: number
-      url?: string
-      onPress?: () => void
-    }) => (
-      <TouchableOpacity
-        style={[styles.menuItem, styles.menuItemMargin]}
-        onPress={onPress ? onPress : () => onNavigate(url || '/')}>
-        <View style={[styles.menuItemIconWrapper]}>
-          {icon === 'home' ? (
-            <HomeIcon style={styles.menuItemIcon} size="32" />
-          ) : icon === 'user-group' ? (
-            <UserGroupIcon style={styles.menuItemIcon} size="36" />
-          ) : icon === 'bell' ? (
-            <BellIcon style={styles.menuItemIcon} size="32" />
-          ) : (
-            <FontAwesomeIcon
-              icon={icon}
-              style={styles.menuItemIcon}
-              size={28}
-            />
-          )}
-        </View>
-        {count ? (
-          <View style={styles.menuItemCount}>
-            <Text style={styles.menuItemCountLabel}>{count}</Text>
-          </View>
-        ) : undefined}
-        <Text style={styles.menuItemLabel} numberOfLines={1}>
-          {label}
-        </Text>
-      </TouchableOpacity>
-    )
-    const MenuItemActor = ({
-      label,
-      url,
-      count,
-    }: {
-      label: string
-      url: string
-      count?: number
-    }) => (
-      <TouchableOpacity
-        style={[styles.menuItem, styles.menuItemMargin]}
-        onPress={() => onNavigate(url)}>
-        <View style={s.mb5}>
-          <UserAvatar size={60} displayName={label} handle={label} />
-        </View>
-        {count ? (
-          <View style={styles.menuItemCount}>
-            <Text style={styles.menuItemCountLabel}>{count}</Text>
-          </View>
-        ) : undefined}
-        <Text style={styles.menuItemLabel} numberOfLines={1}>
-          {label}
-        </Text>
-      </TouchableOpacity>
-    )
-
-    if (!active) {
-      return <View />
-    }
-
-    const MenuItems = ({
-      children,
-    }: {
-      children: (JSX.Element | JSX.Element[])[]
-    }) => {
-      const groups = _chunk(children.flat(), 4)
-      const lastGroup = groups.at(-1)
-      while (lastGroup && lastGroup.length < 4) {
-        lastGroup.push(<MenuItemBlank />)
-      }
-      return (
-        <>
-          {groups.map((group, i) => (
-            <View key={i} style={[styles.menuItems]}>
-              {group.map((el, j) => (
-                <React.Fragment key={j}>{el}</React.Fragment>
-              ))}
-            </View>
-          ))}
-        </>
-      )
-    }
-
-    /*TODO <MenuItem icon={['far', 'compass']} label="Discover" url="/" />*/
-    return (
-      <>
-        <TouchableWithoutFeedback onPress={onClose}>
-          <View style={styles.bg} />
-        </TouchableWithoutFeedback>
-        <Animated.View
-          style={[
-            styles.wrapper,
-            {bottom: insetBottom + 45},
-            wrapperAnimStyle,
-          ]}>
-          <SafeAreaView>
-            <View style={[styles.topSection]}>
-              <TouchableOpacity
-                style={styles.profile}
-                onPress={() => onNavigate(`/profile/${store.me.handle || ''}`)}>
-                <View style={styles.profileImage}>
-                  <UserAvatar
-                    size={35}
-                    displayName={store.me.displayName}
-                    handle={store.me.handle || ''}
-                  />
-                </View>
-                <Text style={styles.profileText} numberOfLines={1}>
-                  {store.me.displayName || store.me.handle || 'My profile'}
-                </Text>
-              </TouchableOpacity>
-              <View style={[s.flex1]} />
-              <TouchableOpacity
-                style={styles.settings}
-                onPress={() => onNavigate(`/settings`)}>
-                <FontAwesomeIcon
-                  icon="gear"
-                  style={styles.settingsIcon}
-                  size={24}
-                />
-              </TouchableOpacity>
-            </View>
-            <Animated.View
-              style={[
-                styles.section,
-                styles.menuItemsAnimContainer,
-                menuItemsAnimStyle,
-              ]}>
-              <MenuItems>
-                <MenuItem icon="home" label="Home" url="/" />
-                <MenuItem
-                  icon="bell"
-                  label="Notifications"
-                  url="/notifications"
-                  count={store.me.notificationCount}
-                />
-              </MenuItems>
-
-              <Text style={styles.heading}>Scenes</Text>
-              <MenuItems>
-                <MenuItem
-                  icon={'user-group'}
-                  label="Create Scene"
-                  onPress={onPressCreateScene}
-                />
-                {store.me.memberships ? (
-                  store.me.memberships.memberships.map((membership, i) => (
-                    <MenuItemActor
-                      key={i}
-                      label={membership.displayName || membership.handle}
-                      url={`/profile/${membership.handle}`}
-                    />
-                  ))
-                ) : (
-                  <MenuItemBlank />
-                )}
-              </MenuItems>
-            </Animated.View>
-          </SafeAreaView>
-        </Animated.View>
-      </>
-    )
-  },
-)
-
-const styles = StyleSheet.create({
-  bg: {
-    position: 'absolute',
-    top: 0,
-    right: 0,
-    bottom: 0,
-    left: 0,
-    // backgroundColor: '#000',
-    opacity: 0,
-  },
-  wrapper: {
-    position: 'absolute',
-    top: 0,
-    width: '100%',
-    backgroundColor: '#fff',
-  },
-
-  topSection: {
-    flexDirection: 'row',
-    alignItems: 'center',
-    height: 40,
-    paddingHorizontal: 10,
-    marginTop: 12,
-    marginBottom: 20,
-  },
-  section: {
-    paddingHorizontal: 10,
-  },
-  heading: {
-    fontSize: 21,
-    fontWeight: 'bold',
-    paddingHorizontal: 10,
-    paddingTop: 6,
-    paddingBottom: 12,
-  },
-
-  profile: {
-    paddingVertical: 10,
-    paddingHorizontal: 10,
-    flexDirection: 'row',
-    alignItems: 'center',
-  },
-  profileImage: {
-    marginRight: 8,
-  },
-  profileText: {
-    fontSize: 17,
-    fontWeight: 'bold',
-  },
-
-  settings: {},
-  settingsIcon: {
-    color: colors.gray5,
-    marginRight: 10,
-  },
-
-  menuItemsAnimContainer: {
-    position: 'relative',
-  },
-  menuItems: {
-    flexDirection: 'row',
-    marginBottom: 20,
-  },
-  menuItem: {
-    flex: 1,
-    alignItems: 'center',
-  },
-  menuItemMargin: {
-    marginRight: 10,
-  },
-  menuItemIconWrapper: {
-    borderRadius: 6,
-    width: 60,
-    height: 60,
-    justifyContent: 'center',
-    alignItems: 'center',
-    marginBottom: 5,
-    backgroundColor: colors.gray1,
-  },
-  menuItemIcon: {
-    color: colors.gray5,
-  },
-  menuItemLabel: {
-    fontSize: 13,
-    textAlign: 'center',
-  },
-  menuItemCount: {
-    position: 'absolute',
-    left: 48,
-    top: 10,
-    backgroundColor: colors.red3,
-    paddingHorizontal: 4,
-    paddingBottom: 1,
-    borderRadius: 6,
-  },
-  menuItemCountLabel: {
-    fontSize: 12,
-    fontWeight: 'bold',
-    color: colors.white,
-  },
-})
diff --git a/src/view/shell/mobile/index.tsx b/src/view/shell/mobile/index.tsx
index e3e30decc..6bb111877 100644
--- a/src/view/shell/mobile/index.tsx
+++ b/src/view/shell/mobile/index.tsx
@@ -33,7 +33,6 @@ import {match, MatchResult} from '../../routes'
 import {Login} from '../../screens/Login'
 import {Onboard} from '../../screens/Onboard'
 import {Modal} from '../../com/modals/Modal'
-import {MainMenu} from './MainMenu'
 import {TabsSelector} from './TabsSelector'
 import {Composer} from './Composer'
 import {s, colors} from '../../lib/styles'
@@ -118,7 +117,6 @@ const Btn = ({
 
 export const MobileShell: React.FC = observer(() => {
   const store = useStores()
-  const [isMainMenuActive, setMainMenuActive] = useState(false)
   const [isTabsSelectorActive, setTabsSelectorActive] = useState(false)
   const scrollElRef = useRef<FlatList | undefined>()
   const winDim = useWindowDimensions()
@@ -134,16 +132,10 @@ export const MobileShell: React.FC = observer(() => {
     if (store.nav.tab.current.url === '/') {
       scrollElRef.current?.scrollToOffset({offset: 0})
     } else {
-      if (store.nav.tab.canGoBack) {
-        // sanity check
-        store.nav.tab.goBackToZero()
-      } else {
-        store.nav.navigate('/')
-      }
+      store.nav.tab.resetTo('/')
     }
   }
-  const onPressMenu = () => setMainMenuActive(true)
-  const onPressNotifications = () => store.nav.navigate('/notifications')
+  const onPressNotifications = () => store.nav.tab.resetTo('/notifications')
   const onPressTabs = () => toggleTabsMenu(!isTabsSelectorActive)
   const doNewTab = (url: string) => () => store.nav.newTab(url)
 
@@ -337,16 +329,7 @@ export const MobileShell: React.FC = observer(() => {
           onLongPress={TABS_ENABLED ? doNewTab('/notifications') : undefined}
           notificationCount={store.me.notificationCount}
         />
-        <Btn
-          icon={isMainMenuActive ? 'menu-solid' : 'menu'}
-          onPress={onPressMenu}
-        />
       </View>
-      <MainMenu
-        active={isMainMenuActive}
-        insetBottom={clamp(safeAreaInsets.bottom, 15, 40)}
-        onClose={() => setMainMenuActive(false)}
-      />
       <Modal />
       <Composer
         active={store.shell.isComposerActive}