import 'package:flutter/material.dart'; import 'dart:async'; import 'dart:typed_data'; import 'dart:ui'; import 'package:permission_handler/permission_handler.dart'; import 'package:qrscan/qrscan.dart' as scanner; import 'package:graphql_flutter/graphql_flutter.dart'; import 'api.dart'; import 'query.dart'; //ignore: must_be_immutable class HistoryListScreen extends StatelessWidget with ChangeNotifier { Uint8List bytes = Uint8List(0); final TextEditingController _outputPubkey = new TextEditingController(); final nRepositories = 3; String pubkey = 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU'; // For debug bool isBuilding = true; // Just for debug ScrollController _scrollController = new ScrollController(); @override Widget build(BuildContext context) { print('Build pubkey : ' + pubkey); print('Build this.pubkey : ' + this.pubkey); print('isBuilding: ' + isBuilding.toString()); return MaterialApp( home: Scaffold( backgroundColor: Colors.grey[300], body: SafeArea( child: Column( children: masterHome, ), ), floatingActionButton: Container( height: 80.0, width: 80.0, child: FittedBox( child: FloatingActionButton( onPressed: () => _scan(), child: Container( height: 40.0, width: 40.0, child: Image.asset('images/scanner.png')), backgroundColor: Color.fromARGB(500, 204, 255, 255), ), ), ))); } List get masterHome { return [ SizedBox(height: 20), TextField( onChanged: (text) { print("Clé tappxé: $text"); this.pubkey = text; isPubkey(text); }, controller: this._outputPubkey, maxLines: 1, textAlign: TextAlign.center, decoration: InputDecoration( hintText: 'Tappez/Collez une clé publique, ou scannez', hintStyle: TextStyle(fontSize: 15), contentPadding: EdgeInsets.symmetric(horizontal: 7, vertical: 15), border: InputBorder.none, focusedBorder: InputBorder.none, enabledBorder: InputBorder.none, errorBorder: InputBorder.none, disabledBorder: InputBorder.none, ), style: TextStyle( fontSize: 15.0, color: Colors.black, fontWeight: FontWeight.bold)), historyQuery(), ]; } Expanded historyQuery() { return Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ Query( options: QueryOptions( document: gql(getHistory), variables: { 'pubkey': this.pubkey, 'number': nRepositories, // set cursor to null so as to start at the beginning 'cursor': null }, ), builder: (QueryResult result, {refetch, FetchMore fetchMore}) { if (result.isLoading && 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'); } final List blockchainTX = (result.data['txsHistoryBc']['both']['edges'] as List); final Map pageInfo = result.data['txsHistoryBc']['both']['pageInfo']; final String fetchMoreCursor = pageInfo['endCursor'] ?? 'cest null...'; FetchMoreOptions opts = FetchMoreOptions( variables: {'cursor': fetchMoreCursor}, 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; }, ); _scrollController ..addListener(() { if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) { if (!result.isLoading) { print( "DEBUG H fetchMoreCursor in scrollController: $fetchMoreCursor"); fetchMore(opts); } } }); print( "###### DEBUG H Parse blockchainTX list. Cursor: $fetchMoreCursor ######"); List _transBC = parseHistory(blockchainTX); return Expanded( child: HistoryListView( scrollController: _scrollController, transBC: _transBC, historyData: result), ); }, ), ], )); } Future _scan() async { await Permission.camera.request(); String barcode = await scanner.scan(); // this._outputPubkey.text = ""; if (barcode != null) { this._outputPubkey.text = barcode; isPubkey(barcode); } return barcode; } String isPubkey(pubkey) { // final validCharacters = RegExp(r'^[a-zA-Z0-9]+$'); RegExp regExp = new RegExp( r'^[a-zA-Z0-9]+$', caseSensitive: false, multiLine: false, ); if (regExp.hasMatch(pubkey) == true && pubkey.length > 42 && pubkey.length < 45) { print("C'est une pubkey !!!"); return pubkey; } return ''; } } class HistoryListView extends StatelessWidget { const HistoryListView( {Key key, @required ScrollController scrollController, @required this.transBC, @required this.historyData}) : _scrollController = scrollController, super(key: key); final ScrollController _scrollController; final List transBC; final historyData; @override Widget build(BuildContext context) { return 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(100.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( // Comment repository[5].toString(), style: TextStyle( fontSize: 12.0, fontWeight: FontWeight.w400, ), ), ], ), ), ), if (historyData.isLoading) Row( mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator(), ], ), ], ); } }