mirror of
https://github.com/minibits-cash/minibits_wallet.git
synced 2026-10-05 19:28:26 +00:00
331 lines
12 KiB
TypeScript
331 lines
12 KiB
TypeScript
import {observer} from 'mobx-react-lite'
|
|
import React, {FC, useEffect, useState} from 'react'
|
|
import {Switch, TextStyle, View, ViewStyle} from 'react-native'
|
|
import {colors, spacing, useThemeColor} from '../theme'
|
|
import {SettingsStackScreenProps} from '../navigation'
|
|
import {
|
|
Icon,
|
|
ListItem,
|
|
Screen,
|
|
Text,
|
|
Card,
|
|
Loading,
|
|
ErrorModal,
|
|
InfoModal,
|
|
BottomModal,
|
|
Button,
|
|
} from '../components'
|
|
import {useHeader} from '../utils/useHeader'
|
|
import {useStores} from '../models'
|
|
import AppError from '../utils/AppError'
|
|
import EventEmitter from '../utils/eventEmitter'
|
|
import {ResultModalInfo} from './Wallet/ResultModalInfo'
|
|
import {Database, log, WalletTask, WalletTaskResult} from '../services'
|
|
import { getSnapshot } from 'mobx-state-tree'
|
|
|
|
export const BackupScreen: FC<SettingsStackScreenProps<'Backup'>> = observer(function BackupScreen(_props) {
|
|
const {navigation} = _props
|
|
useHeader({
|
|
leftIcon: 'faArrowLeft',
|
|
onLeftPress: () => navigation.goBack(),
|
|
})
|
|
|
|
const {userSettingsStore, proofsStore, mintsStore} = useStores()
|
|
|
|
const [isLoading, setIsLoading] = useState(false)
|
|
const [isLocalBackupOn, setIsLocalBackupOn] = useState<boolean>(
|
|
userSettingsStore.isLocalBackupOn,
|
|
)
|
|
const [error, setError] = useState<AppError | undefined>()
|
|
const [info, setInfo] = useState('')
|
|
const [isBackupModalVisible, setIsBackupModalVisible] =
|
|
useState<boolean>(false)
|
|
const [isHandleSpentFromSpendableSentToQueue, setIsHandleSpentFromSpendableSentToQueue] = useState<boolean>(false)
|
|
const [backupResultMessage, setBackupResultMessage] = useState<string>()
|
|
const [totalSpentCount, setTotalSpentCount] = useState<number>(0)
|
|
const [totalSpentAmount, setTotalSpentAmount] = useState<number>(0)
|
|
|
|
|
|
useEffect(() => {
|
|
const handleSpentByMintTaskResult = async (result: WalletTaskResult) => {
|
|
log.warn('handleSpentByMintTaskResult event handler triggered')
|
|
|
|
if(!isHandleSpentFromSpendableSentToQueue) {
|
|
return false
|
|
}
|
|
|
|
setIsLoading(false)
|
|
// runs per each mint
|
|
if (result && result.spentAmount > 0) {
|
|
setTotalSpentAmount(prev => prev + result.spentAmount)
|
|
setTotalSpentCount(prev => prev + result.spentCount)
|
|
setInfo(
|
|
`${totalSpentCount} ecash proofs, ${totalSpentAmount} in total were removed from the wallet.`,
|
|
)
|
|
return
|
|
}
|
|
|
|
setInfo('No spent ecash found in your wallet')
|
|
}
|
|
|
|
EventEmitter.on('ev__handleSpentByMintTask_result', handleSpentByMintTaskResult)
|
|
|
|
return () => {
|
|
EventEmitter.off('ev__handleSpentByMintTask_result', handleSpentByMintTaskResult)
|
|
}
|
|
}, [isHandleSpentFromSpendableSentToQueue])
|
|
|
|
const toggleBackupSwitch = () => {
|
|
try {
|
|
setIsLoading(true)
|
|
const result = userSettingsStore.setIsLocalBackupOn(!isLocalBackupOn)
|
|
setIsLocalBackupOn(result)
|
|
|
|
if (result === true) {
|
|
|
|
log.trace('[toggleBackupSwitch]', JSON.stringify(proofsStore.getBalances()))
|
|
|
|
if(proofsStore.allProofs.length > 0){
|
|
log.trace('[toggleBackupSwitch]', JSON.stringify(proofsStore.allProofs))
|
|
Database.addOrUpdateProofs(proofsStore.allProofs)
|
|
}
|
|
if(proofsStore.allPendingProofs.length > 0){
|
|
Database.addOrUpdateProofs(proofsStore.allPendingProofs, true)
|
|
}
|
|
|
|
setBackupResultMessage(
|
|
'Your minibits tokens were backed up to local database. New tokens will be backed up automatically.',
|
|
)
|
|
toggleBackupModal()
|
|
setIsLoading(false)
|
|
return
|
|
}
|
|
|
|
Database.removeAllProofs()
|
|
setIsLoading(false)
|
|
setBackupResultMessage(
|
|
'Your backup of minibits tokens has been deleted. New tokens will NOT be backed up.',
|
|
)
|
|
toggleBackupModal()
|
|
} catch (e: any) {
|
|
handleError(e)
|
|
}
|
|
}
|
|
|
|
const toggleBackupModal = () =>
|
|
setIsBackupModalVisible(previousState => !previousState)
|
|
|
|
const gotoLocalRecovery = function () {
|
|
navigation.navigate('LocalRecovery')
|
|
}
|
|
|
|
const gotoRemoteBackup = function () {
|
|
navigation.navigate('RemoteBackup')
|
|
}
|
|
|
|
const gotoRemoteRecovery = function () {
|
|
navigation.navigate('RemoteRecovery', {isAddressOnlyRecovery: true})
|
|
}
|
|
|
|
const checkSpent = async function () {
|
|
setIsLoading(true)
|
|
setIsHandleSpentFromSpendableSentToQueue(true)
|
|
WalletTask.handleSpentFromSpendable()
|
|
}
|
|
|
|
|
|
const increaseCounters = async function () {
|
|
for (const mint of mintsStore.allMints) {
|
|
for(const counter of mint.proofsCounters) {
|
|
mint.increaseProofsCounter(counter.keyset, 50)
|
|
}
|
|
}
|
|
setInfo('Recovery indexes increased by 50')
|
|
}
|
|
|
|
|
|
const handleError = function (e: AppError): void {
|
|
setIsLoading(false)
|
|
setError(e)
|
|
}
|
|
|
|
const headerBg = useThemeColor('header')
|
|
|
|
return (
|
|
<Screen preset='auto' style={$screen}>
|
|
<View style={[$headerContainer, {backgroundColor: headerBg}]}>
|
|
<Text preset="heading" text="Backup" style={{color: 'white'}} />
|
|
</View>
|
|
<View style={$contentContainer}>
|
|
<Card
|
|
style={$card}
|
|
HeadingComponent={
|
|
<>
|
|
<ListItem
|
|
tx="backupScreen.remoteBackup"
|
|
subTx="backupScreen.remoteBackupDescription"
|
|
leftIcon='faUpRightFromSquare'
|
|
leftIconColor={colors.palette.blue200}
|
|
leftIconInverse={true}
|
|
style={$item}
|
|
onPress={gotoRemoteBackup}
|
|
bottomSeparator={true}
|
|
/>
|
|
<ListItem
|
|
text="Wallet address recovery"
|
|
subText="Use your mnemonic phrase from another device to get your original wallet address on this device. This will not recover balances."
|
|
leftIcon='faCircleUser'
|
|
leftIconColor={colors.palette.iconGreyBlue400}
|
|
leftIconInverse={true}
|
|
style={$item}
|
|
onPress={gotoRemoteRecovery}
|
|
/>
|
|
</>
|
|
}
|
|
/>
|
|
<Card
|
|
style={$card}
|
|
HeadingComponent={
|
|
<>
|
|
<ListItem
|
|
tx="backupScreen.localBackup"
|
|
subTx="backupScreen.localBackupDescription"
|
|
leftIcon='faDownload'
|
|
leftIconColor={
|
|
isLocalBackupOn
|
|
? colors.palette.success200
|
|
: colors.palette.neutral400
|
|
}
|
|
leftIconInverse={true}
|
|
RightComponent={
|
|
<View style={$rightContainer}>
|
|
<Switch
|
|
onValueChange={toggleBackupSwitch}
|
|
value={isLocalBackupOn}
|
|
/>
|
|
</View>
|
|
}
|
|
style={$item}
|
|
/>
|
|
{isLocalBackupOn && (
|
|
<ListItem
|
|
tx="backupScreen.recoveryTool"
|
|
subTx="backupScreen.recoveryToolDescription"
|
|
leftIcon='faUpload'
|
|
leftIconColor={colors.palette.focus300}
|
|
leftIconInverse={true}
|
|
style={$item}
|
|
onPress={gotoLocalRecovery}
|
|
topSeparator={true}
|
|
/>
|
|
)}
|
|
</>
|
|
}
|
|
/>
|
|
<Card
|
|
style={$card}
|
|
HeadingComponent={
|
|
<>
|
|
<ListItem
|
|
tx="backupScreen.removeSpentCoins"
|
|
subTx="backupScreen.removeSpentCoinsDescription"
|
|
leftIcon='faRecycle'
|
|
leftIconColor={colors.palette.secondary300}
|
|
leftIconInverse={true}
|
|
RightComponent={
|
|
<View style={$rightContainer}>
|
|
<Button
|
|
onPress={checkSpent}
|
|
text='Remove'
|
|
preset='secondary'
|
|
/>
|
|
</View>
|
|
}
|
|
style={$item}
|
|
/>
|
|
</>
|
|
}
|
|
/>
|
|
<Card
|
|
style={$card}
|
|
HeadingComponent={
|
|
<>
|
|
<ListItem
|
|
text="Increase recovery indexes"
|
|
subText={`After incomplete recovery from seed or other rare issue, you may encounter 'duplicate outputs' error when trying to send. This resets your recovery indexes to higher value in order to resolve the issue.`}
|
|
leftIcon='faArrowUp'
|
|
leftIconColor={colors.palette.success300}
|
|
leftIconInverse={true}
|
|
RightComponent={
|
|
<View style={$rightContainer}>
|
|
<Button
|
|
onPress={increaseCounters}
|
|
text='Increase'
|
|
preset='secondary'
|
|
/>
|
|
</View>
|
|
}
|
|
style={$item}
|
|
/>
|
|
</>
|
|
}
|
|
/>
|
|
{isLoading && <Loading />}
|
|
</View>
|
|
<BottomModal
|
|
isVisible={isBackupModalVisible}
|
|
style={{paddingHorizontal: spacing.small}}
|
|
ContentComponent={
|
|
<ResultModalInfo
|
|
icon={'faDownload'}
|
|
iconColor={
|
|
isLocalBackupOn
|
|
? colors.palette.success200
|
|
: colors.palette.neutral400
|
|
}
|
|
title={
|
|
isLocalBackupOn ? 'Local backup is on' : 'Local backup is off'
|
|
}
|
|
message={backupResultMessage as string}
|
|
/>
|
|
}
|
|
onBackButtonPress={toggleBackupModal}
|
|
onBackdropPress={toggleBackupModal}
|
|
/>
|
|
{error && <ErrorModal error={error} />}
|
|
{info && <InfoModal message={info} />}
|
|
</Screen>
|
|
)
|
|
},
|
|
)
|
|
|
|
const $screen: ViewStyle = {}
|
|
|
|
const $headerContainer: TextStyle = {
|
|
alignItems: 'center',
|
|
padding: spacing.medium,
|
|
height: spacing.screenHeight * 0.1,
|
|
}
|
|
|
|
const $contentContainer: TextStyle = {
|
|
// flex: 1,
|
|
padding: spacing.extraSmall,
|
|
// alignItems: 'center',
|
|
}
|
|
|
|
const $card: ViewStyle = {
|
|
marginBottom: spacing.small,
|
|
}
|
|
|
|
const $item: ViewStyle = {
|
|
paddingHorizontal: spacing.small,
|
|
paddingLeft: 0,
|
|
}
|
|
|
|
const $rightContainer: ViewStyle = {
|
|
// padding: spacing.extraSmall,
|
|
// alignSelf: 'center',
|
|
marginLeft: spacing.tiny,
|
|
marginRight: -10
|
|
}
|