about summary refs log tree commit diff
path: root/src/view/shell
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/shell')
-rw-r--r--src/view/shell/Composer.web.tsx3
-rw-r--r--src/view/shell/Drawer.tsx68
-rw-r--r--src/view/shell/bottom-bar/BottomBar.tsx (renamed from src/view/shell/BottomBar.tsx)86
-rw-r--r--src/view/shell/bottom-bar/BottomBarStyles.tsx61
-rw-r--r--src/view/shell/bottom-bar/BottomBarWeb.tsx101
-rw-r--r--src/view/shell/index.web.tsx43
6 files changed, 237 insertions, 125 deletions
diff --git a/src/view/shell/Composer.web.tsx b/src/view/shell/Composer.web.tsx
index e3994bb23..ed0450c01 100644
--- a/src/view/shell/Composer.web.tsx
+++ b/src/view/shell/Composer.web.tsx
@@ -4,6 +4,7 @@ import {StyleSheet, View} from 'react-native'
 import {ComposePost} from '../com/composer/Composer'
 import {ComposerOpts} from 'state/models/ui/shell'
 import {usePalette} from 'lib/hooks/usePalette'
+import {isMobileWeb} from 'platform/detection'
 
 export const Composer = observer(
   ({
@@ -60,7 +61,7 @@ const styles = StyleSheet.create({
     width: '100%',
     paddingVertical: 0,
     paddingHorizontal: 2,
-    borderRadius: 8,
+    borderRadius: isMobileWeb ? 0 : 8,
     marginBottom: '10vh',
   },
 })
diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx
index ebadb2126..de36463e1 100644
--- a/src/view/shell/Drawer.tsx
+++ b/src/view/shell/Drawer.tsx
@@ -8,11 +8,7 @@ import {
   View,
   ViewStyle,
 } from 'react-native'
-import {
-  useNavigation,
-  useNavigationState,
-  StackActions,
-} from '@react-navigation/native'
+import {useNavigation, StackActions} from '@react-navigation/native'
 import {observer} from 'mobx-react-lite'
 import {
   FontAwesomeIcon,
@@ -40,6 +36,8 @@ import {useAnalytics} from 'lib/analytics'
 import {pluralize} from 'lib/strings/helpers'
 import {getTabState, TabState} from 'lib/routes/helpers'
 import {NavigationProp} from 'lib/routes/types'
+import {useNavigationTabState} from 'lib/hooks/useNavigationTabState'
+import {isWeb} from 'platform/detection'
 
 export const DrawerContent = observer(() => {
   const theme = useTheme()
@@ -47,16 +45,7 @@ export const DrawerContent = observer(() => {
   const store = useStores()
   const navigation = useNavigation<NavigationProp>()
   const {track} = useAnalytics()
-  const {isAtHome, isAtSearch, isAtNotifications} = useNavigationState(
-    state => {
-      return {
-        isAtHome: getTabState(state, 'Home') !== TabState.Outside,
-        isAtSearch: getTabState(state, 'Search') !== TabState.Outside,
-        isAtNotifications:
-          getTabState(state, 'Notifications') !== TabState.Outside,
-      }
-    },
-  )
+  const {isAtHome, isAtSearch, isAtNotifications} = useNavigationTabState()
 
   // events
   // =
@@ -66,14 +55,19 @@ export const DrawerContent = observer(() => {
       track('Menu:ItemClicked', {url: tab})
       const state = navigation.getState()
       store.shell.closeDrawer()
-      const tabState = getTabState(state, tab)
-      if (tabState === TabState.InsideAtRoot) {
-        store.emitScreenSoftReset()
-      } else if (tabState === TabState.Inside) {
-        navigation.dispatch(StackActions.popToTop())
-      } else {
+      if (isWeb) {
         // @ts-ignore must be Home, Search, or Notifications
-        navigation.navigate(`${tab}Tab`)
+        navigation.navigate(tab)
+      } else {
+        const tabState = getTabState(state, tab)
+        if (tabState === TabState.InsideAtRoot) {
+          store.emitScreenSoftReset()
+        } else if (tabState === TabState.Inside) {
+          navigation.dispatch(StackActions.popToTop())
+        } else {
+          // @ts-ignore must be Home, Search, or Notifications
+          navigation.navigate(`${tab}Tab`)
+        }
       }
     },
     [store, track, navigation],
@@ -240,20 +234,22 @@ export const DrawerContent = observer(() => {
         </View>
         <View style={s.flex1} />
         <View style={styles.footer}>
-          <TouchableOpacity
-            onPress={onDarkmodePress}
-            style={[
-              styles.footerBtn,
-              theme.colorScheme === 'light'
-                ? pal.btn
-                : styles.footerBtnDarkMode,
-            ]}>
-            <MoonIcon
-              size={22}
-              style={pal.text as StyleProp<ViewStyle>}
-              strokeWidth={2}
-            />
-          </TouchableOpacity>
+          {!isWeb && (
+            <TouchableOpacity
+              onPress={onDarkmodePress}
+              style={[
+                styles.footerBtn,
+                theme.colorScheme === 'light'
+                  ? pal.btn
+                  : styles.footerBtnDarkMode,
+              ]}>
+              <MoonIcon
+                size={22}
+                style={pal.text as StyleProp<ViewStyle>}
+                strokeWidth={2}
+              />
+            </TouchableOpacity>
+          )}
           <TouchableOpacity
             onPress={onPressFeedback}
             style={[
diff --git a/src/view/shell/BottomBar.tsx b/src/view/shell/bottom-bar/BottomBar.tsx
index b01366b2b..59b21968d 100644
--- a/src/view/shell/BottomBar.tsx
+++ b/src/view/shell/bottom-bar/BottomBar.tsx
@@ -2,7 +2,6 @@ import React from 'react'
 import {
   Animated,
   GestureResponderEvent,
-  StyleSheet,
   TouchableOpacity,
   View,
 } from 'react-native'
@@ -13,7 +12,6 @@ import {observer} from 'mobx-react-lite'
 import {Text} from 'view/com/util/text/Text'
 import {useStores} from 'state/index'
 import {useAnalytics} from 'lib/analytics'
-import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
 import {clamp} from 'lib/numbers'
 import {
   HomeIcon,
@@ -24,14 +22,14 @@ import {
   BellIconSolid,
   UserIcon,
 } from 'lib/icons'
-import {colors} from 'lib/styles'
 import {usePalette} from 'lib/hooks/usePalette'
 import {getTabState, TabState} from 'lib/routes/helpers'
+import {styles} from './BottomBarStyles'
+import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
 
 export const BottomBar = observer(({navigation}: BottomTabBarProps) => {
   const store = useStores()
   const pal = usePalette('default')
-  const minimalShellInterp = useAnimatedValue(0)
   const safeAreaInsets = useSafeAreaInsets()
   const {track} = useAnalytics()
   const {isAtHome, isAtSearch, isAtNotifications} = useNavigationState(
@@ -52,26 +50,7 @@ export const BottomBar = observer(({navigation}: BottomTabBarProps) => {
     },
   )
 
-  React.useEffect(() => {
-    if (store.shell.minimalShellMode) {
-      Animated.timing(minimalShellInterp, {
-        toValue: 1,
-        duration: 100,
-        useNativeDriver: true,
-        isInteraction: false,
-      }).start()
-    } else {
-      Animated.timing(minimalShellInterp, {
-        toValue: 0,
-        duration: 100,
-        useNativeDriver: true,
-        isInteraction: false,
-      }).start()
-    }
-  }, [minimalShellInterp, store.shell.minimalShellMode])
-  const footerMinimalShellTransform = {
-    transform: [{translateY: Animated.multiply(minimalShellInterp, 100)}],
-  }
+  const {footerMinimalShellTransform} = useMinimalShellMode()
 
   const onPressTab = React.useCallback(
     (tab: string) => {
@@ -217,62 +196,3 @@ function Btn({
     </TouchableOpacity>
   )
 }
-
-const styles = StyleSheet.create({
-  bottomBar: {
-    position: 'absolute',
-    bottom: 0,
-    left: 0,
-    right: 0,
-    flexDirection: 'row',
-    borderTopWidth: 1,
-    paddingLeft: 5,
-    paddingRight: 10,
-  },
-  ctrl: {
-    flex: 1,
-    paddingTop: 13,
-    paddingBottom: 4,
-  },
-  notificationCount: {
-    position: 'absolute',
-    left: '52%',
-    top: 8,
-    backgroundColor: colors.blue3,
-    paddingHorizontal: 4,
-    paddingBottom: 1,
-    borderRadius: 6,
-    zIndex: 1,
-  },
-  notificationCountLight: {
-    borderColor: colors.white,
-  },
-  notificationCountDark: {
-    borderColor: colors.gray8,
-  },
-  notificationCountLabel: {
-    fontSize: 12,
-    fontWeight: 'bold',
-    color: colors.white,
-    fontVariant: ['tabular-nums'],
-  },
-  ctrlIcon: {
-    marginLeft: 'auto',
-    marginRight: 'auto',
-  },
-  ctrlIconSizingWrapper: {
-    height: 27,
-  },
-  homeIcon: {
-    top: 0,
-  },
-  searchIcon: {
-    top: -2,
-  },
-  bellIcon: {
-    top: -2.5,
-  },
-  profileIcon: {
-    top: -4,
-  },
-})
diff --git a/src/view/shell/bottom-bar/BottomBarStyles.tsx b/src/view/shell/bottom-bar/BottomBarStyles.tsx
new file mode 100644
index 000000000..3d5adbc9e
--- /dev/null
+++ b/src/view/shell/bottom-bar/BottomBarStyles.tsx
@@ -0,0 +1,61 @@
+import {StyleSheet} from 'react-native'
+import {colors} from 'lib/styles'
+
+export const styles = StyleSheet.create({
+  bottomBar: {
+    position: 'absolute',
+    bottom: 0,
+    left: 0,
+    right: 0,
+    flexDirection: 'row',
+    borderTopWidth: 1,
+    paddingLeft: 5,
+    paddingRight: 10,
+  },
+  ctrl: {
+    flex: 1,
+    paddingTop: 13,
+    paddingBottom: 4,
+  },
+  notificationCount: {
+    position: 'absolute',
+    left: '52%',
+    top: 8,
+    backgroundColor: colors.blue3,
+    paddingHorizontal: 4,
+    paddingBottom: 1,
+    borderRadius: 6,
+    zIndex: 1,
+  },
+  notificationCountLight: {
+    borderColor: colors.white,
+  },
+  notificationCountDark: {
+    borderColor: colors.gray8,
+  },
+  notificationCountLabel: {
+    fontSize: 12,
+    fontWeight: 'bold',
+    color: colors.white,
+    fontVariant: ['tabular-nums'],
+  },
+  ctrlIcon: {
+    marginLeft: 'auto',
+    marginRight: 'auto',
+  },
+  ctrlIconSizingWrapper: {
+    height: 27,
+  },
+  homeIcon: {
+    top: 0,
+  },
+  searchIcon: {
+    top: -2,
+  },
+  bellIcon: {
+    top: -2.5,
+  },
+  profileIcon: {
+    top: -4,
+  },
+})
diff --git a/src/view/shell/bottom-bar/BottomBarWeb.tsx b/src/view/shell/bottom-bar/BottomBarWeb.tsx
new file mode 100644
index 000000000..b7daac5af
--- /dev/null
+++ b/src/view/shell/bottom-bar/BottomBarWeb.tsx
@@ -0,0 +1,101 @@
+import React from 'react'
+import {observer} from 'mobx-react-lite'
+import {useStores} from 'state/index'
+import {usePalette} from 'lib/hooks/usePalette'
+import {Animated} from 'react-native'
+import {useNavigationState} from '@react-navigation/native'
+import {useSafeAreaInsets} from 'react-native-safe-area-context'
+import {getCurrentRoute, isTab} from 'lib/routes/helpers'
+import {styles} from './BottomBarStyles'
+import {clamp} from 'lib/numbers'
+import {
+  BellIcon,
+  BellIconSolid,
+  HomeIcon,
+  HomeIconSolid,
+  MagnifyingGlassIcon2,
+  MagnifyingGlassIcon2Solid,
+  UserIcon,
+} from 'lib/icons'
+import {Link} from 'view/com/util/Link'
+import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
+
+export const BottomBarWeb = observer(() => {
+  const store = useStores()
+  const pal = usePalette('default')
+  const safeAreaInsets = useSafeAreaInsets()
+  const {footerMinimalShellTransform} = useMinimalShellMode()
+
+  return (
+    <Animated.View
+      style={[
+        styles.bottomBar,
+        pal.view,
+        pal.border,
+        {paddingBottom: clamp(safeAreaInsets.bottom, 15, 30)},
+        footerMinimalShellTransform,
+      ]}>
+      <NavItem routeName="Home" href="/">
+        {({isActive}) => {
+          const Icon = isActive ? HomeIconSolid : HomeIcon
+          return (
+            <Icon
+              strokeWidth={4}
+              size={24}
+              style={[styles.ctrlIcon, pal.text, styles.homeIcon]}
+            />
+          )
+        }}
+      </NavItem>
+      <NavItem routeName="Search" href="/search">
+        {({isActive}) => {
+          const Icon = isActive
+            ? MagnifyingGlassIcon2Solid
+            : MagnifyingGlassIcon2
+          return (
+            <Icon
+              size={25}
+              style={[styles.ctrlIcon, pal.text, styles.searchIcon]}
+              strokeWidth={1.8}
+            />
+          )
+        }}
+      </NavItem>
+      <NavItem routeName="Notifications" href="/notifications">
+        {({isActive}) => {
+          const Icon = isActive ? BellIconSolid : BellIcon
+          return (
+            <Icon
+              size={24}
+              strokeWidth={1.9}
+              style={[styles.ctrlIcon, pal.text, styles.bellIcon]}
+            />
+          )
+        }}
+      </NavItem>
+      <NavItem routeName="Profile" href={`/profile/${store.me.handle}`}>
+        {() => (
+          <UserIcon
+            size={28}
+            strokeWidth={1.5}
+            style={[styles.ctrlIcon, pal.text, styles.profileIcon]}
+          />
+        )}
+      </NavItem>
+    </Animated.View>
+  )
+})
+
+const NavItem: React.FC<{
+  children: (props: {isActive: boolean}) => React.ReactChild
+  href: string
+  routeName: string
+}> = ({children, href, routeName}) => {
+  const currentRoute = useNavigationState(getCurrentRoute)
+  const isActive = isTab(currentRoute.name, routeName)
+  return (
+    <Link href={href} style={styles.ctrl}>
+      {children({isActive})}
+    </Link>
+  )
+}
diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx
index 96a120642..86d120127 100644
--- a/src/view/shell/index.web.tsx
+++ b/src/view/shell/index.web.tsx
@@ -1,6 +1,6 @@
 import React from 'react'
 import {observer} from 'mobx-react-lite'
-import {View, StyleSheet} from 'react-native'
+import {View, StyleSheet, TouchableOpacity} from 'react-native'
 import {useStores} from 'state/index'
 import {DesktopLeftNav} from './desktop/LeftNav'
 import {DesktopRightNav} from './desktop/RightNav'
@@ -11,9 +11,13 @@ import {Composer} from './Composer.web'
 import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
 import {s, colors} from 'lib/styles'
 import {RoutesContainer, FlatNavigator} from '../../Navigation'
+import {DrawerContent} from './Drawer'
+import {useWebMediaQueries} from '../../lib/hooks/useWebMediaQueries'
+import {BottomBarWeb} from './bottom-bar/BottomBarWeb'
 
 const ShellInner = observer(() => {
   const store = useStores()
+  const {isDesktop} = useWebMediaQueries()
 
   return (
     <>
@@ -22,10 +26,14 @@ const ShellInner = observer(() => {
           <FlatNavigator />
         </ErrorBoundary>
       </View>
-      <DesktopLeftNav />
-      <DesktopRightNav />
-      <View style={[styles.viewBorder, styles.viewBorderLeft]} />
-      <View style={[styles.viewBorder, styles.viewBorderRight]} />
+      {isDesktop && (
+        <>
+          <DesktopLeftNav />
+          <DesktopRightNav />
+          <View style={[styles.viewBorder, styles.viewBorderLeft]} />
+          <View style={[styles.viewBorder, styles.viewBorderRight]} />
+        </>
+      )}
       <Composer
         active={store.shell.isComposerActive}
         onClose={() => store.shell.closeComposer()}
@@ -34,8 +42,18 @@ const ShellInner = observer(() => {
         quote={store.shell.composerOpts?.quote}
         onPost={store.shell.composerOpts?.onPost}
       />
+      {!isDesktop && <BottomBarWeb />}
       <ModalsContainer />
       <Lightbox />
+      {!isDesktop && store.shell.isDrawerOpen && (
+        <TouchableOpacity
+          onPress={() => store.shell.closeDrawer()}
+          style={styles.drawerMask}>
+          <View style={styles.drawerContainer}>
+            <DrawerContent />
+          </View>
+        </TouchableOpacity>
+      )}
     </>
   )
 })
@@ -71,4 +89,19 @@ const styles = StyleSheet.create({
   viewBorderRight: {
     left: 'calc(50vw + 300px)',
   },
+  drawerMask: {
+    position: 'absolute',
+    width: '100%',
+    height: '100%',
+    top: 0,
+    left: 0,
+    backgroundColor: 'rgba(0,0,0,0.25)',
+  },
+  drawerContainer: {
+    display: 'flex',
+    position: 'absolute',
+    top: 0,
+    left: 0,
+    height: '100%',
+  },
 })