forked from axiom-team/gecko
Remove states management, keep just history pagination mechanic, clean code.
This commit is contained in:
parent
7652b8e602
commit
9a83df3d00
259
lib/api.dart
259
lib/api.dart
|
@ -1,260 +1,11 @@
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import "package:dio/dio.dart" as dio;
|
|
||||||
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';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
// Configure node
|
// Configure node
|
||||||
// const graphqlEndpoint = "https://g1.librelois.fr/gva";
|
const graphqlEndpoint = "https://g1.librelois.fr/gva";
|
||||||
const graphqlEndpoint = 'http://127.0.0.1:10060/gva';
|
// const graphqlEndpoint = 'http://192.168.1.91:10060/gva';
|
||||||
|
|
||||||
// // Check node connection
|
|
||||||
// Future getHttp() async {
|
|
||||||
// try {
|
|
||||||
// final client = await dio.Dio().get(graphqlEndpoint);
|
|
||||||
// print(client);
|
|
||||||
// return 0;
|
|
||||||
// } catch (e) {
|
|
||||||
// print(e);
|
|
||||||
// return e;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Build queries
|
|
||||||
Future buildQ(query) async {
|
|
||||||
var client;
|
|
||||||
try {
|
|
||||||
client = dio.Dio();
|
|
||||||
print(client);
|
|
||||||
} catch (e) {
|
|
||||||
print(e);
|
|
||||||
}
|
|
||||||
// final client = dio.Dio();
|
|
||||||
Link link;
|
|
||||||
link = DioLink(
|
|
||||||
graphqlEndpoint,
|
|
||||||
client: client,
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
|
||||||
final res = await link
|
|
||||||
.request(Request(
|
|
||||||
operation: Operation(document: gqlLang.parseString(query)),
|
|
||||||
))
|
|
||||||
.first;
|
|
||||||
return res;
|
|
||||||
} catch (e) {
|
|
||||||
print("Erreur: Noeud injoingnable.");
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Requests functions */
|
|
||||||
|
|
||||||
// Get current UD
|
|
||||||
Future getUD() async {
|
|
||||||
const query = """{
|
|
||||||
currentUd {
|
|
||||||
amount
|
|
||||||
base
|
|
||||||
}
|
|
||||||
}""";
|
|
||||||
|
|
||||||
final result = await buildQ(query);
|
|
||||||
return result.data["currentUd"]["amount"];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get balance
|
|
||||||
Future getBalance(String pubkey) async {
|
|
||||||
var query = """{
|
|
||||||
balance(script: "$pubkey") {
|
|
||||||
amount
|
|
||||||
base
|
|
||||||
}
|
|
||||||
}""";
|
|
||||||
|
|
||||||
final result = await buildQ(query);
|
|
||||||
return result.data["balance"]["amount"] / 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
// // Get history
|
|
||||||
// Future getHistory(String pubkey) async {
|
|
||||||
// print(pubkey);
|
|
||||||
// var number = 20;
|
|
||||||
// var query = """{
|
|
||||||
// txsHistoryBc(
|
|
||||||
// pubkeyOrScript: "$pubkey"
|
|
||||||
// pagination: { pageSize: $number, ord: DESC }
|
|
||||||
// ) {
|
|
||||||
// both {
|
|
||||||
// pageInfo {
|
|
||||||
// hasPreviousPage
|
|
||||||
// hasNextPage
|
|
||||||
// startCursor
|
|
||||||
// endCursor
|
|
||||||
// }
|
|
||||||
// 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
|
|
||||||
// }
|
|
||||||
// }""";
|
|
||||||
|
|
||||||
// final res = await buildQ(query);
|
|
||||||
|
|
||||||
// // Parse history
|
|
||||||
// var resBC, resMP;
|
|
||||||
// print(res.toString());
|
|
||||||
// try {
|
|
||||||
// resBC = res.data["txsHistoryBc"]['both']['edges'];
|
|
||||||
// resMP = res.data["txsHistoryMp"];
|
|
||||||
// } catch (e) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// var i = 0;
|
|
||||||
// // String outPubkey;
|
|
||||||
// var transBC = [];
|
|
||||||
// final currentBase = res.data['currentUd']['base'];
|
|
||||||
// final currentUD = res.data['currentUd']['amount'] / 100;
|
|
||||||
|
|
||||||
// // Get tx blockchain
|
|
||||||
// for (final trans in resBC) {
|
|
||||||
// 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] = [];
|
|
||||||
// transBC[i].add(transaction['writtenTime']);
|
|
||||||
// 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']);
|
|
||||||
// transBC[i].add(base);
|
|
||||||
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Get tx mempool
|
|
||||||
// var transMP = [];
|
|
||||||
// i = 0;
|
|
||||||
// for (var transaction in resMP['receiving']) {
|
|
||||||
// if (transMP == null) {
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// var output = transaction['outputs'][0];
|
|
||||||
// var outPubkey = output.split("SIG(")[1].replaceAll(')', '');
|
|
||||||
// transMP.add(i);
|
|
||||||
// transMP[i] = [];
|
|
||||||
// transMP[i].add(transaction['writtenTime']);
|
|
||||||
// transMP[i].add(transaction['issuers'][0]);
|
|
||||||
// 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;
|
|
||||||
// transMP[i].add(amount);
|
|
||||||
// final amountUD = amount / currentUD;
|
|
||||||
// transMP[i].add(amountUD.toStringAsFixed(2));
|
|
||||||
// transMP[i].add(transaction['comment']);
|
|
||||||
// transMP[i].add(base);
|
|
||||||
// transMP[i].add(outPubkey);
|
|
||||||
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// transMP = [];
|
|
||||||
// i = 0;
|
|
||||||
// for (var transaction in resMP['sending']) {
|
|
||||||
// if (transMP == null) {
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// var output = transaction['outputs'][0];
|
|
||||||
// var outPubkey = output.split("SIG(")[1].replaceAll(')', '');
|
|
||||||
// transMP.add(i);
|
|
||||||
// transMP[i] = [];
|
|
||||||
// transMP[i].add(transaction['writtenTime']);
|
|
||||||
// transMP[i].add(transaction['issuers'][0]);
|
|
||||||
// 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;
|
|
||||||
// transMP[i].add(-amount);
|
|
||||||
// final amountUD = amount / currentUD;
|
|
||||||
// transMP[i].add(amountUD.toStringAsFixed(2));
|
|
||||||
// transMP[i].add(transaction['comment']);
|
|
||||||
// transMP[i].add(base);
|
|
||||||
// transMP[i].add(outPubkey);
|
|
||||||
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Order transactions by date
|
|
||||||
// transBC.sort((b, a) => Comparable.compare(a[0], b[0]));
|
|
||||||
// transMP.sort((b, a) => Comparable.compare(a[0], b[0]));
|
|
||||||
|
|
||||||
// // // Keep only base if there is base change
|
|
||||||
// // var lastBase = 0;
|
|
||||||
// // for (i in trans) {
|
|
||||||
// // if (i[5] == lastBase){
|
|
||||||
// // i[6] = null;
|
|
||||||
// // }
|
|
||||||
// // else {
|
|
||||||
// // lastBase = i[6];
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// // print(trans);
|
|
||||||
// return [transBC, transMP];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// NEW WAY //
|
|
||||||
|
|
||||||
List parseHistory(txs) {
|
List parseHistory(txs) {
|
||||||
// print(blockchainTX[0]['node']['comment']);
|
|
||||||
|
|
||||||
var transBC = [];
|
var transBC = [];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
@ -263,12 +14,9 @@ List parseHistory(txs) {
|
||||||
|
|
||||||
for (final trans in txs) {
|
for (final trans in txs) {
|
||||||
var direction = trans['direction'];
|
var direction = trans['direction'];
|
||||||
|
|
||||||
// print(trans);
|
|
||||||
final transaction = trans['node'];
|
final transaction = trans['node'];
|
||||||
var output = transaction['outputs'][0];
|
var output = transaction['outputs'][0];
|
||||||
|
|
||||||
print("DEBUG comment: " + transaction['comment'].toString());
|
|
||||||
transBC.add(i);
|
transBC.add(i);
|
||||||
transBC[i] = [];
|
transBC[i] = [];
|
||||||
final dateBrut =
|
final dateBrut =
|
||||||
|
@ -277,6 +25,8 @@ List parseHistory(txs) {
|
||||||
final date = formatter.format(dateBrut);
|
final date = formatter.format(dateBrut);
|
||||||
transBC[i].add(transaction['writtenTime']);
|
transBC[i].add(transaction['writtenTime']);
|
||||||
transBC[i].add(date);
|
transBC[i].add(date);
|
||||||
|
print(
|
||||||
|
"DEBUG date et comment: ${date.toString()} -- ${transaction['comment'].toString()}");
|
||||||
var amountBrut = int.parse(output.split(':')[0]);
|
var amountBrut = int.parse(output.split(':')[0]);
|
||||||
final base = int.parse(output.split(':')[1]);
|
final base = int.parse(output.split(':')[1]);
|
||||||
final applyBase = base - currentBase;
|
final applyBase = base - currentBase;
|
||||||
|
@ -298,6 +48,5 @@ List parseHistory(txs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// transBC.sort((b, a) => Comparable.compare(a[0], b[0]));
|
// transBC.sort((b, a) => Comparable.compare(a[0], b[0]));
|
||||||
|
|
||||||
return transBC;
|
return transBC;
|
||||||
}
|
}
|
||||||
|
|
489
lib/home.dart
489
lib/home.dart
|
@ -4,263 +4,30 @@ import 'dart:typed_data';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:qrscan/qrscan.dart' as scanner;
|
import 'package:qrscan/qrscan.dart' as scanner;
|
||||||
import 'api.dart';
|
|
||||||
// import "package:dio/dio.dart";
|
|
||||||
import 'package:graphql_flutter/graphql_flutter.dart';
|
import 'package:graphql_flutter/graphql_flutter.dart';
|
||||||
|
import 'api.dart';
|
||||||
import 'query.dart';
|
import 'query.dart';
|
||||||
|
|
||||||
//ignore: must_be_immutable
|
//ignore: must_be_immutable
|
||||||
class HistoryListScreen extends StatefulWidget {
|
class HistoryListScreen extends StatelessWidget with ChangeNotifier {
|
||||||
@override
|
|
||||||
_HistoryListScreenState createState() => _HistoryListScreenState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _HistoryListScreenState extends State<HistoryListScreen>
|
|
||||||
with ChangeNotifier {
|
|
||||||
Uint8List bytes = Uint8List(0);
|
Uint8List bytes = Uint8List(0);
|
||||||
TextEditingController _outputPubkey;
|
final TextEditingController _outputPubkey = new TextEditingController();
|
||||||
TextEditingController _outputBalance;
|
|
||||||
final nRepositories = 3;
|
final nRepositories = 3;
|
||||||
var pubkey = '';
|
String pubkey = 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU'; // For debug
|
||||||
bool isBuilding = true; // Just for debug
|
bool isBuilding = true; // Just for debug
|
||||||
ScrollController _scrollController = new ScrollController();
|
ScrollController _scrollController = new ScrollController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
initState() {
|
|
||||||
super.initState();
|
|
||||||
this._outputPubkey = new TextEditingController();
|
|
||||||
this._outputBalance = new TextEditingController();
|
|
||||||
// checkNode().then((result) {
|
|
||||||
// setState(() {
|
|
||||||
// _result = result;
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
pubkey = 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU';
|
print('Build pubkey : ' + pubkey);
|
||||||
|
print('Build this.pubkey : ' + this.pubkey);
|
||||||
// var pubkey = '';
|
|
||||||
print('Build state : ' + pubkey);
|
|
||||||
print('isBuilding: ' + isBuilding.toString());
|
print('isBuilding: ' + isBuilding.toString());
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
home: Scaffold(
|
home: Scaffold(
|
||||||
backgroundColor: Colors.grey[300],
|
backgroundColor: Colors.grey[300],
|
||||||
body: Container(
|
body: SafeArea(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: masterHome,
|
||||||
SizedBox(height: 20),
|
|
||||||
TextField(
|
|
||||||
// enabled: false,
|
|
||||||
onChanged: (text) {
|
|
||||||
print("Clé tappxé: $text");
|
|
||||||
pubkey = text;
|
|
||||||
// pubkey =
|
|
||||||
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)),
|
|
||||||
TextField(
|
|
||||||
// Affichage balance
|
|
||||||
enabled: false,
|
|
||||||
controller: this._outputBalance,
|
|
||||||
maxLines: 1,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: '',
|
|
||||||
hintStyle: TextStyle(fontSize: 15),
|
|
||||||
contentPadding:
|
|
||||||
EdgeInsets.symmetric(horizontal: 7, vertical: 15),
|
|
||||||
focusedBorder: InputBorder.none,
|
|
||||||
enabledBorder: InputBorder.none,
|
|
||||||
errorBorder: InputBorder.none,
|
|
||||||
disabledBorder: InputBorder.none,
|
|
||||||
),
|
|
||||||
style: TextStyle(fontSize: 30.0, color: Colors.black)),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: <Widget>[
|
|
||||||
Query(
|
|
||||||
options: QueryOptions(
|
|
||||||
document: gql(getHistory),
|
|
||||||
variables: <String, dynamic>{
|
|
||||||
'pubkey': pubkey, // 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<dynamic> blockchainTX =
|
|
||||||
(result.data['txsHistoryBc']['both']['edges']
|
|
||||||
as List<dynamic>);
|
|
||||||
|
|
||||||
// final List<dynamic> mempoolTX =
|
|
||||||
// (result.data['txsHistoryBc']['both']['edges']
|
|
||||||
// as List<dynamic>);
|
|
||||||
|
|
||||||
final Map pageInfo =
|
|
||||||
result.data['txsHistoryBc']['both']['pageInfo'];
|
|
||||||
|
|
||||||
final String fetchMoreCursor =
|
|
||||||
pageInfo['endCursor'] ?? 'cest null...';
|
|
||||||
|
|
||||||
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<dynamic> repos = [
|
|
||||||
...previousResultData['txsHistoryBc']['both']
|
|
||||||
['edges'] as List<dynamic>,
|
|
||||||
...fetchMoreResultData['txsHistoryBc']['both']
|
|
||||||
['edges'] as List<dynamic>
|
|
||||||
];
|
|
||||||
|
|
||||||
fetchMoreResultData['txsHistoryBc']['both']
|
|
||||||
['edges'] = repos;
|
|
||||||
print('DEBUG NULL OPTION: ');
|
|
||||||
print(fetchMoreResultData);
|
|
||||||
print(fetchMoreCursor);
|
|
||||||
return fetchMoreResultData;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
_scrollController
|
|
||||||
..addListener(() {
|
|
||||||
if (_scrollController.position.pixels ==
|
|
||||||
_scrollController.position.maxScrollExtent) {
|
|
||||||
if (!result.isLoading) {
|
|
||||||
print('DEBUG NULL scrollController: ' +
|
|
||||||
fetchMoreCursor);
|
|
||||||
fetchMore(opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
print(
|
|
||||||
'DEBUG blockchainTX: ' + blockchainTX.toString());
|
|
||||||
List transBC = parseHistory(blockchainTX);
|
|
||||||
// parseHistory(mempoolTX);
|
|
||||||
|
|
||||||
return Expanded(
|
|
||||||
child: ListView(
|
|
||||||
controller: _scrollController,
|
|
||||||
children: <Widget>[
|
|
||||||
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: <Widget>[
|
|
||||||
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.isLoading)
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
CircularProgressIndicator(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
floatingActionButton: Container(
|
floatingActionButton: Container(
|
||||||
|
@ -279,17 +46,125 @@ class _HistoryListScreenState extends State<HistoryListScreen>
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Future checkNode() async {
|
List<Widget> get masterHome {
|
||||||
// final response = await Dio().post(graphqlEndpoint);
|
return <Widget>[
|
||||||
// showHistory(response);
|
SizedBox(height: 20),
|
||||||
// return response;
|
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: <Widget>[
|
||||||
|
Query(
|
||||||
|
options: QueryOptions(
|
||||||
|
document: gql(getHistory),
|
||||||
|
variables: <String, dynamic>{
|
||||||
|
'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<dynamic> blockchainTX =
|
||||||
|
(result.data['txsHistoryBc']['both']['edges'] as List<dynamic>);
|
||||||
|
|
||||||
|
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<dynamic> repos = [
|
||||||
|
...previousResultData['txsHistoryBc']['both']['edges']
|
||||||
|
as List<dynamic>,
|
||||||
|
...fetchMoreResultData['txsHistoryBc']['both']['edges']
|
||||||
|
as List<dynamic>
|
||||||
|
];
|
||||||
|
|
||||||
|
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 {
|
Future _scan() async {
|
||||||
await Permission.camera.request();
|
await Permission.camera.request();
|
||||||
String barcode = await scanner.scan();
|
String barcode = await scanner.scan();
|
||||||
// this._outputPubkey.text = "";
|
// this._outputPubkey.text = "";
|
||||||
if (barcode != null) {
|
if (barcode != null) {
|
||||||
|
this._outputPubkey.text = barcode;
|
||||||
isPubkey(barcode);
|
isPubkey(barcode);
|
||||||
}
|
}
|
||||||
return barcode;
|
return barcode;
|
||||||
|
@ -307,46 +182,92 @@ class _HistoryListScreenState extends State<HistoryListScreen>
|
||||||
pubkey.length > 42 &&
|
pubkey.length > 42 &&
|
||||||
pubkey.length < 45) {
|
pubkey.length < 45) {
|
||||||
print("C'est une pubkey !!!");
|
print("C'est une pubkey !!!");
|
||||||
showHistory(pubkey);
|
|
||||||
|
|
||||||
// var tata = _scrollController;
|
|
||||||
|
|
||||||
notifyListeners();
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
print('setPubkey: ' + pubkey);
|
|
||||||
pubkey = pubkey;
|
|
||||||
// // fetchMoreCursor = fetchMoreCursor;
|
|
||||||
});
|
|
||||||
|
|
||||||
return pubkey;
|
return pubkey;
|
||||||
} else {
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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: <Widget>[
|
||||||
|
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: <Widget>[
|
||||||
|
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: <Widget>[
|
||||||
|
CircularProgressIndicator(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future showHistory(pubkey) async {
|
|
||||||
// String pubkey = await _scan();
|
|
||||||
if (pubkey == null) {
|
|
||||||
print('nothing return.');
|
|
||||||
} else {
|
|
||||||
this._outputPubkey.text = "";
|
|
||||||
this._outputBalance.text = "";
|
|
||||||
// final udValue = await getUD();
|
|
||||||
this._outputPubkey.text = pubkey;
|
|
||||||
final myBalance = await getBalance(pubkey.toString());
|
|
||||||
this._outputBalance.text = myBalance.toString() + " Ğ1";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Future _generateBarCode(String inputCode) async {
|
|
||||||
// if (inputCode != null && inputCode.isNotEmpty) {
|
|
||||||
// // print("Résultat du scan: " + inputCode);
|
|
||||||
// Uint8List result = await scanner.generateBarCode(inputCode);
|
|
||||||
// this.setState(() => this.bytes = result);
|
|
||||||
// } else {
|
|
||||||
// print("Veuillez renseigner une clé publique");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,15 +11,13 @@ class Gecko extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final _httpLink = HttpLink(
|
final _httpLink = HttpLink(
|
||||||
'http://127.0.0.1:30901/gva',
|
// 'http://192.168.1.91:10060/gva',
|
||||||
// defaultHeaders: <String, String>{
|
'https://g1.librelois.fr/gva',
|
||||||
// 'Content-Type': 'application/json',
|
|
||||||
// },
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final _client = ValueNotifier(
|
final _client = ValueNotifier(
|
||||||
GraphQLClient(
|
GraphQLClient(
|
||||||
cache: GraphQLCache(),
|
cache: GraphQLCache(store: null),
|
||||||
link: _httpLink,
|
link: _httpLink,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
20
pubspec.lock
20
pubspec.lock
|
@ -99,13 +99,6 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.5"
|
version: "2.1.5"
|
||||||
dio:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: dio
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.10"
|
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -170,13 +163,6 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.10"
|
version: "1.0.10"
|
||||||
gql_dio_link:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: gql_dio_link
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.0.4"
|
|
||||||
gql_error_link:
|
gql_error_link:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -185,7 +171,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.1-alpha+1601131172858"
|
version: "0.1.1-alpha+1601131172858"
|
||||||
gql_exec:
|
gql_exec:
|
||||||
dependency: "direct main"
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: gql_exec
|
name: gql_exec
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
|
@ -199,7 +185,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.2"
|
version: "0.3.2"
|
||||||
gql_link:
|
gql_link:
|
||||||
dependency: "direct main"
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: gql_link
|
name: gql_link
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
|
@ -283,7 +269,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.3"
|
version: "2.2.3"
|
||||||
intl:
|
intl:
|
||||||
dependency: "direct main"
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
|
|
|
@ -23,16 +23,11 @@ environment:
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
flutter_launcher_icons: "^0.8.0"
|
||||||
qrscan: ^0.2.21
|
qrscan: ^0.2.21
|
||||||
permission_handler:
|
permission_handler:
|
||||||
image_gallery_saver:
|
image_gallery_saver:
|
||||||
image_picker:
|
image_picker:
|
||||||
dio:
|
|
||||||
gql_dio_link:
|
|
||||||
gql_exec:
|
|
||||||
gql_link:
|
|
||||||
intl:
|
|
||||||
flutter_launcher_icons: "^0.8.0"
|
|
||||||
infinite_scroll_pagination: ^2.2.3
|
infinite_scroll_pagination: ^2.2.3
|
||||||
graphql_flutter: ^4.0.0-beta.6 #^3.1.0
|
graphql_flutter: ^4.0.0-beta.6 #^3.1.0
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue