mirror of
https://github.com/minibits-cash/minibits_wallet.git
synced 2026-08-09 08:14:44 +00:00
162 lines
6.8 KiB
TypeScript
162 lines
6.8 KiB
TypeScript
import React, { FC, useState, useEffect } from 'react'
|
|
import { View, ScrollView, LayoutAnimation, Platform, UIManager, ViewStyle } from 'react-native'
|
|
import { BottomModal, Button, Icon, ListItem, Text } from '../components'
|
|
import AppError, { Err } from '../utils/AppError'
|
|
import { spacing, useThemeColor, colors } from '../theme'
|
|
import { CashuUtils } from '../services/cashu/cashuUtils'
|
|
import JSONTree from 'react-native-json-tree'
|
|
import Clipboard from '@react-native-clipboard/clipboard'
|
|
import { useStores } from '../models'
|
|
import useIsInternetReachable from '../utils/useIsInternetReachable'
|
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
|
|
type ErrorModalProps = {
|
|
error: AppError
|
|
}
|
|
|
|
export const ErrorModal: FC<ErrorModalProps> = function ({ error }) {
|
|
|
|
const {walletStore, authStore, walletProfileStore} = useStores()
|
|
|
|
const [isErrorVisible, setIsErrorVisible] = useState<boolean>(true)
|
|
const [isParamsVisible, setIsParamsVisible] = useState<boolean>(false)
|
|
|
|
// needed for error to re-appear
|
|
useEffect(() => {
|
|
setIsErrorVisible(true)
|
|
}, [error])
|
|
|
|
const toggleParams = () => {
|
|
LayoutAnimation.easeInEaseOut()
|
|
setIsParamsVisible(previousState => !previousState)
|
|
}
|
|
|
|
const onClose = () => {
|
|
setIsErrorVisible(false)
|
|
}
|
|
|
|
const onCopy = function () {
|
|
try {
|
|
Clipboard.setString(JSON.stringify(error.params))
|
|
} catch (e: any) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
const isInternetReachable = useIsInternetReachable()
|
|
|
|
const enrollDevice = async () => {
|
|
const keys = await walletStore.getCachedWalletKeys()
|
|
if (keys.NOSTR && isInternetReachable === true) {
|
|
authStore.enrollDevice(keys.NOSTR, walletProfileStore.device)
|
|
.then(() => {
|
|
setIsErrorVisible(false)
|
|
})
|
|
.catch((e: any) => {
|
|
error = new AppError(Err.AUTH_ERROR, 'Failed to re-enroll device', { message: e.message })
|
|
})
|
|
}
|
|
}
|
|
|
|
const bg = useThemeColor('error')
|
|
const insets = useSafeAreaInsets()
|
|
|
|
return (
|
|
<BottomModal
|
|
isVisible={isErrorVisible}
|
|
onBackdropPress={onClose}
|
|
onBackButtonPress={onClose}
|
|
style={{ marginBottom: Platform.OS === 'android' ? -(insets.top + insets.bottom) : 0 }}
|
|
ContentComponent={
|
|
<View>
|
|
<View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: spacing.small }}>
|
|
<Icon icon="faTriangleExclamation" size={spacing.large} color={bg} />
|
|
<Text style={{ marginLeft: spacing.small }}>{error.name}</Text>
|
|
</View>
|
|
<ScrollView
|
|
style={{
|
|
maxHeight: spacing.screenHeight * 0.1,
|
|
}}>
|
|
<Text style={{ marginBottom: spacing.small }}>{error.message}</Text>
|
|
</ScrollView>
|
|
{error.name === Err.AUTH_ERROR && (error.message?.includes('re-authenticate') || error.message.includes('expired refresh token')) ? (
|
|
<Button
|
|
onPress={enrollDevice}
|
|
text='Login again'
|
|
preset='secondary'
|
|
/>
|
|
) : (
|
|
<>
|
|
{error.params && CashuUtils.isObj(error.params) && (
|
|
<>
|
|
{isParamsVisible ? (
|
|
<>
|
|
<ScrollView style={{
|
|
alignSelf: 'stretch',
|
|
borderRadius: spacing.small,
|
|
backgroundColor: '#fff',
|
|
padding: spacing.tiny,
|
|
maxHeight: spacing.screenHeight * 0.3,
|
|
maxWidth: spacing.screenWidth * 0.9
|
|
}}>
|
|
<JSONTree
|
|
hideRoot
|
|
data={error.params}
|
|
theme={{
|
|
scheme: 'codeschool',
|
|
author: 'brettof86',
|
|
base00: '#000000',
|
|
base01: '#2e2f30',
|
|
base02: '#515253',
|
|
base03: '#737475',
|
|
base04: '#959697',
|
|
base05: '#b7b8b9',
|
|
base06: '#dadbdc',
|
|
base07: '#fcfdfe',
|
|
base08: '#e31a1c',
|
|
base09: '#e6550d',
|
|
base0A: '#dca060',
|
|
base0B: '#31a354',
|
|
base0C: '#80b1d3',
|
|
base0D: '#3182bd',
|
|
base0E: '#756bb1',
|
|
base0F: '#b15928'
|
|
}}
|
|
/>
|
|
</ScrollView>
|
|
<View style={$buttonContainer}>
|
|
<Button
|
|
onPress={toggleParams}
|
|
text='Hide details'
|
|
preset='tertiary'
|
|
/>
|
|
<Button
|
|
onPress={onCopy}
|
|
text='Copy'
|
|
preset='tertiary'
|
|
/>
|
|
</View>
|
|
</>
|
|
) : (
|
|
<Button
|
|
onPress={toggleParams}
|
|
text='Show details'
|
|
preset='tertiary'
|
|
/>
|
|
)}
|
|
</>
|
|
)}
|
|
</>
|
|
)}
|
|
|
|
</View>
|
|
}
|
|
/>
|
|
)
|
|
}
|
|
|
|
const $buttonContainer: ViewStyle = {
|
|
flexDirection: 'row',
|
|
marginTop: spacing.small,
|
|
}
|