diff --git a/src/view/shell/mobile/BottomBar.tsx b/src/view/shell/mobile/BottomBar.tsx
new file mode 100644
index 0000000000..2c3ead32a7
--- /dev/null
+++ b/src/view/shell/mobile/BottomBar.tsx
@@ -0,0 +1,292 @@
+import React from 'react'
+import {
+ Animated,
+ GestureResponderEvent,
+ StyleSheet,
+ TouchableOpacity,
+ View,
+} from 'react-native'
+import {useSafeAreaInsets} from 'react-native-safe-area-context'
+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 {TabPurpose, TabPurposeMainPath} from 'state/models/navigation'
+import {clamp} from 'lib/numbers'
+import {
+ HomeIcon,
+ HomeIconSolid,
+ MagnifyingGlassIcon2,
+ MagnifyingGlassIcon2Solid,
+ ComposeIcon2,
+ BellIcon,
+ BellIconSolid,
+ UserIcon,
+} from 'lib/icons'
+import {colors} from 'lib/styles'
+import {usePalette} from 'lib/hooks/usePalette'
+
+export const BottomBar = observer(() => {
+ const store = useStores()
+ const pal = usePalette('default')
+ const minimalShellInterp = useAnimatedValue(0)
+ const safeAreaInsets = useSafeAreaInsets()
+ const {track} = useAnalytics()
+
+ 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 onPressHome = React.useCallback(() => {
+ track('MobileShell:HomeButtonPressed')
+ if (store.nav.tab.fixedTabPurpose === TabPurpose.Default) {
+ if (!store.nav.tab.canGoBack) {
+ store.emitScreenSoftReset()
+ } else {
+ store.nav.tab.fixedTabReset()
+ }
+ } else {
+ store.nav.switchTo(TabPurpose.Default, false)
+ if (store.nav.tab.index === 0) {
+ store.nav.tab.fixedTabReset()
+ }
+ }
+ }, [store, track])
+ const onPressSearch = React.useCallback(() => {
+ track('MobileShell:SearchButtonPressed')
+ if (store.nav.tab.fixedTabPurpose === TabPurpose.Search) {
+ if (!store.nav.tab.canGoBack) {
+ store.emitScreenSoftReset()
+ } else {
+ store.nav.tab.fixedTabReset()
+ }
+ } else {
+ store.nav.switchTo(TabPurpose.Search, false)
+ if (store.nav.tab.index === 0) {
+ store.nav.tab.fixedTabReset()
+ }
+ }
+ }, [store, track])
+ const onPressCompose = React.useCallback(() => {
+ track('MobileShell:ComposeButtonPressed')
+ store.shell.openComposer({})
+ }, [store, track])
+ const onPressNotifications = React.useCallback(() => {
+ track('MobileShell:NotificationsButtonPressed')
+ if (store.nav.tab.fixedTabPurpose === TabPurpose.Notifs) {
+ if (!store.nav.tab.canGoBack) {
+ store.emitScreenSoftReset()
+ } else {
+ store.nav.tab.fixedTabReset()
+ }
+ } else {
+ store.nav.switchTo(TabPurpose.Notifs, false)
+ if (store.nav.tab.index === 0) {
+ store.nav.tab.fixedTabReset()
+ }
+ }
+ }, [store, track])
+ const onPressProfile = React.useCallback(() => {
+ track('MobileShell:ProfileButtonPressed')
+ store.nav.navigate(`/profile/${store.me.handle}`)
+ }, [store, track])
+
+ 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 (
+
+
+ ) : (
+
+ )
+ }
+ onPress={onPressHome}
+ />
+
+ ) : (
+
+ )
+ }
+ onPress={onPressSearch}
+ />
+
+
+
+ }
+ onPress={onPressCompose}
+ />
+
+ ) : (
+
+ )
+ }
+ onPress={onPressNotifications}
+ notificationCount={store.me.notifications.unreadCount}
+ />
+
+
+
+ }
+ onPress={onPressProfile}
+ />
+
+ )
+})
+
+function Btn({
+ icon,
+ notificationCount,
+ onPress,
+ onLongPress,
+}: {
+ icon: JSX.Element
+ notificationCount?: number
+ onPress?: (event: GestureResponderEvent) => void
+ onLongPress?: (event: GestureResponderEvent) => void
+}) {
+ return (
+
+ {notificationCount ? (
+
+ {notificationCount}
+
+ ) : undefined}
+ {icon}
+
+ )
+}
+
+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: '56%',
+ top: 10,
+ backgroundColor: colors.blue3,
+ paddingHorizontal: 4,
+ paddingBottom: 1,
+ borderRadius: 8,
+ zIndex: 1,
+ },
+ notificationCountLabel: {
+ fontSize: 12,
+ fontWeight: 'bold',
+ color: colors.white,
+ },
+ ctrlIcon: {
+ marginLeft: 'auto',
+ marginRight: 'auto',
+ },
+ ctrlIconSizingWrapper: {
+ height: 27,
+ },
+ homeIcon: {
+ top: 0,
+ },
+ searchIcon: {
+ top: -2,
+ },
+ bellIcon: {
+ top: -2.5,
+ },
+ composeIcon: {
+ top: -4.5,
+ },
+ profileIcon: {
+ top: -4,
+ },
+})
diff --git a/src/view/shell/mobile/Menu.tsx b/src/view/shell/mobile/Menu.tsx
index 23c09b82ce..6c5aa1adbb 100644
--- a/src/view/shell/mobile/Menu.tsx
+++ b/src/view/shell/mobile/Menu.tsx
@@ -119,7 +119,6 @@ export const Menu = observer(({onClose}: {onClose: () => void}) => {
style={[
styles.view,
theme.colorScheme === 'light' ? pal.view : styles.viewDarkMode,
- store.shell.minimalShellMode && styles.viewMinimalShell,
]}>
void
- onLongPress?: (event: GestureResponderEvent) => void
-}) => {
- return (
-
- {notificationCount ? (
-
- {notificationCount}
-
- ) : undefined}
- {icon}
-
- )
-}
export const MobileShell: React.FC = observer(() => {
const theme = useTheme()
@@ -79,87 +35,8 @@ export const MobileShell: React.FC = observer(() => {
const winDim = useWindowDimensions()
const [menuSwipingDirection, setMenuSwipingDirection] = useState(0)
const swipeGestureInterp = useAnimatedValue(0)
- const minimalShellInterp = useAnimatedValue(0)
const safeAreaInsets = useSafeAreaInsets()
const screenRenderDesc = constructScreenRenderDesc(store.nav)
- const {track} = useAnalytics()
-
- const onPressHome = () => {
- track('MobileShell:HomeButtonPressed')
- if (store.nav.tab.fixedTabPurpose === TabPurpose.Default) {
- if (!store.nav.tab.canGoBack) {
- store.emitScreenSoftReset()
- } else {
- store.nav.tab.fixedTabReset()
- }
- } else {
- store.nav.switchTo(TabPurpose.Default, false)
- if (store.nav.tab.index === 0) {
- store.nav.tab.fixedTabReset()
- }
- }
- }
- const onPressSearch = () => {
- track('MobileShell:SearchButtonPressed')
- if (store.nav.tab.fixedTabPurpose === TabPurpose.Search) {
- if (!store.nav.tab.canGoBack) {
- store.emitScreenSoftReset()
- } else {
- store.nav.tab.fixedTabReset()
- }
- } else {
- store.nav.switchTo(TabPurpose.Search, false)
- if (store.nav.tab.index === 0) {
- store.nav.tab.fixedTabReset()
- }
- }
- }
- const onPressCompose = () => {
- track('MobileShell:ComposeButtonPressed')
- store.shell.openComposer({})
- }
- const onPressNotifications = () => {
- track('MobileShell:NotificationsButtonPressed')
- if (store.nav.tab.fixedTabPurpose === TabPurpose.Notifs) {
- if (!store.nav.tab.canGoBack) {
- store.emitScreenSoftReset()
- } else {
- store.nav.tab.fixedTabReset()
- }
- } else {
- store.nav.switchTo(TabPurpose.Notifs, false)
- if (store.nav.tab.index === 0) {
- store.nav.tab.fixedTabReset()
- }
- }
- }
- const onPressProfile = () => {
- track('MobileShell:ProfileButtonPressed')
- store.nav.navigate(`/profile/${store.me.handle}`)
- }
-
- // minimal shell animation
- // =
- 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)}],
- }
// navigation swipes
// =
@@ -231,13 +108,6 @@ export const MobileShell: React.FC = observer(() => {
}),
}
: undefined
- // TODO
- // const tabMenuTransform = {
- // transform: [{translateY: Animated.multiply(tabMenuInterp, -320)}],
- // }
- // const newTabTransform = {
- // transform: [{scale: newTabInterp}],
- // }
if (store.hackUpgradeNeeded) {
return (
@@ -286,13 +156,6 @@ export const MobileShell: React.FC = observer(() => {
)
}
- 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]
-
const screenBg = {
backgroundColor: theme.colorScheme === 'dark' ? colors.gray7 : colors.gray1,
}
@@ -360,6 +223,7 @@ export const MobileShell: React.FC = observer(() => {
},
)}
+
{isMenuActive || menuSwipingDirection !== 0 ? (
store.shell.setMainMenuOpen(false)}>
@@ -373,95 +237,6 @@ export const MobileShell: React.FC = observer(() => {
)}
-
-
- ) : (
-
- )
- }
- onPress={onPressHome}
- />
-
- ) : (
-
- )
- }
- onPress={onPressSearch}
- />
-
-
-
- }
- onPress={onPressCompose}
- />
-
- ) : (
-
- )
- }
- onPress={onPressNotifications}
- notificationCount={store.me.notifications.unreadCount}
- />
-
-
-
- }
- onPress={onPressProfile}
- />
-