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()); + } + } }