diff --git a/config/indexer_endpoints.json b/config/indexer_endpoints.json index 9e8dc83..feb604e 100644 --- a/config/indexer_endpoints.json +++ b/config/indexer_endpoints.json @@ -1,4 +1,4 @@ [ - "https://duniter-indexer.coinduf.eu/v1/graphql", - "http://192.168.1.72:8080/v1/graphql" + "https://duniter-indexer.coinduf.eu", + "http://192.168.1.72:8080" ] diff --git a/lib/main.dart b/lib/main.dart index c56bff1..01d339c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -58,6 +58,7 @@ Future main() async { HomeProvider _homeProvider = HomeProvider(); DuniterIndexer _duniterIndexer = DuniterIndexer(); + await initHiveForFlutter(); await _homeProvider.initHive(); appVersion = await _homeProvider.getAppVersion(); prefs = await SharedPreferences.getInstance(); @@ -67,7 +68,6 @@ Future main() async { Hive.registerAdapter(ChestDataAdapter()); Hive.registerAdapter(G1WalletsListAdapter()); Hive.registerAdapter(IdAdapter()); - // Hive.registerAdapter(KeyStoreDataAdapter()); walletBox = await Hive.openBox("walletBox"); chestBox = await Hive.openBox("chestBox"); @@ -82,10 +82,7 @@ Future main() async { } // log.d(await configBox.get('endpoint')); - await _duniterIndexer.getValidIndexerEndpoint(); - // _duniterIndexer.indexerEndpoint = "http://192.168.1.72:8080/v1/graphql"; - // _duniterIndexer.indexerEndpoint = - // "https://duniter-indexer.coinduf.eu/v1/graphql"; + _duniterIndexer.getValidIndexerEndpoint(); HttpOverrides.global = MyHttpOverrides(); @@ -131,20 +128,11 @@ class Gecko extends StatelessWidget { @override Widget build(BuildContext context) { SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); - final _httpLink = HttpLink( - indexerEndpoint!, - ); - final _client = ValueNotifier( - GraphQLClient( - cache: GraphQLCache(), - link: _httpLink, - ), - ); + // To configure multi_endpoints GraphQLProvider: https://stackoverflow.com/q/70656513/8301867 return MultiProvider( providers: [ - // Provider(create: (context) => HistoryProvider()), ChangeNotifierProvider(create: (_) => HomeProvider()), ChangeNotifierProvider(create: (_) => WalletsProfilesProvider('')), ChangeNotifierProvider(create: (_) => MyWalletsProvider()), @@ -156,44 +144,41 @@ class Gecko extends StatelessWidget { ChangeNotifierProvider(create: (_) => SubstrateSdk()), ChangeNotifierProvider(create: (_) => DuniterIndexer()) ], - child: GraphQLProvider( - client: _client, - child: MaterialApp( - builder: (context, widget) => ResponsiveWrapper.builder( - BouncingScrollWrapper.builder(context, widget!), - maxWidth: 1200, - minWidth: 480, - defaultScale: true, - breakpoints: [ - const ResponsiveBreakpoint.resize(480, name: MOBILE), - const ResponsiveBreakpoint.autoScale(800, name: TABLET), - const ResponsiveBreakpoint.resize(1000, name: DESKTOP), - ], - background: Container(color: backgroundColor)), - title: 'Ğecko', - theme: ThemeData( - appBarTheme: const AppBarTheme( - color: Color(0xffFFD58D), - foregroundColor: Color(0xFF000000), - ), - primaryColor: const Color(0xffFFD58D), - textTheme: const TextTheme( - bodyText1: TextStyle(fontSize: 16), - bodyText2: TextStyle(fontSize: 18), - ).apply( - bodyColor: const Color(0xFF000000), - ), - colorScheme: - ColorScheme.fromSwatch().copyWith(secondary: Colors.grey[850]), + child: MaterialApp( + builder: (context, widget) => ResponsiveWrapper.builder( + BouncingScrollWrapper.builder(context, widget!), + maxWidth: 1200, + minWidth: 480, + defaultScale: true, + breakpoints: [ + const ResponsiveBreakpoint.resize(480, name: MOBILE), + const ResponsiveBreakpoint.autoScale(800, name: TABLET), + const ResponsiveBreakpoint.resize(1000, name: DESKTOP), + ], + background: Container(color: backgroundColor)), + title: 'Ğecko', + theme: ThemeData( + appBarTheme: const AppBarTheme( + color: Color(0xffFFD58D), + foregroundColor: Color(0xFF000000), ), - home: const HomeScreen(), - initialRoute: "/", - routes: { - '/mywallets': (context) => const WalletsHome(), - '/search': (context) => const SearchScreen(), - '/searchResult': (context) => const SearchResultScreen(), - }, + primaryColor: const Color(0xffFFD58D), + textTheme: const TextTheme( + bodyText1: TextStyle(fontSize: 16), + bodyText2: TextStyle(fontSize: 18), + ).apply( + bodyColor: const Color(0xFF000000), + ), + colorScheme: + ColorScheme.fromSwatch().copyWith(secondary: Colors.grey[850]), ), + home: const HomeScreen(), + initialRoute: "/", + routes: { + '/mywallets': (context) => const WalletsHome(), + '/search': (context) => const SearchScreen(), + '/searchResult': (context) => const SearchResultScreen(), + }, ), ); } diff --git a/lib/models/queries_indexer.dart b/lib/models/queries_indexer.dart index 5c75ba3..25483cb 100644 --- a/lib/models/queries_indexer.dart +++ b/lib/models/queries_indexer.dart @@ -52,19 +52,31 @@ query ($address: String!) { '''; const String getHistoryByAddressQ3 = r''' -query ($address: String!) { +query ($address: String!, $number: Int!, $cursor: String) { transaction_connection(where: {_or: [ {issuer_id: {_eq: $address}}, {receiver_id: {_eq: $address}} ]}, - order_by: {created_at: desc}) { + order_by: {created_at: desc}, + first: $number, + after: $cursor) { edges { node { amount created_at issuer_id receiver_id + issuer { + identity { + name + } + } + receiver { + identity { + name + } + } } } pageInfo { diff --git a/lib/providers/duniter_indexer.dart b/lib/providers/duniter_indexer.dart index 8d66b66..4a5a501 100644 --- a/lib/providers/duniter_indexer.dart +++ b/lib/providers/duniter_indexer.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; - import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; @@ -17,7 +16,11 @@ import 'package:provider/provider.dart'; class DuniterIndexer with ChangeNotifier { Map walletNameIndexer = {}; + String? fetchMoreCursor; Map? pageInfo; + int nPage = 1; + int nRepositories = 20; + List? transBC; void reload() { notifyListeners(); @@ -30,7 +33,8 @@ class DuniterIndexer with ChangeNotifier { final _client = HttpClient(); _client.connectionTimeout = const Duration(milliseconds: 1000); try { - final request = await _client.postUrl(Uri.parse(oldEndpoint)); + final request = + await _client.postUrl(Uri.parse('$oldEndpoint/v1/graphql')); final response = await request.close(); if (response.statusCode != 200) { log.d('INDEXER IS OFFILINE'); @@ -74,7 +78,8 @@ class DuniterIndexer with ChangeNotifier { } try { - final request = await _client.postUrl(Uri.parse(_listEndpoints[i])); + final request = + await _client.postUrl(Uri.parse('${_listEndpoints[i]}/v1/graphql')); final response = await request.close(); indexerEndpoint = _listEndpoints[i]; @@ -122,54 +127,67 @@ class DuniterIndexer with ChangeNotifier { } } } + final _httpLink = HttpLink( + '$indexerEndpoint/v1/graphql', + ); - return Query( - options: QueryOptions( - document: gql( - getNameByAddressQ), // this is the query string you just created - variables: { - 'address': address, - }, - // pollInterval: const Duration(seconds: 10), - ), - builder: (QueryResult result, - {VoidCallback? refetch, FetchMore? fetchMore}) { - if (result.hasException) { - return Text(result.exception.toString()); - } + final _client = ValueNotifier( + GraphQLClient( + cache: GraphQLCache(store: HiveStore()), + link: _httpLink, + ), + ); + return GraphQLProvider( + client: _client, + child: Query( + options: QueryOptions( + document: gql( + getNameByAddressQ), // this is the query string you just created + variables: { + 'address': address, + }, + // pollInterval: const Duration(seconds: 10), + ), + builder: (QueryResult result, + {VoidCallback? refetch, FetchMore? fetchMore}) { + if (result.hasException) { + return Text(result.exception.toString()); + } - if (result.isLoading) { - return const Text('Loading'); - } + if (result.isLoading) { + return const Text('Loading'); + } - walletNameIndexer[address] = - result.data?['account_by_pk']?['identity']?['name']; + walletNameIndexer[address] = + result.data?['account_by_pk']?['identity']?['name']; - if (walletNameIndexer[address] == null) { - if (wallet == null) { - return const SizedBox(); - } else { - if (canEdit) { - return _walletOptions.walletName(context, wallet, size, _color); + if (walletNameIndexer[address] == null) { + if (wallet == null) { + return const SizedBox(); } else { - return _walletOptions.walletNameController( - context, wallet, size); + if (canEdit) { + return _walletOptions.walletName( + context, wallet, size, _color); + } else { + return _walletOptions.walletNameController( + context, wallet, size); + } } } - } - return Text( - _color == Colors.grey[700]! - ? '(${walletNameIndexer[address]!})' - : walletNameIndexer[address]!, - style: TextStyle( - fontSize: size, - color: _color, - fontWeight: fontWeight, - fontStyle: fontStyle, - ), - ); - }); + return Text( + _color == Colors.grey[700]! + ? '(${walletNameIndexer[address]!})' + : walletNameIndexer[address]!, + style: TextStyle( + fontSize: size, + color: _color, + fontWeight: fontWeight, + fontStyle: fontStyle, + ), + ); + }), + ); } Widget searchIdentity(BuildContext context, String name) { @@ -183,85 +201,184 @@ class DuniterIndexer with ChangeNotifier { return const Text('Aucun résultat'); } - return Query( - options: QueryOptions( - document: gql( - searchAddressByNameQ), // this is the query string you just created - variables: { - 'name': name, - }, - // pollInterval: const Duration(seconds: 10), - ), - builder: (QueryResult result, - {VoidCallback? refetch, FetchMore? fetchMore}) { - if (result.hasException) { - return Text(result.exception.toString()); - } + final _httpLink = HttpLink( + '$indexerEndpoint/v1/graphql', + ); - if (result.isLoading) { - return const Text('Loading'); - } + final _client = ValueNotifier( + GraphQLClient( + cache: GraphQLCache(store: HiveStore()), + link: _httpLink, + ), + ); + return GraphQLProvider( + client: _client, + child: Query( + options: QueryOptions( + document: gql( + searchAddressByNameQ), // this is the query string you just created + variables: { + 'name': name, + }, + // pollInterval: const Duration(seconds: 10), + ), + builder: (QueryResult result, + {VoidCallback? refetch, FetchMore? fetchMore}) { + if (result.hasException) { + return Text(result.exception.toString()); + } - final List identities = result.data?['search_identity'] ?? []; + if (result.isLoading) { + return const Text('Loading'); + } - if (identities.isEmpty) { - return const Text('Aucun résultat'); - } + final List identities = result.data?['search_identity'] ?? []; - int keyID = 0; - double _avatarSize = 55; - return Expanded( - child: ListView(children: [ - for (Map profile in identities) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 5), - child: ListTile( - key: Key('searchResult${keyID++}'), - horizontalTitleGap: 40, - contentPadding: const EdgeInsets.all(5), - leading: _cesiumPlusProvider.defaultAvatar(_avatarSize), - title: Row(children: [ - Text(getShortPubkey(profile['id']), - style: const TextStyle( - fontSize: 18, - fontFamily: 'Monospace', - fontWeight: FontWeight.w500), - textAlign: TextAlign.center), - ]), - trailing: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [balance(context, profile['id'], 16)]), - subtitle: Row(children: [ - Text(profile['name'] ?? '', - style: const TextStyle( - fontSize: 18, fontWeight: FontWeight.w500), - textAlign: TextAlign.center), - ]), - dense: false, - isThreeLine: false, - onTap: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - _walletsProfiles.address = profile['id']; - return WalletViewScreen( - pubkey: profile['id'], - username: - g1WalletsBox.get(profile['id'])?.id?.username, - avatar: g1WalletsBox.get(profile['id'])?.avatar, - ); - }), - ); - }), - ), - ]), - ); - }); + if (identities.isEmpty) { + return const Text('Aucun résultat'); + } + + int keyID = 0; + double _avatarSize = 55; + return Expanded( + child: ListView(children: [ + for (Map profile in identities) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 5), + child: ListTile( + key: Key('searchResult${keyID++}'), + horizontalTitleGap: 40, + contentPadding: const EdgeInsets.all(5), + leading: _cesiumPlusProvider.defaultAvatar(_avatarSize), + title: Row(children: [ + Text(getShortPubkey(profile['id']), + style: const TextStyle( + fontSize: 18, + fontFamily: 'Monospace', + fontWeight: FontWeight.w500), + textAlign: TextAlign.center), + ]), + trailing: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [balance(context, profile['id'], 16)]), + subtitle: Row(children: [ + Text(profile['name'] ?? '', + style: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w500), + textAlign: TextAlign.center), + ]), + dense: false, + isThreeLine: false, + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + _walletsProfiles.address = profile['id']; + return WalletViewScreen( + pubkey: profile['id'], + username: g1WalletsBox + .get(profile['id']) + ?.id + ?.username, + avatar: g1WalletsBox.get(profile['id'])?.avatar, + ); + }), + ); + }), + ), + ]), + ); + }), + ); } + List parseHistory(blockchainTX, _pubkey) { + var transBC = []; + int i = 0; -checkHistoryResult(QueryResult result, FetchMoreOptions options, String address) { - -} + for (final trans in blockchainTX) { + final transaction = trans['node']; + final direction = + transaction['issuer_id'] != _pubkey ? 'RECEIVED' : 'SENT'; + transBC.add(i); + transBC[i] = []; + transBC[i].add(DateTime.parse(transaction['created_at'])); + final int amountBrut = transaction['amount']; + final num amount = removeDecimalZero(amountBrut / 100); + if (direction == "RECEIVED") { + transBC[i].add(transaction['issuer_id']); + transBC[i].add(transaction['issuer']['identity']?['name'] ?? ''); + transBC[i].add(amount.toString()); + } else if (direction == "SENT") { + transBC[i].add(transaction['receiver_id']); + transBC[i].add(transaction['receiver']['identity']?['name'] ?? ''); + transBC[i].add('- ' + amount.toString()); + } + // transBC[i].add(''); //transaction comment + + i++; + } + return transBC; + } + + FetchMoreOptions? checkQueryResult(result, opts, _pubkey) { + final List? blockchainTX = + (result.data['transaction_connection']['edges'] as List?); + // final List mempoolTX = + // (result.data['txsHistoryMp']['receiving'] as List); + + pageInfo = result.data['transaction_connection']['pageInfo']; + fetchMoreCursor = pageInfo!['endCursor']; + if (fetchMoreCursor == null) nPage = 1; + + log.d(fetchMoreCursor); + + if (nPage == 1) { + nRepositories = 40; + } else if (nPage == 2) { + nRepositories = 100; + } + // nRepositories = 10; + nPage++; + + if (fetchMoreCursor != null) { + opts = FetchMoreOptions( + variables: {'cursor': fetchMoreCursor, 'number': nRepositories}, + updateQuery: (previousResultData, fetchMoreResultData) { + final List repos = [ + ...previousResultData!['transaction_connection']['edges'] + as List, + ...fetchMoreResultData!['transaction_connection']['edges'] + as List + ]; + + log.d('repos: ' + previousResultData.toString()); + log.d('repos: ' + fetchMoreResultData.toString()); + log.d('repos: ' + repos.toString()); + + fetchMoreResultData['transaction_connection']['edges'] = repos; + return fetchMoreResultData; + }, + ); + } + + log.d( + "###### DEBUG H Parse blockchainTX list. Cursor: $fetchMoreCursor ######"); + if (fetchMoreCursor != null) { + transBC = parseHistory(blockchainTX, _pubkey); + } else { + log.i("###### DEBUG H - Début de l'historique"); + } + + return opts; + } + + num removeDecimalZero(double n) { + String result = n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 2); + return num.parse(result); + } + + // checkHistoryResult( + // QueryResult result, FetchMoreOptions options, String address) {} } diff --git a/lib/providers/wallet_options.dart b/lib/providers/wallet_options.dart index 2a6cc0b..a123809 100644 --- a/lib/providers/wallet_options.dart +++ b/lib/providers/wallet_options.dart @@ -577,7 +577,7 @@ Widget getCerts(BuildContext context, String address, double size, return FutureBuilder( future: _sdk.getCerts(address), builder: (BuildContext context, AsyncSnapshot> _certs) { - log.d(_certs.data); + // log.d(_certs.data); return _certs.data?[0] != 0 && _certs.data != null ? Row( diff --git a/lib/providers/wallets_profiles.dart b/lib/providers/wallets_profiles.dart index 267f364..731a9a9 100644 --- a/lib/providers/wallets_profiles.dart +++ b/lib/providers/wallets_profiles.dart @@ -1,32 +1,24 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; -import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/screens/wallet_view.dart'; -import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:jdenticon_dart/jdenticon_dart.dart'; import 'package:permission_handler/permission_handler.dart'; // import 'package:qrscan/qrscan.dart' as scanner; import 'package:barcode_scan2/barcode_scan2.dart'; -import 'dart:math'; -import 'package:intl/intl.dart'; class WalletsProfilesProvider with ChangeNotifier { WalletsProfilesProvider(this.address); String? address = ''; String pubkeyShort = ''; - List? transBC; - String? fetchMoreCursor; - Map? pageInfo; + bool isHistoryScreen = false; String historySwitchButtun = "Voir l'historique"; String? rawSvg; TextEditingController payAmount = TextEditingController(); TextEditingController payComment = TextEditingController(); num? balance; - int nRepositories = 20; - int nPage = 1; Future scan(context) async { if (Platform.isAndroid || Platform.isIOS) { @@ -97,117 +89,10 @@ class WalletsProfilesProvider with ChangeNotifier { // Matograine portefeuille: 9p5nHsES6xujFR7pw2yGy4PLKKHgWsMvsDHaHF64Uj25. // Lion simone: 78jhpprYkMNF6i5kQPXfkAVBpd2aqcpieNsXTSW4c21f - List parseHistory(txs, _pubkey) { - var transBC = []; - int i = 0; - - const currentBase = 0; - double currentUD = 10.54; - - for (final trans in txs) { - var direction = trans['direction']; - final transaction = trans['node']; - String? output; - if (direction == "RECEIVED") { - for (String line in transaction['outputs']) { - if (line.contains(_pubkey)) { - output = line; - } - } - } else { - output = transaction['outputs'][0]; - } - if (output == null) { - continue; - } - - transBC.add(i); - transBC[i] = []; - final dateBrut = DateTime.fromMillisecondsSinceEpoch( - transaction['writtenTime'] * 1000); - final DateFormat formatter = DateFormat('dd-MM-yy\nHH:mm'); - final date = formatter.format(dateBrut); - transBC[i].add(transaction['writtenTime']); - transBC[i].add(date); - final int amountBrut = int.parse(output.split(':')[0]); - final base = int.parse(output.split(':')[1]); - final int applyBase = base - currentBase; - final num amount = - removeDecimalZero(amountBrut * pow(10, applyBase) / 100); - num amountUD = amount / currentUD; - if (direction == "RECEIVED") { - transBC[i].add(transaction['issuers'][0]); - transBC[i].add(getShortPubkey(transaction['issuers'][0])); - transBC[i].add(amount.toString()); - transBC[i].add(amountUD.toStringAsFixed(2)); - } else if (direction == "SENT") { - final outPubkey = output.split("SIG(")[1].replaceAll(')', ''); - transBC[i].add(outPubkey); - transBC[i].add(getShortPubkey(outPubkey)); - transBC[i].add('- ' + amount.toString()); - transBC[i].add(amountUD.toStringAsFixed(2)); - } - transBC[i].add(transaction['comment']); - - i++; - } - return transBC; - } - - FetchMoreOptions? checkQueryResult(result, opts, _pubkey) { - final List? blockchainTX = - (result.data['txsHistoryBc']['both']['edges'] as List?); - // final List mempoolTX = - // (result.data['txsHistoryMp']['receiving'] as List); - - pageInfo = result.data['txsHistoryBc']['both']['pageInfo']; - fetchMoreCursor = pageInfo!['endCursor']; - if (fetchMoreCursor == null) nPage = 1; - - if (nPage == 1) { - nRepositories = 40; - } else if (nPage == 2) { - nRepositories = 100; - } - nPage++; - - if (fetchMoreCursor != null) { - opts = FetchMoreOptions( - variables: {'cursor': fetchMoreCursor, 'number': nRepositories}, - updateQuery: (previousResultData, fetchMoreResultData) { - final List repos = [ - ...previousResultData!['txsHistoryBc']['both']['edges'] - as List, - ...fetchMoreResultData!['txsHistoryBc']['both']['edges'] - as List - ]; - - fetchMoreResultData['txsHistoryBc']['both']['edges'] = repos; - return fetchMoreResultData; - }, - ); - } - - log.d( - "###### DEBUG H Parse blockchainTX list. Cursor: $fetchMoreCursor ######"); - if (fetchMoreCursor != null) { - transBC = parseHistory(blockchainTX, _pubkey); - } else { - log.i("###### DEBUG H - Début de l'historique"); - } - - return opts; - } - void resetdHistory() { notifyListeners(); } - num removeDecimalZero(double n) { - String result = n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 2); - return num.parse(result); - } - String generateIdenticon(String _pubkey) { return Jdenticon.toSvg(_pubkey); } diff --git a/lib/screens/activity.dart b/lib/screens/activity.dart index 714195a..27cb32d 100644 --- a/lib/screens/activity.dart +++ b/lib/screens/activity.dart @@ -51,84 +51,109 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier { DuniterIndexer _duniterIndexer = Provider.of(context, listen: false); - return Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Query( - options: QueryOptions( - document: gql(getHistoryByAddressQ3), - variables: { - 'address': address, - }, - ), - builder: (QueryResult result, {fetchMore, refetch}) { - log.d(result.data); - if (result.isLoading && result.data == null) { - return const Center( - child: CircularProgressIndicator(), - ); - } + if (indexerEndpoint == '') { + Column(children: const [ + SizedBox(height: 50), + Text( + "L'état du réseau ne permet pas\nd'afficher l'historique du compte", + textAlign: TextAlign.center, + style: TextStyle(fontSize: 18), + ) + ]); + } - if (result.hasException) { - log.e('Error Indexer: ' + result.exception.toString()); - return Column(children: const [ - SizedBox(height: 50), - Text( - "L'état du réseau ne permet pas\nd'afficher l'historique du compte", - textAlign: TextAlign.center, - style: TextStyle(fontSize: 18), - ) - ]); - } else if (result.data == null) { - return Column(children: const [ - SizedBox(height: 50), - Text( - "Aucune donnée à afficher.", - style: TextStyle(fontSize: 18), - ) - ]); - } + final _httpLink = HttpLink( + '$indexerEndpoint/v1beta1/relay', + ); - if (result.isNotLoading) { - // log.d(result.data); - opts = - _duniterIndexer.checkHistoryResult(result, opts!, address!); - } + final _client = ValueNotifier( + GraphQLClient( + cache: GraphQLCache(), + link: _httpLink, + ), + ); - // Build history list - return NotificationListener( - child: Builder( - builder: (context) => Expanded( - child: ListView( - key: const Key('listTransactions'), - controller: scrollController, - children: [historyView(context, result)], + return GraphQLProvider( + client: _client, + child: Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Query( + options: QueryOptions( + document: gql(getHistoryByAddressQ3), + variables: { + 'address': address, + 'number': 20, + 'cursor': null + }, + ), + builder: (QueryResult result, {fetchMore, refetch}) { + if (result.isLoading && result.data == null) { + return const Center( + child: CircularProgressIndicator(), + ); + } + + if (result.hasException) { + log.e('Error Indexer: ' + result.exception.toString()); + return Column(children: const [ + SizedBox(height: 50), + Text( + "L'état du réseau ne permet pas\nd'afficher l'historique du compte", + textAlign: TextAlign.center, + style: TextStyle(fontSize: 18), + ) + ]); + } else if (result.data == null) { + return Column(children: const [ + SizedBox(height: 50), + Text( + "Aucune donnée à afficher.", + style: TextStyle(fontSize: 18), + ) + ]); + } + + if (result.isNotLoading) { + // log.d(result.data); + opts = _duniterIndexer.checkQueryResult(result, opts, address!); + } + + // Build history list + return NotificationListener( + child: Builder( + builder: (context) => Expanded( + child: ListView( + key: const Key('listTransactions'), + controller: scrollController, + children: [historyView(context, result)], + ), ), ), - ), - onNotification: (dynamic t) { - if (t is ScrollEndNotification && - scrollController.position.pixels >= - scrollController.position.maxScrollExtent * 0.7 && - _duniterIndexer.pageInfo!['hasPreviousPage'] && - result.isNotLoading) { - fetchMore!(opts!); - } - return true; - }); - }, - ), - ], - )); + onNotification: (dynamic t) { + if (t is ScrollEndNotification && + scrollController.position.pixels >= + scrollController.position.maxScrollExtent * 0.7 && + _duniterIndexer.pageInfo!['hasNextPage'] && + result.isNotLoading) { + fetchMore!(opts!); + } + return true; + }); + }, + ), + ], + )), + ); } Widget historyView(context, result) { - WalletsProfilesProvider _historyProvider = - Provider.of(context, listen: false); + DuniterIndexer _duniterIndexer = + Provider.of(context, listen: false); - return _historyProvider.transBC == null + return _duniterIndexer.transBC == null ? Column(children: const [ SizedBox(height: 50), Text( @@ -137,16 +162,16 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier { ) ]) : Column(children: [ - getTransactionTile(context, _historyProvider), + getTransactionTile(context, _duniterIndexer), if (result.isLoading && - _historyProvider.pageInfo!['hasPreviousPage']) + _duniterIndexer.pageInfo!['hasPreviousPage']) Row( mainAxisAlignment: MainAxisAlignment.center, children: const [ CircularProgressIndicator(), ], ), - if (!_historyProvider.pageInfo!['hasPreviousPage']) + if (!_duniterIndexer.pageInfo!['hasNextPage']) Column( children: const [ SizedBox(height: 15), @@ -160,7 +185,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier { } Widget getTransactionTile( - BuildContext context, WalletsProfilesProvider _historyProvider) { + BuildContext context, DuniterIndexer _duniterIndexer) { CesiumPlusProvider _cesiumPlusProvider = Provider.of(context, listen: false); int keyID = 0; @@ -188,9 +213,11 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier { }; return Column( - children: _historyProvider.transBC!.map((repository) { + children: _duniterIndexer.transBC!.map((repository) { + // log.d('bbbbbbbbbbbbbbbbbbbbbb: ' + repository.toString()); + DateTime now = DateTime.now(); - DateTime date = DateTime.fromMillisecondsSinceEpoch(repository[0] * 1000); + DateTime date = repository[0]; String dateForm; if ({4, 10, 11, 12}.contains(date.month)) { @@ -257,52 +284,12 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier { key: Key('transaction${keyID++}'), contentPadding: const EdgeInsets.only( left: 20, right: 30, top: 15, bottom: 15), - leading: g1WalletsBox.get(repository[2])?.avatar == null - ? FutureBuilder( - future: _cesiumPlusProvider.getAvatar( - repository[2], _avatarSize), - builder: (BuildContext context, - AsyncSnapshot _avatar) { - if (_avatar.connectionState != - ConnectionState.done || - _avatar.hasError) { - return Stack(children: [ - _cesiumPlusProvider.defaultAvatar(_avatarSize), - Positioned( - top: 8, - right: 0, - width: 12, - height: 12, - child: CircularProgressIndicator( - strokeWidth: 1, - color: orangeC, - ), - ), - ]); - } - if (_avatar.hasData) { - g1WalletsBox.get(repository[2])?.avatar = - _avatar.data; - return ClipOval(child: _avatar.data); - } else { - g1WalletsBox.get(repository[2])?.avatar = - _cesiumPlusProvider - .defaultAvatar(repository[2]); - return _cesiumPlusProvider - .defaultAvatar(_avatarSize); - } - }) - : ClipOval( - child: Image( - image: - g1WalletsBox.get(repository[2])!.avatar!.image, - height: _avatarSize, - ), - ), + leading: ClipOval( + child: _cesiumPlusProvider.defaultAvatar(_avatarSize), + ), title: Padding( - padding: EdgeInsets.only( - bottom: 5, top: repository[6] != '' ? 0 : 0), - child: Text(repository[3], + padding: const EdgeInsets.only(bottom: 5), + child: Text(getShortPubkey(repository[1]), style: const TextStyle( fontSize: 18, fontFamily: 'Monospace')), ), @@ -316,7 +303,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier { TextSpan( text: dateForm, ), - if (repository[6] != '') + if (repository[2] != '') TextSpan( text: ' · ', style: TextStyle( @@ -325,7 +312,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier { ), ), TextSpan( - text: repository[6], + text: repository[2], style: TextStyle( fontStyle: FontStyle.italic, color: Colors.grey[600], @@ -334,19 +321,19 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier { ], ), ), - trailing: Text("${repository[4]} $currencyName", + trailing: Text("${repository[3]} $currencyName", style: const TextStyle( fontSize: 18, fontWeight: FontWeight.w500), textAlign: TextAlign.justify), dense: false, isThreeLine: false, onTap: () { - _historyProvider.nPage = 1; + _duniterIndexer.nPage = 1; // _cesiumPlusProvider.avatarCancelToken.cancel('cancelled'); Navigator.push( context, MaterialPageRoute(builder: (context) { - return WalletViewScreen(pubkey: repository[2]); + return WalletViewScreen(pubkey: repository[1]); }), ); // Navigator.pop(context); diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index 9644306..e2ac1c4 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -8,6 +8,7 @@ import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/wallets_profiles.dart'; +import 'package:gecko/screens/activity.dart'; import 'package:gecko/screens/avatar_fullscreen.dart'; import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/myWallets/choose_wallet.dart'; @@ -88,8 +89,7 @@ class WalletViewScreen extends StatelessWidget { height: buttonSize, child: ClipOval( child: Material( - color: Colors - .grey[300], //const Color(0xffFFD58D), // button color + color: yellowC, //const Color(0xffFFD58D), // button color child: InkWell( key: const Key('viewHistory'), splashColor: orangeC, // inkwell color @@ -100,20 +100,16 @@ class WalletViewScreen extends StatelessWidget { 'assets/walletOptions/clock.png'), height: 90)), onTap: () { - //// Wait for subsquid indexer // _historyProvider.nPage = 1; - // Navigator.push( - // context, - // FaderTransition( - // page: HistoryScreen( - // pubkey: pubkey, - // username: username ?? - // g1WalletsBox.get(pubkey)?.username, - // avatar: avatar ?? - // g1WalletsBox.get(pubkey)?.avatar, - // ), - // isFast: false), - // ); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return ActivityScreen( + address: pubkey, + avatar: + _cesiumPlusProvider.defaultAvatar(50)); + }), + ); }), ), ),