5
5
Text ,
6
6
View ,
7
7
ActivityIndicator ,
8
+ TouchableOpacity ,
8
9
} from "react-native" ;
9
10
import { useState } from "react" ;
10
11
import { useFacade } from "@/data/facades" ;
@@ -15,6 +16,7 @@ import { AccountFormat } from "@ironfish/sdk";
15
16
export default function MenuNetwork ( ) {
16
17
const [ modalVisible , setModalVisible ] = useState ( false ) ;
17
18
const [ isChangingNetwork , setIsChangingNetwork ] = useState ( false ) ;
19
+ const [ pendingNetwork , setPendingNetwork ] = useState < Network | null > ( null ) ;
18
20
19
21
const facade = useFacade ( ) ;
20
22
const setAppSetting = facade . setAppSetting . useMutation ( ) ;
@@ -25,8 +27,13 @@ export default function MenuNetwork() {
25
27
26
28
const currentNetwork =
27
29
networkSetting . data ?. [ SettingsKey . Network ] ?? Network . MAINNET ;
28
- const targetNetwork =
29
- currentNetwork === Network . MAINNET ? Network . TESTNET : Network . MAINNET ;
30
+
31
+ const handleNetworkPress = ( network : Network ) => {
32
+ if ( network !== currentNetwork ) {
33
+ setPendingNetwork ( network ) ;
34
+ setModalVisible ( true ) ;
35
+ }
36
+ } ;
30
37
31
38
const handleNetworkChange = async ( network : Network ) => {
32
39
setIsChangingNetwork ( true ) ;
@@ -58,6 +65,7 @@ export default function MenuNetwork() {
58
65
} finally {
59
66
setIsChangingNetwork ( false ) ;
60
67
setModalVisible ( false ) ;
68
+ setPendingNetwork ( null ) ;
61
69
}
62
70
} ;
63
71
@@ -72,59 +80,85 @@ export default function MenuNetwork() {
72
80
73
81
return (
74
82
< View style = { styles . container } >
75
- < Modal animationType = "slide" visible = { modalVisible } >
76
- < View style = { styles . container } >
77
- { isChangingNetwork ? (
78
- < >
79
- < ActivityIndicator size = "large" />
80
- < Text style = { styles . loadingText } >
81
- Changing network and re-importing accounts...
82
- </ Text >
83
- </ >
84
- ) : (
85
- < >
86
- < Text > Switch to { targetNetwork } ?</ Text >
87
- < Text >
88
- Switching networks will upload your accounts to the{ " " }
89
- { targetNetwork } server. It may take a few minutes for your
90
- accounts to sync.
91
- </ Text >
92
- < Button
93
- title = "Yes, Change Network"
94
- onPress = { ( ) => handleNetworkChange ( targetNetwork ) }
95
- />
96
- < Button
97
- title = "I changed my mind"
98
- onPress = { ( ) => setModalVisible ( false ) }
99
- />
100
- </ >
101
- ) }
83
+ < Modal animationType = "fade" visible = { modalVisible } transparent >
84
+ < View style = { styles . modalOverlay } >
85
+ < View style = { styles . modalContent } >
86
+ { isChangingNetwork ? (
87
+ < >
88
+ < ActivityIndicator size = "large" color = "#007AFF" />
89
+ < Text style = { styles . modalText } >
90
+ Changing network and re-importing accounts...
91
+ </ Text >
92
+ </ >
93
+ ) : (
94
+ < >
95
+ < Text style = { styles . modalTitle } >
96
+ Switch to { pendingNetwork } ?
97
+ </ Text >
98
+ < Text style = { styles . modalText } >
99
+ Switching networks will upload your accounts to the{ " " }
100
+ { pendingNetwork } server. It may take a few minutes for your
101
+ accounts to sync.
102
+ </ Text >
103
+ < View style = { styles . modalButtons } >
104
+ < Button
105
+ title = "Yes, Change Network"
106
+ onPress = { ( ) => handleNetworkChange ( pendingNetwork ! ) }
107
+ color = "#007AFF"
108
+ />
109
+ < Button
110
+ title = "Cancel"
111
+ onPress = { ( ) => {
112
+ setModalVisible ( false ) ;
113
+ setPendingNetwork ( null ) ;
114
+ } }
115
+ color = "#666"
116
+ />
117
+ </ View >
118
+ </ >
119
+ ) }
120
+ </ View >
102
121
</ View >
103
122
</ Modal >
104
- < View style = { styles . networkOption } >
105
- < View style = { styles . networkInfo } >
106
- < Text style = { styles . networkTitle } > Mainnet</ Text >
107
- < Text style = { styles . networkDescription } >
108
- The live blockchain network where real transactions with value
109
- occur.
110
- </ Text >
111
- { currentNetwork === Network . MAINNET && (
112
- < Text style = { styles . selectedText } > (Selected)</ Text >
113
- ) }
114
- </ View >
115
- </ View >
116
- < View style = { styles . networkOption } >
117
- < View style = { styles . networkInfo } >
118
- < Text style = { styles . networkTitle } > Testnet</ Text >
119
- < Text style = { styles . networkDescription } >
120
- A separate environment for testing without real asset risks.
121
- </ Text >
122
- { currentNetwork === Network . TESTNET && (
123
- < Text style = { styles . selectedText } > (Selected)</ Text >
124
- ) }
125
- </ View >
123
+
124
+ < View style = { styles . content } >
125
+ < TouchableOpacity
126
+ style = { [
127
+ styles . networkOption ,
128
+ currentNetwork === Network . MAINNET && styles . networkOptionSelected ,
129
+ ] }
130
+ onPress = { ( ) => handleNetworkPress ( Network . MAINNET ) }
131
+ >
132
+ < View style = { styles . networkInfo } >
133
+ < Text style = { styles . networkTitle } > Mainnet</ Text >
134
+ < Text style = { styles . networkDescription } >
135
+ The live blockchain network where real transactions with value
136
+ occur.
137
+ </ Text >
138
+ { currentNetwork === Network . MAINNET && (
139
+ < Text style = { styles . selectedText } > (Selected)</ Text >
140
+ ) }
141
+ </ View >
142
+ </ TouchableOpacity >
143
+
144
+ < TouchableOpacity
145
+ style = { [
146
+ styles . networkOption ,
147
+ currentNetwork === Network . TESTNET && styles . networkOptionSelected ,
148
+ ] }
149
+ onPress = { ( ) => handleNetworkPress ( Network . TESTNET ) }
150
+ >
151
+ < View style = { styles . networkInfo } >
152
+ < Text style = { styles . networkTitle } > Testnet</ Text >
153
+ < Text style = { styles . networkDescription } >
154
+ A separate environment for testing without real asset risks.
155
+ </ Text >
156
+ { currentNetwork === Network . TESTNET && (
157
+ < Text style = { styles . selectedText } > (Selected)</ Text >
158
+ ) }
159
+ </ View >
160
+ </ TouchableOpacity >
126
161
</ View >
127
- < Button title = "Change Network" onPress = { ( ) => setModalVisible ( true ) } />
128
162
</ View >
129
163
) ;
130
164
}
@@ -133,35 +167,90 @@ const styles = StyleSheet.create({
133
167
container : {
134
168
flex : 1 ,
135
169
backgroundColor : "#fff" ,
136
- alignItems : "center" ,
137
- justifyContent : "center" ,
138
170
} ,
139
- networkOption : {
140
- width : "100%" ,
171
+ content : {
172
+ flex : 1 ,
141
173
padding : 16 ,
142
- borderBottomWidth : 1 ,
143
- borderBottomColor : "#eee" ,
174
+ } ,
175
+ networkOption : {
176
+ backgroundColor : "#F8F9FC" ,
177
+ borderRadius : 12 ,
178
+ marginBottom : 16 ,
179
+ padding : 20 ,
180
+ shadowColor : "#000" ,
181
+ shadowOffset : {
182
+ width : 0 ,
183
+ height : 2 ,
184
+ } ,
185
+ shadowOpacity : 0.1 ,
186
+ shadowRadius : 3 ,
187
+ elevation : 3 ,
188
+ borderWidth : 2 ,
189
+ borderColor : "transparent" ,
190
+ } ,
191
+ networkOptionSelected : {
192
+ borderColor : "#007AFF" ,
193
+ backgroundColor : "#F0F7FF" ,
144
194
} ,
145
195
networkInfo : {
146
196
alignItems : "center" ,
147
197
} ,
148
198
networkTitle : {
149
- fontSize : 18 ,
150
- fontWeight : "bold " ,
199
+ fontSize : 20 ,
200
+ fontWeight : "600 " ,
151
201
marginBottom : 8 ,
202
+ color : "#000" ,
152
203
} ,
153
204
networkDescription : {
154
205
textAlign : "center" ,
155
206
color : "#666" ,
156
207
marginBottom : 8 ,
208
+ lineHeight : 20 ,
157
209
} ,
158
210
selectedText : {
159
211
color : "#007AFF" ,
160
- fontWeight : "500" ,
212
+ fontWeight : "600" ,
213
+ marginTop : 4 ,
161
214
} ,
162
215
loadingText : {
163
216
marginTop : 16 ,
164
217
fontSize : 16 ,
165
218
color : "#666" ,
219
+ textAlign : "center" ,
220
+ } ,
221
+ buttonContainer : {
222
+ padding : 16 ,
223
+ paddingBottom : 32 ,
224
+ } ,
225
+ modalOverlay : {
226
+ flex : 1 ,
227
+ backgroundColor : "rgba(0, 0, 0, 0.5)" ,
228
+ justifyContent : "center" ,
229
+ alignItems : "center" ,
230
+ } ,
231
+ modalContent : {
232
+ backgroundColor : "#fff" ,
233
+ borderRadius : 12 ,
234
+ padding : 24 ,
235
+ width : "90%" ,
236
+ maxWidth : 400 ,
237
+ alignItems : "center" ,
238
+ } ,
239
+ modalTitle : {
240
+ fontSize : 20 ,
241
+ fontWeight : "600" ,
242
+ marginBottom : 16 ,
243
+ textAlign : "center" ,
244
+ } ,
245
+ modalText : {
246
+ fontSize : 16 ,
247
+ color : "#666" ,
248
+ textAlign : "center" ,
249
+ marginBottom : 24 ,
250
+ lineHeight : 22 ,
251
+ } ,
252
+ modalButtons : {
253
+ width : "100%" ,
254
+ gap : 12 ,
166
255
} ,
167
256
} ) ;
0 commit comments