From 1bcfa738ccca3754b2b3754dab39479d4a9bfaac Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 21 Dec 2020 03:59:25 +0100 Subject: [PATCH] better --- lib/api.dart | 53 ++++++ lib/data/respository.dart | 36 ---- lib/home.dart | 323 ++++++++++++++++++-------------- lib/main.dart | 16 +- lib/query.dart | 45 +++++ lib/ui/history_list_item.dart | 1 - lib/ui/history_list_screen.dart | 1 - lib/ui/history_list_view.dart | 1 - pubspec.lock | 159 ++++++++++++++++ pubspec.yaml | 3 +- 10 files changed, 460 insertions(+), 178 deletions(-) delete mode 100644 lib/data/respository.dart create mode 100644 lib/query.dart delete mode 100644 lib/ui/history_list_item.dart delete mode 100644 lib/ui/history_list_screen.dart delete mode 100644 lib/ui/history_list_view.dart diff --git a/lib/api.dart b/lib/api.dart index 8a3676d..d50b0f2 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -4,6 +4,7 @@ import 'package:gql/language.dart' as gqlLang; import 'package:gql_dio_link/gql_dio_link.dart'; import 'package:gql_exec/gql_exec.dart'; import "package:gql_link/gql_link.dart"; +import 'package:intl/intl.dart'; // Configure node const graphqlEndpoint = "https://g1.librelois.fr/gva"; @@ -245,3 +246,55 @@ Future getHistory(String pubkey) async { // print(trans); return [transBC, transMP]; } + +// NEW WAY // + +List parseHistory(txs) { + // print(blockchainTX[0]['node']['comment']); + + var transBC = []; + int i = 0; + + final currentBase = 0; + double currentUD = 10.54; + + for (final trans in txs) { + var direction = trans['direction']; + + print(trans); + final transaction = trans['node']; + var output = transaction['outputs'][0]; + + print("DEBUG1 " + transaction['writtenTime'].toString()); + transBC.add(i); + transBC[i] = []; + final dateBrut = + DateTime.fromMillisecondsSinceEpoch(transaction['writtenTime'] * 1000); + final DateFormat formatter = DateFormat('dd-MM-yy - H:M'); + final date = formatter.format(dateBrut); + transBC[i].add(transaction['writtenTime']); + transBC[i].add(date); + var amountBrut = int.parse(output.split(':')[0]); + final base = int.parse(output.split(':')[1]); + final applyBase = base - currentBase; + final amount = amountBrut * pow(10, applyBase) / 100; + var amountUD = amount / currentUD; + if (direction == "RECEIVED") { + transBC[i].add(transaction['issuers'][0]); + transBC[i].add(amount); + transBC[i].add(amountUD.toStringAsFixed(2)); + } else if (direction == "SENT") { + final outPubkey = output.split("SIG(")[1].replaceAll(')', ''); + transBC[i].add(outPubkey); + transBC[i].add(-amount); + transBC[i].add(amountUD.toStringAsFixed(2)); + } + transBC[i].add(transaction['comment']); + + i++; + } + + transBC.sort((b, a) => Comparable.compare(a[0], b[0])); + + return transBC; +} diff --git a/lib/data/respository.dart b/lib/data/respository.dart deleted file mode 100644 index cbc5273..0000000 --- a/lib/data/respository.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:readwenderlich/data/stores/in_memory_store.dart'; -import 'package:readwenderlich/data/stores/remote/remote_store.dart'; -import 'package:readwenderlich/entities/article.dart'; -import 'package:readwenderlich/entities/article_category.dart'; -import 'package:readwenderlich/entities/article_difficulty.dart'; -import 'package:readwenderlich/entities/article_platform.dart'; -import 'package:readwenderlich/entities/list_page.dart'; -import 'package:readwenderlich/entities/sort_method.dart'; - -/// Gets data from both [RemoteStore] and [InMemoryStore]. -class Repository { - const Repository({ - @required this.remoteStore, - @required this.inMemoryStore, - }) : assert(remoteStore != null), - assert(inMemoryStore != null); - final RemoteStore remoteStore; - final InMemoryStore inMemoryStore; - - Future> getArticleListPage({ - int number, - int size, - List filteredPlatformIds, - List filteredCategoryIds, - List filteredDifficulties, - SortMethod sortMethod, - }) => - remoteStore.getArticleListPage( - number: number, - size: size, - filteredPlatformIds: filteredPlatformIds, - filteredCategoryIds: filteredCategoryIds, - filteredDifficulties: filteredDifficulties, - sortMethod: sortMethod, - ); \ No newline at end of file diff --git a/lib/home.dart b/lib/home.dart index 8f34a47..4bc3854 100644 --- a/lib/home.dart +++ b/lib/home.dart @@ -4,10 +4,10 @@ import 'dart:typed_data'; import 'dart:ui'; import 'package:permission_handler/permission_handler.dart'; import 'package:qrscan/qrscan.dart' as scanner; -import 'package:intl/intl.dart'; import 'api.dart'; import "package:dio/dio.dart"; -import 'ui/history_list_view.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; +import 'query.dart'; /// Integrates a list of articles with [ListPreferencesScreen]. class HistoryListScreen extends StatefulWidget { @@ -15,7 +15,6 @@ class HistoryListScreen extends StatefulWidget { _HistoryListScreenState createState() => _HistoryListScreenState(); } - // class HistoryListScreen extends StatefulWidget { // // GeckoHome({Key key, this.title}) : super(key: key); // // final String title; @@ -37,14 +36,15 @@ class _HistoryListScreenState extends State { Uint8List bytes = Uint8List(0); TextEditingController _outputPubkey; TextEditingController _outputBalance; - TextEditingController _outputHistory; + final nRepositories = 20; + var pubkey = ''; + ScrollController _scrollController = new ScrollController(); @override initState() { super.initState(); this._outputPubkey = new TextEditingController(); this._outputBalance = new TextEditingController(); - this._outputHistory = new TextEditingController(); // checkNode().then((result) { // setState(() { // _result = result; @@ -54,10 +54,14 @@ class _HistoryListScreenState extends State { @override Widget build(BuildContext context) { + // final pubkey = 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU'; + + // var pubkey = ''; + print('Build state : ' + pubkey); return MaterialApp( home: Scaffold( backgroundColor: Colors.grey[300], - body: SafeArea( + body: Container( child: Column( children: [ SizedBox(height: 20), @@ -65,6 +69,7 @@ class _HistoryListScreenState extends State { // enabled: false, onChanged: (text) { print("Clé tappé: $text"); + // pubkey = text; isPubkey(text); }, controller: this._outputPubkey, @@ -103,9 +108,164 @@ class _HistoryListScreenState extends State { ), style: TextStyle(fontSize: 30.0, color: Colors.black)), Expanded( - child: HistoryListView( - repository: Provider.of(context) - )) + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Query( + options: QueryOptions( + documentNode: gql(getMyRepositories), + variables: { + 'pubkey': pubkey, // this._outputPubkey, + 'number': nRepositories, + // set cursor to null so as to start at the beginning + // 'cursor': 10 + }, + ), + builder: (QueryResult result, + {refetch, FetchMore fetchMore}) { + if (result.loading && result.data == null) { + return const Center( + child: CircularProgressIndicator(), + ); + } + + if (result.hasException) { + return Text( + '\nErrors: \n ' + result.exception.toString()); + } + + if (result.data == null && + result.exception.toString() == null) { + return const Text( + 'Both data and errors are null, this is a known bug after refactoring, you might forget to set Github token'); + } + + final List blockchainTX = + (result.data['txsHistoryBc']['both']['edges'] + as List); + + // final List mempoolTX = + // (result.data['txsHistoryBc']['both']['edges'] + // as List); + + final Map pageInfo = + result.data['txsHistoryBc']['both']['pageInfo']; + final String fetchMoreCursor = pageInfo['endCursor']; + + FetchMoreOptions opts = FetchMoreOptions( + variables: {'cursor': fetchMoreCursor}, + updateQuery: + (previousResultData, fetchMoreResultData) { + // this is where you combine your previous data and response + // in this case, we want to display previous repos plus next repos + // so, we combine data in both into a single list of repos + final List repos = [ + ...previousResultData['txsHistoryBc']['both'] + ['edges'] as List, + ...fetchMoreResultData['txsHistoryBc']['both'] + ['edges'] as List + ]; + + fetchMoreResultData['txsHistoryBc']['both'] + ['edges'] = repos; + + return fetchMoreResultData; + }, + ); + + _scrollController + ..addListener(() { + if (_scrollController.position.pixels == + _scrollController.position.maxScrollExtent) { + if (!result.loading) { + fetchMore(opts); + } + } + }); + + List transBC = parseHistory(blockchainTX); + // parseHistory(mempoolTX); + + return Expanded( + child: ListView( + controller: _scrollController, + children: [ + for (var repository in transBC) + Card( + // 1 + elevation: 2.0, + // 2 + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(3.0)), + // 3 + child: Padding( + padding: const EdgeInsets.all(8.0), + // 4 + child: Column( + children: [ + SizedBox( + height: 8.0, + ), + Text( + // Date + repository[1].toString(), + style: TextStyle( + fontSize: 12.0, + fontWeight: FontWeight.w300, + ), + ), + Text( + // Issuer + repository[2], + style: TextStyle( + fontSize: 13.0, + fontWeight: FontWeight.w500, + ), + ), + Text( + // Amount + repository[3].toString(), + style: TextStyle( + fontSize: 15.0, + fontWeight: FontWeight.w500, + ), + ), + // Text( + // // amountUD + // repository[4].toString(), + // style: TextStyle( + // fontSize: 12.0, + // fontWeight: FontWeight.w500, + // ), + // ), + Text( + // Comment + repository[5].toString(), + style: TextStyle( + fontSize: 12.0, + fontWeight: FontWeight.w400, + ), + ), + ], + ), + ), + ), + if (result.loading) + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CircularProgressIndicator(), + ], + ), + ], + ), + ); + }, + ), + ], + )), ], ), ), @@ -126,43 +286,6 @@ class _HistoryListScreenState extends State { ))); } - Widget buildTranscationCard(Transaction transaction) { - return Card( - // 1 - elevation: 2.0, - // 2 - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)), - // 3 - child: Padding( - padding: const EdgeInsets.all(16.0), - // 4 - child: Column( - children: [ - // 5 - SizedBox( - height: 14.0, - ), - // 6 - Text( - transaction.pubkey, - style: TextStyle( - fontSize: 20.0, - fontWeight: FontWeight.w700, - fontFamily: "Palatino", - ), - ), - Text(transaction.date, - style: TextStyle( - fontSize: 20.0, - fontWeight: FontWeight.w700, - fontFamily: "Palatino", - )) - ], - ), - ), - ); - } - Future checkNode() async { final response = await Dio().post(graphqlEndpoint); showHistory(response); @@ -179,7 +302,7 @@ class _HistoryListScreenState extends State { return barcode; } - Future isPubkey(pubkey) async { + String isPubkey(pubkey) { // final validCharacters = RegExp(r'^[a-zA-Z0-9]+$'); RegExp regExp = new RegExp( r'^[a-zA-Z0-9]+$', @@ -191,9 +314,24 @@ class _HistoryListScreenState extends State { pubkey.length > 42 && pubkey.length < 45) { print("C'est une pubkey !!!"); - print(pubkey.length); showHistory(pubkey); + + setState(({pubkey = 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU'}) { + pubkey = 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU'; + }); + + // return pubkey; + + // print(pubkey); + // setState(({pubkey = 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU'}) { + // pubkey = pubkey; + // print('setState : ' + pubkey); + // }); + } else { + // return ''; } + + return ''; } Future showHistory(pubkey) async { @@ -203,7 +341,6 @@ class _HistoryListScreenState extends State { } else { this._outputPubkey.text = ""; this._outputBalance.text = ""; - this._outputHistory.text = ""; // final udValue = await getUD(); this._outputPubkey.text = pubkey; final myBalance = await getBalance(pubkey.toString()); @@ -222,91 +359,3 @@ class _HistoryListScreenState extends State { // } } - -class Transaction { - String pubkey; - String date; - - Transaction(this.pubkey, this.date); - - // TODO: Build this list !!!! - // static List samples = List getHistory(pubkey.toString()); - - Future buildHistory() async { - final myHistory = await getHistory(pubkey.toString()); - if (myHistory == false) { - return false; - } - - String historyBC = ""; - for (var i in myHistory[0]) { - var dateBrut = i[0]; - dateBrut = DateTime.fromMillisecondsSinceEpoch(dateBrut * 1000); - final DateFormat formatter = DateFormat('dd-MM-yy - H:M'); - final String date = formatter.format(dateBrut); - final issuer = i[1]; - final amount = i[2]; - // final amountUD = i[3]; - final comment = i[4]; - historyBC += date.toString() + - " \n " + - issuer.toString() + - " \n " + - amount.toString() + - " Ğ1\n " + - comment.toString() + - "\n---\n"; - } - - String historyMP = ""; - for (var i in myHistory[1]) { - if (i == null) { - break; - } - var dateBrut = "Now"; - final issuer = i[1]; - final amount = i[2]; - // final amountUD = i[3]; - final comment = i[4]; - historyMP += dateBrut.toString() + - " \n " + - issuer.toString() + - " \n " + - amount.toString() + - " Ğ1\n " + - comment.toString() + - "\n------------------\n"; - } - - var history; - // print(historyMP.toString()); - if (historyMP == "") { - history = historyBC; - } else { - history = "EN COURS DE TRAITEMENT\n" + historyMP + "VALIDÉ\n" + historyBC; - } - // this._outputHistory.text = history; - - List samples = List - - return myHistory[0]; - } - - // static List samples = buildHistory(); - - var list = json - .decode(response.body)['results'] - .map((data) => Model.fromJson(data)) - .toList(); - - // static List samples = [ - // Transaction( - // "Spaghetti and Meatballs", - // "assets/2126711929_ef763de2b3_w.jpg", - // ), - // Transaction( - // "Tomato Soup", - // "assets/27729023535_a57606c1be.jpg", - // ) - // ]; -} diff --git a/lib/main.dart b/lib/main.dart index c7b2839..997531e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; // import 'package:image_gallery_saver/image_gallery_saver.dart'; // import 'package:flutter_html_view'; import 'home.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; void main() { runApp(Gecko()); @@ -11,10 +12,23 @@ void main() { class Gecko extends StatelessWidget { @override Widget build(BuildContext context) { + final _httpLink = HttpLink( + uri: 'https://g1.librelois.fr/gva', + ); + + final _client = ValueNotifier( + GraphQLClient( + cache: InMemoryCache(), + link: _httpLink, + ), + ); return MaterialApp( title: 'Ğecko', theme: ThemeData(primaryColor: Colors.white, accentColor: Colors.black), - home: HistoryListScreen(), + home: GraphQLProvider( + client: _client, + child: HistoryListScreen(), + ), ); } } diff --git a/lib/query.dart b/lib/query.dart new file mode 100644 index 0000000..22b63df --- /dev/null +++ b/lib/query.dart @@ -0,0 +1,45 @@ +const String getMyRepositories = r''' + query ($pubkey: String!, $number: Int!) { + txsHistoryBc( + pubkeyOrScript: $pubkey + pagination: { pageSize: $number, ord: DESC } + ) { + both { + pageInfo { + hasPreviousPage + hasNextPage + } + edges { + direction + node { + currency + issuers + outputs + comment + writtenTime + } + } + } + } + txsHistoryMp(pubkey: $pubkey) { + receiving { + currency + issuers + comment + outputs + writtenTime + } + sending { + currency + issuers + comment + outputs + writtenTime + } + } + currentUd { + amount + base + } + } + '''; diff --git a/lib/ui/history_list_item.dart b/lib/ui/history_list_item.dart deleted file mode 100644 index 8b13789..0000000 --- a/lib/ui/history_list_item.dart +++ /dev/null @@ -1 +0,0 @@ - diff --git a/lib/ui/history_list_screen.dart b/lib/ui/history_list_screen.dart deleted file mode 100644 index 8b13789..0000000 --- a/lib/ui/history_list_screen.dart +++ /dev/null @@ -1 +0,0 @@ - diff --git a/lib/ui/history_list_view.dart b/lib/ui/history_list_view.dart deleted file mode 100644 index 8b13789..0000000 --- a/lib/ui/history_list_view.dart +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pubspec.lock b/pubspec.lock index 2093bdc..5239b57 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -57,6 +57,34 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0-nullsafety.3" + connectivity: + dependency: transitive + description: + name: connectivity + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.9+5" + connectivity_for_web: + dependency: transitive + description: + name: connectivity_for_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.1+4" + connectivity_macos: + dependency: transitive + description: + name: connectivity_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0+7" + connectivity_platform_interface: + dependency: transitive + description: + name: connectivity_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.6" convert: dependency: transitive description: @@ -85,6 +113,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0-nullsafety.1" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "5.2.1" flutter: dependency: "direct main" description: flutter @@ -109,6 +151,11 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" gql: dependency: transitive description: @@ -137,6 +184,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.3.1" + graphql: + dependency: transitive + description: + name: graphql + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + graphql_flutter: + dependency: "direct main" + description: + name: graphql_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" http: dependency: transitive description: @@ -207,6 +268,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0-nullsafety.3" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.7" path: dependency: transitive description: @@ -214,6 +282,41 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0-nullsafety.1" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.24" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+2" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4+6" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4+3" pedantic: dependency: transitive description: @@ -242,6 +345,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" plugin_platform_interface: dependency: transitive description: @@ -249,6 +359,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.3" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.13" qrscan: dependency: "direct main" description: @@ -256,6 +373,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.2.21" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.5" + rxdart: + dependency: transitive + description: + name: rxdart + url: "https://pub.dartlang.org" + source: hosted + version: "0.24.1" sky_engine: dependency: transitive description: flutter @@ -317,6 +448,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0-nullsafety.3" + uuid_enhanced: + dependency: transitive + description: + name: uuid_enhanced + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" vector_math: dependency: transitive description: @@ -324,6 +462,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0-nullsafety.3" + websocket: + dependency: transitive + description: + name: websocket + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.5" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.4" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" xml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index fa07172..66dacaa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.0.0+3 +version: 0.0.0+4 environment: sdk: ">=2.7.0 <3.0.0" @@ -34,6 +34,7 @@ dependencies: intl: flutter_launcher_icons: "^0.8.0" infinite_scroll_pagination: ^2.2.3 + graphql_flutter: ^3.0.1 flutter_icons: