about summary refs log tree commit diff
path: root/src/view/shell/mobile
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/shell/mobile')
-rw-r--r--src/view/shell/mobile/Menu.tsx253
-rw-r--r--src/view/shell/mobile/TabsSelector.tsx327
-rw-r--r--src/view/shell/mobile/index.tsx288
3 files changed, 257 insertions, 611 deletions
diff --git a/src/view/shell/mobile/Menu.tsx b/src/view/shell/mobile/Menu.tsx
index ceeda8c58..23c09b82c 100644
--- a/src/view/shell/mobile/Menu.tsx
+++ b/src/view/shell/mobile/Menu.tsx
@@ -17,19 +17,23 @@ import {FEEDBACK_FORM_URL} from 'lib/constants'
 import {useStores} from 'state/index'
 import {
   HomeIcon,
+  HomeIconSolid,
   BellIcon,
+  BellIconSolid,
   UserIcon,
   CogIcon,
-  MagnifyingGlassIcon,
+  MagnifyingGlassIcon2,
+  MagnifyingGlassIcon2Solid,
 } from 'lib/icons'
 import {TabPurpose, TabPurposeMainPath} from 'state/models/navigation'
 import {UserAvatar} from '../../com/util/UserAvatar'
 import {Text} from '../../com/util/text/Text'
