1
1
import { StatusBar } from "expo-status-bar" ;
2
- import { Button , Modal , StyleSheet , Text , View } from "react-native" ;
3
- import { useRouter } from "expo-router" ;
2
+ import {
3
+ Button ,
4
+ Modal ,
5
+ StyleSheet ,
6
+ Text ,
7
+ View ,
8
+ ActivityIndicator ,
9
+ } from "react-native" ;
4
10
import { useState } from "react" ;
5
11
import { useFacade } from "@/data/facades" ;
6
12
import { SettingsKey } from "@/data/settings/db" ;
7
13
import { Network } from "@/data/constants" ;
14
+ import { AccountFormat } from "@ironfish/sdk" ;
8
15
9
16
export default function MenuNetwork ( ) {
10
- const router = useRouter ( ) ;
11
-
12
17
const [ modalVisible , setModalVisible ] = useState ( false ) ;
18
+ const [ isChangingNetwork , setIsChangingNetwork ] = useState ( false ) ;
13
19
14
20
const facade = useFacade ( ) ;
15
-
16
21
const setAppSetting = facade . setAppSetting . useMutation ( ) ;
22
+ const getAccounts = facade . getAccounts . useQuery ( ) ;
23
+ const exportAccount = facade . exportAccount . useMutation ( ) ;
24
+ const importAccount = facade . importAccount . useMutation ( ) ;
25
+ const networkSetting = facade . getAppSettings . useQuery ( ) ;
26
+
27
+ const currentNetwork =
28
+ networkSetting . data ?. [ SettingsKey . Network ] ?? Network . MAINNET ;
29
+ const targetNetwork =
30
+ currentNetwork === Network . MAINNET ? Network . TESTNET : Network . MAINNET ;
31
+
32
+ const handleNetworkChange = async ( network : Network ) => {
33
+ setIsChangingNetwork ( true ) ;
34
+ try {
35
+ // First update the network setting
36
+ await setAppSetting . mutateAsync ( {
37
+ key : SettingsKey . Network ,
38
+ value : network ,
39
+ } ) ;
40
+
41
+ // Re-import all accounts for the new network
42
+ const accounts = getAccounts . data ?? [ ] ;
43
+ for ( const account of accounts ) {
44
+ // Export the account first
45
+ const encodedAccount = await exportAccount . mutateAsync ( {
46
+ name : account . name ,
47
+ format : AccountFormat . Base64Json ,
48
+ } ) ;
49
+ // Then import it for the new network
50
+ try {
51
+ await importAccount . mutateAsync ( {
52
+ account : encodedAccount ,
53
+ name : account . name ,
54
+ } ) ;
55
+ } catch ( error ) {
56
+ console . error ( error ) ;
57
+ }
58
+ }
59
+ } finally {
60
+ setIsChangingNetwork ( false ) ;
61
+ setModalVisible ( false ) ;
62
+ }
63
+ } ;
64
+
65
+ if ( getAccounts . isLoading || networkSetting . isLoading ) {
66
+ return (
67
+ < View style = { styles . container } >
68
+ < ActivityIndicator size = "large" />
69
+ < Text style = { styles . loadingText } > Loading...</ Text >
70
+ </ View >
71
+ ) ;
72
+ }
17
73
18
74
return (
19
75
< View style = { styles . container } >
20
76
< Modal animationType = "slide" visible = { modalVisible } >
21
77
< View style = { styles . container } >
22
- < Text > Switch to Testnet?</ Text >
23
- < Text >
24
- Switching networks requires a blockchain rescan, which may take time
25
- based on your last sync.
26
- </ Text >
27
- < Button
28
- title = "Yes, Change Network"
29
- onPress = { ( ) => {
30
- setAppSetting . mutate ( {
31
- key : SettingsKey . Network ,
32
- value : Network . TESTNET ,
33
- } ) ;
34
- setModalVisible ( false ) ;
35
- } }
36
- />
37
- < Button
38
- title = "I changed my mind"
39
- onPress = { ( ) => setModalVisible ( false ) }
40
- />
78
+ { isChangingNetwork ? (
79
+ < >
80
+ < ActivityIndicator size = "large" />
81
+ < Text style = { styles . loadingText } >
82
+ Changing network and re-importing accounts...
83
+ </ Text >
84
+ </ >
85
+ ) : (
86
+ < >
87
+ < Text > Switch to { targetNetwork } ?</ Text >
88
+ < Text >
89
+ Switching networks will upload your accounts to the{ " " }
90
+ { targetNetwork } server. It may take a few minutes for your
91
+ accounts to sync.
92
+ </ Text >
93
+ < Button
94
+ title = "Yes, Change Network"
95
+ onPress = { ( ) => handleNetworkChange ( targetNetwork ) }
96
+ />
97
+ < Button
98
+ title = "I changed my mind"
99
+ onPress = { ( ) => setModalVisible ( false ) }
100
+ />
101
+ </ >
102
+ ) }
41
103
</ View >
42
104
</ Modal >
43
- < Button title = "Back" onPress = { ( ) => router . dismiss ( ) } />
44
- < Text > Mainnet</ Text >
45
- < Text >
46
- The live blockchain network where real transactions with value occur.
47
- </ Text >
48
- < Text > Testnet</ Text >
49
- < Text > A separate environment for testing without real asset risks.</ Text >
105
+ < View style = { styles . networkOption } >
106
+ < View style = { styles . networkInfo } >
107
+ < Text style = { styles . networkTitle } > Mainnet</ Text >
108
+ < Text style = { styles . networkDescription } >
109
+ The live blockchain network where real transactions with value
110
+ occur.
111
+ </ Text >
112
+ { currentNetwork === Network . MAINNET && (
113
+ < Text style = { styles . selectedText } > (Selected)</ Text >
114
+ ) }
115
+ </ View >
116
+ </ View >
117
+ < View style = { styles . networkOption } >
118
+ < View style = { styles . networkInfo } >
119
+ < Text style = { styles . networkTitle } > Testnet</ Text >
120
+ < Text style = { styles . networkDescription } >
121
+ A separate environment for testing without real asset risks.
122
+ </ Text >
123
+ { currentNetwork === Network . TESTNET && (
124
+ < Text style = { styles . selectedText } > (Selected)</ Text >
125
+ ) }
126
+ </ View >
127
+ </ View >
50
128
< Button title = "Change Network" onPress = { ( ) => setModalVisible ( true ) } />
51
129
< StatusBar style = "auto" />
52
130
</ View >
@@ -60,4 +138,32 @@ const styles = StyleSheet.create({
60
138
alignItems : "center" ,
61
139
justifyContent : "center" ,
62
140
} ,
141
+ networkOption : {
142
+ width : "100%" ,
143
+ padding : 16 ,
144
+ borderBottomWidth : 1 ,
145
+ borderBottomColor : "#eee" ,
146
+ } ,
147
+ networkInfo : {
148
+ alignItems : "center" ,
149
+ } ,
150
+ networkTitle : {
151
+ fontSize : 18 ,
152
+ fontWeight : "bold" ,
153
+ marginBottom : 8 ,
154
+ } ,
155
+ networkDescription : {
156
+ textAlign : "center" ,
157
+ color : "#666" ,
158
+ marginBottom : 8 ,
159
+ } ,
160
+ selectedText : {
161
+ color : "#007AFF" ,
162
+ fontWeight : "500" ,
163
+ } ,
164
+ loadingText : {
165
+ marginTop : 16 ,
166
+ fontSize : 16 ,
167
+ color : "#666" ,
168
+ } ,
63
169
} ) ;
0 commit comments