nostros/frontend/Pages/RelaysPage/index.tsx

272 lines
7.6 KiB
TypeScript
Raw Normal View History

2023-01-14 14:52:10 +00:00
import React, { useContext, useState } from 'react'
2023-01-27 21:03:09 +00:00
import { ScrollView, StyleSheet, View } from 'react-native'
import Clipboard from '@react-native-clipboard/clipboard'
2022-11-05 18:04:17 +00:00
import { useTranslation } from 'react-i18next'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
2023-01-14 14:52:10 +00:00
import { Relay } from '../../Functions/DatabaseFunctions/Relays'
2023-01-13 11:51:30 +00:00
import { defaultRelays, REGEX_SOCKET_LINK } from '../../Constants/Relay'
2023-01-13 16:36:05 +00:00
import {
List,
Switch,
AnimatedFAB,
useTheme,
Text,
Button,
TextInput,
IconButton,
Divider,
2023-01-17 13:21:32 +00:00
Snackbar,
2023-01-13 16:36:05 +00:00
} from 'react-native-paper'
import RBSheet from 'react-native-raw-bottom-sheet'
2022-11-05 18:04:17 +00:00
export const RelaysPage: React.FC = () => {
2023-01-13 16:36:05 +00:00
const defaultRelayInput = React.useMemo(() => 'wss://', [])
2023-01-25 15:38:18 +00:00
const { activeRelayItem, desactiveRelayItem, addRelayItem, removeRelayItem, relays } =
useContext(RelayPoolContext)
2022-11-05 18:04:17 +00:00
const { t } = useTranslation('common')
2023-01-13 16:36:05 +00:00
const theme = useTheme()
const bottomSheetAddRef = React.useRef<RBSheet>(null)
const bottomSheetEditRef = React.useRef<RBSheet>(null)
const [selectedRelay, setSelectedRelay] = useState<Relay>()
const [addRelayInput, setAddRelayInput] = useState<string>(defaultRelayInput)
2023-01-16 20:06:12 +00:00
const [showNotification, setShowNotification] = useState<string>()
2022-11-05 18:04:17 +00:00
2023-01-14 14:52:10 +00:00
const addRelay: (url: string) => void = (url) => {
addRelayItem({
url,
2023-01-25 15:38:18 +00:00
active: true,
2023-01-14 14:52:10 +00:00
}).then(() => {
setShowNotification('add')
})
2022-11-05 18:04:17 +00:00
}
2023-01-14 14:52:10 +00:00
const removeRelay: (url: string) => void = (url) => {
removeRelayItem({
url,
}).then(() => {
setShowNotification('remove')
})
2022-11-05 18:04:17 +00:00
}
2023-01-25 15:38:18 +00:00
const activeRelay: (relay: Relay) => void = (relay) => {
activeRelayItem(relay).then(() => {
setShowNotification('active')
})
}
const desactiveRelay: (relay: Relay) => void = (relay) => {
desactiveRelayItem(relay).then(() => {
setShowNotification('desactive')
})
}
2023-01-02 21:17:16 +00:00
const onPressAddRelay: () => void = () => {
2023-01-13 16:42:12 +00:00
if (REGEX_SOCKET_LINK.test(addRelayInput)) {
2023-01-13 16:36:05 +00:00
bottomSheetAddRef.current?.close()
2023-01-25 15:38:18 +00:00
addRelay(addRelayInput)
2023-01-13 16:36:05 +00:00
setAddRelayInput(defaultRelayInput)
2023-01-02 21:17:16 +00:00
} else {
2023-01-13 16:36:05 +00:00
bottomSheetAddRef.current?.close()
setShowNotification('badFormat')
2023-01-02 21:17:16 +00:00
}
}
2023-01-14 20:35:35 +00:00
const rbSheetCustomStyles = React.useMemo(() => {
return {
container: {
backgroundColor: theme.colors.background,
paddingTop: 16,
paddingRight: 16,
paddingBottom: 32,
paddingLeft: 16,
2023-01-18 21:54:28 +00:00
borderTopRightRadius: 28,
borderTopLeftRadius: 28,
height: 'auto',
2023-01-14 20:35:35 +00:00
},
}
}, [])
2023-01-25 15:38:18 +00:00
const myRelays = relays.filter((relay) => !defaultRelays.includes(relay.url))
2022-11-05 18:04:17 +00:00
return (
2023-01-13 16:36:05 +00:00
<View style={styles.container}>
2023-01-22 12:43:30 +00:00
<ScrollView horizontal={false}>
2023-01-25 18:52:22 +00:00
{myRelays.length > 0 && (
2023-01-25 15:38:18 +00:00
<>
<Text style={styles.title} variant='titleMedium'>
{t('relaysPage.myList')}
</Text>
2023-01-27 21:03:09 +00:00
{myRelays.length > 0 &&
myRelays.map((relay, index) => {
return (
<List.Item
key={index}
title={relay.url.split('wss://')[1]?.split('/')[0]}
right={() => (
<Switch
value={relay.active}
onValueChange={() =>
relay.active ? desactiveRelay(relay) : activeRelay(relay)
}
/>
)}
onPress={() => {
setSelectedRelay(relay)
bottomSheetEditRef.current?.open()
}}
/>
)
})}
2023-01-25 15:38:18 +00:00
</>
)}
<Text style={styles.title} variant='titleMedium'>
{t('relaysPage.recommended')}
</Text>
2023-01-27 21:03:09 +00:00
{defaultRelays.map((url, index) => {
const relay = {
url,
active: relays.find((relay) => relay.url === url && relay.active) !== undefined,
}
return (
<List.Item
key={index}
title={url.split('wss://')[1]?.split('/')[0]}
right={() => (
<Switch
value={relay.active}
onValueChange={() => (relay.active ? desactiveRelay(relay) : activeRelay(relay))}
/>
)}
onPress={() => {
setSelectedRelay(relay)
bottomSheetEditRef.current?.open()
}}
/>
)
})}
2023-01-22 12:43:30 +00:00
</ScrollView>
2023-01-13 16:36:05 +00:00
<AnimatedFAB
style={styles.fab}
2023-01-16 09:03:01 +00:00
icon='plus'
label='Add'
2023-01-13 16:36:05 +00:00
onPress={() => bottomSheetAddRef.current?.open()}
2023-01-16 09:03:01 +00:00
animateFrom='right'
iconMode='static'
2023-01-13 16:36:05 +00:00
extended={false}
/>
2023-01-16 20:06:12 +00:00
{showNotification && (
2023-01-17 13:21:32 +00:00
<Snackbar
style={styles.snackbar}
visible={showNotification !== undefined}
duration={Snackbar.DURATION_SHORT}
onIconPress={() => setShowNotification(undefined)}
onDismiss={() => setShowNotification(undefined)}
2023-01-16 20:06:12 +00:00
>
{t(`relaysPage.notifications.${showNotification}`)}
2023-01-17 13:21:32 +00:00
</Snackbar>
2023-01-16 20:06:12 +00:00
)}
2023-01-16 12:09:18 +00:00
<RBSheet
ref={bottomSheetAddRef}
closeOnDragDown={true}
customStyles={rbSheetCustomStyles}
>
2023-01-25 15:38:18 +00:00
<View style={styles.addRelay}>
2023-01-13 16:36:05 +00:00
<TextInput
mode='outlined'
label={t('relaysPage.labelAdd') ?? ''}
onChangeText={setAddRelayInput}
value={addRelayInput}
/>
<Button mode='contained' onPress={onPressAddRelay}>
{t('relaysPage.add')}
</Button>
<Button
mode='outlined'
onPress={() => {
bottomSheetAddRef.current?.close()
setAddRelayInput(defaultRelayInput)
}}
>
{t('relaysPage.cancel')}
</Button>
</View>
</RBSheet>
<RBSheet
ref={bottomSheetEditRef}
closeOnDragDown={true}
2023-01-14 20:35:35 +00:00
customStyles={rbSheetCustomStyles}
2023-01-13 16:36:05 +00:00
>
<View>
<View style={styles.relayActions}>
<View style={styles.actionButton}>
<IconButton
icon='trash-can-outline'
size={28}
onPress={() => {
2023-01-14 14:52:10 +00:00
if (selectedRelay) removeRelay(selectedRelay.url)
2023-01-13 16:36:05 +00:00
bottomSheetEditRef.current?.close()
}}
/>
<Text>{t('relaysPage.removeRelay')}</Text>
</View>
<View style={styles.actionButton}>
<IconButton
icon='content-copy'
size={28}
onPress={() => {
if (selectedRelay) Clipboard.setString(selectedRelay.url)
}}
/>
<Text>{t('relaysPage.copyRelay')}</Text>
</View>
</View>
2023-01-14 20:35:35 +00:00
<Divider style={styles.divider} />
2023-01-13 16:42:12 +00:00
<Text variant='titleLarge'>{selectedRelay?.url.split('wss://')[1]?.split('/')[0]}</Text>
2023-01-13 16:36:05 +00:00
</View>
</RBSheet>
</View>
2022-11-05 18:04:17 +00:00
)
}
2023-01-13 16:36:05 +00:00
const styles = StyleSheet.create({
2023-01-25 15:38:18 +00:00
title: {
paddingLeft: 16,
},
2023-01-13 16:36:05 +00:00
container: {
padding: 0,
2023-01-22 12:43:30 +00:00
paddingBottom: 32,
2023-01-13 16:36:05 +00:00
},
list: {
padding: 0,
2023-01-22 12:43:30 +00:00
paddingBottom: 45,
2023-01-13 16:36:05 +00:00
},
snackbar: {
margin: 16,
bottom: 70,
},
fab: {
bottom: 16,
right: 16,
position: 'absolute',
},
2023-01-25 15:38:18 +00:00
addRelay: {
alignContent: 'center',
height: '80%',
justifyContent: 'space-between',
},
2023-01-13 16:36:05 +00:00
relayActions: {
flexDirection: 'row',
},
actionButton: {
justifyContent: 'center',
alignItems: 'center',
2023-01-14 20:35:35 +00:00
width: 80,
2023-01-13 16:36:05 +00:00
},
divider: {
marginBottom: 26,
2023-01-14 20:35:35 +00:00
marginTop: 26,
},
2023-01-13 16:36:05 +00:00
})
2022-11-05 18:04:17 +00:00
export default RelaysPage