fix pow node edits (#3078)

This commit is contained in:
malik1004x
2026-03-13 23:20:25 +01:00
committed by GitHub
parent 531b7f2e6f
commit 9a6fd46e04
3 changed files with 113 additions and 129 deletions
+3 -2
View File
@@ -629,9 +629,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.newPowNode:
final args = settings.arguments as Map<String, dynamic>?;
final page = getIt.get<PowNodeCreateOrEditPage>(
param1: args?['editingNode'] as Node?, param2: args?['isSelected'] as bool?);
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<PowNodeCreateOrEditPage>(
param1: args?['editingNode'] as Node?, param2: args?['isSelected'] as bool?));
builder: (_) => page);
case Routes.accountCreation:
return CupertinoPageRoute<String>(
@@ -1,7 +1,10 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/new-ui/widgets/keyboard_hide_overlay.dart';
import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
import 'package:cake_wallet/src/screens/nodes/widgets/node_form.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:cw_core/node.dart';
@@ -13,76 +16,30 @@ import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart';
class PowNodeCreateOrEditPage extends BasePage {
class PowNodeCreateOrEditPage extends StatefulWidget {
PowNodeCreateOrEditPage(
{required this.nodeCreateOrEditViewModel, this.editingNode, this.isSelected})
: _addressController = TextEditingController(),
_portController = TextEditingController(),
_loginController = TextEditingController(),
_passwordController = TextEditingController() {
reaction((_) => nodeCreateOrEditViewModel.address, (String address) {
if (address != _addressController.text) {
_addressController.text = address;
}
});
;
reaction((_) => nodeCreateOrEditViewModel.port, (String port) {
if (port != _portController.text) {
_portController.text = port;
}
});
if (nodeCreateOrEditViewModel.hasAuthCredentials) {
reaction((_) => nodeCreateOrEditViewModel.login, (String login) {
if (login != _loginController.text) {
_loginController.text = login;
}
});
reaction((_) => nodeCreateOrEditViewModel.password, (String password) {
if (password != _passwordController.text) {
_passwordController.text = password;
}
});
}
_addressController
.addListener(() => nodeCreateOrEditViewModel.address = _addressController.text);
_portController.addListener(() => nodeCreateOrEditViewModel.port = _portController.text);
_loginController.addListener(() => nodeCreateOrEditViewModel.login = _loginController.text);
_passwordController
.addListener(() => nodeCreateOrEditViewModel.password = _passwordController.text);
}
final TextEditingController _addressController;
final TextEditingController _portController;
final TextEditingController _loginController;
final TextEditingController _passwordController;
@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(context);
},
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;
final _formKey = GlobalKey<NodeFormState>();
@override
Widget body(BuildContext context) {
reaction((_) => nodeCreateOrEditViewModel.connectionState, (ExecutionState state) {
State<PowNodeCreateOrEditPage> createState() => _PowNodeCreateOrEditPageState();
}
class _PowNodeCreateOrEditPageState extends State<PowNodeCreateOrEditPage> {
final _formKey = GlobalKey<NodeFormState>();
@override
void initState() {
super.initState();
reaction((_) => widget.nodeCreateOrEditViewModel.connectionState, (ExecutionState state) {
if (state is ExecutedSuccessfullyState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
showPopUp<void>(
@@ -111,73 +68,98 @@ class PowNodeCreateOrEditPage extends BasePage {
});
}
});
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(left: 24, right: 24),
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 24.0, top: 8),
content: NodeForm(
key: _formKey,
nodeViewModel: nodeCreateOrEditViewModel,
),
bottomSectionPadding: EdgeInsets.only(bottom: 24),
bottomSection: Observer(
builder: (_) => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: Container(
padding: EdgeInsets.only(right: 8.0),
child: LoadingPrimaryButton(
onPressed: () async {
final confirmed = await showPopUp<bool>(
context: context,
builder: (BuildContext context) {
return AlertWithTwoActions(
alertTitle: S.of(context).remove_node,
alertContent: S.of(context).remove_node_message,
rightButtonText: S.of(context).remove,
leftButtonText: S.of(context).cancel,
actionRightButton: () => Navigator.pop(context, true),
actionLeftButton: () => Navigator.pop(context, false));
}) ??
false;
if (confirmed) {
await editingNode!.delete();
Navigator.of(context).pop();
}
},
text: S.of(context).delete,
isDisabled: !nodeCreateOrEditViewModel.isReady || (isSelected ?? false),
color: Theme.of(context).colorScheme.errorContainer,
textColor: Theme.of(context).colorScheme.onPrimary,
),
),
),
Flexible(
child: Container(
padding: EdgeInsets.only(left: 8.0),
child: PrimaryButton(
onPressed: () async {
if (_formKey.currentState != null &&
!_formKey.currentState!.validate()) {
return;
}
await nodeCreateOrEditViewModel.save(
editingNode: editingNode, saveAsCurrent: isSelected ?? false);
Navigator.of(context).pop();
},
text: S.of(context).save,
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary,
isDisabled: (!nodeCreateOrEditViewModel.isReady) ||
(nodeCreateOrEditViewModel.connectionState is IsExecutingState),
),
)),
],
color: Theme.of(context).colorScheme.surface,
child: KeyboardHideOverlay(
child: Column(
children: [
ModalTopBar(
title: widget.editingNode != null ? S.current.edit_node : S.current.node_new,
leadingIcon: Icon(Icons.arrow_back_ios_new),
onLeadingPressed: Navigator.of(context).pop,
trailingIcon: CakeImageWidget(imageUrl:
"assets/new-ui/scan.svg",width:24,height:24,
colorFilter: ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn),
),
onTrailingPressed: () => widget.nodeCreateOrEditViewModel.scanQRCodeForNewNode(context),
),
Expanded(
child: Container(
padding: EdgeInsets.only(left: 24, right: 24),
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 24.0, top: 8),
content: NodeForm(
key: _formKey,
nodeViewModel: widget.nodeCreateOrEditViewModel,
),
bottomSectionPadding: EdgeInsets.only(bottom: 24),
bottomSection: Observer(
builder: (_) => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: Container(
padding: EdgeInsets.only(right: 8.0),
child: LoadingPrimaryButton(
onPressed: () async {
final confirmed = await showPopUp<bool>(
context: context,
builder: (BuildContext context) {
return AlertWithTwoActions(
alertTitle: S.of(context).remove_node,
alertContent: S.of(context).remove_node_message,
rightButtonText: S.of(context).remove,
leftButtonText: S.of(context).cancel,
actionRightButton: () => Navigator.pop(context, true),
actionLeftButton: () => Navigator.pop(context, false));
}) ??
false;
if (confirmed) {
await widget.editingNode!.delete();
Navigator.of(context).pop();
}
},
text: S.of(context).delete,
isDisabled: !widget.nodeCreateOrEditViewModel.isReady || (widget.isSelected ?? false),
color: Theme.of(context).colorScheme.errorContainer,
textColor: Theme.of(context).colorScheme.onPrimary,
),
),
),
Flexible(
child: Container(
padding: EdgeInsets.only(left: 8.0),
child: PrimaryButton(
onPressed: () async {
if (_formKey.currentState != null &&
!_formKey.currentState!.validate()) {
return;
}
await widget.nodeCreateOrEditViewModel.save(
editingNode: widget.editingNode, saveAsCurrent: widget.isSelected ?? false);
Navigator.of(context).pop();
},
text: S.of(context).save,
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary,
isDisabled: (!widget.nodeCreateOrEditViewModel.isReady) ||
(widget.nodeCreateOrEditViewModel.connectionState is IsExecutingState),
),
)),
],
)),
)),
));
),
],
),
),
);
}
}
@@ -15,7 +15,8 @@ import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
class ManageNodesPage extends BasePage {
ManageNodesPage(this.isPow, {this.nodeListViewModel, this.powNodeListViewModel})
: assert((isPow && powNodeListViewModel != null) || (!isPow && nodeListViewModel != null));
: assert((isPow && powNodeListViewModel != null) || (!isPow && nodeListViewModel != null)),
assert(powNodeListViewModel == null || nodeListViewModel == null);
final NodeListViewModel? nodeListViewModel;
final PowNodeListViewModel? powNodeListViewModel;
@@ -34,7 +35,7 @@ class ManageNodesPage extends BasePage {
button: true,
child: NodeHeaderListRow(
title: S.of(context).add_new_node,
onTap: (_) async => await Navigator.of(context).pushNamed(Routes.newNode),
onTap: (_) async => await Navigator.of(context).pushNamed(isPow ? Routes.newPowNode : Routes.newNode),
),
),
if (FeatureFlag.isAutomaticNodeSwitchingEnabled)
@@ -80,7 +81,7 @@ class ManageNodesPage extends BasePage {
title: node.uriRaw,
node: node,
isSelected: isSelected,
isPow: false,
isPow: isPow,
onTap: (_) async {
if (isSelected) {
return;