From 36f28114edf9c9427f325a97c9dd13fa203d1c41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Olav?= Date: Sat, 4 Nov 2023 13:19:42 +0100 Subject: [PATCH] tabs/settings: make it possible reset to file settings --- lib/pages/tabs/settings_tab.dart | 106 +++++++++++++++++- .../lib/widgets/inputs/text_field.dart | 3 + 2 files changed, 105 insertions(+), 4 deletions(-) diff --git a/lib/pages/tabs/settings_tab.dart b/lib/pages/tabs/settings_tab.dart index 4c66b51a..f16c3ae7 100644 --- a/lib/pages/tabs/settings_tab.dart +++ b/lib/pages/tabs/settings_tab.dart @@ -6,6 +6,7 @@ import 'package:get_it/get_it.dart'; import 'package:sail_ui/sail_ui.dart'; import 'package:sail_ui/theme/theme.dart'; import 'package:sail_ui/widgets/core/sail_text.dart'; +import 'package:sidesail/rpc/rpc_config.dart'; import 'package:sidesail/rpc/rpc_mainchain.dart'; import 'package:sidesail/rpc/rpc_sidechain.dart'; import 'package:stacked/stacked.dart'; @@ -39,6 +40,7 @@ class SettingsTabPage extends StatelessWidget { settings: viewModel.sidechainSettings, testConnectionValues: viewModel.reconnectSidechain, connectionError: viewModel.sidechainConnectionError, + readError: viewModel.sidechainFileError, loading: viewModel.sidechainBusy, ), NodeConnectionSettings( @@ -47,6 +49,7 @@ class SettingsTabPage extends StatelessWidget { settings: viewModel.mainchainSettings, testConnectionValues: viewModel.reconnectMainchain, connectionError: viewModel.mainchainConnectionError, + readError: viewModel.mainchainFileError, loading: viewModel.mainchainBusy, ), ], @@ -67,6 +70,7 @@ class NodeConnectionSettings extends ViewModelWidget { final SingleNodeConnectionSettings settings; final VoidCallback testConnectionValues; final String? connectionError; + final String? readError; final bool loading; const NodeConnectionSettings({ @@ -76,6 +80,7 @@ class NodeConnectionSettings extends ViewModelWidget { required this.settings, required this.testConnectionValues, required this.connectionError, + required this.readError, required this.loading, }); @@ -105,12 +110,20 @@ class NodeConnectionSettings extends ViewModelWidget { ], ), if (connectionError != null) SailText.secondary12(connectionError!), + if (readError != null) SailText.secondary12(readError!), ], ), SailTextField( label: 'Config path', controller: settings.configPathController, hintText: '/the/path/to/your/somethingchain.conf', + suffixWidget: Padding( + padding: const EdgeInsets.only(left: SailStyleValues.padding08), + child: SailTextButton( + label: 'Read file', + onPressed: settings.readAndSetValuesFromFile, + ), + ), ), SailTextField( label: 'Host', @@ -138,10 +151,9 @@ class NodeConnectionSettings extends ViewModelWidget { Expanded(child: Container()), SailButton.secondary( 'Reset to config file values', - disabled: true, + disabled: !settings.inputDifferentThanFile, onPressed: () { - // TODO: implement this logic! must always keep track of config - // file values to do that + settings.resetToFileValues(); }, size: ButtonSize.regular, ), @@ -175,15 +187,24 @@ class NodeConnectionViewModel extends BaseViewModel { String? get sidechainConnectionError => sideRPC.connectionError; String? get mainchainConnectionError => mainRPC.connectionError; + String? get sidechainFileError => sideRPC.connectionSettings.readError; + String? get mainchainFileError => mainRPC.connectionSettings.readError; + bool get sidechainBusy => _sidechainBusy; bool get mainchainBusy => _mainchainBusy; bool _sidechainBusy = false; bool _mainchainBusy = false; + bool get sidechainSettingsDifferent => sideRPC.connectionSettings.inputDifferentThanFile; + bool get mainchainSettingsDifferent => mainRPC.connectionSettings.inputDifferentThanFile; + NodeConnectionViewModel() { mainRPC.addListener(notifyListeners); + mainRPC.connectionSettings.addListener(notifyListeners); + sideRPC.addListener(notifyListeners); + sideRPC.connectionSettings.addListener(notifyListeners); } Timer? _connectionTimer; @@ -218,7 +239,9 @@ class NodeConnectionViewModel extends BaseViewModel { void dispose() { _connectionTimer?.cancel(); sideRPC.removeListener(notifyListeners); + sideRPC.connectionSettings.removeListener(notifyListeners); mainRPC.removeListener(notifyListeners); + mainRPC.connectionSettings.removeListener(notifyListeners); super.dispose(); } } @@ -236,6 +259,20 @@ class SingleNodeConnectionSettings extends ChangeNotifier { String get password => passwordController.text; final ssl = false; + String? readError; + + late String fileConfigPath; + late String fileHost; + late int filePort; + late String fileUsername; + late String filePassword; + bool get inputDifferentThanFile => + configPathController.text != fileConfigPath || + hostController.text != fileHost || + portController.text != filePort.toString() || + usernameController.text != fileUsername || + passwordController.text != filePassword; + SingleNodeConnectionSettings( String path, String host, @@ -243,12 +280,73 @@ class SingleNodeConnectionSettings extends ChangeNotifier { String username, String password, ) { - // initial values are those of the config file, hmmmm + fileConfigPath = path; + fileHost = host; + filePort = port; + fileUsername = username; + filePassword = password; + configPathController.text = path; hostController.text = host; portController.text = port.toString(); usernameController.text = username; passwordController.text = password; + + configPathController.addListener(notifyListeners); + hostController.addListener(notifyListeners); + portController.addListener(notifyListeners); + usernameController.addListener(notifyListeners); + passwordController.addListener(notifyListeners); + } + + void resetToFileValues() { + configPathController.text = fileConfigPath; + hostController.text = fileHost; + portController.text = filePort.toString(); + usernameController.text = fileUsername; + passwordController.text = filePassword; + + notifyListeners(); + } + + void readAndSetValuesFromFile() async { + try { + var parts = splitPath(configPathController.text); + String dataDir = parts.$1; + String confFile = parts.$2; + readError = null; + + final config = await readRpcConfig(dataDir, confFile); + configPathController.text = config.path; + hostController.text = config.host; + portController.text = config.port.toString(); + usernameController.text = config.username; + passwordController.text = config.password; + } catch (error) { + readError = error.toString(); + } + + notifyListeners(); + } + + (String, String) splitPath(String path) { + if (!path.contains('/')) { + return ('', ''); + } + String directory = path.substring(0, path.lastIndexOf('/')); + String fileName = path.split('/').last; + + return (directory, fileName); + } + + @override + void dispose() { + super.dispose(); + configPathController.removeListener(notifyListeners); + hostController.removeListener(notifyListeners); + portController.removeListener(notifyListeners); + usernameController.removeListener(notifyListeners); + passwordController.removeListener(notifyListeners); } static SingleNodeConnectionSettings empty() { diff --git a/packages/sail_ui/lib/widgets/inputs/text_field.dart b/packages/sail_ui/lib/widgets/inputs/text_field.dart index 46d11e58..d2067a25 100644 --- a/packages/sail_ui/lib/widgets/inputs/text_field.dart +++ b/packages/sail_ui/lib/widgets/inputs/text_field.dart @@ -13,6 +13,7 @@ class SailTextField extends StatelessWidget { final String? label; final String hintText; final String? suffix; + final Widget? suffixWidget; final TextFieldType textFieldType; final String? prefix; final TextFieldSize size; @@ -24,6 +25,7 @@ class SailTextField extends StatelessWidget { required this.hintText, this.textFieldType = TextFieldType.text, this.suffix, + this.suffixWidget, this.prefix, this.size = TextFieldSize.regular, }); @@ -78,6 +80,7 @@ class SailTextField extends StatelessWidget { fontSize: textSize, ), suffixText: suffix, + suffix: suffixWidget, prefixStyle: TextStyle( color: SailTheme.of(context).colors.textTertiary, fontSize: textSize,