UX: global improvements
This commit is contained in:
parent
3ba04470f9
commit
26cc024b87
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
|
@ -203,5 +203,7 @@
|
||||||
"sent": "Sent",
|
"sent": "Sent",
|
||||||
"createIdentity": "Create a new \nidentity",
|
"createIdentity": "Create a new \nidentity",
|
||||||
"memberAccountOf": "Account of {}",
|
"memberAccountOf": "Account of {}",
|
||||||
"pasteAddress": "Paste address from\nclipboard"
|
"pasteAddress": "Paste address from\nclipboard",
|
||||||
|
"historyStart" :"Beginning of history",
|
||||||
|
"blockchainStart": "Beginning of the ĞDev"
|
||||||
}
|
}
|
|
@ -204,5 +204,7 @@
|
||||||
"sent": "Sent",
|
"sent": "Sent",
|
||||||
"createIdentity": "Create a new \nidentity",
|
"createIdentity": "Create a new \nidentity",
|
||||||
"memberAccountOf": "Account of {}",
|
"memberAccountOf": "Account of {}",
|
||||||
"pasteAddress": "Paste address from\nclipboard"
|
"pasteAddress": "Paste address from\nclipboard",
|
||||||
|
"historyStart" :"Beginning of history",
|
||||||
|
"blockchainStart": "Comienzo de la ĞDev"
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,5 +204,7 @@
|
||||||
"sent": "Envoyés",
|
"sent": "Envoyés",
|
||||||
"createIdentity": "Créer sa nouvelle\nidentité",
|
"createIdentity": "Créer sa nouvelle\nidentité",
|
||||||
"memberAccountOf": "Compte de {}",
|
"memberAccountOf": "Compte de {}",
|
||||||
"pasteAddress": "Coller l'adresse depuis\nle presse-papier"
|
"pasteAddress": "Coller l'adresse depuis\nle presse-papier",
|
||||||
|
"historyStart" :"Début de l'historique",
|
||||||
|
"blockchainStart": "Début de la ĞDev"
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,17 +57,17 @@ late DateTime startBlockchainTime;
|
||||||
|
|
||||||
late int currentUdIndex;
|
late int currentUdIndex;
|
||||||
|
|
||||||
final Map<int, String> monthsInYear = {
|
final Map<int, String> monthsInYear = {
|
||||||
1: "month1".tr(),
|
1: "month1".tr(),
|
||||||
2: "month2".tr(),
|
2: "month2".tr(),
|
||||||
3: "month3".tr(),
|
3: "month3".tr(),
|
||||||
4: "month4".tr(),
|
4: "month4".tr(),
|
||||||
5: "month5".tr(),
|
5: "month5".tr(),
|
||||||
6: "month6".tr(),
|
6: "month6".tr(),
|
||||||
7: "month7".tr(),
|
7: "month7".tr(),
|
||||||
8: "month8".tr(),
|
8: "month8".tr(),
|
||||||
9: "month9".tr(),
|
9: "month9".tr(),
|
||||||
10: "month10".tr(),
|
10: "month10".tr(),
|
||||||
11: "month11".tr(),
|
11: "month11".tr(),
|
||||||
12: "month12".tr()
|
12: "month12".tr()
|
||||||
};
|
};
|
||||||
|
|
|
@ -264,9 +264,9 @@ Map computeHistoryView(repository, lastDateDelimiter, isDouble) {
|
||||||
bool isDelimiter = true;
|
bool isDelimiter = true;
|
||||||
|
|
||||||
if ({4, 10, 11, 12}.contains(date.month)) {
|
if ({4, 10, 11, 12}.contains(date.month)) {
|
||||||
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 3)}.";
|
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 3)}";
|
||||||
} else if ({1, 2, 7, 9}.contains(date.month)) {
|
} else if ({1, 2, 7, 9}.contains(date.month)) {
|
||||||
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 4)}.";
|
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 4)}";
|
||||||
} else {
|
} else {
|
||||||
dateForm = "${date.day} ${monthsInYear[date.month]}";
|
dateForm = "${date.day} ${monthsInYear[date.month]}";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:durt/durt.dart' as durt;
|
import 'package:durt/durt.dart' as durt;
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:gecko/globals.dart';
|
import 'package:gecko/globals.dart';
|
||||||
|
@ -88,8 +89,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
|
|
||||||
log.i("Is $expectedWord equal to input $normInputWord ?");
|
log.i("Is $expectedWord equal to input $normInputWord ?");
|
||||||
if (expectedWord == normInputWord ||
|
if (expectedWord == normInputWord ||
|
||||||
inputWord == 'triche' ||
|
(kDebugMode && inputWord == 'triche')) {
|
||||||
inputWord == '3.14') {
|
|
||||||
log.d('Word is OK');
|
log.d('Word is OK');
|
||||||
isAskedWordValid = true;
|
isAskedWordValid = true;
|
||||||
askedWordColor = Colors.green[600];
|
askedWordColor = Colors.green[600];
|
||||||
|
|
|
@ -3,43 +3,22 @@
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
|
||||||
import 'package:gecko/globals.dart';
|
import 'package:gecko/globals.dart';
|
||||||
import 'package:gecko/models/queries_indexer.dart';
|
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
import 'package:gecko/providers/duniter_indexer.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gecko/widgets/bottom_app_bar.dart';
|
import 'package:gecko/widgets/bottom_app_bar.dart';
|
||||||
import 'package:gecko/widgets/header_profile.dart';
|
import 'package:gecko/widgets/header_profile.dart';
|
||||||
import 'package:gecko/widgets/transaction_tile.dart';
|
import 'package:gecko/widgets/history_query.dart';
|
||||||
import 'package:graphql_flutter/graphql_flutter.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
class ActivityScreen extends StatefulWidget with ChangeNotifier {
|
class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
||||||
ActivityScreen({required this.address, required this.avatar, this.username})
|
ActivityScreen({required this.address, required this.avatar, this.username})
|
||||||
: super(key: keyActivityScreen);
|
: super(key: keyActivityScreen);
|
||||||
final String address;
|
final String address;
|
||||||
final String? username;
|
final String? username;
|
||||||
final Image avatar;
|
final Image avatar;
|
||||||
|
|
||||||
@override
|
|
||||||
State<ActivityScreen> createState() => _ActivityScreenState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ActivityScreenState extends State<ActivityScreen> {
|
|
||||||
// @override
|
|
||||||
// void initState() {
|
|
||||||
// super.initState();
|
|
||||||
// }
|
|
||||||
|
|
||||||
final ScrollController scrollController = ScrollController();
|
|
||||||
final double avatarsSize = 80;
|
|
||||||
FetchMore? fetchMore;
|
|
||||||
FetchMoreOptions? opts;
|
|
||||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: _scaffoldKey,
|
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
toolbarHeight: 60 * ratio,
|
toolbarHeight: 60 * ratio,
|
||||||
|
@ -50,212 +29,8 @@ class _ActivityScreenState extends State<ActivityScreen> {
|
||||||
),
|
),
|
||||||
bottomNavigationBar: const GeckoBottomAppBar(),
|
bottomNavigationBar: const GeckoBottomAppBar(),
|
||||||
body: Column(children: <Widget>[
|
body: Column(children: <Widget>[
|
||||||
HeaderProfile(address: widget.address, username: widget.username),
|
HeaderProfile(address: address, username: username),
|
||||||
historyQuery(context),
|
HistoryQuery(address: address),
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget historyQuery(context) {
|
|
||||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
|
||||||
int nPage = 1;
|
|
||||||
int nRepositories = 20;
|
|
||||||
|
|
||||||
if (indexerEndpoint == '') {
|
|
||||||
return Column(children: <Widget>[
|
|
||||||
const SizedBox(height: 50),
|
|
||||||
Text(
|
|
||||||
"noNetworkNoHistory".tr(),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: const TextStyle(fontSize: 18),
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
final httpLink = HttpLink(
|
|
||||||
'$indexerEndpoint/v1beta1/relay',
|
|
||||||
);
|
|
||||||
|
|
||||||
final client = ValueNotifier(
|
|
||||||
GraphQLClient(
|
|
||||||
cache: GraphQLCache(),
|
|
||||||
link: httpLink,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
return GraphQLProvider(
|
|
||||||
client: client,
|
|
||||||
child: Expanded(
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: <Widget>[
|
|
||||||
Query(
|
|
||||||
options: QueryOptions(
|
|
||||||
document: gql(getHistoryByAddressQ),
|
|
||||||
variables: <String, dynamic>{
|
|
||||||
'address': widget.address,
|
|
||||||
'number': 20,
|
|
||||||
'cursor': null
|
|
||||||
},
|
|
||||||
),
|
|
||||||
builder: (QueryResult result, {fetchMore, refetch}) {
|
|
||||||
if (result.isLoading && result.data == null) {
|
|
||||||
return const Center(
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
color: orangeC,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.hasException) {
|
|
||||||
log.e('Error Indexer: ${result.exception}');
|
|
||||||
return Column(children: <Widget>[
|
|
||||||
const SizedBox(height: 50),
|
|
||||||
Text(
|
|
||||||
"noNetworkNoHistory".tr(),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: const TextStyle(fontSize: 18),
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
} else if (result
|
|
||||||
.data?['transaction_connection']?['edges'].isEmpty) {
|
|
||||||
return Column(children: <Widget>[
|
|
||||||
const SizedBox(height: 50),
|
|
||||||
Text(
|
|
||||||
"noDataToDisplay".tr(),
|
|
||||||
style: const TextStyle(fontSize: 18),
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.isNotLoading) {
|
|
||||||
if (duniterIndexer.fetchMoreCursor == null) nPage = 1;
|
|
||||||
|
|
||||||
// log.d('nPage: $nPage');
|
|
||||||
|
|
||||||
if (nPage <= 3) {
|
|
||||||
nRepositories = 20;
|
|
||||||
} else if (nPage <= 6) {
|
|
||||||
nRepositories = 40;
|
|
||||||
} else if (nPage <= 12) {
|
|
||||||
nRepositories = 80;
|
|
||||||
} else {
|
|
||||||
nRepositories = 120;
|
|
||||||
}
|
|
||||||
nPage++;
|
|
||||||
opts = duniterIndexer.mergeQueryResult(
|
|
||||||
result, opts, widget.address, nRepositories);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build history list
|
|
||||||
return NotificationListener(
|
|
||||||
child: Builder(
|
|
||||||
builder: (context) => Expanded(
|
|
||||||
child: ListView(
|
|
||||||
key: keyListTransactions,
|
|
||||||
controller: scrollController,
|
|
||||||
children: <Widget>[historyView(context, result)],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
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) {
|
|
||||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
|
||||||
int keyID = 0;
|
|
||||||
const double avatarSize = 200;
|
|
||||||
String? lastDateDelimiter;
|
|
||||||
bool? isDouble;
|
|
||||||
bool isMigrationPassed = false;
|
|
||||||
|
|
||||||
return duniterIndexer.transBC == null
|
|
||||||
? Column(children: <Widget>[
|
|
||||||
const SizedBox(height: 50),
|
|
||||||
Text(
|
|
||||||
"noTransactionToDisplay".tr(),
|
|
||||||
style: const TextStyle(fontSize: 18),
|
|
||||||
)
|
|
||||||
])
|
|
||||||
: Column(children: <Widget>[
|
|
||||||
Column(
|
|
||||||
children: duniterIndexer.transBC!.map((repository) {
|
|
||||||
final answer =
|
|
||||||
computeHistoryView(repository, lastDateDelimiter, isDouble);
|
|
||||||
isDouble = lastDateDelimiter == answer['dateDelimiter'] ||
|
|
||||||
answer['dateDelimiter'] == '';
|
|
||||||
lastDateDelimiter = answer['dateDelimiter'];
|
|
||||||
bool isMigrationTime = false;
|
|
||||||
if (answer['isMigrationTime'] && !isMigrationPassed) {
|
|
||||||
isMigrationPassed = true;
|
|
||||||
isMigrationTime = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Column(children: <Widget>[
|
|
||||||
if (isMigrationTime)
|
|
||||||
const Padding(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 30),
|
|
||||||
child: Text(
|
|
||||||
'Début de la ĞDev',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 25,
|
|
||||||
color: Colors.blueAccent,
|
|
||||||
fontWeight: FontWeight.w500),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (!isDouble!)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 30),
|
|
||||||
child: Text(
|
|
||||||
answer['dateDelimiter'],
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 23,
|
|
||||||
color: orangeC,
|
|
||||||
fontWeight: FontWeight.w300),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
TransactionTile(
|
|
||||||
widget: widget,
|
|
||||||
keyID: keyID,
|
|
||||||
avatarSize: avatarSize,
|
|
||||||
repository: repository,
|
|
||||||
dateForm: answer['dateForm'],
|
|
||||||
finalAmount: answer['finalAmount'],
|
|
||||||
duniterIndexer: duniterIndexer,
|
|
||||||
context: context),
|
|
||||||
]);
|
|
||||||
}).toList()),
|
|
||||||
if (result.isLoading && duniterIndexer.pageInfo!['hasPreviousPage'])
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: const <Widget>[
|
|
||||||
CircularProgressIndicator(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (!duniterIndexer.pageInfo!['hasNextPage'])
|
|
||||||
Column(
|
|
||||||
children: const <Widget>[
|
|
||||||
SizedBox(height: 15),
|
|
||||||
Text("Début de l'historique.",
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(fontSize: 20)),
|
|
||||||
SizedBox(height: 15)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import 'package:gecko/providers/chest_provider.dart';
|
||||||
import 'package:gecko/providers/my_wallets.dart';
|
import 'package:gecko/providers/my_wallets.dart';
|
||||||
import 'package:gecko/providers/substrate_sdk.dart';
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
import 'package:gecko/screens/common_elements.dart';
|
import 'package:gecko/screens/common_elements.dart';
|
||||||
import 'package:gecko/screens/myWallets/change_pin.dart';
|
|
||||||
import 'package:gecko/screens/myWallets/custom_derivations.dart';
|
import 'package:gecko/screens/myWallets/custom_derivations.dart';
|
||||||
import 'package:gecko/screens/myWallets/show_seed.dart';
|
import 'package:gecko/screens/myWallets/show_seed.dart';
|
||||||
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
||||||
|
@ -106,26 +105,27 @@ class ChestOptions extends StatelessWidget {
|
||||||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||||
return InkWell(
|
return InkWell(
|
||||||
key: keyChangePin,
|
key: keyChangePin,
|
||||||
onTap: sub.nodeConnected
|
onTap: null,
|
||||||
? () async {
|
// sub.nodeConnected
|
||||||
// await _chestProvider.changePin(context, cesiumWallet);
|
// ? () async {
|
||||||
String? pinResult = await Navigator.push(
|
// // await _chestProvider.changePin(context, cesiumWallet);
|
||||||
context,
|
// String? pinResult = await Navigator.push(
|
||||||
MaterialPageRoute(
|
// context,
|
||||||
builder: (context) {
|
// MaterialPageRoute(
|
||||||
return ChangePinScreen(
|
// builder: (context) {
|
||||||
walletName: currentChest.name,
|
// return ChangePinScreen(
|
||||||
walletProvider: walletProvider,
|
// walletName: currentChest.name,
|
||||||
);
|
// walletProvider: walletProvider,
|
||||||
},
|
// );
|
||||||
),
|
// },
|
||||||
);
|
// ),
|
||||||
|
// );
|
||||||
|
|
||||||
if (pinResult != null) {
|
// if (pinResult != null) {
|
||||||
walletProvider.pinCode = pinResult;
|
// walletProvider.pinCode = pinResult;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
: null,
|
// : null,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 50,
|
height: 50,
|
||||||
child: Row(children: <Widget>[
|
child: Row(children: <Widget>[
|
||||||
|
@ -140,7 +140,7 @@ class ChestOptions extends StatelessWidget {
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
color: sub.nodeConnected
|
color: sub.nodeConnected
|
||||||
? Colors.black
|
? Colors.grey[500]
|
||||||
: Colors.grey[500]),
|
: Colors.grey[500]),
|
||||||
),
|
),
|
||||||
])),
|
])),
|
||||||
|
|
|
@ -14,7 +14,6 @@ import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
import 'package:gecko/providers/wallet_options.dart';
|
import 'package:gecko/providers/wallet_options.dart';
|
||||||
import 'package:gecko/screens/common_elements.dart';
|
import 'package:gecko/screens/common_elements.dart';
|
||||||
import 'package:gecko/screens/myWallets/chest_options.dart';
|
import 'package:gecko/screens/myWallets/chest_options.dart';
|
||||||
import 'package:gecko/screens/myWallets/choose_chest.dart';
|
|
||||||
import 'package:gecko/screens/myWallets/import_g1_v1.dart';
|
import 'package:gecko/screens/myWallets/import_g1_v1.dart';
|
||||||
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
||||||
import 'package:gecko/screens/myWallets/wallet_options.dart';
|
import 'package:gecko/screens/myWallets/wallet_options.dart';
|
||||||
|
@ -183,22 +182,23 @@ class WalletsHome extends StatelessWidget {
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
InkWell(
|
InkWell(
|
||||||
key: keyChangeChest,
|
key: keyChangeChest,
|
||||||
onTap: () {
|
onTap: null,
|
||||||
Navigator.push(
|
// () {
|
||||||
context,
|
// Navigator.push(
|
||||||
MaterialPageRoute(builder: (context) {
|
// context,
|
||||||
return const ChooseChest();
|
// MaterialPageRoute(builder: (context) {
|
||||||
}),
|
// return const ChooseChest();
|
||||||
);
|
// }),
|
||||||
},
|
// );
|
||||||
|
// },
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 400,
|
width: 400,
|
||||||
height: 60,
|
height: 60,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text('changeChest'.tr(),
|
child: Text('changeChest'.tr(),
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 22,
|
fontSize: 22,
|
||||||
color: orangeC,
|
color: Colors.grey[500],
|
||||||
fontWeight: FontWeight.w500))),
|
fontWeight: FontWeight.w500))),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -72,6 +72,12 @@ class OnboardingStepNine extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
Text(
|
||||||
|
'Pendant la phase de test de Ğecko,\nles codes secrets\nsont systématiquement AAAAA.'
|
||||||
|
.tr(),
|
||||||
|
style: TextStyle(color: Colors.grey[700], fontSize: 15),
|
||||||
|
textAlign: TextAlign.center),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
|
|
|
@ -0,0 +1,233 @@
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gecko/globals.dart';
|
||||||
|
import 'package:gecko/models/queries_indexer.dart';
|
||||||
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
|
import 'package:gecko/providers/duniter_indexer.dart';
|
||||||
|
import 'package:gecko/widgets/transaction_tile.dart';
|
||||||
|
import 'package:graphql_flutter/graphql_flutter.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class HistoryQuery extends StatelessWidget {
|
||||||
|
const HistoryQuery({Key? key, required this.address}) : super(key: key);
|
||||||
|
final String address;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||||
|
|
||||||
|
final ScrollController scrollController = ScrollController();
|
||||||
|
FetchMoreOptions? opts;
|
||||||
|
|
||||||
|
int nPage = 1;
|
||||||
|
int nRepositories = 20;
|
||||||
|
|
||||||
|
if (indexerEndpoint == '') {
|
||||||
|
return Column(children: <Widget>[
|
||||||
|
const SizedBox(height: 50),
|
||||||
|
Text(
|
||||||
|
"noNetworkNoHistory".tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(fontSize: 18),
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
final httpLink = HttpLink(
|
||||||
|
'$indexerEndpoint/v1beta1/relay',
|
||||||
|
);
|
||||||
|
|
||||||
|
final client = ValueNotifier(
|
||||||
|
GraphQLClient(
|
||||||
|
cache: GraphQLCache(),
|
||||||
|
link: httpLink,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return GraphQLProvider(
|
||||||
|
client: client,
|
||||||
|
child: Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: <Widget>[
|
||||||
|
Query(
|
||||||
|
options: QueryOptions(
|
||||||
|
document: gql(getHistoryByAddressQ),
|
||||||
|
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(
|
||||||
|
color: orangeC,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.hasException) {
|
||||||
|
log.e('Error Indexer: ${result.exception}');
|
||||||
|
return Column(children: <Widget>[
|
||||||
|
const SizedBox(height: 50),
|
||||||
|
Text(
|
||||||
|
"noNetworkNoHistory".tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(fontSize: 18),
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
} else if (result
|
||||||
|
.data?['transaction_connection']?['edges'].isEmpty) {
|
||||||
|
return Column(children: <Widget>[
|
||||||
|
const SizedBox(height: 50),
|
||||||
|
Text(
|
||||||
|
"noDataToDisplay".tr(),
|
||||||
|
style: const TextStyle(fontSize: 18),
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.isNotLoading) {
|
||||||
|
if (duniterIndexer.fetchMoreCursor == null) nPage = 1;
|
||||||
|
|
||||||
|
// log.d('nPage: $nPage');
|
||||||
|
|
||||||
|
if (nPage <= 3) {
|
||||||
|
nRepositories = 20;
|
||||||
|
} else if (nPage <= 6) {
|
||||||
|
nRepositories = 40;
|
||||||
|
} else if (nPage <= 12) {
|
||||||
|
nRepositories = 80;
|
||||||
|
} else {
|
||||||
|
nRepositories = 120;
|
||||||
|
}
|
||||||
|
nPage++;
|
||||||
|
opts = duniterIndexer.mergeQueryResult(
|
||||||
|
result, opts, address, nRepositories);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build history list
|
||||||
|
return NotificationListener(
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) => Expanded(
|
||||||
|
child: ListView(
|
||||||
|
key: keyListTransactions,
|
||||||
|
controller: scrollController,
|
||||||
|
children: <Widget>[historyView(context, result)],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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) {
|
||||||
|
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||||
|
int keyID = 0;
|
||||||
|
const double avatarSize = 200;
|
||||||
|
String? lastDateDelimiter;
|
||||||
|
bool? isDouble;
|
||||||
|
bool isMigrationPassed = false;
|
||||||
|
|
||||||
|
return duniterIndexer.transBC == null
|
||||||
|
? Column(children: <Widget>[
|
||||||
|
const SizedBox(height: 50),
|
||||||
|
Text(
|
||||||
|
"noTransactionToDisplay".tr(),
|
||||||
|
style: const TextStyle(fontSize: 18),
|
||||||
|
)
|
||||||
|
])
|
||||||
|
: Column(children: <Widget>[
|
||||||
|
Column(
|
||||||
|
children: duniterIndexer.transBC!.map((repository) {
|
||||||
|
final answer =
|
||||||
|
computeHistoryView(repository, lastDateDelimiter, isDouble);
|
||||||
|
isDouble = lastDateDelimiter == answer['dateDelimiter'] ||
|
||||||
|
answer['dateDelimiter'] == '';
|
||||||
|
lastDateDelimiter = answer['dateDelimiter'];
|
||||||
|
bool isMigrationTime = false;
|
||||||
|
if (answer['isMigrationTime'] && !isMigrationPassed) {
|
||||||
|
isMigrationPassed = true;
|
||||||
|
isMigrationTime = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Column(children: <Widget>[
|
||||||
|
if (isMigrationTime)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 30),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Image(
|
||||||
|
image: AssetImage('assets/party.png'), height: 40),
|
||||||
|
const SizedBox(width: 40),
|
||||||
|
Text(
|
||||||
|
'blockchainStart'.tr(),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 25,
|
||||||
|
color: Colors.blueAccent,
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 40),
|
||||||
|
const Image(
|
||||||
|
image: AssetImage('assets/party.png'), height: 40),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (!isDouble!)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 30),
|
||||||
|
child: Text(
|
||||||
|
answer['dateDelimiter'],
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 23,
|
||||||
|
color: orangeC,
|
||||||
|
fontWeight: FontWeight.w300),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TransactionTile(
|
||||||
|
keyID: keyID,
|
||||||
|
avatarSize: avatarSize,
|
||||||
|
repository: repository,
|
||||||
|
dateForm: answer['dateForm'],
|
||||||
|
finalAmount: answer['finalAmount'],
|
||||||
|
duniterIndexer: duniterIndexer,
|
||||||
|
context: context),
|
||||||
|
]);
|
||||||
|
}).toList()),
|
||||||
|
if (result.isLoading && duniterIndexer.pageInfo!['hasPreviousPage'])
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: const <Widget>[
|
||||||
|
CircularProgressIndicator(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (!duniterIndexer.pageInfo!['hasNextPage'])
|
||||||
|
Column(
|
||||||
|
children: <Widget>[
|
||||||
|
const SizedBox(height: 15),
|
||||||
|
Text("historyStart".tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(fontSize: 20)),
|
||||||
|
const SizedBox(height: 15)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -115,6 +115,7 @@ class SearchIdentityQuery extends StatelessWidget {
|
||||||
dense: false,
|
dense: false,
|
||||||
isThreeLine: false,
|
isThreeLine: false,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) {
|
MaterialPageRoute(builder: (context) {
|
||||||
|
|
|
@ -93,6 +93,7 @@ class SearchResult extends StatelessWidget {
|
||||||
dense: false,
|
dense: false,
|
||||||
isThreeLine: false,
|
isThreeLine: false,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) {
|
MaterialPageRoute(builder: (context) {
|
||||||
|
|
|
@ -3,14 +3,12 @@ import 'package:gecko/models/widgets_keys.dart';
|
||||||
import 'package:gecko/providers/cesium_plus.dart';
|
import 'package:gecko/providers/cesium_plus.dart';
|
||||||
import 'package:gecko/providers/duniter_indexer.dart';
|
import 'package:gecko/providers/duniter_indexer.dart';
|
||||||
import 'package:gecko/providers/substrate_sdk.dart';
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
import 'package:gecko/screens/activity.dart';
|
|
||||||
import 'package:gecko/screens/wallet_view.dart';
|
import 'package:gecko/screens/wallet_view.dart';
|
||||||
import 'package:gecko/widgets/page_route_no_transition.dart';
|
import 'package:gecko/widgets/page_route_no_transition.dart';
|
||||||
|
|
||||||
class TransactionTile extends StatelessWidget {
|
class TransactionTile extends StatelessWidget {
|
||||||
const TransactionTile({
|
const TransactionTile({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.widget,
|
|
||||||
required this.keyID,
|
required this.keyID,
|
||||||
required this.avatarSize,
|
required this.avatarSize,
|
||||||
required this.repository,
|
required this.repository,
|
||||||
|
@ -20,7 +18,6 @@ class TransactionTile extends StatelessWidget {
|
||||||
required this.context,
|
required this.context,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final ActivityScreen widget;
|
|
||||||
final int keyID;
|
final int keyID;
|
||||||
final double avatarSize;
|
final double avatarSize;
|
||||||
final List repository;
|
final List repository;
|
||||||
|
@ -49,7 +46,7 @@ class TransactionTile extends StatelessWidget {
|
||||||
subtitle: RichText(
|
subtitle: RichText(
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 17,
|
||||||
color: Colors.grey[700],
|
color: Colors.grey[700],
|
||||||
),
|
),
|
||||||
children: <TextSpan>[
|
children: <TextSpan>[
|
||||||
|
@ -60,22 +57,27 @@ class TransactionTile extends StatelessWidget {
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: ' · ',
|
text: ' · ',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 25,
|
||||||
color: Colors.grey[550],
|
color: Colors.grey[550],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: repository[2],
|
text: repository[2],
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontStyle: FontStyle.italic,
|
fontStyle: FontStyle.italic,
|
||||||
color: Colors.grey[600],
|
color: Colors.grey[600],
|
||||||
),
|
fontSize: 19),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
trailing: Text(finalAmount,
|
trailing: Text(finalAmount,
|
||||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: repository[4] == 'RECEIVED'
|
||||||
|
? Colors.green[700]
|
||||||
|
: Colors.blue[700]),
|
||||||
textAlign: TextAlign.justify),
|
textAlign: TextAlign.justify),
|
||||||
dense: false,
|
dense: false,
|
||||||
isThreeLine: false,
|
isThreeLine: false,
|
||||||
|
@ -85,7 +87,7 @@ class TransactionTile extends StatelessWidget {
|
||||||
PageNoTransit(builder: (context) {
|
PageNoTransit(builder: (context) {
|
||||||
return WalletViewScreen(
|
return WalletViewScreen(
|
||||||
address: repository[1],
|
address: repository[1],
|
||||||
username: widget.username ?? '',
|
username: repository[2] ?? '',
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,7 +5,7 @@ description: Pay with G1.
|
||||||
# pub.dev using `pub publish`. This is preferred for private packages.
|
# pub.dev using `pub publish`. This is preferred for private packages.
|
||||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||||
|
|
||||||
version: 0.0.15+48
|
version: 0.0.15+50
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.12.0 <3.0.0'
|
sdk: '>=2.12.0 <3.0.0'
|
||||||
|
|
Loading…
Reference in New Issue