This commit is contained in:
poka 2020-12-21 03:59:25 +01:00
parent 7936de25fc
commit 1bcfa738cc
10 changed files with 460 additions and 178 deletions

View File

@ -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;
}

View File

@ -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<ListPage<Article>> getArticleListPage({
int number,
int size,
List<int> filteredPlatformIds,
List<int> filteredCategoryIds,
List<ArticleDifficulty> filteredDifficulties,
SortMethod sortMethod,
}) =>
remoteStore.getArticleListPage(
number: number,
size: size,
filteredPlatformIds: filteredPlatformIds,
filteredCategoryIds: filteredCategoryIds,
filteredDifficulties: filteredDifficulties,
sortMethod: sortMethod,
);

View File

@ -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<HistoryListScreen> {
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<HistoryListScreen> {
@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: <Widget>[
SizedBox(height: 20),
@ -65,6 +69,7 @@ class _HistoryListScreenState extends State<HistoryListScreen> {
// enabled: false,
onChanged: (text) {
print("Clé tappé: $text");
// pubkey = text;
isPubkey(text);
},
controller: this._outputPubkey,
@ -103,9 +108,164 @@ class _HistoryListScreenState extends State<HistoryListScreen> {
),
style: TextStyle(fontSize: 30.0, color: Colors.black)),
Expanded(
child: HistoryListView(
repository: Provider.of<Repository>(context)
))
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Query(
options: QueryOptions(
documentNode: gql(getMyRepositories),
variables: <String, dynamic>{
'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<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'];
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;
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: <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(8.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.loading)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(),
],
),
],
),
);
},
),
],
)),
],
),
),
@ -126,43 +286,6 @@ class _HistoryListScreenState extends State<HistoryListScreen> {
)));
}
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: <Widget>[
// 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<HistoryListScreen> {
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<HistoryListScreen> {
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<HistoryListScreen> {
} 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<HistoryListScreen> {
// }
}
class Transaction {
String pubkey;
String date;
Transaction(this.pubkey, this.date);
// TODO: Build this list !!!!
// static List<Transaction> samples = List<Transaction> 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<Transaction> samples = List<Transaction>
return myHistory[0];
}
// static List<Transaction> samples = buildHistory();
var list = json
.decode(response.body)['results']
.map((data) => Model.fromJson(data))
.toList();
// static List<Transaction> samples = [
// Transaction(
// "Spaghetti and Meatballs",
// "assets/2126711929_ef763de2b3_w.jpg",
// ),
// Transaction(
// "Tomato Soup",
// "assets/27729023535_a57606c1be.jpg",
// )
// ];
}

View File

@ -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(),
),
);
}
}

45
lib/query.dart Normal file
View File

@ -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
}
}
''';

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@

View File

@ -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:

View File

@ -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: