mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
at push-notifications 162 lines 4.0 kB view raw
1import React from 'react' 2import {observer} from 'mobx-react-lite' 3import { 4 ActivityIndicator, 5 StyleSheet, 6 TouchableOpacity, 7 View, 8} from 'react-native' 9import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 10import {UserAvatar} from './UserAvatar' 11import {Text} from './text/Text' 12import {MagnifyingGlassIcon} from '../../lib/icons' 13import {useStores} from '../../../state' 14import {usePalette} from '../../lib/hooks/usePalette' 15import {colors} from '../../lib/styles' 16 17const HITSLOP = {left: 10, top: 10, right: 10, bottom: 10} 18const BACK_HITSLOP = {left: 10, top: 10, right: 30, bottom: 10} 19 20export const ViewHeader = observer(function ViewHeader({ 21 title, 22 subtitle, 23 canGoBack, 24}: { 25 title: string 26 subtitle?: string 27 canGoBack?: boolean 28}) { 29 const pal = usePalette('default') 30 const store = useStores() 31 const onPressBack = () => { 32 store.nav.tab.goBack() 33 } 34 const onPressMenu = () => { 35 store.shell.setMainMenuOpen(true) 36 } 37 const onPressSearch = () => { 38 store.nav.navigate('/search') 39 } 40 const onPressReconnect = () => { 41 store.session.connect().catch(e => { 42 store.log.warn('Failed to reconnect to server', e) 43 }) 44 } 45 if (typeof canGoBack === 'undefined') { 46 canGoBack = store.nav.tab.canGoBack 47 } 48 return ( 49 <View style={[styles.header, pal.view]}> 50 <TouchableOpacity 51 testID="viewHeaderBackOrMenuBtn" 52 onPress={canGoBack ? onPressBack : onPressMenu} 53 hitSlop={BACK_HITSLOP} 54 style={canGoBack ? styles.backBtn : styles.backBtnWide}> 55 {canGoBack ? ( 56 <FontAwesomeIcon 57 size={18} 58 icon="angle-left" 59 style={[styles.backIcon, pal.text]} 60 /> 61 ) : ( 62 <UserAvatar 63 size={30} 64 handle={store.me.handle} 65 displayName={store.me.displayName} 66 avatar={store.me.avatar} 67 /> 68 )} 69 </TouchableOpacity> 70 <View style={styles.titleContainer} pointerEvents="none"> 71 <Text type="title" style={[pal.text, styles.title]}> 72 {title} 73 </Text> 74 {subtitle ? ( 75 <Text 76 type="title-sm" 77 style={[styles.subtitle, pal.textLight]} 78 numberOfLines={1}> 79 {subtitle} 80 </Text> 81 ) : undefined} 82 </View> 83 <TouchableOpacity 84 onPress={onPressSearch} 85 hitSlop={HITSLOP} 86 style={styles.btn}> 87 <MagnifyingGlassIcon size={21} strokeWidth={3} style={pal.text} /> 88 </TouchableOpacity> 89 {!store.session.online ? ( 90 <TouchableOpacity style={styles.btn} onPress={onPressReconnect}> 91 {store.session.attemptingConnect ? ( 92 <ActivityIndicator /> 93 ) : ( 94 <> 95 <FontAwesomeIcon icon="signal" style={pal.text} size={16} /> 96 <FontAwesomeIcon 97 icon="x" 98 style={[ 99 styles.littleXIcon, 100 {backgroundColor: pal.colors.background}, 101 ]} 102 size={8} 103 /> 104 </> 105 )} 106 </TouchableOpacity> 107 ) : undefined} 108 </View> 109 ) 110}) 111 112const styles = StyleSheet.create({ 113 header: { 114 flexDirection: 'row', 115 alignItems: 'center', 116 paddingHorizontal: 12, 117 paddingTop: 6, 118 paddingBottom: 6, 119 }, 120 121 titleContainer: { 122 flexDirection: 'row', 123 alignItems: 'baseline', 124 marginRight: 'auto', 125 }, 126 title: { 127 fontWeight: 'bold', 128 }, 129 subtitle: { 130 marginLeft: 4, 131 maxWidth: 200, 132 fontWeight: 'normal', 133 }, 134 135 backBtn: { 136 width: 30, 137 height: 30, 138 }, 139 backBtnWide: { 140 width: 40, 141 height: 30, 142 marginLeft: 6, 143 }, 144 backIcon: { 145 marginTop: 6, 146 }, 147 btn: { 148 flexDirection: 'row', 149 alignItems: 'center', 150 justifyContent: 'center', 151 width: 36, 152 height: 36, 153 borderRadius: 20, 154 marginLeft: 4, 155 }, 156 littleXIcon: { 157 color: colors.red3, 158 position: 'absolute', 159 right: 7, 160 bottom: 7, 161 }, 162})