feat: Introduce QR Scanning to add new node (#1007)

* feat: Introduce QR Scanning to add new node * fix: Exception handing for scan qr and invalid qr value * fix: Exception handing for scan qr and invalid qr value

Adegoke David committed Aug 4, 2023 at 12:27 UTC e9df03b49b3fb8b06222ee81b5ab1f27c83d02ff
3 files changed +64 -2
lib/src/screens/nodes/node_create_or_edit_page.dart
+13
@@ -66,6 +66,19 @@ class NodeCreateOrEditPage extends BasePage {
66 @override
67 String get title => editingNode != null ? S.current.edit_node : S.current.node_new;
68
69 + @override
70 + Widget trailing(BuildContext context) => IconButton(
71 + onPressed: () async {
72 + await nodeCreateOrEditViewModel.scanQRCodeForNewNode();
73 + },
74 + splashColor: Colors.transparent,
75 + highlightColor: Colors.transparent,
76 + hoverColor: Colors.transparent,
77 + icon: Image.asset(
78 + 'assets/images/qr_code_icon.png',
79 + ),
80 + );
81 +
82 final NodeCreateOrEditViewModel nodeCreateOrEditViewModel;
83 final Node? editingNode;
84 final bool? isSelected;
lib/src/screens/nodes/widgets/node_form.dart
+11
@@ -44,6 +44,17 @@ class NodeForm extends StatelessWidget {
44 }
45 });
46 }
47 + reaction((_) => nodeViewModel.address, (String address) {
48 + if (address != _addressController.text) {
49 + _addressController.text = address;
50 + }
51 + });
52 +
53 + reaction((_) => nodeViewModel.port, (String port) {
54 + if (port != _portController.text) {
55 + _portController.text = port;
56 + }
57 + });
58
59 _addressController.addListener(() => nodeViewModel.address = _addressController.text);
60 _portController.addListener(() => nodeViewModel.port = _portController.text);
lib/view_model/node_list/node_create_or_edit_view_model.dart
+40 -2
@@ -1,4 +1,5 @@
1 import 'package:cake_wallet/core/execution_state.dart';
2 +import 'package:cake_wallet/entities/qr_scanner.dart';
3 import 'package:cake_wallet/store/settings_store.dart';
4 import 'package:hive/hive.dart';
5 import 'package:mobx/mobx.dart';
@@ -8,10 +9,12 @@ import 'package:collection/collection.dart';
9
10 part 'node_create_or_edit_view_model.g.dart';
11
11 -class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase with _$NodeCreateOrEditViewModel;
12 +class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase
13 + with _$NodeCreateOrEditViewModel;
14
15 abstract class NodeCreateOrEditViewModelBase with Store {
14 - NodeCreateOrEditViewModelBase(this._nodeSource, this._walletType, this._settingsStore)
16 + NodeCreateOrEditViewModelBase(
17 + this._nodeSource, this._walletType, this._settingsStore)
18 : state = InitialExecutionState(),
19 connectionState = InitialExecutionState(),
20 useSSL = false,
@@ -170,4 +173,39 @@ abstract class NodeCreateOrEditViewModelBase with Store {
173
174 @action
175 void setAsCurrent(Node node) => _settingsStore.nodes[_walletType] = node;
176 +
177 + @action
178 + Future<void> scanQRCodeForNewNode() async {
179 + try {
180 + String code = await presentQRScanner();
181 +
182 + if (code.isEmpty) {
183 + throw Exception('Unexpected scan QR code value: value is empty');
184 + }
185 +
186 + final uri = Uri.tryParse(code);
187 +
188 + if (uri == null) {
189 + throw Exception('Unexpected scan QR code value: Value is invalid');
190 + }
191 +
192 + final userInfo = uri.userInfo.split(':');
193 +
194 + if (userInfo.length < 2) {
195 + throw Exception('Unexpected scan QR code value: Value is invalid');
196 + }
197 +
198 + final rpcUser = userInfo[0];
199 + final rpcPassword = userInfo[1];
200 + final ipAddress = uri.host;
201 + final port = uri.port.toString();
202 +
203 + setAddress(ipAddress);
204 + setPassword(rpcPassword);
205 + setLogin(rpcUser);
206 + setPort(port);
207 + } on Exception catch (e) {
208 + connectionState = FailureState(e.toString());
209 + }
210 + }
211 }