Hello Activity screen; paged history works for all profiles

This commit is contained in:
poka 2022-06-16 19:45:34 +02:00
parent 1c4da17db9
commit a4f5b44a13
8 changed files with 410 additions and 428 deletions

View File

@ -1,4 +1,4 @@
[
"https://duniter-indexer.coinduf.eu/v1/graphql",
"http://192.168.1.72:8080/v1/graphql"
"https://duniter-indexer.coinduf.eu",
"http://192.168.1.72:8080"
]

View File

@ -58,6 +58,7 @@ Future<void> main() async {
HomeProvider _homeProvider = HomeProvider();
DuniterIndexer _duniterIndexer = DuniterIndexer();
await initHiveForFlutter();
await _homeProvider.initHive();
appVersion = await _homeProvider.getAppVersion();
prefs = await SharedPreferences.getInstance();
@ -67,7 +68,6 @@ Future<void> main() async {
Hive.registerAdapter(ChestDataAdapter());
Hive.registerAdapter(G1WalletsListAdapter());
Hive.registerAdapter(IdAdapter());
// Hive.registerAdapter(KeyStoreDataAdapter());
walletBox = await Hive.openBox<WalletData>("walletBox");
chestBox = await Hive.openBox<ChestData>("chestBox");
@ -82,10 +82,7 @@ Future<void> main() async {
}
// log.d(await configBox.get('endpoint'));
await _duniterIndexer.getValidIndexerEndpoint();
// _duniterIndexer.indexerEndpoint = "http://192.168.1.72:8080/v1/graphql";
// _duniterIndexer.indexerEndpoint =
// "https://duniter-indexer.coinduf.eu/v1/graphql";
_duniterIndexer.getValidIndexerEndpoint();
HttpOverrides.global = MyHttpOverrides();
@ -131,20 +128,11 @@ class Gecko extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
final _httpLink = HttpLink(
indexerEndpoint!,
);
final _client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(),
link: _httpLink,
),
);
// To configure multi_endpoints GraphQLProvider: https://stackoverflow.com/q/70656513/8301867
return MultiProvider(
providers: [
// Provider(create: (context) => HistoryProvider()),
ChangeNotifierProvider(create: (_) => HomeProvider()),
ChangeNotifierProvider(create: (_) => WalletsProfilesProvider('')),
ChangeNotifierProvider(create: (_) => MyWalletsProvider()),
@ -156,44 +144,41 @@ class Gecko extends StatelessWidget {
ChangeNotifierProvider(create: (_) => SubstrateSdk()),
ChangeNotifierProvider(create: (_) => DuniterIndexer())
],
child: GraphQLProvider(
client: _client,
child: MaterialApp(
builder: (context, widget) => ResponsiveWrapper.builder(
BouncingScrollWrapper.builder(context, widget!),
maxWidth: 1200,
minWidth: 480,
defaultScale: true,
breakpoints: [
const ResponsiveBreakpoint.resize(480, name: MOBILE),
const ResponsiveBreakpoint.autoScale(800, name: TABLET),
const ResponsiveBreakpoint.resize(1000, name: DESKTOP),
],
background: Container(color: backgroundColor)),
title: 'Ğecko',
theme: ThemeData(
appBarTheme: const AppBarTheme(
color: Color(0xffFFD58D),
foregroundColor: Color(0xFF000000),
),
primaryColor: const Color(0xffFFD58D),
textTheme: const TextTheme(
bodyText1: TextStyle(fontSize: 16),
bodyText2: TextStyle(fontSize: 18),
).apply(
bodyColor: const Color(0xFF000000),
),
colorScheme:
ColorScheme.fromSwatch().copyWith(secondary: Colors.grey[850]),
child: MaterialApp(
builder: (context, widget) => ResponsiveWrapper.builder(
BouncingScrollWrapper.builder(context, widget!),
maxWidth: 1200,
minWidth: 480,
defaultScale: true,
breakpoints: [
const ResponsiveBreakpoint.resize(480, name: MOBILE),
const ResponsiveBreakpoint.autoScale(800, name: TABLET),
const ResponsiveBreakpoint.resize(1000, name: DESKTOP),
],
background: Container(color: backgroundColor)),
title: 'Ğecko',
theme: ThemeData(
appBarTheme: const AppBarTheme(
color: Color(0xffFFD58D),
foregroundColor: Color(0xFF000000),
),
home: const HomeScreen(),
initialRoute: "/",
routes: {
'/mywallets': (context) => const WalletsHome(),
'/search': (context) => const SearchScreen(),
'/searchResult': (context) => const SearchResultScreen(),
},
primaryColor: const Color(0xffFFD58D),
textTheme: const TextTheme(
bodyText1: TextStyle(fontSize: 16),
bodyText2: TextStyle(fontSize: 18),
).apply(
bodyColor: const Color(0xFF000000),
),
colorScheme:
ColorScheme.fromSwatch().copyWith(secondary: Colors.grey[850]),
),
home: const HomeScreen(),
initialRoute: "/",
routes: {
'/mywallets': (context) => const WalletsHome(),
'/search': (context) => const SearchScreen(),
'/searchResult': (context) => const SearchResultScreen(),
},
),
);
}

View File

@ -52,19 +52,31 @@ query ($address: String!) {
''';
const String getHistoryByAddressQ3 = r'''
query ($address: String!) {
query ($address: String!, $number: Int!, $cursor: String) {
transaction_connection(where:
{_or: [
{issuer_id: {_eq: $address}},
{receiver_id: {_eq: $address}}
]},
order_by: {created_at: desc}) {
order_by: {created_at: desc},
first: $number,
after: $cursor) {
edges {
node {
amount
created_at
issuer_id
receiver_id
issuer {
identity {
name
}
}
receiver {
identity {
name
}
}
}
}
pageInfo {

View File

@ -1,7 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
@ -17,7 +16,11 @@ import 'package:provider/provider.dart';
class DuniterIndexer with ChangeNotifier {
Map<String, String?> walletNameIndexer = {};
String? fetchMoreCursor;
Map? pageInfo;
int nPage = 1;
int nRepositories = 20;
List? transBC;
void reload() {
notifyListeners();
@ -30,7 +33,8 @@ class DuniterIndexer with ChangeNotifier {
final _client = HttpClient();
_client.connectionTimeout = const Duration(milliseconds: 1000);
try {
final request = await _client.postUrl(Uri.parse(oldEndpoint));
final request =
await _client.postUrl(Uri.parse('$oldEndpoint/v1/graphql'));
final response = await request.close();
if (response.statusCode != 200) {
log.d('INDEXER IS OFFILINE');
@ -74,7 +78,8 @@ class DuniterIndexer with ChangeNotifier {
}
try {
final request = await _client.postUrl(Uri.parse(_listEndpoints[i]));
final request =
await _client.postUrl(Uri.parse('${_listEndpoints[i]}/v1/graphql'));
final response = await request.close();
indexerEndpoint = _listEndpoints[i];
@ -122,54 +127,67 @@ class DuniterIndexer with ChangeNotifier {
}
}
}
final _httpLink = HttpLink(
'$indexerEndpoint/v1/graphql',
);
return Query(
options: QueryOptions(
document: gql(
getNameByAddressQ), // this is the query string you just created
variables: {
'address': address,
},
// pollInterval: const Duration(seconds: 10),
),
builder: (QueryResult result,
{VoidCallback? refetch, FetchMore? fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
final _client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(store: HiveStore()),
link: _httpLink,
),
);
return GraphQLProvider(
client: _client,
child: Query(
options: QueryOptions(
document: gql(
getNameByAddressQ), // this is the query string you just created
variables: {
'address': address,
},
// pollInterval: const Duration(seconds: 10),
),
builder: (QueryResult result,
{VoidCallback? refetch, FetchMore? fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return const Text('Loading');
}
if (result.isLoading) {
return const Text('Loading');
}
walletNameIndexer[address] =
result.data?['account_by_pk']?['identity']?['name'];
walletNameIndexer[address] =
result.data?['account_by_pk']?['identity']?['name'];
if (walletNameIndexer[address] == null) {
if (wallet == null) {
return const SizedBox();
} else {
if (canEdit) {
return _walletOptions.walletName(context, wallet, size, _color);
if (walletNameIndexer[address] == null) {
if (wallet == null) {
return const SizedBox();
} else {
return _walletOptions.walletNameController(
context, wallet, size);
if (canEdit) {
return _walletOptions.walletName(
context, wallet, size, _color);
} else {
return _walletOptions.walletNameController(
context, wallet, size);
}
}
}
}
return Text(
_color == Colors.grey[700]!
? '(${walletNameIndexer[address]!})'
: walletNameIndexer[address]!,
style: TextStyle(
fontSize: size,
color: _color,
fontWeight: fontWeight,
fontStyle: fontStyle,
),
);
});
return Text(
_color == Colors.grey[700]!
? '(${walletNameIndexer[address]!})'
: walletNameIndexer[address]!,
style: TextStyle(
fontSize: size,
color: _color,
fontWeight: fontWeight,
fontStyle: fontStyle,
),
);
}),
);
}
Widget searchIdentity(BuildContext context, String name) {
@ -183,85 +201,184 @@ class DuniterIndexer with ChangeNotifier {
return const Text('Aucun résultat');
}
return Query(
options: QueryOptions(
document: gql(
searchAddressByNameQ), // this is the query string you just created
variables: {
'name': name,
},
// pollInterval: const Duration(seconds: 10),
),
builder: (QueryResult result,
{VoidCallback? refetch, FetchMore? fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
final _httpLink = HttpLink(
'$indexerEndpoint/v1/graphql',
);
if (result.isLoading) {
return const Text('Loading');
}
final _client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(store: HiveStore()),
link: _httpLink,
),
);
return GraphQLProvider(
client: _client,
child: Query(
options: QueryOptions(
document: gql(
searchAddressByNameQ), // this is the query string you just created
variables: {
'name': name,
},
// pollInterval: const Duration(seconds: 10),
),
builder: (QueryResult result,
{VoidCallback? refetch, FetchMore? fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
final List identities = result.data?['search_identity'] ?? [];
if (result.isLoading) {
return const Text('Loading');
}
if (identities.isEmpty) {
return const Text('Aucun résultat');
}
final List identities = result.data?['search_identity'] ?? [];
int keyID = 0;
double _avatarSize = 55;
return Expanded(
child: ListView(children: <Widget>[
for (Map profile in identities)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: ListTile(
key: Key('searchResult${keyID++}'),
horizontalTitleGap: 40,
contentPadding: const EdgeInsets.all(5),
leading: _cesiumPlusProvider.defaultAvatar(_avatarSize),
title: Row(children: <Widget>[
Text(getShortPubkey(profile['id']),
style: const TextStyle(
fontSize: 18,
fontFamily: 'Monospace',
fontWeight: FontWeight.w500),
textAlign: TextAlign.center),
]),
trailing: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [balance(context, profile['id'], 16)]),
subtitle: Row(children: <Widget>[
Text(profile['name'] ?? '',
style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.w500),
textAlign: TextAlign.center),
]),
dense: false,
isThreeLine: false,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
_walletsProfiles.address = profile['id'];
return WalletViewScreen(
pubkey: profile['id'],
username:
g1WalletsBox.get(profile['id'])?.id?.username,
avatar: g1WalletsBox.get(profile['id'])?.avatar,
);
}),
);
}),
),
]),
);
});
if (identities.isEmpty) {
return const Text('Aucun résultat');
}
int keyID = 0;
double _avatarSize = 55;
return Expanded(
child: ListView(children: <Widget>[
for (Map profile in identities)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: ListTile(
key: Key('searchResult${keyID++}'),
horizontalTitleGap: 40,
contentPadding: const EdgeInsets.all(5),
leading: _cesiumPlusProvider.defaultAvatar(_avatarSize),
title: Row(children: <Widget>[
Text(getShortPubkey(profile['id']),
style: const TextStyle(
fontSize: 18,
fontFamily: 'Monospace',
fontWeight: FontWeight.w500),
textAlign: TextAlign.center),
]),
trailing: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [balance(context, profile['id'], 16)]),
subtitle: Row(children: <Widget>[
Text(profile['name'] ?? '',
style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.w500),
textAlign: TextAlign.center),
]),
dense: false,
isThreeLine: false,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
_walletsProfiles.address = profile['id'];
return WalletViewScreen(
pubkey: profile['id'],
username: g1WalletsBox
.get(profile['id'])
?.id
?.username,
avatar: g1WalletsBox.get(profile['id'])?.avatar,
);
}),
);
}),
),
]),
);
}),
);
}
List parseHistory(blockchainTX, _pubkey) {
var transBC = [];
int i = 0;
checkHistoryResult(QueryResult<Object?> result, FetchMoreOptions options, String address) {
}
for (final trans in blockchainTX) {
final transaction = trans['node'];
final direction =
transaction['issuer_id'] != _pubkey ? 'RECEIVED' : 'SENT';
transBC.add(i);
transBC[i] = [];
transBC[i].add(DateTime.parse(transaction['created_at']));
final int amountBrut = transaction['amount'];
final num amount = removeDecimalZero(amountBrut / 100);
if (direction == "RECEIVED") {
transBC[i].add(transaction['issuer_id']);
transBC[i].add(transaction['issuer']['identity']?['name'] ?? '');
transBC[i].add(amount.toString());
} else if (direction == "SENT") {
transBC[i].add(transaction['receiver_id']);
transBC[i].add(transaction['receiver']['identity']?['name'] ?? '');
transBC[i].add('- ' + amount.toString());
}
// transBC[i].add(''); //transaction comment
i++;
}
return transBC;
}
FetchMoreOptions? checkQueryResult(result, opts, _pubkey) {
final List<dynamic>? blockchainTX =
(result.data['transaction_connection']['edges'] as List<dynamic>?);
// final List<dynamic> mempoolTX =
// (result.data['txsHistoryMp']['receiving'] as List<dynamic>);
pageInfo = result.data['transaction_connection']['pageInfo'];
fetchMoreCursor = pageInfo!['endCursor'];
if (fetchMoreCursor == null) nPage = 1;
log.d(fetchMoreCursor);
if (nPage == 1) {
nRepositories = 40;
} else if (nPage == 2) {
nRepositories = 100;
}
// nRepositories = 10;
nPage++;
if (fetchMoreCursor != null) {
opts = FetchMoreOptions(
variables: {'cursor': fetchMoreCursor, 'number': nRepositories},
updateQuery: (previousResultData, fetchMoreResultData) {
final List<dynamic> repos = [
...previousResultData!['transaction_connection']['edges']
as List<dynamic>,
...fetchMoreResultData!['transaction_connection']['edges']
as List<dynamic>
];
log.d('repos: ' + previousResultData.toString());
log.d('repos: ' + fetchMoreResultData.toString());
log.d('repos: ' + repos.toString());
fetchMoreResultData['transaction_connection']['edges'] = repos;
return fetchMoreResultData;
},
);
}
log.d(
"###### DEBUG H Parse blockchainTX list. Cursor: $fetchMoreCursor ######");
if (fetchMoreCursor != null) {
transBC = parseHistory(blockchainTX, _pubkey);
} else {
log.i("###### DEBUG H - Début de l'historique");
}
return opts;
}
num removeDecimalZero(double n) {
String result = n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 2);
return num.parse(result);
}
// checkHistoryResult(
// QueryResult<Object?> result, FetchMoreOptions options, String address) {}
}

