From 8394a00861418c2eb60410cc6137d6c89db93b88 Mon Sep 17 00:00:00 2001 From: vjrj <vjrj@comunes.org> Date: Sun, 14 Jan 2024 13:45:42 +0100 Subject: [PATCH] Added v2 new node types --- lib/data/models/node.dart | 38 +---------------- lib/data/models/node_list_cubit.dart | 14 ++++++ lib/data/models/node_list_state.dart | 35 ++++++++++++++- lib/data/models/node_list_state.g.dart | 57 ++++++++++++++++++------- lib/data/models/node_lists_default.dart | 45 +++++++++++++++++++ lib/data/models/node_manager.dart | 14 +++++- lib/data/models/node_type.dart | 2 +- lib/ui/screens/node_list_page.dart | 16 +++++++ 8 files changed, 164 insertions(+), 57 deletions(-) create mode 100644 lib/data/models/node_lists_default.dart diff --git a/lib/data/models/node.dart b/lib/data/models/node.dart index aab95bf6..51da570d 100644 --- a/lib/data/models/node.dart +++ b/lib/data/models/node.dart @@ -1,13 +1,10 @@ import 'package:equatable/equatable.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:json_annotation/json_annotation.dart'; -import 'is_json_serializable.dart'; - part 'node.g.dart'; @JsonSerializable() -class Node extends Equatable implements IsJsonSerializable<Node> { +class Node extends Equatable { const Node( {required this.url, this.latency = 99999, @@ -35,43 +32,10 @@ class Node extends Equatable implements IsJsonSerializable<Node> { return 'node url: $url latency: $latency errors: $errors currentBlock: $currentBlock'; } - @override Map<String, dynamic> toJson() => _$NodeToJson(this); - @override Node fromJson(Map<String, dynamic> json) => Node.fromJson(json); @override List<Object?> get props => <dynamic>[url]; } - -List<Node> _splitList(String list) => - list.split(' ').map((String url) => Node(url: url)).toList(); - -List<Node> _readDotNodeConfig(String entry) => _splitList(dotenv.env[entry]!); - -List<Node> defaultDuniterNodes = <Node>{ - ..._readDotNodeConfig('DUNITER_NODES'), - ..._splitList( - 'duniter.pini.fr duniter.g1.pfouque.xyz fania.g1server.net g1.brussels.ovh g1.cgeek.fr g1.computhings.be g1.cuates.net g1.geragc.es g1.madeirawonders.com g1.rendall.fr g1.trentesaux.fr gibraleon.g1server.net vit.fdn.org') -}.toList(); - -List<Node> defaultCesiumPlusNodes = <Node>{ - ..._readDotNodeConfig('CESIUM_PLUS_NODES'), - ..._splitList( - 'https://g1.data.brussels.ovh https://g1.data.e-is.pro https://g1.data.mithril.re https://g1.data.pini.fr https://g1.data.presles.fr https://g1.data.geragc.es') -}.toList(); -List<Node> defaultGvaNodes = <Node>{ - ..._readDotNodeConfig('GVA_NODES'), - ..._splitList( - 'https://g1.cuates.net/gva https://g1.madeirawonders.com/gva https://g1.brussels.ovh/gva https://g1.geragc.es/gva https://gva.seeds4c.org/gva') -}.toList(); - -// We test local duniter node in dev mode -/* List<Node> defaultGvaNodes = kReleaseMode - ? readDotNodeConfig('GVA_NODES') - : <Node>[const Node(url: 'http://localhost:30901/gva/')] - ..addAll(readDotNodeConfig('GVA_NODES')); -// List<Node> defaultGvaNodes = readDotNodeConfig('GVA_NODES'); - : <Node>[const Node(url: 'http://localhost:30901/gva/')] - ..addAll(readDotNodeConfig('GVA_NODES')); */ diff --git a/lib/data/models/node_list_cubit.dart b/lib/data/models/node_list_cubit.dart index b041ae2b..0511e35f 100644 --- a/lib/data/models/node_list_cubit.dart +++ b/lib/data/models/node_list_cubit.dart @@ -25,6 +25,10 @@ class NodeListCubit extends HydratedCubit<NodeListState> { emit(state.copyWith(duniterNodes: nodes)); } + void setDuniterIndexerNodes(List<Node> nodes) { + emit(state.copyWith(duniterIndexerNodes: nodes)); + } + void setCesiumPlusNodes(List<Node> nodes) { emit(state.copyWith(cesiumPlusNodes: nodes)); } @@ -33,12 +37,20 @@ class NodeListCubit extends HydratedCubit<NodeListState> { emit(state.copyWith(gvaNodes: nodes)); } + void setEndpointNodes(List<Node> nodes) { + emit(state.copyWith(endpointNodes: nodes)); + } + List<Node> get duniterNodes => state.duniterNodes; List<Node> get cesiumPlusNodes => state.cesiumPlusNodes; List<Node> get gvaNodes => state.gvaNodes; + List<Node> get endpointNodes => state.endpointNodes; + + List<Node> get duniterIndexerNodes => state.duniterIndexerNodes; + @override NodeListState? fromJson(Map<String, dynamic> json) => NodeListState.fromJson(json); @@ -53,6 +65,8 @@ class NodeListCubit extends HydratedCubit<NodeListState> { gvaNodes: state.gvaNodes, duniterNodes: state.duniterNodes, cesiumPlusNodes: state.cesiumPlusNodes, + endpointNodes: state.endpointNodes, + duniterIndexerNodes: state.duniterIndexerNodes, isLoading: state.isLoading)); } } diff --git a/lib/data/models/node_list_state.dart b/lib/data/models/node_list_state.dart index a948a771..4fb400fd 100644 --- a/lib/data/models/node_list_state.dart +++ b/lib/data/models/node_list_state.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:json_annotation/json_annotation.dart'; import 'node.dart'; +import 'node_lists_default.dart'; part 'node_list_state.g.dart'; @@ -15,25 +16,55 @@ class NodeListState extends Equatable { {List<Node>? duniterNodes, List<Node>? cesiumPlusNodes, List<Node>? gvaNodes, + List<Node>? endpointNodes, + List<Node>? duniterIndexerNodes, this.currentGvaNode, bool? isLoading}) : duniterNodes = duniterNodes ?? defaultDuniterNodes, cesiumPlusNodes = cesiumPlusNodes ?? defaultCesiumPlusNodes, gvaNodes = gvaNodes ?? defaultGvaNodes, + endpointNodes = endpointNodes ?? defaultEndPointNodes, + duniterIndexerNodes = duniterIndexerNodes ?? defaultDuniterIndexerNodes, isLoading = isLoading ?? false; factory NodeListState.fromJson(Map<String, dynamic> json) => _$NodeListStateFromJson(json); + @JsonKey(fromJson: _nodesFromJson, toJson: _nodesToJson) final List<Node> duniterNodes; + @JsonKey(fromJson: _nodesFromJson, toJson: _nodesToJson) final List<Node> cesiumPlusNodes; + @JsonKey(fromJson: _nodesFromJson, toJson: _nodesToJson) final List<Node> gvaNodes; + @JsonKey(fromJson: _nodesFromJson, toJson: _nodesToJson) + final List<Node> endpointNodes; + @JsonKey(fromJson: _nodesFromJson, toJson: _nodesToJson) + final List<Node> duniterIndexerNodes; final bool isLoading; + @JsonKey(fromJson: _nodeFromJson, toJson: _nodeToJson) final Node? currentGvaNode; @override - List<Object?> get props => - <Object>[duniterNodes, cesiumPlusNodes, gvaNodes, isLoading]; + List<Object?> get props => <Object>[ + duniterNodes, + cesiumPlusNodes, + gvaNodes, + endpointNodes, + duniterIndexerNodes, + isLoading + ]; Map<String, dynamic> toJson() => _$NodeListStateToJson(this); + + static Node? _nodeFromJson(Map<String, dynamic>? json) => + json != null ? Node.fromJson(json) : null; + + static Map<String, dynamic>? _nodeToJson(Node? node) => node?.toJson(); + + static List<Node> _nodesFromJson(List<dynamic> json) => json + .map((dynamic item) => Node.fromJson(item as Map<String, dynamic>)) + .toList(); + + static List<Map<String, dynamic>> _nodesToJson(List<Node> nodes) => + nodes.map((Node item) => item.toJson()).toList(); } diff --git a/lib/data/models/node_list_state.g.dart b/lib/data/models/node_list_state.g.dart index 475f26f0..a5de96b7 100644 --- a/lib/data/models/node_list_state.g.dart +++ b/lib/data/models/node_list_state.g.dart @@ -13,6 +13,10 @@ abstract class _$NodeListStateCWProxy { NodeListState gvaNodes(List<Node>? gvaNodes); + NodeListState endpointNodes(List<Node>? endpointNodes); + + NodeListState duniterIndexerNodes(List<Node>? duniterIndexerNodes); + NodeListState currentGvaNode(Node? currentGvaNode); NodeListState isLoading(bool? isLoading); @@ -27,6 +31,8 @@ abstract class _$NodeListStateCWProxy { List<Node>? duniterNodes, List<Node>? cesiumPlusNodes, List<Node>? gvaNodes, + List<Node>? endpointNodes, + List<Node>? duniterIndexerNodes, Node? currentGvaNode, bool? isLoading, }); @@ -49,6 +55,14 @@ class _$NodeListStateCWProxyImpl implements _$NodeListStateCWProxy { @override NodeListState gvaNodes(List<Node>? gvaNodes) => this(gvaNodes: gvaNodes); + @override + NodeListState endpointNodes(List<Node>? endpointNodes) => + this(endpointNodes: endpointNodes); + + @override + NodeListState duniterIndexerNodes(List<Node>? duniterIndexerNodes) => + this(duniterIndexerNodes: duniterIndexerNodes); + @override NodeListState currentGvaNode(Node? currentGvaNode) => this(currentGvaNode: currentGvaNode); @@ -68,6 +82,8 @@ class _$NodeListStateCWProxyImpl implements _$NodeListStateCWProxy { Object? duniterNodes = const $CopyWithPlaceholder(), Object? cesiumPlusNodes = const $CopyWithPlaceholder(), Object? gvaNodes = const $CopyWithPlaceholder(), + Object? endpointNodes = const $CopyWithPlaceholder(), + Object? duniterIndexerNodes = const $CopyWithPlaceholder(), Object? currentGvaNode = const $CopyWithPlaceholder(), Object? isLoading = const $CopyWithPlaceholder(), }) { @@ -84,6 +100,14 @@ class _$NodeListStateCWProxyImpl implements _$NodeListStateCWProxy { ? _value.gvaNodes // ignore: cast_nullable_to_non_nullable : gvaNodes as List<Node>?, + endpointNodes: endpointNodes == const $CopyWithPlaceholder() + ? _value.endpointNodes + // ignore: cast_nullable_to_non_nullable + : endpointNodes as List<Node>?, + duniterIndexerNodes: duniterIndexerNodes == const $CopyWithPlaceholder() + ? _value.duniterIndexerNodes + // ignore: cast_nullable_to_non_nullable + : duniterIndexerNodes as List<Node>?, currentGvaNode: currentGvaNode == const $CopyWithPlaceholder() ? _value.currentGvaNode // ignore: cast_nullable_to_non_nullable @@ -108,26 +132,27 @@ extension $NodeListStateCopyWith on NodeListState { NodeListState _$NodeListStateFromJson(Map<String, dynamic> json) => NodeListState( - duniterNodes: (json['duniterNodes'] as List<dynamic>?) - ?.map((e) => Node.fromJson(e as Map<String, dynamic>)) - .toList(), - cesiumPlusNodes: (json['cesiumPlusNodes'] as List<dynamic>?) - ?.map((e) => Node.fromJson(e as Map<String, dynamic>)) - .toList(), - gvaNodes: (json['gvaNodes'] as List<dynamic>?) - ?.map((e) => Node.fromJson(e as Map<String, dynamic>)) - .toList(), - currentGvaNode: json['currentGvaNode'] == null - ? null - : Node.fromJson(json['currentGvaNode'] as Map<String, dynamic>), + duniterNodes: NodeListState._nodesFromJson(json['duniterNodes'] as List), + cesiumPlusNodes: + NodeListState._nodesFromJson(json['cesiumPlusNodes'] as List), + gvaNodes: NodeListState._nodesFromJson(json['gvaNodes'] as List), + endpointNodes: + NodeListState._nodesFromJson(json['endpointNodes'] as List), + duniterIndexerNodes: + NodeListState._nodesFromJson(json['duniterIndexerNodes'] as List), + currentGvaNode: NodeListState._nodeFromJson( + json['currentGvaNode'] as Map<String, dynamic>?), isLoading: json['isLoading'] as bool?, ); Map<String, dynamic> _$NodeListStateToJson(NodeListState instance) => <String, dynamic>{ - 'duniterNodes': instance.duniterNodes, - 'cesiumPlusNodes': instance.cesiumPlusNodes, - 'gvaNodes': instance.gvaNodes, + 'duniterNodes': NodeListState._nodesToJson(instance.duniterNodes), + 'cesiumPlusNodes': NodeListState._nodesToJson(instance.cesiumPlusNodes), + 'gvaNodes': NodeListState._nodesToJson(instance.gvaNodes), + 'endpointNodes': NodeListState._nodesToJson(instance.endpointNodes), + 'duniterIndexerNodes': + NodeListState._nodesToJson(instance.duniterIndexerNodes), 'isLoading': instance.isLoading, - 'currentGvaNode': instance.currentGvaNode, + 'currentGvaNode': NodeListState._nodeToJson(instance.currentGvaNode), }; diff --git a/lib/data/models/node_lists_default.dart b/lib/data/models/node_lists_default.dart new file mode 100644 index 00000000..19357972 --- /dev/null +++ b/lib/data/models/node_lists_default.dart @@ -0,0 +1,45 @@ +import 'package:flutter/foundation.dart'; + +import '../../env.dart'; +import 'node.dart'; + +List<Node> _splitList(String list) => + list.split(' ').map((String url) => Node(url: url)).toList(); + +List<Node> _readDotNodeConfig(String entry) => _splitList(entry); + +List<Node> defaultDuniterNodes = <Node>{ + ..._readDotNodeConfig(Env.duniterNodes), + ..._splitList( + 'duniter.pini.fr duniter.g1.pfouque.xyz fania.g1server.net g1.brussels.ovh g1.cgeek.fr g1.computhings.be g1.cuates.net g1.geragc.es g1.madeirawonders.com g1.rendall.fr g1.trentesaux.fr gibraleon.g1server.net vit.fdn.org') +}.toList(); + +List<Node> defaultCesiumPlusNodes = <Node>{ + ..._readDotNodeConfig(Env.cesiumPlusNodes), + ..._splitList( + 'https://g1.data.brussels.ovh https://g1.data.e-is.pro https://g1.data.mithril.re https://g1.data.pini.fr https://g1.data.presles.fr https://g1.data.geragc.es') +}.toList(); +List<Node> defaultGvaNodes = <Node>{ + ..._readDotNodeConfig(Env.gvaNodes), + ..._splitList( + 'https://g1.cuates.net/gva https://g1.madeirawonders.com/gva https://g1.brussels.ovh/gva https://g1.geragc.es/gva https://gva.seeds4c.org/gva') +}.toList(); + +List<Node> defaultEndPointNodes = <Node>{ + // For doing tests of faulty nodes + if (kDebugMode) const Node(url: 'wss://just-testing-a-wrong-node.com/ws'), + ..._readDotNodeConfig(Env.endPoints), +}.toList(); + +List<Node> defaultDuniterIndexerNodes = <Node>{ + ..._readDotNodeConfig(Env.duniterIndexerNodes), +}.toList(); + +// We test local duniter node in dev mode +/* List<Node> defaultGvaNodes = kReleaseMode + ? readDotNodeConfig('GVA_NODES') + : <Node>[const Node(url: 'http://localhost:30901/gva/')] + ..addAll(readDotNodeConfig('GVA_NODES')); +// List<Node> defaultGvaNodes = readDotNodeConfig('GVA_NODES'); + : <Node>[const Node(url: 'http://localhost:30901/gva/')] + ..addAll(readDotNodeConfig('GVA_NODES')); */ diff --git a/lib/data/models/node_manager.dart b/lib/data/models/node_manager.dart index b8ef08b5..46d4974d 100644 --- a/lib/data/models/node_manager.dart +++ b/lib/data/models/node_manager.dart @@ -21,15 +21,21 @@ class NodeManager { final List<Node> duniterNodes = <Node>[]; final List<Node> cesiumPlusNodes = <Node>[]; final List<Node> gvaNodes = <Node>[]; + final List<Node> endpointNodes = <Node>[]; + final List<Node> duniterIndexerNodes = <Node>[]; void loadFromCubit(NodeListCubit cubit) { NodeManagerObserver.instance.cubit = cubit; duniterNodes.clear(); cesiumPlusNodes.clear(); gvaNodes.clear(); + endpointNodes.clear(); + duniterIndexerNodes.clear(); duniterNodes.addAll(cubit.duniterNodes); cesiumPlusNodes.addAll(cubit.cesiumPlusNodes); gvaNodes.addAll(cubit.gvaNodes); + endpointNodes.addAll(cubit.endpointNodes); + duniterIndexerNodes.addAll(cubit.duniterIndexerNodes); } void updateNodes(NodeType type, List<Node> newNodes, {bool notify = true}) { @@ -69,7 +75,11 @@ class NodeManager { ? duniterNodes : type == NodeType.cesiumPlus ? cesiumPlusNodes - : gvaNodes; + : type == NodeType.endpoint + ? endpointNodes + : type == NodeType.duniterIndexer + ? duniterIndexerNodes + : gvaNodes; void addNode(NodeType type, Node node, {bool notify = true}) { final List<Node> nodes = _getList(type); @@ -181,6 +191,8 @@ class NodeManagerObserver { cubit.setDuniterNodes(nodeManager.duniterNodes); cubit.setCesiumPlusNodes(nodeManager.cesiumPlusNodes); cubit.setGvaNodes(nodeManager.gvaNodes); + cubit.setEndpointNodes(nodeManager.endpointNodes); + cubit.setDuniterIndexerNodes(nodeManager.duniterIndexerNodes); } void setCurrentGvaNode(Node node) => cubit.setCurrentGvaNode(node); diff --git a/lib/data/models/node_type.dart b/lib/data/models/node_type.dart index c55a2a7c..acf6534a 100644 --- a/lib/data/models/node_type.dart +++ b/lib/data/models/node_type.dart @@ -1 +1 @@ -enum NodeType { duniter, cesiumPlus, gva } +enum NodeType { duniter, cesiumPlus, gva, endpoint, duniterIndexer } diff --git a/lib/ui/screens/node_list_page.dart b/lib/ui/screens/node_list_page.dart index 0a7a2d63..662bf513 100644 --- a/lib/ui/screens/node_list_page.dart +++ b/lib/ui/screens/node_list_page.dart @@ -23,6 +23,10 @@ class NodeListPage extends StatelessWidget { @override Widget build(BuildContext context) { final NodeListState state = context.watch<NodeListCubit>().state; + final List<Node> endPointNodes = + filterAndSortNodesByType(state.endpointNodes, NodeType.endpoint); + final List<Node> duniterIndexerNodes = filterAndSortNodesByType( + state.duniterIndexerNodes, NodeType.duniterIndexer); final List<Node> duniterNodes = filterAndSortNodesByType(state.duniterNodes, NodeType.duniter); final List<Node> cesiumPlusNodes = @@ -47,6 +51,18 @@ class NodeListPage extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ + const DebugNodeHeader(type: NodeType.endpoint), + if (endPointNodes.isNotEmpty) + NodeListWidget( + nodes: endPointNodes, + type: NodeType.endpoint, + currentBlock: endPointNodes[0].currentBlock), + const DebugNodeHeader(type: NodeType.duniterIndexer), + if (duniterIndexerNodes.isNotEmpty) + NodeListWidget( + nodes: duniterNodes, + type: NodeType.duniterIndexer, + currentBlock: duniterIndexerNodes[0].currentBlock), const DebugNodeHeader(type: NodeType.gva), if (gvaNodes.isNotEmpty) NodeListWidget( -- GitLab