-import {ToggleButton} from '../../com/util/forms/ToggleButton'
+import {useTheme} from 'lib/ThemeContext'
 import {usePalette} from 'lib/hooks/usePalette'
 import {useAnalytics} from 'lib/analytics'
 
 export const Menu = observer(({onClose}: {onClose: () => void}) => {
+  const theme = useTheme()
   const pal = usePalette('default')
   const store = useStores()
   const {track} = useAnalytics()
@@ -89,11 +93,8 @@ export const Menu = observer(({onClose}: {onClose: () => void}) => {
         ) : undefined}
       </View>
       <Text
-        type="title"
-        style={[
-          pal.text,
-          bold ? styles.menuItemLabelBold : styles.menuItemLabel,
-        ]}
+        type={bold ? '2xl-bold' : '2xl'}
+        style={[pal.text, s.flex1]}
         numberOfLines={1}>
         {label}
       </Text>
@@ -105,68 +106,114 @@ export const Menu = observer(({onClose}: {onClose: () => void}) => {
     store.shell.setDarkMode(!store.shell.darkMode)
   }
 
+  const isAtHome =
+    store.nav.tab.current.url === TabPurposeMainPath[TabPurpose.Default]
+  const isAtSearch =
+    store.nav.tab.current.url === TabPurposeMainPath[TabPurpose.Search]
+  const isAtNotifications =
+    store.nav.tab.current.url === TabPurposeMainPath[TabPurpose.Notifs]
+
   return (
     <View
       testID="menuView"
       style={[
         styles.view,
-        pal.view,
+        theme.colorScheme === 'light' ? pal.view : styles.viewDarkMode,
         store.shell.minimalShellMode && styles.viewMinimalShell,
       ]}>
       <TouchableOpacity
         testID="profileCardButton"
-        onPress={() => onNavigate(`/profile/${store.me.handle}`)}
-        style={styles.profileCard}>
+        onPress={() => onNavigate(`/profile/${store.me.handle}`)}>
         <UserAvatar
-          size={60}
+          size={80}
           displayName={store.me.displayName}
           handle={store.me.handle}
           avatar={store.me.avatar}
         />
-        <View style={s.flex1}>
-          <Text
-            type="title-lg"
-            style={[pal.text, styles.profileCardDisplayName]}
-            numberOfLines={1}>
-            {store.me.displayName || store.me.handle}
-          </Text>
-          <Text
-            style={[pal.textLight, styles.profileCardHandle]}
-            numberOfLines={1}>
-            @{store.me.handle}
-          </Text>
-        </View>
-      </TouchableOpacity>
-      <TouchableOpacity
-        testID="searchBtn"
-        style={[styles.searchBtn, pal.btn]}
-        onPress={() => onNavigate('/search')}>
-        <MagnifyingGlassIcon
-          style={pal.text as StyleProp<ViewStyle>}
-          size={25}
-        />
-        <Text type="title" style={[pal.text, styles.searchBtnLabel]}>
-          Search
+        <Text
+          type="title-lg"
+          style={[pal.text, s.bold, styles.profileCardDisplayName]}
+          numberOfLines={1}>
+          {store.me.displayName || store.me.handle}
+        </Text>
+        <Text
+          type="2xl"
+          style={[pal.textLight, styles.profileCardHandle]}
+          numberOfLines={1}>
+          @{store.me.handle}
         </Text>
       </TouchableOpacity>
-      <View style={[styles.section, pal.border, s.pt5]}>
+      <View style={s.flex1} />
+      <View>
+        <MenuItem
+          icon={
+            isAtSearch ? (
+              <MagnifyingGlassIcon2Solid
+                style={pal.text as StyleProp<ViewStyle>}
+                size={24}
+                strokeWidth={1.7}
+              />
+            ) : (
+              <MagnifyingGlassIcon2
+                style={pal.text as StyleProp<ViewStyle>}
+                size={24}
+                strokeWidth={1.7}
+              />
+            )
+          }
+          label="Search"
+          url="/search"
+          bold={isAtSearch}
+        />
         <MenuItem
-          icon={<HomeIcon style={pal.text as StyleProp<ViewStyle>} size="26" />}
+          icon={
+            isAtHome ? (
+              <HomeIconSolid
+                style={pal.text as StyleProp<ViewStyle>}
+                size="24"
+                strokeWidth={3.25}
+                fillOpacity={1}
+              />
+            ) : (
+              <HomeIcon
+                style={pal.text as StyleProp<ViewStyle>}
+                size="24"
+                strokeWidth={3.25}
+              />
+            )
+          }
           label="Home"
           url="/"
+          bold={isAtHome}
         />
         <MenuItem
-          icon={<BellIcon style={pal.text as StyleProp<ViewStyle>} size="28" />}
+          icon={
+            isAtNotifications ? (
+              <BellIconSolid
+                style={pal.text as StyleProp<ViewStyle>}
+                size="24"
+                strokeWidth={1.7}
+                fillOpacity={1}
+              />
+            ) : (
+              <BellIcon
+                style={pal.text as StyleProp<ViewStyle>}
+                size="24"
+                strokeWidth={1.7}
+              />
+            )
+          }
           label="Notifications"
           url="/notifications"
           count={store.me.notifications.unreadCount}
+          bold={isAtNotifications}
         />
         <MenuItem
           icon={
             <UserIcon
               style={pal.text as StyleProp<ViewStyle>}
-              size="30"
-              strokeWidth={2}
+              size="26"
+              strokeWidth={1.5}
             />
           }
           label="Profile"
@@ -176,34 +223,46 @@ export const Menu = observer(({onClose}: {onClose: () => void}) => {
           icon={
             <CogIcon
               style={pal.text as StyleProp<ViewStyle>}
-              size="30"
-              strokeWidth={2}
+              size="26"
+              strokeWidth={1.75}
             />
           }
           label="Settings"
           url="/settings"
         />
       </View>
-      <View style={[styles.section, pal.border]}>
-        <ToggleButton
-          label="Dark mode"
-          isSelected={store.shell.darkMode}
-          onPress={onDarkmodePress}
-        />
-      </View>
       <View style={s.flex1} />
       <View style={styles.footer}>
-        <MenuItem
-          icon={
-            <FontAwesomeIcon
-              style={pal.text as FontAwesomeIconStyle}
-              size={24}
-              icon={['far', 'message']}
-            />
-          }
-          label="Feedback"
+        <TouchableOpacity
+          onPress={onDarkmodePress}
+          style={[
+            styles.footerBtn,
+            theme.colorScheme === 'light' ? pal.btn : styles.footerBtnDarkMode,
+          ]}>
+          <CogIcon
+            style={pal.text as StyleProp<ViewStyle>}
+            size="26"
+            strokeWidth={1.75}
+          />
+        </TouchableOpacity>
+        <TouchableOpacity
           onPress={onPressFeedback}
-        />
+          style={[
+            styles.footerBtn,
+            styles.footerBtnFeedback,
+            theme.colorScheme === 'light'
+              ? styles.footerBtnFeedbackLight
+              : styles.footerBtnFeedbackDark,
+          ]}>
+          <FontAwesomeIcon
+            style={pal.link as FontAwesomeIconStyle}
+            size={19}
+            icon={['far', 'message']}
+          />
+          <Text type="2xl-medium" style={[pal.link, s.pl10]}>
+            Feedback
+          </Text>
+        </TouchableOpacity>
       </View>
     </View>
   )
@@ -212,70 +271,37 @@ export const Menu = observer(({onClose}: {onClose: () => void}) => {
 const styles = StyleSheet.create({
   view: {
     flex: 1,
+    paddingTop: 10,
     paddingBottom: 90,
+    paddingLeft: 30,
+  },
+  viewDarkMode: {
+    backgroundColor: colors.gray8,
   },
   viewMinimalShell: {
     paddingBottom: 50,
   },
-  section: {
-    paddingHorizontal: 10,
-    paddingTop: 10,
-    paddingBottom: 10,
-    borderBottomWidth: 1,
-  },
-  heading: {
-    paddingVertical: 8,
-    paddingHorizontal: 4,
-  },
 
-  profileCard: {
-    flexDirection: 'row',
-    alignItems: 'center',
-    margin: 10,
-    marginBottom: 6,
-  },
   profileCardDisplayName: {
-    marginLeft: 12,
+    marginTop: 20,
   },
   profileCardHandle: {
-    marginLeft: 12,
-  },
-
-  searchBtn: {
-    flexDirection: 'row',
-    borderRadius: 8,
-    margin: 10,
-    marginBottom: 0,
-    paddingVertical: 10,
-    paddingHorizontal: 12,
-  },
-  searchBtnLabel: {
-    marginLeft: 14,
-    fontWeight: 'normal',
+    marginTop: 4,
   },
 
   menuItem: {
     flexDirection: 'row',
     alignItems: 'center',
-    paddingVertical: 6,
-    paddingLeft: 6,
+    paddingVertical: 16,
     paddingRight: 10,
   },
   menuItemIconWrapper: {
-    width: 36,
-    height: 36,
+    width: 24,
+    height: 24,
     alignItems: 'center',
     justifyContent: 'center',
     marginRight: 12,
   },
-  menuItemLabel: {
-    flex: 1,
-    fontWeight: 'normal',
-  },
-  menuItemLabelBold: {
-    flex: 1,
-    fontWeight: 'bold',
-  },
   menuItemCount: {
     position: 'absolute',
     right: -6,
@@ -292,6 +318,27 @@ const styles = StyleSheet.create({
   },
 
   footer: {
-    paddingHorizontal: 10,
+    flexDirection: 'row',
+    justifyContent: 'space-between',
+    paddingRight: 30,
+    paddingTop: 20,
+  },
+  footerBtn: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    padding: 10,
+    borderRadius: 25,
+  },
+  footerBtnDarkMode: {
+    backgroundColor: colors.black,
+  },
+  footerBtnFeedback: {
+    paddingHorizontal: 24,
+  },
+  footerBtnFeedbackLight: {
+    backgroundColor: '#DDEFFF',
+  },
+  footerBtnFeedbackDark: {
+    backgroundColor: colors.blue6,
   },
 })
diff --git a/src/view/shell/mobile/TabsSelector.tsx b/src/view/shell/mobile/TabsSelector.tsx
deleted file mode 100644
index 92854e3b6..000000000
--- a/src/view/shell/mobile/TabsSelector.tsx
+++ /dev/null
@@ -1,327 +0,0 @@
-import React, {createRef, useRef, useMemo, useState} from 'react'
-import {observer} from 'mobx-react-lite'
-import {
-  Animated,
-  ScrollView,
-  Share,
-  StyleSheet,
-  TouchableWithoutFeedback,
-  View,
-} from 'react-native'
-import {useSafeAreaInsets} from 'react-native-safe-area-context'
-import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
-import {Text} from '../../com/util/text/Text'
-import Swipeable from 'react-native-gesture-handler/Swipeable'
-import {useStores} from 'state/index'
-import {s, colors} from 'lib/styles'
-import {toShareUrl} from 'lib/strings/url-helpers'
-import {match} from '../../routes'
-import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
-
-const TAB_HEIGHT = 42
-
-export const TabsSelector = observer(
-  ({
-    active,
-    tabMenuInterp,
-    onClose,
-  }: {
-    active: boolean
-    tabMenuInterp: Animated.Value
-    onClose: () => void
-  }) => {
-    const store = useStores()
-    const insets = useSafeAreaInsets()
-    const [closingTabIndex, setClosingTabIndex] = useState<number | undefined>(
-      undefined,
-    )
-    const closeInterp = useAnimatedValue(0)
-    const tabsContainerRef = useRef<View>(null)
-    const tabsRef = useRef<ScrollView>(null)
-    const tabRefs = useMemo(
-      () =>
-        Array.from({length: store.nav.tabs.length}).map(() =>
-          createRef<View>(),
-        ),
-      [store.nav.tabs.length],
-    )
-
-    const wrapperAnimStyle = {
-      transform: [
-        {
-          translateY: tabMenuInterp.interpolate({
-            inputRange: [0, 1.0],
-            outputRange: [320, 0],
-          }),
-        },
-      ],
-    }
-
-    // events
-    // =
-
-    const onPressNewTab = () => {
-      store.nav.newTab('/')
-      onClose()
-    }
-    const onPressCloneTab = () => {
-      store.nav.newTab(store.nav.tab.current.url)
-      onClose()
-    }
-    const onPressShareTab = () => {
-      onClose()
-      Share.share({url: toShareUrl(store.nav.tab.current.url)})
-    }
-    const onPressChangeTab = (tabIndex: number) => {
-      store.nav.setActiveTab(tabIndex)
-      onClose()
-    }
-    const onCloseTab = (tabIndex: number) => {
-      setClosingTabIndex(tabIndex)
-      closeInterp.setValue(0)
-      Animated.timing(closeInterp, {
-        toValue: 1,
-        duration: 300,
-        useNativeDriver: false,
-      }).start(() => {
-        setClosingTabIndex(undefined)
-        store.nav.closeTab(tabIndex)
-      })
-    }
-    const onLayout = () => {
-      // focus the current tab
-      const targetTab = tabRefs[store.nav.tabIndex]
-      if (tabsContainerRef.current && tabsRef.current && targetTab.current) {
-        targetTab.current.measureLayout?.(
-          tabsContainerRef.current,
-          (_left: number, top: number) => {
-            tabsRef.current?.scrollTo({y: top, animated: false})
-          },
-          () => {},
-        )
-      }
-    }
-
-    // rendering
-    // =
-
-    const renderSwipeActions = () => {
-      return <View style={[s.p2]} />
-    }
-
-    const currentTabIndex = store.nav.tabIndex
-    const closingTabAnimStyle = {
-      height: Animated.multiply(TAB_HEIGHT, Animated.subtract(1, closeInterp)),
-      opacity: Animated.subtract(1, closeInterp),
-      marginBottom: Animated.multiply(4, Animated.subtract(1, closeInterp)),
-    }
-
-    if (!active) {
-      return <View testID="emptyView" />
-    }
-
-    return (
-      <Animated.View
-        testID="tabsSelectorView"
-        style={[
-          styles.wrapper,
-          {bottom: insets.bottom + 55},
-          wrapperAnimStyle,
-        ]}>
-        <View onLayout={onLayout}>
-          <View style={[s.p10, styles.section]}>
-            <View style={styles.btns}>
-              <TouchableWithoutFeedback
-                testID="shareButton"
-                onPress={onPressShareTab}>
-                <View style={[styles.btn]}>
-                  <View style={styles.btnIcon}>
-                    <FontAwesomeIcon size={16} icon="share" />
-                  </View>
-                  <Text style={styles.btnText}>Share</Text>
-                </View>
-              </TouchableWithoutFeedback>
-              <TouchableWithoutFeedback
-                testID="cloneButton"
-                onPress={onPressCloneTab}>
-                <View style={[styles.btn]}>
-                  <View style={styles.btnIcon}>
-                    <FontAwesomeIcon size={16} icon={['far', 'clone']} />
-                  </View>
-                  <Text style={styles.btnText}>Clone tab</Text>
-                </View>
-              </TouchableWithoutFeedback>
-              <TouchableWithoutFeedback
-                testID="newTabButton"
-                onPress={onPressNewTab}>
-                <View style={[styles.btn]}>
-                  <View style={styles.btnIcon}>
-                    <FontAwesomeIcon size={16} icon="plus" />
-                  </View>
-                  <Text style={styles.btnText}>New tab</Text>
-                </View>
-              </TouchableWithoutFeedback>
-            </View>
-          </View>
-          <View
-            ref={tabsContainerRef}
-            style={[s.p10, styles.section, styles.sectionGrayBg]}>
-            <ScrollView ref={tabsRef} style={styles.tabs}>
-              {store.nav.tabs.map((tab, tabIndex) => {
-                const {icon} = match(tab.current.url)
-                const isActive = tabIndex === currentTabIndex
-                const isClosing = closingTabIndex === tabIndex
-                return (
-                  <Swipeable
-                    key={tab.id}
-                    testID="tabsSwipable"
-                    renderLeftActions={renderSwipeActions}
-                    renderRightActions={renderSwipeActions}
-                    leftThreshold={100}
-                    rightThreshold={100}
-                    onSwipeableWillOpen={() => onCloseTab(tabIndex)}>
-                    <Animated.View
-                      style={[
-                        styles.tabOuter,
-                        isClosing ? closingTabAnimStyle : undefined,
-                      ]}>
-                      <Animated.View
-                        // HOTFIX
-                        // TabsSelector.test.tsx snapshot fails if the
-                        // ref was set like this: ref={tabRefs[tabIndex]}
-                        ref={(ref: any) => (tabRefs[tabIndex] = ref)}
-                        style={[
-                          styles.tab,
-                          styles.existing,
-                          isActive && styles.active,
-                        ]}>
-                        <TouchableWithoutFeedback
-                          testID="changeTabButton"
-                          onPress={() => onPressChangeTab(tabIndex)}>
-                          <View style={styles.tabInner}>
-                            <View style={styles.tabIcon}>
-                              <FontAwesomeIcon size={20} icon={icon} />
-                            </View>
-                            <Text
-                              ellipsizeMode="tail"
-                              numberOfLines={1}
-                              suppressHighlighting={true}
-                              style={[
-                                styles.tabText,
-                                isActive && styles.tabTextActive,
-                              ]}>
-                              {tab.current.title || tab.current.url}
-                            </Text>
-                          </View>
-                        </TouchableWithoutFeedback>
-                        <TouchableWithoutFeedback
-                          testID="closeTabButton"
-                          onPress={() => onCloseTab(tabIndex)}>
-                          <View style={styles.tabClose}>
-                            <FontAwesomeIcon
-                              size={14}
-                              icon="x"
-                              style={styles.tabCloseIcon}
-                            />
-                          </View>
-                        </TouchableWithoutFeedback>
-                      </Animated.View>
-                    </Animated.View>
-                  </Swipeable>
-                )
-              })}
-            </ScrollView>
-          </View>
-        </View>
-      </Animated.View>
-    )
-  },
-)
-
-const styles = StyleSheet.create({
-  wrapper: {
-    position: 'absolute',
-    width: '100%',
-    height: 320,
-    borderTopColor: colors.gray2,
-    borderTopWidth: 1,
-    backgroundColor: '#fff',
-    opacity: 1,
-  },
-  section: {
-    borderBottomColor: colors.gray2,
-    borderBottomWidth: 1,
-  },
-  sectionGrayBg: {
-    backgroundColor: colors.gray1,
-  },
-  tabs: {
-    height: 240,
-  },
-  tabOuter: {
-    height: TAB_HEIGHT + 4,
-    overflow: 'hidden',
-  },
-  tab: {
-    flexDirection: 'row',
-    height: TAB_HEIGHT,
-    backgroundColor: colors.gray1,
-    alignItems: 'center',
-    borderRadius: 4,
-  },
-  tabInner: {
-    flexDirection: 'row',
-    flex: 1,
-    alignItems: 'center',
-    paddingLeft: 12,
-    paddingVertical: 12,
-  },
-  existing: {
-    borderColor: colors.gray4,
-    borderWidth: 1,
-  },
-  active: {
-    backgroundColor: colors.white,
-    borderColor: colors.black,
-    borderWidth: 1,
-  },
-  tabIcon: {},
-  tabText: {
-    flex: 1,
-    paddingHorizontal: 10,
-    fontSize: 16,
-  },
-  tabTextActive: {
-    fontWeight: '500',
-  },
-  tabClose: {
-    paddingVertical: 16,
-    paddingRight: 16,
-  },
-  tabCloseIcon: {
-    color: '#655',
-  },
-  btns: {
-    flexDirection: 'row',
-    paddingTop: 2,
-  },
-  btn: {
-    flexDirection: 'row',
-    flex: 1,
-    alignItems: 'center',
-    justifyContent: 'center',
-    backgroundColor: colors.gray1,
-    borderRadius: 4,
-    marginRight: 5,
-    paddingLeft: 12,
-    paddingRight: 16,
-    paddingVertical: 10,
-  },
-  btnIcon: {
-    marginRight: 8,
-  },
-  btnText: {
-    fontWeight: '500',
-    fontSize: 16,
-  },
-})
diff --git a/src/view/shell/mobile/index.tsx b/src/view/shell/mobile/index.tsx
index 89a834ee1..6ab19d651 100644
--- a/src/view/shell/mobile/index.tsx
+++ b/src/view/shell/mobile/index.tsx
@@ -2,21 +2,17 @@ import React, {useState, useEffect} from 'react'
 import {observer} from 'mobx-react-lite'
 import {
   Animated,
-  Easing,
   GestureResponderEvent,
   StatusBar,
   StyleSheet,
   TouchableOpacity,
   TouchableWithoutFeedback,
-  useColorScheme,
   useWindowDimensions,
   View,
 } from 'react-native'
 import {ScreenContainer, Screen} from 'react-native-screens'
 import {useSafeAreaInsets} from 'react-native-safe-area-context'
-import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import {IconProp} from '@fortawesome/fontawesome-svg-core'
-import {TABS_ENABLED} from 'lib/build-flags'
 import {useStores} from 'state/index'
 import {
   NavigationModel,
@@ -31,18 +27,18 @@ import {ModalsContainer} from '../../com/modals/Modal'
 import {Lightbox} from '../../com/lightbox/Lightbox'
 import {Text} from '../../com/util/text/Text'
 import {ErrorBoundary} from '../../com/util/ErrorBoundary'
-import {TabsSelector} from './TabsSelector'
 import {Composer} from './Composer'
 import {s, colors} from 'lib/styles'
 import {clamp} from 'lib/numbers'
 import {
-  GridIcon,
-  GridIconSolid,
   HomeIcon,
   HomeIconSolid,
-  MagnifyingGlassIcon,
+  MagnifyingGlassIcon2,
+  MagnifyingGlassIcon2Solid,
+  ComposeIcon2,
   BellIcon,
   BellIconSolid,
+  UserIcon,
 } from 'lib/icons'
 import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
 import {useTheme} from 'lib/ThemeContext'
@@ -52,74 +48,14 @@ import {useAnalytics} from 'lib/analytics'
 const Btn = ({
   icon,
   notificationCount,
-  tabCount,
   onPress,
   onLongPress,
 }: {
-  icon:
-    | IconProp
-    | 'menu'
-    | 'menu-solid'
-    | 'home'
-    | 'home-solid'
-    | 'search'
-    | 'search-solid'
-    | 'bell'
-    | 'bell-solid'
+  icon: JSX.Element
   notificationCount?: number
-  tabCount?: number
   onPress?: (event: GestureResponderEvent) => void
   onLongPress?: (event: GestureResponderEvent) => void
 }) => {
-  const pal = usePalette('default')
-  let iconEl
-  if (icon === 'menu') {
-    iconEl = <GridIcon style={[styles.ctrlIcon, pal.text]} />
-  } else if (icon === 'menu-solid') {
-    iconEl = <GridIconSolid style={[styles.ctrlIcon, pal.text]} />
-  } else if (icon === 'home') {
-    iconEl = <HomeIcon size={27} style={[styles.ctrlIcon, pal.text]} />
-  } else if (icon === 'home-solid') {
-    iconEl = <HomeIconSolid size={27} style={[styles.ctrlIcon, pal.text]} />
-  } else if (icon === 'search') {
-    iconEl = (
-      <MagnifyingGlassIcon
-        size={28}
-        style={[styles.ctrlIcon, pal.text, styles.bumpUpOnePixel]}
-      />
-    )
-  } else if (icon === 'search-solid') {
-    iconEl = (
-      <MagnifyingGlassIcon
-        size={28}
-        strokeWidth={3}
-        style={[styles.ctrlIcon, pal.text, styles.bumpUpOnePixel]}
-      />
-    )
-  } else if (icon === 'bell') {
-    iconEl = (
-      <BellIcon
-        size={27}
-        style={[styles.ctrlIcon, pal.text, styles.bumpUpOnePixel]}
-      />
-    )
-  } else if (icon === 'bell-solid') {
-    iconEl = (
-      <BellIconSolid
-        size={27}
-        style={[styles.ctrlIcon, pal.text, styles.bumpUpOnePixel]}
-      />
-    )
-  } else {
-    iconEl = (
-      <FontAwesomeIcon
-        icon={icon}
-        size={24}
-        style={[styles.ctrlIcon, pal.text]}
-      />
-    )
-  }
-
   return (
     <TouchableOpacity
       style={styles.ctrl}
@@ -131,12 +67,7 @@ const Btn = ({
           <Text style={styles.notificationCountLabel}>{notificationCount}</Text>
         </View>
       ) : undefined}
-      {tabCount && tabCount > 1 ? (
-        <View style={styles.tabCount}>
-          <Text style={styles.tabCountLabel}>{tabCount}</Text>
-        </View>
-      ) : undefined}
-      {iconEl}
+      {icon}
     </TouchableOpacity>
   )
 }
@@ -145,15 +76,10 @@ export const MobileShell: React.FC = observer(() => {
   const theme = useTheme()
   const pal = usePalette('default')
   const store = useStores()
-  const [isTabsSelectorActive, setTabsSelectorActive] = useState(false)
   const winDim = useWindowDimensions()
   const [menuSwipingDirection, setMenuSwipingDirection] = useState(0)
   const swipeGestureInterp = useAnimatedValue(0)
   const minimalShellInterp = useAnimatedValue(0)
-  const tabMenuInterp = useAnimatedValue(0)
-  const newTabInterp = useAnimatedValue(0)
-  const [isRunningNewTabAnim, setIsRunningNewTabAnim] = useState(false)
-  const colorScheme = useColorScheme()
   const safeAreaInsets = useSafeAreaInsets()
   const screenRenderDesc = constructScreenRenderDesc(store.nav)
   const {track} = useAnalytics()
@@ -188,6 +114,10 @@ export const MobileShell: React.FC = observer(() => {
       }
     }
   }
+  const onPressCompose = () => {
+    track('MobileShell:ComposeButtonPressed')
+    store.shell.openComposer({})
+  }
   const onPressNotifications = () => {
     track('MobileShell:NotificationsButtonPressed')
     if (store.nav.tab.fixedTabPurpose === TabPurpose.Notifs) {
@@ -203,8 +133,10 @@ export const MobileShell: React.FC = observer(() => {
       }
     }
   }
-  const onPressTabs = () => toggleTabsMenu(!isTabsSelectorActive)
-  const doNewTab = (url: string) => () => store.nav.newTab(url)
+  const onPressProfile = () => {
+    track('MobileShell:ProfileButtonPressed')
+    store.nav.navigate(`/profile/${store.me.handle}`)
+  }
 
   // minimal shell animation
   // =
@@ -229,60 +161,6 @@ export const MobileShell: React.FC = observer(() => {
     transform: [{translateY: Animated.multiply(minimalShellInterp, 100)}],
   }
 
-  // tab selector animation
-  // =
-  const toggleTabsMenu = (active: boolean) => {
-    if (active) {
-      // will trigger the animation below
-      setTabsSelectorActive(true)
-    } else {
-      Animated.timing(tabMenuInterp, {
-        toValue: 0,
-        duration: 100,
-        useNativeDriver: false,
-      }).start(() => {
-        // hide once the animation has finished
-        setTabsSelectorActive(false)
-      })
-    }
-  }
-  useEffect(() => {
-    if (isTabsSelectorActive) {
-      // trigger the animation once the tabs selector is rendering
-      Animated.timing(tabMenuInterp, {
-        toValue: 1,
-        duration: 100,
-        useNativeDriver: false,
-      }).start()
-    }
-  }, [tabMenuInterp, isTabsSelectorActive])
-
-  // new tab animation
-  // =
-  useEffect(() => {
-    if (screenRenderDesc.hasNewTab && !isRunningNewTabAnim) {
-      setIsRunningNewTabAnim(true)
-    }
-  }, [isRunningNewTabAnim, screenRenderDesc.hasNewTab])
-  useEffect(() => {
-    if (isRunningNewTabAnim) {
-      const reset = () => {
-        store.nav.tab.setIsNewTab(false)
-        setIsRunningNewTabAnim(false)
-      }
-      Animated.timing(newTabInterp, {
-        toValue: 1,
-        duration: 250,
-        easing: Easing.out(Easing.exp),
-        useNativeDriver: false,
-      }).start(() => {
-        reset()
-      })
-    } else {
-      newTabInterp.setValue(0)
-    }
-  }, [newTabInterp, store.nav.tab, isRunningNewTabAnim])
-
   // navigation swipes
   // =
   const isMenuActive = store.shell.isMainMenuOpen
@@ -495,20 +373,6 @@ export const MobileShell: React.FC = observer(() => {
           )}
         </HorzSwipe>
       </View>
-      {isTabsSelectorActive ? (
-        <View
-          style={[
-            styles.topBarProtector,
-            colorScheme === 'dark' ? styles.topBarProtectorDark : undefined,
-            {height: safeAreaInsets.top},
-          ]}
-        />
-      ) : undefined}
-      <TabsSelector
-        active={isTabsSelectorActive}
-        tabMenuInterp={tabMenuInterp}
-        onClose={() => toggleTabsMenu(false)}
-      />
       <Animated.View
         style={[
           styles.bottomBar,
@@ -518,28 +382,85 @@ export const MobileShell: React.FC = observer(() => {
           footerMinimalShellTransform,
         ]}>
         <Btn
-          icon={isAtHome ? 'home-solid' : 'home'}
+          icon={
+            isAtHome ? (
+              <HomeIconSolid
+                strokeWidth={4}
+                size={24}
+                style={[styles.ctrlIcon, pal.text, styles.homeIcon]}
+              />
+            ) : (
+              <HomeIcon
+                strokeWidth={4}
+                size={24}
+                style={[styles.ctrlIcon, pal.text, styles.homeIcon]}
+              />
+            )
+          }
           onPress={onPressHome}
-          onLongPress={TABS_ENABLED ? doNewTab('/') : undefined}
         />
         <Btn
-          icon={isAtSearch ? 'search-solid' : 'search'}
+          icon={
+            isAtSearch ? (
+              <MagnifyingGlassIcon2Solid
+                size={25}
+                style={[styles.ctrlIcon, pal.text, styles.searchIcon]}
+                strokeWidth={1.8}
+              />
+            ) : (
+              <MagnifyingGlassIcon2
+                size={25}
+                style={[styles.ctrlIcon, pal.text, styles.searchIcon]}
+                strokeWidth={1.8}
+              />
+            )
+          }
           onPress={onPressSearch}
-          onLongPress={TABS_ENABLED ? doNewTab('/') : undefined}
         />
-        {TABS_ENABLED ? (
-          <Btn
-            icon={isTabsSelectorActive ? 'clone' : ['far', 'clone']}
-            onPress={onPressTabs}
-            tabCount={store.nav.tabCount}
-          />
-        ) : undefined}
         <Btn
-          icon={isAtNotifications ? 'bell-solid' : 'bell'}
+          icon={
+            <View style={styles.ctrlIconSizingWrapper}>
+              <ComposeIcon2
+                strokeWidth={1.5}
+                size={29}
+                style={[styles.ctrlIcon, pal.text, styles.composeIcon]}
+                backgroundColor={pal.colors.background}
+              />
+            </View>
+          }
+          onPress={onPressCompose}
+        />
+        <Btn
+          icon={
+            isAtNotifications ? (
+              <BellIconSolid
+                size={24}
+                strokeWidth={1.9}
+                style={[styles.ctrlIcon, pal.text, styles.bellIcon]}
+              />
+            ) : (
+              <BellIcon
+                size={24}
+                strokeWidth={1.9}
+                style={[styles.ctrlIcon, pal.text, styles.bellIcon]}
+              />
+            )
+          }
           onPress={onPressNotifications}
-          onLongPress={TABS_ENABLED ? doNewTab('/notifications') : undefined}
           notificationCount={store.me.notifications.unreadCount}
         />
+        <Btn
+          icon={
+            <View style={styles.ctrlIconSizingWrapper}>
+              <UserIcon
+                size={28}
+                strokeWidth={1.5}
+                style={[styles.ctrlIcon, pal.text, styles.profileIcon]}
+              />
+            </View>
+          }
+          onPress={onPressProfile}
+        />
       </Animated.View>
       <ModalsContainer />
       <Lightbox />
@@ -650,46 +571,51 @@ const styles = StyleSheet.create({
     flexDirection: 'row',
     borderTopWidth: 1,
     paddingLeft: 5,
-    paddingRight: 25,
+    paddingRight: 10,
   },
   ctrl: {
     flex: 1,
-    paddingTop: 12,
-    paddingBottom: 5,
+    paddingTop: 13,
+    paddingBottom: 4,
   },
   notificationCount: {
     position: 'absolute',
-    left: '60%',
+    left: '56%',
     top: 10,
-    backgroundColor: colors.red3,
+    backgroundColor: colors.blue3,
     paddingHorizontal: 4,
     paddingBottom: 1,
     borderRadius: 8,
+    zIndex: 1,
   },
   notificationCountLabel: {
     fontSize: 12,
     fontWeight: 'bold',
     color: colors.white,
   },
-  tabCount: {
-    position: 'absolute',
-    left: 46,
-    top: 30,
-  },
-  tabCountLabel: {
-    fontSize: 12,
-    fontWeight: 'bold',
-    color: colors.black,
-  },
   ctrlIcon: {
     marginLeft: 'auto',
     marginRight: 'auto',
   },
+  ctrlIconSizingWrapper: {
+    height: 27,
+  },
   inactive: {
     color: colors.gray3,
   },
-  bumpUpOnePixel: {
-    position: 'relative',
-    top: -1,
+  homeIcon: {
+    top: 0,
+  },
+  searchIcon: {
+    top: -2,
+  },
+  bellIcon: {
+    top: -2.5,
+  },
+  composeIcon: {
+    top: -4.5,
+  },
+  profileIcon: {
+    top: -4,
   },
 })