View File

@ -577,7 +577,7 @@ Widget getCerts(BuildContext context, String address, double size,
return FutureBuilder(
future: _sdk.getCerts(address),
builder: (BuildContext context, AsyncSnapshot<List<int>> _certs) {
log.d(_certs.data);
// log.d(_certs.data);
return _certs.data?[0] != 0 && _certs.data != null
? Row(

View File

@ -1,32 +1,24 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/screens/wallet_view.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:jdenticon_dart/jdenticon_dart.dart';
import 'package:permission_handler/permission_handler.dart';
// import 'package:qrscan/qrscan.dart' as scanner;
import 'package:barcode_scan2/barcode_scan2.dart';
import 'dart:math';
import 'package:intl/intl.dart';
class WalletsProfilesProvider with ChangeNotifier {
WalletsProfilesProvider(this.address);
String? address = '';
String pubkeyShort = '';
List? transBC;
String? fetchMoreCursor;
Map? pageInfo;
bool isHistoryScreen = false;
String historySwitchButtun = "Voir l'historique";
String? rawSvg;
TextEditingController payAmount = TextEditingController();
TextEditingController payComment = TextEditingController();
num? balance;
int nRepositories = 20;
int nPage = 1;
Future<String> scan(context) async {
if (Platform.isAndroid || Platform.isIOS) {
@ -97,117 +89,10 @@ class WalletsProfilesProvider with ChangeNotifier {
// Matograine portefeuille: 9p5nHsES6xujFR7pw2yGy4PLKKHgWsMvsDHaHF64Uj25.
// Lion simone: 78jhpprYkMNF6i5kQPXfkAVBpd2aqcpieNsXTSW4c21f
List parseHistory(txs, _pubkey) {
var transBC = [];
int i = 0;
const currentBase = 0;
double currentUD = 10.54;
for (final trans in txs) {
var direction = trans['direction'];
final transaction = trans['node'];
String? output;
if (direction == "RECEIVED") {
for (String line in transaction['outputs']) {
if (line.contains(_pubkey)) {
output = line;
}
}
} else {
output = transaction['outputs'][0];
}
if (output == null) {
continue;
}
transBC.add(i);
transBC[i] = [];
final dateBrut = DateTime.fromMillisecondsSinceEpoch(
transaction['writtenTime'] * 1000);
final DateFormat formatter = DateFormat('dd-MM-yy\nHH:mm');
final date = formatter.format(dateBrut);
transBC[i].add(transaction['writtenTime']);
transBC[i].add(date);
final int amountBrut = int.parse(output.split(':')[0]);
final base = int.parse(output.split(':')[1]);
final int applyBase = base - currentBase;
final num amount =
removeDecimalZero(amountBrut * pow(10, applyBase) / 100);
num amountUD = amount / currentUD;
if (direction == "RECEIVED") {
transBC[i].add(transaction['issuers'][0]);
transBC[i].add(getShortPubkey(transaction['issuers'][0]));
transBC[i].add(amount.toString());
transBC[i].add(amountUD.toStringAsFixed(2));
} else if (direction == "SENT") {
final outPubkey = output.split("SIG(")[1].replaceAll(')', '');
transBC[i].add(outPubkey);
transBC[i].add(getShortPubkey(outPubkey));
transBC[i].add('- ' + amount.toString());
transBC[i].add(amountUD.toStringAsFixed(2));
}
transBC[i].add(transaction['comment']);
i++;
}
return transBC;
}
FetchMoreOptions? checkQueryResult(result, opts, _pubkey) {
final List<dynamic>? blockchainTX =
(result.data['txsHistoryBc']['both']['edges'] as List<dynamic>?);
// final List<dynamic> mempoolTX =
// (result.data['txsHistoryMp']['receiving'] as List<dynamic>);
pageInfo = result.data['txsHistoryBc']['both']['pageInfo'];
fetchMoreCursor = pageInfo!['endCursor'];
if (fetchMoreCursor == null) nPage = 1;
if (nPage == 1) {
nRepositories = 40;
} else if (nPage == 2) {
nRepositories = 100;
}
nPage++;
if (fetchMoreCursor != null) {
opts = FetchMoreOptions(
variables: {'cursor': fetchMoreCursor, 'number': nRepositories},
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;
},
);
}
log.d(
"###### DEBUG H Parse blockchainTX list. Cursor: $fetchMoreCursor ######");
if (fetchMoreCursor != null) {
transBC = parseHistory(blockchainTX, _pubkey);
} else {
log.i("###### DEBUG H - Début de l'historique");
}
return opts;
}
void resetdHistory() {
notifyListeners();
}
num removeDecimalZero(double n) {
String result = n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 2);
return num.parse(result);
}
String generateIdenticon(String _pubkey) {
return Jdenticon.toSvg(_pubkey);
}

View File

@ -51,84 +51,109 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
DuniterIndexer _duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
return Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Query(
options: QueryOptions(
document: gql(getHistoryByAddressQ3),
variables: <String, dynamic>{
'address': address,
},
),
builder: (QueryResult result, {fetchMore, refetch}) {
log.d(result.data);
if (result.isLoading && result.data == null) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (indexerEndpoint == '') {
Column(children: const <Widget>[
SizedBox(height: 50),
Text(
"L'état du réseau ne permet pas\nd'afficher l'historique du compte",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18),
)
]);
}
if (result.hasException) {
log.e('Error Indexer: ' + result.exception.toString());
return Column(children: const <Widget>[
SizedBox(height: 50),
Text(
"L'état du réseau ne permet pas\nd'afficher l'historique du compte",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18),
)
]);
} else if (result.data == null) {
return Column(children: const <Widget>[
SizedBox(height: 50),
Text(
"Aucune donnée à afficher.",
style: TextStyle(fontSize: 18),
)
]);
}
final _httpLink = HttpLink(
'$indexerEndpoint/v1beta1/relay',
);
if (result.isNotLoading) {
// log.d(result.data);
opts =
_duniterIndexer.checkHistoryResult(result, opts!, address!);
}
final _client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(),
link: _httpLink,
),
);
// Build history list
return NotificationListener(
child: Builder(
builder: (context) => Expanded(
child: ListView(
key: const Key('listTransactions'),
controller: scrollController,
children: <Widget>[historyView(context, result)],
return GraphQLProvider(
client: _client,
child: Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Query(
options: QueryOptions(
document: gql(getHistoryByAddressQ3),
variables: <String, dynamic>{
'address': address,
'number': 20,
'cursor': null
},
),
builder: (QueryResult result, {fetchMore, refetch}) {
if (result.isLoading && result.data == null) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (result.hasException) {
log.e('Error Indexer: ' + result.exception.toString());
return Column(children: const <Widget>[
SizedBox(height: 50),
Text(
"L'état du réseau ne permet pas\nd'afficher l'historique du compte",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18),
)
]);
} else if (result.data == null) {
return Column(children: const <Widget>[
SizedBox(height: 50),
Text(
"Aucune donnée à afficher.",
style: TextStyle(fontSize: 18),
)
]);
}
if (result.isNotLoading) {
// log.d(result.data);
opts = _duniterIndexer.checkQueryResult(result, opts, address!);
}
// Build history list
return NotificationListener(
child: Builder(
builder: (context) => Expanded(
child: ListView(
key: const Key('listTransactions'),
controller: scrollController,
children: <Widget>[historyView(context, result)],
),
),
),
),
onNotification: (dynamic t) {
if (t is ScrollEndNotification &&
scrollController.position.pixels >=
scrollController.position.maxScrollExtent * 0.7 &&
_duniterIndexer.pageInfo!['hasPreviousPage'] &&
result.isNotLoading) {
fetchMore!(opts!);
}
return true;
});
},
),
],
));
onNotification: (dynamic t) {
if (t is ScrollEndNotification &&
scrollController.position.pixels >=
scrollController.position.maxScrollExtent * 0.7 &&
_duniterIndexer.pageInfo!['hasNextPage'] &&
result.isNotLoading) {
fetchMore!(opts!);
}
return true;
});
},
),
],
)),
);
}
Widget historyView(context, result) {
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
DuniterIndexer _duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
return _historyProvider.transBC == null
return _duniterIndexer.transBC == null
? Column(children: const <Widget>[
SizedBox(height: 50),
Text(
@ -137,16 +162,16 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
)
])
: Column(children: <Widget>[
getTransactionTile(context, _historyProvider),
getTransactionTile(context, _duniterIndexer),
if (result.isLoading &&
_historyProvider.pageInfo!['hasPreviousPage'])
_duniterIndexer.pageInfo!['hasPreviousPage'])
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
CircularProgressIndicator(),
],
),
if (!_historyProvider.pageInfo!['hasPreviousPage'])
if (!_duniterIndexer.pageInfo!['hasNextPage'])
Column(
children: const <Widget>[
SizedBox(height: 15),
@ -160,7 +185,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
}
Widget getTransactionTile(
BuildContext context, WalletsProfilesProvider _historyProvider) {
BuildContext context, DuniterIndexer _duniterIndexer) {
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
int keyID = 0;
@ -188,9 +213,11 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
};
return Column(
children: _historyProvider.transBC!.map((repository) {
children: _duniterIndexer.transBC!.map((repository) {
// log.d('bbbbbbbbbbbbbbbbbbbbbb: ' + repository.toString());
DateTime now = DateTime.now();
DateTime date = DateTime.fromMillisecondsSinceEpoch(repository[0] * 1000);
DateTime date = repository[0];
String dateForm;
if ({4, 10, 11, 12}.contains(date.month)) {
@ -257,52 +284,12 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
key: Key('transaction${keyID++}'),
contentPadding: const EdgeInsets.only(
left: 20, right: 30, top: 15, bottom: 15),
leading: g1WalletsBox.get(repository[2])?.avatar == null
? FutureBuilder(
future: _cesiumPlusProvider.getAvatar(
repository[2], _avatarSize),
builder: (BuildContext context,
AsyncSnapshot<Image?> _avatar) {
if (_avatar.connectionState !=
ConnectionState.done ||
_avatar.hasError) {
return Stack(children: [
_cesiumPlusProvider.defaultAvatar(_avatarSize),
Positioned(
top: 8,
right: 0,
width: 12,
height: 12,
child: CircularProgressIndicator(
strokeWidth: 1,
color: orangeC,
),
),
]);
}
if (_avatar.hasData) {
g1WalletsBox.get(repository[2])?.avatar =
_avatar.data;
return ClipOval(child: _avatar.data);
} else {
g1WalletsBox.get(repository[2])?.avatar =
_cesiumPlusProvider
.defaultAvatar(repository[2]);
return _cesiumPlusProvider
.defaultAvatar(_avatarSize);
}
})
: ClipOval(
child: Image(
image:
g1WalletsBox.get(repository[2])!.avatar!.image,
height: _avatarSize,
),
),
leading: ClipOval(
child: _cesiumPlusProvider.defaultAvatar(_avatarSize),
),
title: Padding(
padding: EdgeInsets.only(
bottom: 5, top: repository[6] != '' ? 0 : 0),
child: Text(repository[3],
padding: const EdgeInsets.only(bottom: 5),
child: Text(getShortPubkey(repository[1]),
style: const TextStyle(
fontSize: 18, fontFamily: 'Monospace')),
),
@ -316,7 +303,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
TextSpan(
text: dateForm,
),
if (repository[6] != '')
if (repository[2] != '')
TextSpan(
text: ' · ',
style: TextStyle(
@ -325,7 +312,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
),
),
TextSpan(
text: repository[6],
text: repository[2],
style: TextStyle(
fontStyle: FontStyle.italic,
color: Colors.grey[600],
@ -334,19 +321,19 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
],
),
),
trailing: Text("${repository[4]} $currencyName",
trailing: Text("${repository[3]} $currencyName",
style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.w500),
textAlign: TextAlign.justify),
dense: false,
isThreeLine: false,
onTap: () {
_historyProvider.nPage = 1;
_duniterIndexer.nPage = 1;
// _cesiumPlusProvider.avatarCancelToken.cancel('cancelled');
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return WalletViewScreen(pubkey: repository[2]);
return WalletViewScreen(pubkey: repository[1]);
}),
);
// Navigator.pop(context);

View File

@ -8,6 +8,7 @@ import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/screens/activity.dart';
import 'package:gecko/screens/avatar_fullscreen.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/choose_wallet.dart';
@ -88,8 +89,7 @@ class WalletViewScreen extends StatelessWidget {
height: buttonSize,
child: ClipOval(
child: Material(
color: Colors
.grey[300], //const Color(0xffFFD58D), // button color
color: yellowC, //const Color(0xffFFD58D), // button color
child: InkWell(
key: const Key('viewHistory'),
splashColor: orangeC, // inkwell color
@ -100,20 +100,16 @@ class WalletViewScreen extends StatelessWidget {
'assets/walletOptions/clock.png'),
height: 90)),
onTap: () {
//// Wait for subsquid indexer
// _historyProvider.nPage = 1;
// Navigator.push(
// context,
// FaderTransition(
// page: HistoryScreen(
// pubkey: pubkey,
// username: username ??
// g1WalletsBox.get(pubkey)?.username,
// avatar: avatar ??
// g1WalletsBox.get(pubkey)?.avatar,
// ),
// isFast: false),
// );
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return ActivityScreen(
address: pubkey,
avatar:
_cesiumPlusProvider.defaultAvatar(50));
}),
);
}),
),
),