diff --git a/lib/globals.dart b/lib/globals.dart index 70cd2ae8ae2890d91149a9de387419bf4dc5f104..46b89cbb7c9d3477504eb43b2d4f4c48b3c20346 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/g1_wallets_list.dart'; +import 'package:gecko/models/g1_wallets_list_live.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:hive/hive.dart'; import 'package:logger/logger.dart'; @@ -18,6 +19,7 @@ Box<WalletData> walletBox; Box<ChestData> chestBox; Box configBox; Box<G1WalletsList> g1WalletsBox; +Box<G1WalletsListLive> g1WalletsBoxLive; String cesiumPod = "https://g1.data.le-sou.org"; // String cesiumPod = "https://g1.data.e-is.pro"; diff --git a/lib/main.dart b/lib/main.dart index b187bfb9dfa74fed506e8525cd46c08ce53edfbd..15f9dcfcf7306d7a8252dc0505e1f770a8a1a946 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -24,6 +24,7 @@ import 'package:gecko/models/change_pin.dart'; import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_provider.dart'; import 'package:gecko/models/g1_wallets_list.dart'; +import 'package:gecko/models/g1_wallets_list_live.dart'; import 'package:gecko/models/generate_wallets.dart'; import 'package:gecko/models/history.dart'; import 'package:gecko/models/home.dart'; @@ -61,10 +62,19 @@ Future<void> main() async { Hive.registerAdapter(ChestDataAdapter()); Hive.registerAdapter(G1WalletsListAdapter()); Hive.registerAdapter(IdAdapter()); + Hive.registerAdapter(G1WalletsListLiveAdapter()); + Hive.registerAdapter(DataAdapter()); + Hive.registerAdapter(WalletsAdapter()); + Hive.registerAdapter(EdgesAdapter()); + Hive.registerAdapter(NodeAdapter()); + Hive.registerAdapter(BalanceAdapter()); + Hive.registerAdapter(IdtyAdapter()); + Hive.registerAdapter(PageInfoAdapter()); walletBox = await Hive.openBox<WalletData>("walletBox"); chestBox = await Hive.openBox<ChestData>("chestBox"); configBox = await Hive.openBox("configBox"); g1WalletsBox = await Hive.openBox<G1WalletsList>("g1WalletsBox"); + g1WalletsBoxLive = await Hive.openBox<G1WalletsListLive>("g1WalletsBoxLive"); // final HiveStore _store = // await HiveStore.open(path: '${appPath.path}/gqlCache'); diff --git a/lib/models/cesium_plus.dart b/lib/models/cesium_plus.dart index 8d73d005d88be993e18930081c483c687304036c..4d2835d3fc75d1d94d3949079476a9f6a71d7865 100644 --- a/lib/models/cesium_plus.dart +++ b/lib/models/cesium_plus.dart @@ -8,7 +8,6 @@ import 'package:path_provider/path_provider.dart'; class CesiumPlusProvider with ChangeNotifier { TextEditingController cesiumName = TextEditingController(); - int iAvatar = 0; bool isComplete = false; Future<List> _buildQuery(_pubkey) async { @@ -95,9 +94,8 @@ class CesiumPlusProvider with ChangeNotifier { responseJson['hits']['hits'][0]['_source']['avatar']['_content']; var avatarFile = - File('${(await getTemporaryDirectory()).path}/avatar$iAvatar.png'); + File('${(await getTemporaryDirectory()).path}/avatar_$_pubkey.png'); await avatarFile.writeAsBytes(base64.decode(_avatar)); - iAvatar++; isComplete = true; return [avatarFile]; diff --git a/lib/models/g1_wallets_list_live.dart b/lib/models/g1_wallets_list_live.dart new file mode 100644 index 0000000000000000000000000000000000000000..2eab83079755e6e2a3267c8aee0ae6dccc16cb3f --- /dev/null +++ b/lib/models/g1_wallets_list_live.dart @@ -0,0 +1,179 @@ +import 'package:hive_flutter/hive_flutter.dart'; +part 'g1_wallets_list_live.g.dart'; + +@HiveType(typeId: 4) +class G1WalletsListLive { + @HiveField(0) + Data data; + + G1WalletsListLive({this.data}); + + G1WalletsListLive.fromJson(Map<String, dynamic> json) { + data = json['data'] != null ? Data.fromJson(json['data']) : null; + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = <String, dynamic>{}; + if (this.data != null) { + data['data'] = this.data.toJson(); + } + return data; + } +} + +@HiveType(typeId: 5) +class Data { + Wallets wallets; + + Data({this.wallets}); + + Data.fromJson(Map<String, dynamic> json) { + wallets = + json['wallets'] != null ? Wallets.fromJson(json['wallets']) : null; + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = <String, dynamic>{}; + if (wallets != null) { + data['wallets'] = wallets.toJson(); + } + return data; + } +} + +@HiveType(typeId: 6) +class Wallets { + List<Edges> edges; + PageInfo pageInfo; + + Wallets({this.edges, this.pageInfo}); + + Wallets.fromJson(Map<String, dynamic> json) { + if (json['edges'] != null) { + edges = <Edges>[]; + json['edges'].forEach((v) { + edges.add(Edges.fromJson(v)); + }); + } + pageInfo = + json['pageInfo'] != null ? PageInfo.fromJson(json['pageInfo']) : null; + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = <String, dynamic>{}; + if (edges != null) { + data['edges'] = edges.map((v) => v.toJson()).toList(); + } + if (pageInfo != null) { + data['pageInfo'] = pageInfo.toJson(); + } + return data; + } +} + +@HiveType(typeId: 7) +class Edges { + Node node; + + Edges({this.node}); + + Edges.fromJson(Map<String, dynamic> json) { + node = json['node'] != null ? Node.fromJson(json['node']) : null; + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = <String, dynamic>{}; + if (node != null) { + data['node'] = node.toJson(); + } + return data; + } +} + +@HiveType(typeId: 8) +class Node { + Balance balance; + Idty idty; + String script; + + Node({this.balance, this.idty, this.script}); + + Node.fromJson(Map<String, dynamic> json) { + balance = + json['balance'] != null ? Balance.fromJson(json['balance']) : null; + idty = json['idty'] != null ? Idty.fromJson(json['idty']) : null; + script = json['script']; + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = <String, dynamic>{}; + if (balance != null) { + data['balance'] = balance.toJson(); + } + if (idty != null) { + data['idty'] = idty.toJson(); + } + data['script'] = script; + return data; + } +} + +@HiveType(typeId: 9) +class Balance { + int amount; + int base; + + Balance({this.amount, this.base}); + + Balance.fromJson(Map<String, dynamic> json) { + amount = json['amount']; + base = json['base']; + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = <String, dynamic>{}; + data['amount'] = amount; + data['base'] = base; + return data; + } +} + +@HiveType(typeId: 10) +class Idty { + bool isMember; + String username; + + Idty({this.isMember, this.username}); + + Idty.fromJson(Map<String, dynamic> json) { + isMember = json['isMember']; + username = json['username']; + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = <String, dynamic>{}; + data['isMember'] = isMember; + data['username'] = username; + return data; + } +} + +@HiveType(typeId: 11) +class PageInfo { + String endCursor; + bool hasNextPage; + + PageInfo({this.endCursor, this.hasNextPage}); + + PageInfo.fromJson(Map<String, dynamic> json) { + endCursor = json['endCursor']; + hasNextPage = json['hasNextPage']; + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = <String, dynamic>{}; + data['endCursor'] = endCursor; + data['hasNextPage'] = hasNextPage; + return data; + } +} diff --git a/lib/models/g1_wallets_list_live.g.dart b/lib/models/g1_wallets_list_live.g.dart new file mode 100644 index 0000000000000000000000000000000000000000..a48669c897bd601d4b19300125145b888109b8c2 --- /dev/null +++ b/lib/models/g1_wallets_list_live.g.dart @@ -0,0 +1,216 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'g1_wallets_list_live.dart'; + +// ************************************************************************** +// TypeAdapterGenerator +// ************************************************************************** + +class G1WalletsListLiveAdapter extends TypeAdapter<G1WalletsListLive> { + @override + final int typeId = 4; + + @override + G1WalletsListLive read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = <int, dynamic>{ + for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), + }; + return G1WalletsListLive( + data: fields[0] as Data, + ); + } + + @override + void write(BinaryWriter writer, G1WalletsListLive obj) { + writer + ..writeByte(1) + ..writeByte(0) + ..write(obj.data); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is G1WalletsListLiveAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} + +class DataAdapter extends TypeAdapter<Data> { + @override + final int typeId = 5; + + @override + Data read(BinaryReader reader) { + return Data(); + } + + @override + void write(BinaryWriter writer, Data obj) { + writer.writeByte(0); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is DataAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} + +class WalletsAdapter extends TypeAdapter<Wallets> { + @override + final int typeId = 6; + + @override + Wallets read(BinaryReader reader) { + return Wallets(); + } + + @override + void write(BinaryWriter writer, Wallets obj) { + writer.writeByte(0); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is WalletsAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} + +class EdgesAdapter extends TypeAdapter<Edges> { + @override + final int typeId = 7; + + @override + Edges read(BinaryReader reader) { + return Edges(); + } + + @override + void write(BinaryWriter writer, Edges obj) { + writer.writeByte(0); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is EdgesAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} + +class NodeAdapter extends TypeAdapter<Node> { + @override + final int typeId = 8; + + @override + Node read(BinaryReader reader) { + return Node(); + } + + @override + void write(BinaryWriter writer, Node obj) { + writer.writeByte(0); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is NodeAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} + +class BalanceAdapter extends TypeAdapter<Balance> { + @override + final int typeId = 9; + + @override + Balance read(BinaryReader reader) { + return Balance(); + } + + @override + void write(BinaryWriter writer, Balance obj) { + writer.writeByte(0); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is BalanceAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} + +class IdtyAdapter extends TypeAdapter<Idty> { + @override + final int typeId = 10; + + @override + Idty read(BinaryReader reader) { + return Idty(); + } + + @override + void write(BinaryWriter writer, Idty obj) { + writer.writeByte(0); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is IdtyAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} + +class PageInfoAdapter extends TypeAdapter<PageInfo> { + @override + final int typeId = 11; + + @override + PageInfo read(BinaryReader reader) { + return PageInfo(); + } + + @override + void write(BinaryWriter writer, PageInfo obj) { + writer.writeByte(0); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is PageInfoAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} diff --git a/lib/models/search.dart b/lib/models/search.dart index ef31a6e139e7dba572e53d8be09fa5093b29329c..8b7a484d2e9082e303ebd2543f369ef53934f129 100644 --- a/lib/models/search.dart +++ b/lib/models/search.dart @@ -3,12 +3,13 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/g1_wallets_list.dart'; +import 'package:gecko/models/g1_wallets_list_live.dart'; import 'package:http/http.dart' as http; class SearchProvider with ChangeNotifier { TextEditingController searchController = TextEditingController(); List searchResult = []; - final cacheDuring = 60 * 60 * 1000; //First number is minutes + final cacheDuring = 0 * 60 * 1000; //First number is minutes int cacheTime = 0; void rebuildWidget() { @@ -20,15 +21,13 @@ class SearchProvider with ChangeNotifier { int searchTime = DateTime.now().millisecondsSinceEpoch; if (cacheTime + cacheDuring <= searchTime) { - var url = Uri.parse('https://g1-stats.axiom-team.fr/data/forbes.json'); - var response = await http.get(url); - // print('Response body: ${response.body}'); - List<G1WalletsList> _listWallets = - await compute(_parseG1Wallets, response.body); - - for (G1WalletsList element in _listWallets) { - await g1WalletsBox.put(element.pubkey, element); - } + g1WalletsBox.clear(); + final url = Uri.parse('https://g1-stats.axiom-team.fr/data/forbes.json'); + final response = await http.get(url); + + List<G1WalletsList> _listWallets = _parseG1Wallets(response.body); + + await g1WalletsBox.addAll(_listWallets); cacheTime = DateTime.now().millisecondsSinceEpoch; } @@ -43,12 +42,45 @@ class SearchProvider with ChangeNotifier { }); return searchResult; + } + + Future<List> searchBlockchainLive() async { + searchResult.clear(); + int searchTime = DateTime.now().millisecondsSinceEpoch; + + if (cacheTime + cacheDuring <= searchTime) { + g1WalletsBox.clear(); + final url = Uri.parse( + 'https://g1.librelois.fr/gva?query={%20wallets(pagination:%20{%20ord:%20ASC,%20pageSize:%20999%20})%20{%20pageInfo%20{%20hasNextPage%20endCursor%20}%20edges%20{%20node%20{%20script%20balance%20{%20amount%20base%20}%20idty%20{%20isMember%20username%20}%20}%20}%20}%20}'); + final response = await http.get(url); + // log.d(response.body); + + G1WalletsListLive _jsonResponse = + G1WalletsListLive.fromJson(json.decode(response.body)); - // notifyListeners(); + while (_jsonResponse.data.wallets.pageInfo.hasNextPage) { + var cursor = _jsonResponse.data.wallets.pageInfo.endCursor; + final url = Uri.parse( + 'https://g1.librelois.fr/gva?query={%20wallets(pagination:%20{%20ord:%20ASC,%20pageSize:%20999%20})%20{%20pageInfo%20{%20hasNextPage%20endCursor%20}%20edges%20{%20node%20{%20script%20balance%20{%20amount%20base%20}%20idty%20{%20isMember%20username%20}%20}%20}%20}%20}'); + final response = await http.get(url); + } + + await configBox.put('g1WalletCache', _jsonResponse); + cacheTime = DateTime.now().millisecondsSinceEpoch; + } + + for (var value in configBox.get('g1WalletCache').data.wallets.edges) { + if ((value.node.idty != null && + value.node.idty.username != null && + value.node.idty.username.contains(searchController.text)) || + value.node.script.contains(searchController.text)) { + searchResult.add(value); + } + } - // log.i(g1WalletsBox - // .get('1N18iwCfzLYd7u6DTKafVrzs9bPyeYTGHoc5SsLMcfv') - // .balance); + // log.d(configBox.get('g1WalletCache').data.wallets.edges.toString()); + + return searchResult; } } diff --git a/lib/screens/history.dart b/lib/screens/history.dart index a47c6f7f9425a2b361dc260a73fdf6d5f05aed4f..57d275fb987e37dc096772845616a1e0db9506d8 100644 --- a/lib/screens/history.dart +++ b/lib/screens/history.dart @@ -23,7 +23,6 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier { // HistoryProvider _historyProvider; final _formKey = GlobalKey<FormState>(); final FocusNode _pubkeyFocus = FocusNode(); - List cesiumData; final double avatarsSize = 80; FetchMore fetchMore; @@ -199,7 +198,6 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier { ], builder: (BuildContext context, AsyncSnapshot<List> _avatar) { - cesiumData = _avatar.data; // _cesiumPlusProvider.isComplete = true; if (_avatar.connectionState != ConnectionState.done) { @@ -447,6 +445,7 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier { onTap: () { // this._outputPubkey.text = repository[2]; _historyProvider.isPubkey(context, repository[2]); + Navigator.pop(context); }), ), if (result.isLoading) diff --git a/lib/screens/search_result.dart b/lib/screens/search_result.dart index 8971fdfb549f51465a68194289f6c889c1422ac7..0be63ad35b75834e9f575434dc7948996658c857 100644 --- a/lib/screens/search_result.dart +++ b/lib/screens/search_result.dart @@ -1,5 +1,4 @@ import 'dart:io'; - import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; @@ -66,9 +65,10 @@ class SearchResultScreen extends StatelessWidget { ), const SizedBox(height: 20), FutureBuilder( - future: _searchProvider.searchBlockchain(), - initialData: const [], - builder: (context, snapshot) { + future: _searchProvider.searchBlockchain(), + // initialData: const [], + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { return Expanded( child: ListView(children: <Widget>[ for (G1WalletsList g1Wallet in snapshot.data) @@ -129,7 +129,17 @@ class SearchResultScreen extends StatelessWidget { ), ]), ); - }), + } + return Center( + heightFactor: 5, + child: CircularProgressIndicator( + strokeWidth: 3, + backgroundColor: yellowC, + color: orangeC, + ), + ); + }, + ), // Text( // _searchProvider.searchResult.toString(), // ) diff --git a/pubspec.lock b/pubspec.lock index 49c04fe7f4f05580795277d43d1a4d55e53d6bd5..68af98aab2e7dfe9f994b98eb198527b8108ee0a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -544,6 +544,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.4.1" + infinite_scroll_pagination: + dependency: "direct main" + description: + name: infinite_scroll_pagination + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" integration_test: dependency: "direct dev" description: flutter @@ -1002,6 +1009,13 @@ packages: description: flutter source: sdk version: "0.0.99" + sliver_tools: + dependency: transitive + description: + name: sliver_tools + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.5" source_gen: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index ff1e3c0160c7d82bc89dc868153496e8fac4cca8..38f918447e84ebefa478d97f22b3175827f81c65 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.0.3+5 +version: 0.0.3+6 environment: sdk: ">=2.7.0 <3.0.0" @@ -57,6 +57,7 @@ dependencies: carousel_slider: ^4.0.0 flutter_lints: ^1.0.4 confirm_dialog: ^1.0.0 + infinite_scroll_pagination: ^3.1.0 flutter_icons: android: "ic_launcher"