diff options
author | Paul Frazee <pfrazee@gmail.com> | 2022-10-10 21:13:25 -0500 |
---|---|---|
committer | Paul Frazee <pfrazee@gmail.com> | 2022-10-10 21:13:25 -0500 |
commit | ba6580101e5b8f2f994d37be14ae61fd4c3ef1ee (patch) | |
tree | ed0d720d27183cd3a679da71871dadc2894387ae | |
parent | 287f2992fa6400fbac520bf7b9693bd5dcc6e7db (diff) | |
download | voidsky-ba6580101e5b8f2f994d37be14ae61fd4c3ef1ee.tar.zst |
Rework footer controls
-rw-r--r-- | src/view/shell/mobile/HistoryMenu.tsx (renamed from src/view/shell/mobile/history-menu.tsx) | 0 | ||||
-rw-r--r-- | src/view/shell/mobile/LocationNavigator.tsx (renamed from src/view/shell/mobile/location-navigator.tsx) | 0 | ||||
-rw-r--r-- | src/view/shell/mobile/MainMenu.tsx | 210 | ||||
-rw-r--r-- | src/view/shell/mobile/TabsSelector.tsx | 383 | ||||
-rw-r--r-- | src/view/shell/mobile/accounts-menu.tsx | 108 | ||||
-rw-r--r-- | src/view/shell/mobile/index.tsx | 94 | ||||
-rw-r--r-- | src/view/shell/mobile/location-menu.tsx | 89 |
7 files changed, 618 insertions, 266 deletions
diff --git a/src/view/shell/mobile/history-menu.tsx b/src/view/shell/mobile/HistoryMenu.tsx index d0b9b9751..d0b9b9751 100644 --- a/src/view/shell/mobile/history-menu.tsx +++ b/src/view/shell/mobile/HistoryMenu.tsx diff --git a/src/view/shell/mobile/location-navigator.tsx b/src/view/shell/mobile/LocationNavigator.tsx index 28ca23101..28ca23101 100644 --- a/src/view/shell/mobile/location-navigator.tsx +++ b/src/view/shell/mobile/LocationNavigator.tsx diff --git a/src/view/shell/mobile/MainMenu.tsx b/src/view/shell/mobile/MainMenu.tsx new file mode 100644 index 000000000..bf18f7645 --- /dev/null +++ b/src/view/shell/mobile/MainMenu.tsx @@ -0,0 +1,210 @@ +import React from 'react' +import {observer} from 'mobx-react-lite' +import { + Image, + StyleSheet, + Text, + TouchableOpacity, + TouchableWithoutFeedback, + View, +} from 'react-native' +import {IconProp} from '@fortawesome/fontawesome-svg-core' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import LinearGradient from 'react-native-linear-gradient' +import {useStores} from '../../../state' +import {s, colors, gradients} from '../../lib/styles' +import {DEF_AVATER} from '../../lib/assets' + +export const MainMenu = observer( + ({active, onClose}: {active: boolean; onClose: () => void}) => { + const store = useStores() + + // events + // = + + const onNavigate = (url: string) => { + store.nav.navigate(url) + onClose() + } + + // rendering + // = + + const FatMenuItem = ({ + icon, + label, + url, + gradient, + }: { + icon: IconProp + label: string + url: string + gradient: keyof typeof gradients + }) => ( + <TouchableOpacity + style={[styles.fatMenuItem, styles.fatMenuItemMargin]} + onPress={() => onNavigate(url)}> + <LinearGradient + style={[styles.fatMenuItemIconWrapper]} + colors={[gradients[gradient].start, gradients[gradient].end]} + start={{x: 0, y: 0}} + end={{x: 1, y: 1}}> + <FontAwesomeIcon + icon={icon} + style={styles.fatMenuItemIcon} + size={24} + /> + </LinearGradient> + <Text style={styles.fatMenuItemLabel} numberOfLines={1}> + {label} + </Text> + </TouchableOpacity> + ) + if (!active) { + return <View /> + } + + return ( + <> + <TouchableWithoutFeedback onPress={onClose}> + <View style={styles.bg} /> + </TouchableWithoutFeedback> + <View style={styles.wrapper}> + <View style={[styles.topSection]}> + <TouchableOpacity + style={styles.profile} + onPress={() => onNavigate(`/profile/${store.me.name || ''}`)}> + <Image style={styles.profileImage} source={DEF_AVATER} /> + <Text style={styles.profileText} numberOfLines={1}> + {store.me.displayName || store.me.name || '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> + <View style={[styles.section]}> + <View style={styles.fatMenuItems}> + <FatMenuItem + icon="house" + label="Feed" + url="/" + gradient="primary" + /> + <FatMenuItem + icon="bell" + label="Notifications" + url="/notifications" + gradient="purple" + /> + <FatMenuItem + icon="gear" + label="Settings" + url="/settings" + gradient="blue" + /> + </View> + </View> + </View> + </> + ) + }, +) + +const styles = StyleSheet.create({ + bg: { + position: 'absolute', + top: 0, + right: 0, + bottom: 0, + left: 0, + backgroundColor: '#000', + opacity: 0.2, + }, + wrapper: { + position: 'absolute', + bottom: 75, + width: '100%', + backgroundColor: '#fff', + borderRadius: 8, + opacity: 1, + paddingVertical: 10, + }, + + topSection: { + flexDirection: 'row', + alignItems: 'center', + paddingHorizontal: 10, + }, + section: { + paddingHorizontal: 10, + }, + + profile: { + paddingVertical: 10, + paddingHorizontal: 10, + flexDirection: 'row', + alignItems: 'center', + }, + profileImage: { + borderRadius: 15, + width: 30, + height: 30, + marginRight: 5, + }, + profileText: { + fontSize: 15, + fontWeight: 'bold', + }, + + settings: {}, + settingsIcon: { + color: colors.gray5, + marginRight: 10, + }, + + fatMenuItems: { + flexDirection: 'row', + marginTop: 10, + marginBottom: 10, + }, + fatMenuItem: { + width: 80, + alignItems: 'center', + marginRight: 6, + }, + fatMenuItemMargin: { + marginRight: 14, + }, + fatMenuItemIconWrapper: { + borderRadius: 6, + width: 60, + height: 60, + justifyContent: 'center', + alignItems: 'center', + marginBottom: 5, + shadowColor: '#000', + shadowOpacity: 0.2, + shadowOffset: {width: 0, height: 2}, + shadowRadius: 2, + }, + fatMenuItemIcon: { + color: colors.white, + }, + fatMenuImage: { + borderRadius: 30, + width: 60, + height: 60, + marginBottom: 5, + }, + fatMenuItemLabel: { + fontSize: 13, + }, +}) diff --git a/src/view/shell/mobile/TabsSelector.tsx b/src/view/shell/mobile/TabsSelector.tsx new file mode 100644 index 000000000..8e3fba41a --- /dev/null +++ b/src/view/shell/mobile/TabsSelector.tsx @@ -0,0 +1,383 @@ +import React, {createRef, useRef, useMemo, useState} from 'react' +import {observer} from 'mobx-react-lite' +import { + Image, + ScrollView, + StyleSheet, + Text, + TouchableOpacity, + TouchableWithoutFeedback, + View, +} from 'react-native' +import Animated, { + useSharedValue, + useAnimatedStyle, + withTiming, + runOnJS, +} from 'react-native-reanimated' +import {IconProp} from '@fortawesome/fontawesome-svg-core' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import Swipeable from 'react-native-gesture-handler/Swipeable' +import LinearGradient from 'react-native-linear-gradient' +import {useStores} from '../../../state' +import {s, colors, gradients} from '../../lib/styles' +import {DEF_AVATER} from '../../lib/assets' +import {match} from '../../routes' +import {LinkActionsModel} from '../../../state/models/shell' + +const TAB_HEIGHT = 42 + +export const TabsSelector = observer( + ({active, onClose}: {active: boolean; onClose: () => void}) => { + const store = useStores() + const [closingTabIndex, setClosingTabIndex] = useState<number | undefined>( + undefined, + ) + const closeInterp = useSharedValue<number>(0) + const tabsRef = useRef<ScrollView>(null) + const tabRefs = useMemo( + () => + Array.from({length: store.nav.tabs.length}).map(() => + createRef<Animated.View>(), + ), + [store.nav.tabs.length], + ) + + // events + // = + + const onPressNewTab = () => { + store.nav.newTab('/') + onClose() + } + const onPressCloneTab = () => { + store.nav.newTab(store.nav.tab.current.url) + onClose() + } + const onPressShareTab = () => { + onClose() + store.shell.openModal( + new LinkActionsModel( + store.nav.tab.current.url, + store.nav.tab.current.title || 'This Page', + {newTab: false}, + ), + ) + } + const onPressChangeTab = (tabIndex: number) => { + store.nav.setActiveTab(tabIndex) + onClose() + } + const doCloseTab = (index: number) => store.nav.closeTab(index) + const onCloseTab = (tabIndex: number) => { + setClosingTabIndex(tabIndex) + closeInterp.value = 0 + closeInterp.value = withTiming(1, {duration: 300}, () => { + runOnJS(setClosingTabIndex)(undefined) + runOnJS(doCloseTab)(tabIndex) + }) + } + const onNavigate = (url: string) => { + store.nav.navigate(url) + onClose() + } + const onLayout = () => { + // focus the current tab + const targetTab = tabRefs[store.nav.tabIndex] + if (tabsRef.current && targetTab.current) { + targetTab.current.measureLayout?.( + tabsRef.current, + (_left: number, top: number) => { + tabsRef.current?.scrollTo({y: top, animated: false}) + }, + () => {}, + ) + } + } + + // rendering + // = + + const FatMenuItem = ({ + icon, + label, + url, + gradient, + }: { + icon: IconProp + label: string + url: string + gradient: keyof typeof gradients + }) => ( + <TouchableOpacity + style={[styles.fatMenuItem, styles.fatMenuItemMargin]} + onPress={() => onNavigate(url)}> + <LinearGradient + style={[styles.fatMenuItemIconWrapper]} + colors={[gradients[gradient].start, gradients[gradient].end]} + start={{x: 0, y: 0}} + end={{x: 1, y: 1}}> + <FontAwesomeIcon + icon={icon} + style={styles.fatMenuItemIcon} + size={24} + /> + </LinearGradient> + <Text style={styles.fatMenuItemLabel} numberOfLines={1}> + {label} + </Text> + </TouchableOpacity> + ) + + const renderSwipeActions = () => { + return <View style={[s.p2]} /> + } + + const currentTabIndex = store.nav.tabIndex + const closingTabAnimStyle = useAnimatedStyle(() => ({ + height: TAB_HEIGHT * (1 - closeInterp.value), + opacity: 1 - closeInterp.value, + marginBottom: 4 * (1 - closeInterp.value), + })) + + if (!active) { + return <View /> + } + + return ( + <> + <TouchableWithoutFeedback onPress={onClose}> + <View style={styles.bg} /> + </TouchableWithoutFeedback> + <View style={styles.wrapper}> + <View onLayout={onLayout}> + <View style={[s.p10, styles.section]}> + <View style={styles.btns}> + <TouchableWithoutFeedback 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 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 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 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} + renderLeftActions={renderSwipeActions} + renderRightActions={renderSwipeActions} + leftThreshold={100} + rightThreshold={100} + onSwipeableWillOpen={() => onCloseTab(tabIndex)}> + <Animated.View + style={[ + styles.tabOuter, + isClosing ? closingTabAnimStyle : undefined, + ]}> + <Animated.View + ref={tabRefs[tabIndex]} + style={[ + styles.tab, + styles.existing, + isActive && styles.active, + ]}> + <TouchableWithoutFeedback + 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 + 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> + </View> + </> + ) + }, +) + +const styles = StyleSheet.create({ + bg: { + position: 'absolute', + top: 0, + right: 0, + bottom: 0, + left: 0, + backgroundColor: '#000', + opacity: 0.2, + }, + wrapper: { + position: 'absolute', + bottom: 75, + width: '100%', + backgroundColor: '#fff', + borderRadius: 8, + opacity: 1, + }, + section: { + borderBottomColor: colors.gray2, + borderBottomWidth: 1, + }, + sectionGrayBg: { + backgroundColor: colors.gray1, + borderBottomLeftRadius: 8, + borderBottomRightRadius: 8, + }, + fatMenuItems: { + flexDirection: 'row', + marginTop: 10, + marginBottom: 10, + }, + fatMenuItem: { + width: 80, + alignItems: 'center', + marginRight: 6, + }, + fatMenuItemMargin: { + marginRight: 14, + }, + fatMenuItemIconWrapper: { + borderRadius: 6, + width: 60, + height: 60, + justifyContent: 'center', + alignItems: 'center', + marginBottom: 5, + shadowColor: '#000', + shadowOpacity: 0.2, + shadowOffset: {width: 0, height: 2}, + shadowRadius: 2, + }, + fatMenuItemIcon: { + color: colors.white, + }, + fatMenuImage: { + borderRadius: 30, + width: 60, + height: 60, + marginBottom: 5, + }, + fatMenuItemLabel: { + fontSize: 13, + }, + 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/accounts-menu.tsx b/src/view/shell/mobile/accounts-menu.tsx deleted file mode 100644 index ec0e6bf40..000000000 --- a/src/view/shell/mobile/accounts-menu.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import React from 'react' -import { - Image, - StyleSheet, - Text, - TouchableOpacity, - TouchableWithoutFeedback, - View, -} from 'react-native' -import RootSiblings from 'react-native-root-siblings' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {DEF_AVATER} from '../../lib/assets' -import {s, colors} from '../../lib/styles' - -export function createAccountsMenu({ - debug_onPressItem, - onPressLogout, -}: { - debug_onPressItem: () => void - onPressLogout: () => void -}): RootSiblings { - const onPressItem = (_index: number) => { - sibling.destroy() - debug_onPressItem() // TODO - } - const onOuterPress = () => sibling.destroy() - const sibling = new RootSiblings( - ( - <> - <TouchableWithoutFeedback onPress={onOuterPress}> - <View style={styles.bg} /> - </TouchableWithoutFeedback> - <View style={[styles.menu]}> - <TouchableOpacity - style={[styles.menuItem]} - onPress={() => onPressItem(0)}> - <Image style={styles.avi} source={DEF_AVATER} /> - <Text style={[styles.label, s.bold]}>Alice</Text> - </TouchableOpacity> - <TouchableOpacity - style={[styles.menuItem, styles.menuItemBorder]} - onPress={() => onPressItem(0)}> - <FontAwesomeIcon style={styles.icon} icon="plus" /> - <Text style={styles.label}>New Account</Text> - </TouchableOpacity> - <TouchableOpacity - style={[styles.menuItem, styles.menuItemBorder]} - onPress={() => { - sibling.destroy() - onPressLogout() - }}> - <FontAwesomeIcon - style={styles.icon} - icon="arrow-right-from-bracket" - /> - <Text style={styles.label}>Log out</Text> - </TouchableOpacity> - </View> - </> - ), - ) - return sibling -} - -const styles = StyleSheet.create({ - bg: { - position: 'absolute', - top: 0, - right: 0, - bottom: 0, - left: 0, - backgroundColor: '#000', - opacity: 0.1, - }, - menu: { - position: 'absolute', - left: 4, - top: 70, - backgroundColor: '#fff', - borderRadius: 14, - opacity: 1, - paddingVertical: 2, - }, - menuItem: { - flexDirection: 'row', - alignItems: 'center', - paddingVertical: 8, - paddingLeft: 10, - paddingRight: 30, - }, - menuItemBorder: { - borderTopWidth: 1, - borderTopColor: colors.gray1, - }, - avi: { - width: 28, - height: 28, - marginRight: 8, - borderRadius: 14, - }, - icon: { - marginLeft: 6, - marginRight: 6, - }, - label: { - fontSize: 16, - }, -}) diff --git a/src/view/shell/mobile/index.tsx b/src/view/shell/mobile/index.tsx index 90f7470ac..b7c13f35c 100644 --- a/src/view/shell/mobile/index.tsx +++ b/src/view/shell/mobile/index.tsx @@ -28,53 +28,16 @@ import {TabsSelectorModel} from '../../../state/models/shell' import {match, MatchResult} from '../../routes' import {Login} from '../../screens/Login' import {Modal} from '../../com/modals/Modal' -import {LocationNavigator} from './location-navigator' -import {createBackMenu, createForwardMenu} from './history-menu' -import {createAccountsMenu} from './accounts-menu' -import {createLocationMenu} from './location-menu' +import {LocationNavigator} from './LocationNavigator' +import {createBackMenu, createForwardMenu} from './HistoryMenu' +import {MainMenu} from './MainMenu' +import {TabsSelector} from './TabsSelector' import {s, colors} from '../../lib/styles' import {GridIcon, HomeIcon} from '../../lib/icons' -import {DEF_AVATER} from '../../lib/assets' -const locationIconNeedsNudgeUp = (icon: IconProp) => icon === 'house' const SWIPE_GESTURE_DIST_TRIGGER = 0.5 const SWIPE_GESTURE_VEL_TRIGGER = 2500 -const Location = ({ - icon, - title, - onPress, -}: { - icon: IconProp - title?: string - onPress?: (event: GestureResponderEvent) => void -}) => { - const nudgeUp = locationIconNeedsNudgeUp(icon) - return ( - <TouchableOpacity style={styles.location} onPress={onPress}> - {title ? ( - <FontAwesomeIcon - size={12} - style={[ - styles.locationIcon, - nudgeUp ? styles.locationIconNudgeUp : undefined, - ]} - icon={icon} - /> - ) : ( - <FontAwesomeIcon - size={12} - style={styles.locationIconLight} - icon="magnifying-glass" - /> - )} - <Text style={title ? styles.locationText : styles.locationTextLight}> - {title || 'Search'} - </Text> - </TouchableOpacity> - ) -} - const Btn = ({ icon, inactive, @@ -89,7 +52,7 @@ const Btn = ({ onLongPress?: (event: GestureResponderEvent) => void }) => { let IconEl - if (icon === 'bars') { + if (icon === 'menu') { IconEl = GridIcon } else if (icon === 'house') { IconEl = HomeIcon @@ -131,18 +94,12 @@ const Btn = ({ export const MobileShell: React.FC = observer(() => { const store = useStores() const [isLocationMenuActive, setLocationMenuActive] = useState(false) + const [isMainMenuActive, setMainMenuActive] = useState(false) + const [isTabsSelectorActive, setTabsSelectorActive] = useState(false) const winDim = useWindowDimensions() const swipeGestureInterp = useSharedValue<number>(0) const screenRenderDesc = constructScreenRenderDesc(store.nav) - const onPressAvi = () => - createAccountsMenu({ - debug_onPressItem: () => store.nav.navigate('/profile/alice.test'), - onPressLogout: () => store.session.logout(), - }) - const onPressLocation = () => setLocationMenuActive(true) - const onPressEllipsis = () => createLocationMenu() - const onNavigateLocation = (url: string) => { setLocationMenuActive(false) store.nav.navigate(url) @@ -150,13 +107,14 @@ export const MobileShell: React.FC = observer(() => { const onDismissLocationNavigator = () => setLocationMenuActive(false) const onPressBack = () => store.nav.tab.goBack() - const onPressForward = () => store.nav.tab.goForward() + // const onPressForward = () => store.nav.tab.goForward() const onPressHome = () => store.nav.navigate('/') + const onPressMenu = () => setMainMenuActive(true) const onPressNotifications = () => store.nav.navigate('/notifications') - const onPressTabs = () => store.shell.openModal(new TabsSelectorModel()) + const onPressTabs = () => setTabsSelectorActive(true) //store.shell.openModal(new TabsSelectorModel()) const onLongPressBack = () => createBackMenu(store.nav.tab) - const onLongPressForward = () => createForwardMenu(store.nav.tab) + // const onLongPressForward = () => createForwardMenu(store.nav.tab) const goBack = () => store.nav.tab.goBack() const swipeGesture = Gesture.Pan() @@ -205,19 +163,6 @@ export const MobileShell: React.FC = observer(() => { return ( <View style={styles.outerContainer}> - {/* <View style={styles.topBar}> - <TouchableOpacity onPress={onPressAvi}> - <Image style={styles.avi} source={DEF_AVATER} /> - </TouchableOpacity> - <Location - icon={screenRenderDesc.icon} - title={store.nav.tab.current.title} - onPress={onPressLocation} - /> - <TouchableOpacity style={styles.topBarBtn} onPress={onPressEllipsis}> - <FontAwesomeIcon icon="ellipsis" /> - </TouchableOpacity> - </View> */} <SafeAreaView style={styles.innerContainer}> <GestureDetector gesture={swipeGesture}> <ScreenContainer style={styles.screenContainer}> @@ -255,21 +200,32 @@ export const MobileShell: React.FC = observer(() => { onPress={onPressBack} onLongPress={onLongPressBack} /> - <Btn + { + undefined /*<Btn icon="angle-right" inactive={!store.nav.tab.canGoForward} onPress={onPressForward} onLongPress={onLongPressForward} - /> + />*/ + } <Btn icon="house" onPress={onPressHome} /> + <Btn icon="menu" onPress={onPressMenu} /> <Btn icon={['far', 'bell']} onPress={onPressNotifications} notificationCount={store.me.notificationCount} /> - <Btn icon="bars" onPress={onPressTabs} /> + <Btn icon={['far', 'clone']} onPress={onPressTabs} /> </View> <Modal /> + <MainMenu + active={isMainMenuActive} + onClose={() => setMainMenuActive(false)} + /> + <TabsSelector + active={isTabsSelectorActive} + onClose={() => setTabsSelectorActive(false)} + /> {isLocationMenuActive && ( <LocationNavigator url={store.nav.tab.current.url} diff --git a/src/view/shell/mobile/location-menu.tsx b/src/view/shell/mobile/location-menu.tsx deleted file mode 100644 index 598d82c3e..000000000 --- a/src/view/shell/mobile/location-menu.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import React from 'react' -import { - StyleSheet, - Text, - TouchableOpacity, - TouchableWithoutFeedback, - View, -} from 'react-native' -import RootSiblings from 'react-native-root-siblings' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {colors} from '../../lib/styles' - -export function createLocationMenu(): RootSiblings { - const onPressItem = (_index: number) => { - sibling.destroy() - } - const onOuterPress = () => sibling.destroy() - const sibling = new RootSiblings( - ( - <> - <TouchableWithoutFeedback onPress={onOuterPress}> - <View style={styles.bg} /> - </TouchableWithoutFeedback> - <View style={[styles.menu]}> - <TouchableOpacity - style={[styles.menuItem]} - onPress={() => onPressItem(0)}> - <FontAwesomeIcon style={styles.icon} icon="share" /> - <Text style={styles.label}>Share</Text> - </TouchableOpacity> - <TouchableOpacity - style={[styles.menuItem]} - onPress={() => onPressItem(0)}> - <FontAwesomeIcon style={styles.icon} icon="link" /> - <Text style={styles.label}>Copy Link</Text> - </TouchableOpacity> - <TouchableOpacity - style={[styles.menuItem, styles.menuItemBorder]} - onPress={() => onPressItem(0)}> - <FontAwesomeIcon style={styles.icon} icon={['far', 'clone']} /> - <Text style={styles.label}>Duplicate Tab</Text> - </TouchableOpacity> - </View> - </> - ), - ) - return sibling -} - -const styles = StyleSheet.create({ - bg: { - position: 'absolute', - top: 0, - right: 0, - bottom: 0, - left: 0, - backgroundColor: '#000', - opacity: 0.1, - }, - menu: { - position: 'absolute', - right: 4, - top: 70, - backgroundColor: '#fff', - borderRadius: 14, - opacity: 1, - paddingVertical: 6, - }, - menuItem: { - flexDirection: 'row', - alignItems: 'center', - paddingVertical: 6, - paddingLeft: 10, - paddingRight: 30, - }, - menuItemBorder: { - borderTopWidth: 1, - borderTopColor: colors.gray1, - marginTop: 4, - paddingTop: 12, - }, - icon: { - marginLeft: 6, - marginRight: 8, - }, - label: { - fontSize: 15, - }, -}) |