From 6cd6139fb382284503c40c5b286188617dc8e25a Mon Sep 17 00:00:00 2001
From: OleksandrSobol <dr.alexander.sobol@gmail.com>
Date: Thu, 19 Nov 2020 21:13:54 +0200
Subject: [PATCH] CAKE-169 | created connection_state.dart; added connect()
 method and connectionState parameter to node_create_or_edit_view_model.dart;
 replaced Reset button to Connect button and added _setEffects() method to
 node_create_or_edit_page.dart; changed useSSL parameter from false to true in
 the connectToNode() method (monero_wallet.dart)

---
 lib/monero/monero_wallet.dart                 |  2 +-
 .../nodes/node_create_or_edit_page.dart       | 63 ++++++++++++++++++-
 .../node_list/connection_state.dart           | 17 +++++
 .../node_create_or_edit_view_model.dart       | 20 +++++-
 4 files changed, 97 insertions(+), 5 deletions(-)
 create mode 100644 lib/view_model/node_list/connection_state.dart

diff --git a/lib/monero/monero_wallet.dart b/lib/monero/monero_wallet.dart
index 2d4878b4c..a064ed337 100644
--- a/lib/monero/monero_wallet.dart
+++ b/lib/monero/monero_wallet.dart
@@ -147,7 +147,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
           address: node.uri,
           login: node.login,
           password: node.password,
-          useSSL: false,
+          useSSL: true,
           // FIXME: hardcoded value
           isLightWallet: false); // FIXME: hardcoded value
       syncStatus = ConnectedSyncStatus();
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 ee13984c5..0511a21d0 100644
--- a/lib/src/screens/nodes/node_create_or_edit_page.dart
+++ b/lib/src/screens/nodes/node_create_or_edit_page.dart
@@ -1,3 +1,6 @@
+import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
+import 'package:cake_wallet/utils/show_pop_up.dart';
+import 'package:cake_wallet/view_model/node_list/connection_state.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter_mobx/flutter_mobx.dart';
@@ -10,6 +13,7 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
 import 'package:cake_wallet/src/screens/base_page.dart';
 import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
 import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
+import 'package:cake_wallet/view_model/node_list/connection_state.dart';
 
 class NodeCreateOrEditPage extends BasePage {
   NodeCreateOrEditPage(this.nodeCreateOrEditViewModel)
@@ -60,6 +64,8 @@ class NodeCreateOrEditPage extends BasePage {
   final TextEditingController _loginController;
   final TextEditingController _passwordController;
 
+  bool _effectsInstalled = false;
+
   @override
   String get title => S.current.node_new;
 
@@ -67,6 +73,8 @@ class NodeCreateOrEditPage extends BasePage {
 
   @override
   Widget body(BuildContext context) {
+    _setEffects(context);
+
     return Container(
         padding: EdgeInsets.only(left: 24, right: 24),
         child: ScrollableWithBottomSection(
@@ -133,9 +141,18 @@ class NodeCreateOrEditPage extends BasePage {
                       Flexible(
                           child: Container(
                         padding: EdgeInsets.only(right: 8.0),
-                        child: PrimaryButton(
-                            onPressed: () => nodeCreateOrEditViewModel.reset(),
-                            text: S.of(context).reset,
+                        child: LoadingPrimaryButton(
+                            onPressed: () async {
+                              if (!_formKey.currentState.validate()) {
+                                return;
+                              }
+
+                              await nodeCreateOrEditViewModel.connect();
+                            },
+                            isLoading: nodeCreateOrEditViewModel
+                                .connectionState is IsConnectingState,
+                            text: 'Connect',
+                            isDisabled: !nodeCreateOrEditViewModel.isReady,
                             color: Colors.orange,
                             textColor: Colors.white),
                       )),
@@ -161,4 +178,44 @@ class NodeCreateOrEditPage extends BasePage {
                   )),
         ));
   }
+
+  void _setEffects(BuildContext context) {
+    if (_effectsInstalled) {
+      return;
+    }
+
+    reaction((_) => nodeCreateOrEditViewModel.connectionState,
+            (ConnectionToNodeState state) {
+          if (state is ConnectedSuccessfullyState) {
+            WidgetsBinding.instance.addPostFrameCallback((_) {
+              showPopUp<void>(
+                  context: context,
+                  builder: (BuildContext context) =>
+                      AlertWithOneAction(
+                          alertTitle: S.of(context).node_new,
+                          alertContent: state.isAlive
+                              ? 'Connected to node'
+                              : 'Not connected to node',
+                          buttonText: S.of(context).ok,
+                          buttonAction: () => Navigator.of(context).pop()));
+            });
+          }
+
+          if (state is FailureConnectedState) {
+            WidgetsBinding.instance.addPostFrameCallback((_) {
+              showPopUp<void>(
+                  context: context,
+                  builder: (BuildContext context) {
+                    return AlertWithOneAction(
+                        alertTitle: S.of(context).error,
+                        alertContent: state.error,
+                        buttonText: S.of(context).ok,
+                        buttonAction: () => Navigator.of(context).pop());
+                  });
+            });
+          }
+        });
+
+    _effectsInstalled = true;
+  }
 }
diff --git a/lib/view_model/node_list/connection_state.dart b/lib/view_model/node_list/connection_state.dart
new file mode 100644
index 000000000..eb13e474c
--- /dev/null
+++ b/lib/view_model/node_list/connection_state.dart
@@ -0,0 +1,17 @@
+abstract class ConnectionToNodeState {}
+
+class InitialConnectionState extends ConnectionToNodeState {}
+
+class IsConnectingState extends ConnectionToNodeState {}
+
+class ConnectedSuccessfullyState extends ConnectionToNodeState {
+  ConnectedSuccessfullyState(this.isAlive);
+
+  final bool isAlive;
+}
+
+class FailureConnectedState extends ConnectionToNodeState {
+  FailureConnectedState(this.error);
+
+  final String error;
+}
\ No newline at end of file
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 fb6cd195e..df07f6789 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/view_model/node_list/connection_state.dart';
 import 'package:hive/hive.dart';
 import 'package:mobx/mobx.dart';
 import 'package:cake_wallet/core/wallet_base.dart';
@@ -12,7 +13,8 @@ class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase
 
 abstract class NodeCreateOrEditViewModelBase with Store {
   NodeCreateOrEditViewModelBase(this._nodeSource, this._wallet)
-      : state = InitialExecutionState();
+      : state = InitialExecutionState(),
+        connectionState = InitialConnectionState();
 
   @observable
   ExecutionState state;
@@ -29,6 +31,9 @@ abstract class NodeCreateOrEditViewModelBase with Store {
   @observable
   String password;
 
+  @observable
+  ConnectionToNodeState connectionState;
+
   @computed
   bool get isReady =>
       (address?.isNotEmpty ?? false) && (port?.isNotEmpty ?? false);
@@ -68,4 +73,17 @@ abstract class NodeCreateOrEditViewModelBase with Store {
       state = FailureState(e.toString());
     }
   }
+
+  @action
+  Future<void> connect() async {
+    try {
+      connectionState = IsConnectingState();
+      final node =
+        Node(uri: uri, type: _wallet.type, login: login, password: password);
+      final isAlive = await node.requestNode();
+      connectionState = ConnectedSuccessfullyState(isAlive);
+    } catch (e) {
+      connectionState = FailureConnectedState(e.toString());
+    }
+  }
 }