From e9df03b49b3fb8b06222ee81b5ab1f27c83d02ff Mon Sep 17 00:00:00 2001 From: Adegoke David <64401859+Blazebrain@users.noreply.github.com> Date: Fri, 4 Aug 2023 12:27:19 +0100 Subject: [PATCH] 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 --- .../nodes/node_create_or_edit_page.dart | 13 ++++++ lib/src/screens/nodes/widgets/node_form.dart | 11 +++++ .../node_create_or_edit_view_model.dart | 42 ++++++++++++++++++- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/lib/src/screens/nodes/node_create_or_edit_page.dart b/lib/src/screens/nodes/node_create_or_edit_page.dart index 216238b54..c1b07d8c5 100644 --- a/lib/src/screens/nodes/node_create_or_edit_page.dart +++ b/lib/src/screens/nodes/node_create_or_edit_page.dart @@ -66,6 +66,19 @@ class NodeCreateOrEditPage extends BasePage { @override String get title => editingNode != null ? S.current.edit_node : S.current.node_new; + @override + Widget trailing(BuildContext context) => IconButton( + onPressed: () async { + await nodeCreateOrEditViewModel.scanQRCodeForNewNode(); + }, + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + hoverColor: Colors.transparent, + icon: Image.asset( + 'assets/images/qr_code_icon.png', + ), + ); + final NodeCreateOrEditViewModel nodeCreateOrEditViewModel; final Node? editingNode; final bool? isSelected; diff --git a/lib/src/screens/nodes/widgets/node_form.dart b/lib/src/screens/nodes/widgets/node_form.dart index 8ee3ecd2f..91974fce5 100644 --- a/lib/src/screens/nodes/widgets/node_form.dart +++ b/lib/src/screens/nodes/widgets/node_form.dart @@ -44,6 +44,17 @@ class NodeForm extends StatelessWidget { } }); } + reaction((_) => nodeViewModel.address, (String address) { + if (address != _addressController.text) { + _addressController.text = address; + } + }); + + reaction((_) => nodeViewModel.port, (String port) { + if (port != _portController.text) { + _portController.text = port; + } + }); _addressController.addListener(() => nodeViewModel.address = _addressController.text); _portController.addListener(() => nodeViewModel.port = _portController.text); diff --git a/lib/view_model/node_list/node_create_or_edit_view_model.dart b/lib/view_model/node_list/node_create_or_edit_view_model.dart index 4433eb5b6..f749ed0d5 100644 --- a/lib/view_model/node_list/node_create_or_edit_view_model.dart +++ b/lib/view_model/node_list/node_create_or_edit_view_model.dart @@ -1,4 +1,5 @@ import 'package:cake_wallet/core/execution_state.dart'; +import 'package:cake_wallet/entities/qr_scanner.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; @@ -8,10 +9,12 @@ import 'package:collection/collection.dart'; part 'node_create_or_edit_view_model.g.dart'; -class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase with _$NodeCreateOrEditViewModel; +class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase + with _$NodeCreateOrEditViewModel; abstract class NodeCreateOrEditViewModelBase with Store { - NodeCreateOrEditViewModelBase(this._nodeSource, this._walletType, this._settingsStore) + NodeCreateOrEditViewModelBase( + this._nodeSource, this._walletType, this._settingsStore) : state = InitialExecutionState(), connectionState = InitialExecutionState(), useSSL = false, @@ -170,4 +173,39 @@ abstract class NodeCreateOrEditViewModelBase with Store { @action void setAsCurrent(Node node) => _settingsStore.nodes[_walletType] = node; + + @action + Future scanQRCodeForNewNode() async { + try { + String code = await presentQRScanner(); + + if (code.isEmpty) { + throw Exception('Unexpected scan QR code value: value is empty'); + } + + final uri = Uri.tryParse(code); + + if (uri == null) { + throw Exception('Unexpected scan QR code value: Value is invalid'); + } + + final userInfo = uri.userInfo.split(':'); + + if (userInfo.length < 2) { + throw Exception('Unexpected scan QR code value: Value is invalid'); + } + + final rpcUser = userInfo[0]; + final rpcPassword = userInfo[1]; + final ipAddress = uri.host; + final port = uri.port.toString(); + + setAddress(ipAddress); + setPassword(rpcPassword); + setLogin(rpcUser); + setPort(port); + } on Exception catch (e) { + connectionState = FailureState(e.toString()); + } + } }