| 1 | import 'package:cake_wallet/routes.dart'; |
| 2 | import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; |
| 3 | import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart'; |
| 4 | import 'package:cw_core/node.dart'; |
| 5 | import 'package:flutter/material.dart'; |
| 6 | |
| 7 | class NodeListRow extends StatelessWidget { |
| 8 | NodeListRow( |
| 9 | {required this.node, |
| 10 | required this.onTap, |
| 11 | required this.onEditComplete, |
| 12 | required this.isSelected, |
| 13 | required this.isPow, |
| 14 | this.speed, |
| 15 | this.vertical = 10.0, |
| 16 | this.horizontal = 12.0}); |
| 17 | |
| 18 | final Node node; |
| 19 | final bool isPow; |
| 20 | final VoidCallback onTap; |
| 21 | final Future<void> Function(Object?) onEditComplete; |
| 22 | final bool isSelected; |
| 23 | final NodeSpeed? speed; |
| 24 | final double vertical; |
| 25 | final double horizontal; |
| 26 | |
| 27 | @override |
| 28 | Widget build(BuildContext context) { |
| 29 | final leading = buildLeading(context); |
| 30 | final trailing = buildTrailing(context); |
| 31 | |
| 32 | final hasLabel = node.label != null && node.label!.isNotEmpty; |
| 33 | final uriText = "${node.uri.host}:${node.uri.port}"; |
| 34 | return Material( |
| 35 | color: Colors.transparent, |
| 36 | child: InkWell( |
| 37 | onTap: onTap, |
| 38 | child: Padding( |
| 39 | padding: EdgeInsets.symmetric(vertical: vertical, horizontal: horizontal), |
| 40 | child: Row( |
| 41 | spacing: 12, |
| 42 | mainAxisAlignment: MainAxisAlignment.spaceBetween, |
| 43 | children: <Widget>[ |
| 44 | leading, |
| 45 | Expanded( |
| 46 | child: Column( |
| 47 | crossAxisAlignment: CrossAxisAlignment.start, |
| 48 | spacing: 4, |
| 49 | children: [ |
| 50 | Row( |
| 51 | spacing: 4, |
| 52 | mainAxisAlignment: MainAxisAlignment.start, |
| 53 | children: [ |
| 54 | Text( |
| 55 | hasLabel ? node.label! : uriText, |
| 56 | style: TextStyle(fontSize: 12), |
| 57 | ), |
| 58 | if (badgePath != null) |
| 59 | CakeImageWidget( |
| 60 | imageUrl: badgePath, |
| 61 | colorFilter: ColorFilter.mode( |
| 62 | Theme.of(context).colorScheme.primary, BlendMode.srcIn), |
| 63 | ) |
| 64 | ], |
| 65 | ), |
| 66 | if (hasLabel) |
| 67 | Text( |
| 68 | uriText, |
| 69 | style: TextStyle( |
| 70 | fontSize: 12, color: Theme.of(context).colorScheme.onSurfaceVariant), |
| 71 | ), |
| 72 | ], |
| 73 | ), |
| 74 | ), |
| 75 | trailing, |
| 76 | ], |
| 77 | ), |
| 78 | ), |
| 79 | ), |
| 80 | ); |
| 81 | } |
| 82 | |
| 83 | Widget buildLeading(BuildContext context) => isSelected |
| 84 | ? Padding( |
| 85 | padding: const EdgeInsets.all(4.0), |
| 86 | child: Icon( |
| 87 | Icons.check, |
| 88 | size: 16, |
| 89 | color: Theme.of(context).colorScheme.primary, |
| 90 | ), |
| 91 | ) |
| 92 | : SizedBox(width: 24, height: 24); |
| 93 | |
| 94 | Widget buildTrailing(BuildContext context) { |
| 95 | return Row( |
| 96 | children: [ |
| 97 | if (speed != null) |
| 98 | CakeImageWidget( |
| 99 | imageUrl: Theme.of(context).brightness == Brightness.dark |
| 100 | ? speed!.darkIconPath |
| 101 | : speed!.iconPath, |
| 102 | width: 24, |
| 103 | height: 24, |
| 104 | ), |
| 105 | GestureDetector( |
| 106 | behavior: HitTestBehavior.opaque, |
| 107 | onTap: () async { |
| 108 | final res = await Navigator.of(context).pushNamed( |
| 109 | isPow ? Routes.newPowNode : Routes.newNode, |
| 110 | arguments: {'editingNode': node, 'isSelected': isSelected}); |
| 111 | await onEditComplete(res); |
| 112 | }, |
| 113 | child: Padding( |
| 114 | padding: const EdgeInsets.only(right: 8.0, left: 12.0), |
| 115 | child: CakeImageWidget( |
| 116 | imageUrl: "assets/new-ui/3dots_vertical.svg", |
| 117 | colorFilter: |
| 118 | ColorFilter.mode(Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn), |
| 119 | ), |
| 120 | ), |
| 121 | ) |
| 122 | ], |
| 123 | ); |
| 124 | } |
| 125 | |
| 126 | String? get badgePath { |
| 127 | if (node.isOfficial) return "assets/new-ui/official_node.svg"; |
| 128 | if (node.isBuiltin) return "assets/new-ui/default_node.svg"; |
| 129 | return null; |
| 130 | } |
| 131 | } |