mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
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})