diff options
Diffstat (limited to 'src/view/shell/mobile')
-rw-r--r-- | src/view/shell/mobile/MainMenu.tsx | 354 | ||||
-rw-r--r-- | src/view/shell/mobile/index.tsx | 21 |
2 files changed, 2 insertions, 373 deletions
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} |