diff --git a/config/indexer_endpoints.json b/config/indexer_endpoints.json index 062ed8e..66f30c3 100644 --- a/config/indexer_endpoints.json +++ b/config/indexer_endpoints.json @@ -1,6 +1,5 @@ [ - "https://gdev-indexer.p2p.legal", - "https://hasura.gdev.coinduf.eu", - "https://gdev-hasura.cgeek.fr", - "https://hasura-gdev.pini.fr" + "gdev-indexer.p2p.legal", + "gdev-hasura.cgeek.fr", + "hasura-gdev.pini.fr" ] diff --git a/lib/globals.dart b/lib/globals.dart index 7621851..3ca2db8 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -29,7 +29,7 @@ const cesiumPod = "https://g1.data.le-sou.org"; // String cesiumPod = "https://g1.data.presles.fr"; // String cesiumPod = "https://g1.data.e-is.pro"; -const datapodEndpoint = 'https://gdev-datapod.p2p.legal'; +const datapodEndpoint = 'gdev-datapod.p2p.legal'; // const v2sDatapod = 'http://10.0.2.2:8080'; // Contexts diff --git a/lib/providers/duniter_indexer.dart b/lib/providers/duniter_indexer.dart index f979250..8fff32f 100644 --- a/lib/providers/duniter_indexer.dart +++ b/lib/providers/duniter_indexer.dart @@ -16,6 +16,7 @@ class DuniterIndexer with ChangeNotifier { bool isLoadingIndexer = false; bool hasNextPage = false; Future?> Function()? refetch; + late GraphQLClient indexerClient; void reload() { notifyListeners(); @@ -27,10 +28,11 @@ class DuniterIndexer with ChangeNotifier { final client = HttpClient(); client.connectionTimeout = const Duration(milliseconds: 4000); try { - final request = await client.postUrl(Uri.parse('$endpoint/v1/graphql')); + final request = + await client.postUrl(Uri.parse('https://$endpoint/v1/graphql')); final response = await request.close(); if (response.statusCode != 200) { - log.w('INDEXER IS OFFLINE'); + log.w('Indexer $endpoint is offline'); indexerEndpoint = ''; isLoadingIndexer = false; notifyListeners(); @@ -46,7 +48,7 @@ class DuniterIndexer with ChangeNotifier { return true; } } catch (e) { - log.w('INDEXER IS OFFLINE'); + log.w('Indexer $endpoint is offline'); indexerEndpoint = ''; isLoadingIndexer = false; notifyListeners(); @@ -96,7 +98,7 @@ class DuniterIndexer with ChangeNotifier { } try { - final endpointPath = '${listIndexerEndpoints[i]}/v1/graphql'; + final endpointPath = 'https://${listIndexerEndpoints[i]}/v1/graphql'; final request = await client.postUrl(Uri.parse(endpointPath)); final response = await request.close(); @@ -217,42 +219,24 @@ class DuniterIndexer with ChangeNotifier { Future _execQuery( String query, Map variables) async { - final httpLink = HttpLink( - '$indexerEndpoint/v1/graphql', - ); - - final client = GraphQLClient( - cache: GraphQLCache(), - link: httpLink, - ); - final options = QueryOptions(document: gql(query), variables: variables); // 5GMyvKsTNk9wDBy9jwKaX6mhSzmFFtpdK9KNnmrLoSTSuJHv - return await client.query(options); + return await indexerClient.query(options); } Stream subscribeHistoryIssued(String address) { - final wsLink = WebSocketLink( - '${indexerEndpoint.replaceFirst('https', 'wss')}/v1/graphql', - ); - final variables = { 'address': address, }; - final client = GraphQLClient( - cache: GraphQLCache(), - link: wsLink, - ); - final options = SubscriptionOptions( document: gql(subscribeHistoryIssuedQ), variables: variables, ); - return client.subscribe(options); + return indexerClient.subscribe(options); } Map computeHistoryView(repository, String address) { diff --git a/lib/providers/v2s_datapod.dart b/lib/providers/v2s_datapod.dart index 7d17621..5b1d906 100644 --- a/lib/providers/v2s_datapod.dart +++ b/lib/providers/v2s_datapod.dart @@ -11,19 +11,14 @@ import 'package:provider/provider.dart'; import 'package:uuid/uuid.dart'; class V2sDatapodProvider with ChangeNotifier { + late GraphQLClient datapodClient; + Future _execQuery( String query, Map variables) async { - final httpLink = HttpLink('$datapodEndpoint/v1/graphql'); - - final GraphQLClient client = GraphQLClient( - cache: GraphQLCache(), - link: httpLink, - ); - final QueryOptions options = QueryOptions(document: gql(query), variables: variables); - return await client.query(options); + return await datapodClient.query(options); } Future updateProfile( @@ -174,34 +169,21 @@ class V2sDatapodProvider with ChangeNotifier { } Future cacheAvatar(String address, String data) async { - final file = File('${avatarsCacheDirectory.path}/$address'); - return await file.writeAsBytes(base64.decode(data)); + final uuid = const Uuid().v4(); + final tempFile = File('${avatarsCacheDirectory.path}/$uuid$address'); + final targetFile = File('${avatarsCacheDirectory.path}/$address'); + + try { + // Write to a temporary file first to prevent data race + await tempFile.writeAsBytes(base64.decode(data)); + log.d('Caching avatar of $address'); + return await tempFile.rename(targetFile.path); + } catch (e) { + log.e("An error occurred while caching avatar: $e"); + rethrow; + } } - // Future cacheAvatar(String address, String data) async { - // // Get the list of all files in the directory - // final dir = Directory(avatarsCacheDirectory.path); - // var filesList = dir.listSync().whereType().toList(); - - // // Sorting files by modified date, oldest first - // filesList - // .sort((a, b) => a.lastModifiedSync().compareTo(b.lastModifiedSync())); - - // // If there are more than 20 files, remove the oldest ones - // while (filesList.length > 20) { - // filesList.first.deleteSync(); - // filesList.removeAt(0); - // } - - // // Write the new avatar file - // final file = File('${avatarsCacheDirectory.path}/$address'); - // await file.writeAsBytes(base64.decode(data)); - - // log.d('cache files: ${filesList.length}'); - - // return file; - // } - Image getAvatarLocal(String address) { final avatarFile = File('${avatarsCacheDirectory.path}/$address'); return Image.file( diff --git a/lib/screens/home.dart b/lib/screens/home.dart index acbd6ba..318be44 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -20,6 +20,7 @@ import 'package:gecko/screens/myWallets/restore_chest.dart'; import 'package:gecko/screens/onBoarding/1.dart'; import 'package:gecko/widgets/drawer.dart'; import 'package:gecko/widgets/buttons/home_buttons.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:provider/provider.dart'; @@ -76,7 +77,25 @@ class _HomeScreenState extends State { homeProvider.isWalletBoxInit = true; myWalletProvider.reload(); - duniterIndexer.getValidIndexerEndpoint(); + duniterIndexer.getValidIndexerEndpoint().then((validIndexerEndpoint) { + final wsLinkIndexer = WebSocketLink( + 'wss://$validIndexerEndpoint/v1/graphql', + ); + + final wsLinkDatapod = WebSocketLink( + 'wss://$datapodEndpoint/v1/graphql', + ); + + duniterIndexer.indexerClient = GraphQLClient( + cache: GraphQLCache(), + link: wsLinkIndexer, + ); + + datapod.datapodClient = GraphQLClient( + cache: GraphQLCache(), + link: wsLinkDatapod, + ); + }); await homeProvider.getValidEndpoints(); if (configBox.get('isCacheChecked') == null) { @@ -101,7 +120,6 @@ class _HomeScreenState extends State { } }); } - // _duniterIndexer.checkIndexerEndpointBackground(); }); super.initState(); } diff --git a/lib/screens/myWallets/wallet_options.dart b/lib/screens/myWallets/wallet_options.dart index 4308caa..08ac398 100644 --- a/lib/screens/myWallets/wallet_options.dart +++ b/lib/screens/myWallets/wallet_options.dart @@ -86,7 +86,7 @@ class WalletOptions extends StatelessWidget { ? duniterIndexer .walletNameIndexer[walletOptions.address.text]! : wallet.name!, - style: scaledTextStyle(fontSize: 18), + style: scaledTextStyle(fontSize: 19), ); }), actions: [ diff --git a/lib/widgets/certs_list.dart b/lib/widgets/certs_list.dart index 12f1fe4..40cb4fd 100644 --- a/lib/widgets/certs_list.dart +++ b/lib/widgets/certs_list.dart @@ -4,8 +4,10 @@ import 'package:gecko/globals.dart'; import 'package:gecko/models/queries_indexer.dart'; import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; +import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/widgets/cert_tile.dart'; import 'package:graphql_flutter/graphql_flutter.dart'; +import 'package:provider/provider.dart'; class CertsList extends StatelessWidget { const CertsList( @@ -18,14 +20,11 @@ class CertsList extends StatelessWidget { @override Widget build(BuildContext context) { + final indexerProvider = Provider.of(context, listen: false); final screenHeight = MediaQuery.of(context).size.height; final appBarHeight = AppBar().preferredSize.height; final windowHeight = screenHeight - appBarHeight - (isTall ? 170 : 140); - final httpLink = HttpLink( - '$indexerEndpoint/v1/graphql', - ); - late String gertCertsReq; late String certFrom; @@ -37,14 +36,8 @@ class CertsList extends StatelessWidget { certFrom = 'receiver'; } - final client = ValueNotifier( - GraphQLClient( - cache: GraphQLCache(store: HiveStore()), - link: httpLink, - ), - ); return GraphQLProvider( - client: client, + client: ValueNotifier(indexerProvider.indexerClient), child: Query( options: QueryOptions( document: gql(gertCertsReq), @@ -53,7 +46,7 @@ class CertsList extends StatelessWidget { }, ), builder: (QueryResult result, {fetchMore, refetch}) { - if (result.isLoading && result.data == null) { + if (result.isLoading || result.data == null) { return const Center( child: CircularProgressIndicator(), ); diff --git a/lib/widgets/datapod_avatar.dart b/lib/widgets/datapod_avatar.dart index cab71d8..7bf86fa 100644 --- a/lib/widgets/datapod_avatar.dart +++ b/lib/widgets/datapod_avatar.dart @@ -30,21 +30,10 @@ class DatapodAvatar extends StatelessWidget { ); } - final httpLink = HttpLink( - '$datapodEndpoint/v1/graphql', - ); - - final client = ValueNotifier( - GraphQLClient( - cache: GraphQLCache(), - link: httpLink, - ), - ); - return ScaledSizedBox( width: size, child: GraphQLProvider( - client: client, + client: ValueNotifier(datapod.datapodClient), child: Query( options: QueryOptions( document: gql(getAvatarQ), @@ -53,7 +42,7 @@ class DatapodAvatar extends StatelessWidget { }, ), builder: (QueryResult result, {fetchMore, refetch}) { - if (result.isLoading) { + if (result.isLoading || result.data == null) { return Center( child: ClipOval(child: datapod.defaultAvatar(size)), ); diff --git a/lib/widgets/history_query.dart b/lib/widgets/history_query.dart index 3820e10..2b0812c 100644 --- a/lib/widgets/history_query.dart +++ b/lib/widgets/history_query.dart @@ -36,19 +36,8 @@ class HistoryQuery extends StatelessWidget { ]); } - final httpLink = HttpLink( - '$indexerEndpoint/v1/graphql', - ); - - final client = ValueNotifier( - GraphQLClient( - cache: GraphQLCache(), - link: httpLink, - ), - ); - return GraphQLProvider( - client: client, + client: ValueNotifier(duniterIndexer.indexerClient), child: Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.start, diff --git a/lib/widgets/history_view.dart b/lib/widgets/history_view.dart index 4594d8c..6483e34 100644 --- a/lib/widgets/history_view.dart +++ b/lib/widgets/history_view.dart @@ -54,7 +54,8 @@ class HistoryView extends StatelessWidget { return Column(children: [ if (isMigrationTime) Padding( - padding: EdgeInsets.symmetric(vertical: scaleSize(23)), + padding: EdgeInsets.only( + top: scaleSize(25), bottom: scaleSize(15)), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ @@ -64,9 +65,9 @@ class HistoryView extends StatelessWidget { Text( 'blockchainStart'.tr(), style: scaledTextStyle( - fontSize: 19, + fontSize: 20, color: Colors.blueAccent, - fontWeight: FontWeight.w500), + fontWeight: FontWeight.w400), ), Image( image: const AssetImage('assets/party.png'), @@ -83,7 +84,7 @@ class HistoryView extends StatelessWidget { child: Text( answer['dateDelimiter'], style: scaledTextStyle( - fontSize: 19, + fontSize: 20, color: orangeC, fontWeight: FontWeight.w300), ), @@ -131,7 +132,7 @@ class HistoryView extends StatelessWidget { Text( 'identityMigrated'.tr(), style: scaledTextStyle( - fontSize: 19, + fontSize: 20, color: Colors.green[700], fontWeight: FontWeight.w500), ), @@ -155,10 +156,18 @@ class HistoryView extends StatelessWidget { Column( children: [ ScaledSizedBox(height: 15), - Text("historyStart".tr(), - textAlign: TextAlign.center, - style: scaledTextStyle(fontSize: 20)), - ScaledSizedBox(height: 15) + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Icon(Icons.blur_on_outlined, size: scaleSize(31)), + Text("historyStart".tr(), + textAlign: TextAlign.center, + style: scaledTextStyle( + fontSize: 20, fontWeight: FontWeight.w300)), + Icon(Icons.blur_on_outlined, size: scaleSize(31)), + ], + ), + ScaledSizedBox(height: 30) ], ) ]); diff --git a/lib/widgets/name_by_address.dart b/lib/widgets/name_by_address.dart index 763c225..2817fe9 100644 --- a/lib/widgets/name_by_address.dart +++ b/lib/widgets/name_by_address.dart @@ -6,6 +6,7 @@ import 'package:gecko/models/queries_indexer.dart'; import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/duniter_indexer.dart'; +import 'package:gecko/widgets/commons/loading.dart'; import 'package:gecko/widgets/wallet_name.dart'; import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:provider/provider.dart'; @@ -34,22 +35,8 @@ class NameByAddress extends StatelessWidget { return WalletName(wallet: wallet, size: size, color: color); } - // if (g1WalletsBox.get(wallet.address)?.username != null) { - // return Text(g1WalletsBox.get(wallet.address)!.username!); - // } - - final httpLink = HttpLink( - '$indexerEndpoint/v1/graphql', - ); - - final client = ValueNotifier( - GraphQLClient( - cache: GraphQLCache(store: HiveStore()), - link: httpLink, - ), - ); return GraphQLProvider( - client: client, + client: ValueNotifier(duniterIndexer.indexerClient), child: Query( options: QueryOptions( document: gql(getNameByAddressQ), @@ -66,7 +53,7 @@ class NameByAddress extends StatelessWidget { } if (result.isLoading) { - return const Text('Loading'); + return const Loading(); } duniterIndexer.walletNameIndexer[wallet.address] = diff --git a/lib/widgets/search_identity_query.dart b/lib/widgets/search_identity_query.dart index 0f0c893..1d912cf 100644 --- a/lib/widgets/search_identity_query.dart +++ b/lib/widgets/search_identity_query.dart @@ -29,19 +29,8 @@ class SearchIdentityQuery extends StatelessWidget { return Text('noResult'.tr()); } - final httpLink = HttpLink( - '$indexerEndpoint/v1/graphql', - ); - - final client = ValueNotifier( - GraphQLClient( - cache: GraphQLCache( - store: HiveStore()), - link: httpLink, - ), - ); return GraphQLProvider( - client: client, + client: ValueNotifier(duniterIndexer.indexerClient), child: Query( options: QueryOptions( document: gql(searchAddressByNameQ), diff --git a/lib/widgets/transaction_in_progress_tile.dart b/lib/widgets/transaction_in_progress_tile.dart index 4bd1560..4331f84 100644 --- a/lib/widgets/transaction_in_progress_tile.dart +++ b/lib/widgets/transaction_in_progress_tile.dart @@ -108,7 +108,7 @@ class _TransactionInProgressTuleState extends State { Text( 'Transaction en cours', style: scaledTextStyle( - fontSize: 19, + fontSize: 20, color: Colors.blueAccent, fontWeight: FontWeight.w400), ), diff --git a/pubspec.yaml b/pubspec.yaml index d5712c7..bbb7a2d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ description: Pay with G1. # pub.dev using `pub publish`. This is preferred for private packages. publish_to: "none" # Remove this line if you wish to publish to pub.dev -version: 0.1.3+64 +version: 0.1.4+65 environment: sdk: ">=2.12.0 <3.0.0"