diff options
author | Paul Frazee <pfrazee@gmail.com> | 2023-01-26 20:04:11 -0600 |
---|---|---|
committer | Paul Frazee <pfrazee@gmail.com> | 2023-01-26 20:04:11 -0600 |
commit | f7e3b1451e6b9778aeecf8f2991de34589225888 (patch) | |
tree | 3aa26ab91916213496c3c8434a6e7d789ed3e059 /src | |
parent | a3df8840ea6c2e8886a26391ce381e1cdf15d9df (diff) | |
download | voidsky-f7e3b1451e6b9778aeecf8f2991de34589225888.tar.zst |
Add web version of the header
Diffstat (limited to 'src')
-rw-r--r-- | src/view/com/util/ViewHeader.web.tsx | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/view/com/util/ViewHeader.web.tsx b/src/view/com/util/ViewHeader.web.tsx new file mode 100644 index 000000000..0d5c99aac --- /dev/null +++ b/src/view/com/util/ViewHeader.web.tsx @@ -0,0 +1,150 @@ +import React from 'react' +import {observer} from 'mobx-react-lite' +import { + ActivityIndicator, + StyleSheet, + TouchableOpacity, + View, +} from 'react-native' +import { + FontAwesomeIcon, + FontAwesomeIconStyle, +} from '@fortawesome/react-native-fontawesome' +import {CenteredView} from './Views' +import {Text} from './text/Text' +import {useStores} from '../../../state' +import {usePalette} from '../../lib/hooks/usePalette' +import {colors} from '../../lib/styles' + +const BACK_HITSLOP = {left: 10, top: 10, right: 30, bottom: 10} + +export const ViewHeader = observer(function ViewHeader({ + title, + subtitle, + canGoBack, +}: { + title: string + subtitle?: string + canGoBack?: boolean +}) { + const pal = usePalette('default') + const store = useStores() + const onPressBack = () => { + store.nav.tab.goBack() + } + const onPressReconnect = () => { + store.session.connect().catch(e => { + store.log.warn('Failed to reconnect to server', e) + }) + } + if (typeof canGoBack === 'undefined') { + canGoBack = store.nav.tab.canGoBack + } + return ( + <CenteredView style={[styles.header, pal.view]}> + {canGoBack ? ( + <> + <TouchableOpacity + testID="viewHeaderBackOrMenuBtn" + onPress={onPressBack} + hitSlop={BACK_HITSLOP} + style={styles.backBtn}> + <FontAwesomeIcon + size={18} + icon="angle-left" + style={[styles.backIcon, pal.text]} + /> + </TouchableOpacity> + <View style={styles.titleContainer} pointerEvents="none"> + <Text type="title" style={[pal.text, styles.title]}> + {title} + </Text> + {subtitle ? ( + <Text + type="title-sm" + style={[styles.subtitle, pal.textLight]} + numberOfLines={1}> + {subtitle} + </Text> + ) : undefined} + </View> + </> + ) : ( + <View style={styles.titleContainer} pointerEvents="none"> + <Text type="title" style={[pal.text, styles.title]}> + Home + </Text> + </View> + )} + {!store.session.online ? ( + <TouchableOpacity style={styles.btn} onPress={onPressReconnect}> + {store.session.attemptingConnect ? ( + <ActivityIndicator /> + ) : ( + <> + <FontAwesomeIcon + icon="signal" + style={pal.text as FontAwesomeIconStyle} + size={16} + /> + <FontAwesomeIcon + icon="x" + style={[ + styles.littleXIcon, + {backgroundColor: pal.colors.background}, + ]} + size={8} + /> + </> + )} + </TouchableOpacity> + ) : undefined} + </CenteredView> + ) +}) + +const styles = StyleSheet.create({ + header: { + flexDirection: 'row', + alignItems: 'center', + paddingHorizontal: 16, + paddingVertical: 12, + }, + + titleContainer: { + flexDirection: 'row', + alignItems: 'baseline', + marginRight: 'auto', + }, + title: { + fontWeight: 'bold', + }, + subtitle: { + marginLeft: 4, + maxWidth: 200, + fontWeight: 'normal', + }, + + backBtn: { + width: 30, + }, + backIcon: { + position: 'relative', + top: -1, + }, + btn: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + width: 36, + height: 36, + borderRadius: 20, + marginLeft: 4, + }, + littleXIcon: { + color: colors.red3, + position: 'absolute', + right: 7, + bottom: 7, + }, +}) |