Merge branch 'dev'
This commit is contained in:
commit
3ba04470f9
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gecko/models/chest_data.dart';
|
import 'package:gecko/models/chest_data.dart';
|
||||||
import 'package:gecko/models/g1_wallets_list.dart';
|
import 'package:gecko/models/g1_wallets_list.dart';
|
||||||
|
@ -55,3 +56,18 @@ late int udValue;
|
||||||
late DateTime startBlockchainTime;
|
late DateTime startBlockchainTime;
|
||||||
|
|
||||||
late int currentUdIndex;
|
late int currentUdIndex;
|
||||||
|
|
||||||
|
final Map<int, String> monthsInYear = {
|
||||||
|
1: "month1".tr(),
|
||||||
|
2: "month2".tr(),
|
||||||
|
3: "month3".tr(),
|
||||||
|
4: "month4".tr(),
|
||||||
|
5: "month5".tr(),
|
||||||
|
6: "month6".tr(),
|
||||||
|
7: "month7".tr(),
|
||||||
|
8: "month8".tr(),
|
||||||
|
9: "month9".tr(),
|
||||||
|
10: "month10".tr(),
|
||||||
|
11: "month11".tr(),
|
||||||
|
12: "month12".tr()
|
||||||
|
};
|
||||||
|
|
|
@ -6,21 +6,13 @@ 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';
|
||||||
import 'package:gecko/models/queries_indexer.dart';
|
import 'package:gecko/models/queries_indexer.dart';
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
|
||||||
import 'package:gecko/providers/cesium_plus.dart';
|
|
||||||
import 'package:gecko/providers/substrate_sdk.dart';
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
import 'package:gecko/providers/wallets_profiles.dart';
|
|
||||||
import 'package:gecko/screens/wallet_view.dart';
|
|
||||||
import 'package:gecko/widgets/balance.dart';
|
|
||||||
import 'package:graphql_flutter/graphql_flutter.dart';
|
import 'package:graphql_flutter/graphql_flutter.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
class DuniterIndexer with ChangeNotifier {
|
class DuniterIndexer with ChangeNotifier {
|
||||||
Map<String, String?> walletNameIndexer = {};
|
Map<String, String?> walletNameIndexer = {};
|
||||||
String? fetchMoreCursor;
|
String? fetchMoreCursor;
|
||||||
Map? pageInfo;
|
Map? pageInfo;
|
||||||
int nPage = 1;
|
|
||||||
int nRepositories = 20;
|
|
||||||
List? transBC;
|
List? transBC;
|
||||||
List listIndexerEndpoints = [];
|
List listIndexerEndpoints = [];
|
||||||
bool isLoadingIndexer = false;
|
bool isLoadingIndexer = false;
|
||||||
|
@ -91,7 +83,6 @@ class DuniterIndexer with ChangeNotifier {
|
||||||
|
|
||||||
if (configBox.containsKey('customIndexer')) {
|
if (configBox.containsKey('customIndexer')) {
|
||||||
return configBox.get('customIndexer');
|
return configBox.get('customIndexer');
|
||||||
// listIndexerEndpoints.insert(0, configBox.get('customIndexer'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configBox.containsKey('indexerEndpoint')) {
|
if (configBox.containsKey('indexerEndpoint')) {
|
||||||
|
@ -153,123 +144,8 @@ class DuniterIndexer with ChangeNotifier {
|
||||||
return indexerEndpoint;
|
return indexerEndpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget searchIdentity(BuildContext context, String name) {
|
|
||||||
// WalletOptionsProvider _walletOptions =
|
|
||||||
// Provider.of<WalletOptionsProvider>(context, listen: false);
|
|
||||||
WalletsProfilesProvider walletsProfiles =
|
|
||||||
Provider.of<WalletsProfilesProvider>(context, listen: false);
|
|
||||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
|
||||||
if (indexerEndpoint == '') {
|
|
||||||
return const Text('Aucun résultat');
|
|
||||||
}
|
|
||||||
|
|
||||||
log.d(indexerEndpoint);
|
|
||||||
final httpLink = HttpLink(
|
|
||||||
'$indexerEndpoint/v1/graphql',
|
|
||||||
);
|
|
||||||
|
|
||||||
final client = ValueNotifier(
|
|
||||||
GraphQLClient(
|
|
||||||
cache: GraphQLCache(
|
|
||||||
store: HiveStore()), // 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());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.isLoading) {
|
|
||||||
return Text('loading'.tr());
|
|
||||||
}
|
|
||||||
|
|
||||||
final List identities = result.data?['search_identity'] ?? [];
|
|
||||||
|
|
||||||
if (identities.isEmpty) {
|
|
||||||
return Text('noResult'.tr());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Map profile in identities) {
|
|
||||||
duniterIndexer.walletNameIndexer
|
|
||||||
.putIfAbsent(profile['pubkey'], () => profile['name']);
|
|
||||||
}
|
|
||||||
|
|
||||||
double avatarSize = 55;
|
|
||||||
return Expanded(
|
|
||||||
child: ListView(children: <Widget>[
|
|
||||||
for (Map profile in identities)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
|
||||||
child: ListTile(
|
|
||||||
key: keySearchResult(profile['pubkey']),
|
|
||||||
horizontalTitleGap: 40,
|
|
||||||
contentPadding: const EdgeInsets.all(5),
|
|
||||||
leading: defaultAvatar(avatarSize),
|
|
||||||
title: Row(children: <Widget>[
|
|
||||||
Text(getShortPubkey(profile['pubkey']),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
fontFamily: 'Monospace',
|
|
||||||
fontWeight: FontWeight.w500),
|
|
||||||
textAlign: TextAlign.center),
|
|
||||||
]),
|
|
||||||
trailing: SizedBox(
|
|
||||||
width: 110,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Balance(
|
|
||||||
address: profile['pubkey'], size: 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['pubkey'];
|
|
||||||
return WalletViewScreen(
|
|
||||||
address: profile['pubkey'],
|
|
||||||
username: name,
|
|
||||||
avatar:
|
|
||||||
g1WalletsBox.get(profile['pubkey'])?.avatar,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List parseHistory(blockchainTX, pubkey) {
|
List parseHistory(blockchainTX, pubkey) {
|
||||||
var transBC = [];
|
List transBC = [];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (final trans in blockchainTX) {
|
for (final trans in blockchainTX) {
|
||||||
|
@ -291,32 +167,21 @@ class DuniterIndexer with ChangeNotifier {
|
||||||
}
|
}
|
||||||
transBC[i].add(amount);
|
transBC[i].add(amount);
|
||||||
transBC[i].add(direction);
|
transBC[i].add(direction);
|
||||||
// transBC[i].add(''); //transaction comment
|
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return transBC;
|
return transBC;
|
||||||
}
|
}
|
||||||
|
|
||||||
FetchMoreOptions? checkQueryResult(result, opts, pubkey) {
|
FetchMoreOptions? mergeQueryResult(result, opts, pubkey, nRepositories) {
|
||||||
final List<dynamic>? blockchainTX =
|
final List<dynamic>? blockchainTX =
|
||||||
(result.data['transaction_connection']['edges'] as List<dynamic>?);
|
(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'];
|
pageInfo = result.data['transaction_connection']['pageInfo'];
|
||||||
fetchMoreCursor = pageInfo!['endCursor'];
|
fetchMoreCursor = pageInfo!['endCursor'];
|
||||||
if (fetchMoreCursor == null) nPage = 1;
|
final hasNextPage = pageInfo!['hasNextPage'];
|
||||||
|
final hasPreviousPage = pageInfo!['hasPreviousPage'];
|
||||||
log.d(fetchMoreCursor);
|
log.d('endCursor: $fetchMoreCursor $hasNextPage $hasPreviousPage');
|
||||||
|
|
||||||
if (nPage == 1) {
|
|
||||||
nRepositories = 40;
|
|
||||||
} else if (nPage == 2) {
|
|
||||||
nRepositories = 100;
|
|
||||||
}
|
|
||||||
// nRepositories = 10;
|
|
||||||
nPage++;
|
|
||||||
|
|
||||||
if (fetchMoreCursor != null) {
|
if (fetchMoreCursor != null) {
|
||||||
opts = FetchMoreOptions(
|
opts = FetchMoreOptions(
|
||||||
|
@ -329,18 +194,12 @@ class DuniterIndexer with ChangeNotifier {
|
||||||
as List<dynamic>
|
as List<dynamic>
|
||||||
];
|
];
|
||||||
|
|
||||||
log.d('repos: $previousResultData');
|
|
||||||
log.d('repos: $fetchMoreResultData');
|
|
||||||
log.d('repos: $repos');
|
|
||||||
|
|
||||||
fetchMoreResultData['transaction_connection']['edges'] = repos;
|
fetchMoreResultData['transaction_connection']['edges'] = repos;
|
||||||
return fetchMoreResultData;
|
return fetchMoreResultData;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.d(
|
|
||||||
"###### DEBUG H Parse blockchainTX list. Cursor: $fetchMoreCursor ######");
|
|
||||||
if (fetchMoreCursor != null) {
|
if (fetchMoreCursor != null) {
|
||||||
transBC = parseHistory(blockchainTX, pubkey);
|
transBC = parseHistory(blockchainTX, pubkey);
|
||||||
} else {
|
} else {
|
||||||
|
@ -388,3 +247,86 @@ Future<QueryResult> _execQuery(
|
||||||
|
|
||||||
return await client.query(options);
|
return await client.query(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map computeHistoryView(repository, lastDateDelimiter, isDouble) {
|
||||||
|
bool isTody = false;
|
||||||
|
bool isYesterday = false;
|
||||||
|
bool isThisWeek = false;
|
||||||
|
bool isMigrationTime = false;
|
||||||
|
String? dateDelimiter;
|
||||||
|
DateTime now = DateTime.now();
|
||||||
|
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||||
|
|
||||||
|
late double amount;
|
||||||
|
late String finalAmount;
|
||||||
|
DateTime date = repository[0];
|
||||||
|
String dateForm;
|
||||||
|
bool isDelimiter = true;
|
||||||
|
|
||||||
|
if ({4, 10, 11, 12}.contains(date.month)) {
|
||||||
|
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 3)}.";
|
||||||
|
} else if ({1, 2, 7, 9}.contains(date.month)) {
|
||||||
|
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 4)}.";
|
||||||
|
} else {
|
||||||
|
dateForm = "${date.day} ${monthsInYear[date.month]}";
|
||||||
|
}
|
||||||
|
|
||||||
|
final transactionDate = DateTime(date.year, date.month, date.day);
|
||||||
|
final todayDate = DateTime(now.year, now.month, now.day);
|
||||||
|
final yesterdayDate = DateTime(now.year, now.month, now.day - 1);
|
||||||
|
|
||||||
|
if (transactionDate == todayDate && !isTody) {
|
||||||
|
dateDelimiter = lastDateDelimiter = "today".tr();
|
||||||
|
isTody = true;
|
||||||
|
} else if (transactionDate == yesterdayDate && !isYesterday) {
|
||||||
|
dateDelimiter = lastDateDelimiter = "yesterday".tr();
|
||||||
|
isYesterday = true;
|
||||||
|
} else if (weekNumber(date) == weekNumber(now) &&
|
||||||
|
date.year == now.year &&
|
||||||
|
transactionDate != yesterdayDate &&
|
||||||
|
transactionDate != todayDate &&
|
||||||
|
!isThisWeek) {
|
||||||
|
dateDelimiter = lastDateDelimiter = "thisWeek".tr();
|
||||||
|
isThisWeek = true;
|
||||||
|
} else if (lastDateDelimiter != "${monthsInYear[date.month]} ${date.year}" &&
|
||||||
|
transactionDate != todayDate &&
|
||||||
|
transactionDate != yesterdayDate &&
|
||||||
|
!(weekNumber(date) == weekNumber(now) && date.year == now.year)) {
|
||||||
|
if (date.year == now.year) {
|
||||||
|
dateDelimiter = lastDateDelimiter = monthsInYear[date.month];
|
||||||
|
} else {
|
||||||
|
dateDelimiter =
|
||||||
|
lastDateDelimiter = "${monthsInYear[date.month]} ${date.year}";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isDelimiter = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
amount = repository[4] == 'RECEIVED' ? repository[3] : repository[3] * -1;
|
||||||
|
|
||||||
|
if (isUdUnit) {
|
||||||
|
amount = round(amount / balanceRatio);
|
||||||
|
finalAmount = 'ud'.tr(args: ['$amount ']);
|
||||||
|
} else {
|
||||||
|
finalAmount = '$amount $currencyName';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (date.compareTo(startBlockchainTime) < 0) {
|
||||||
|
isMigrationTime = true;
|
||||||
|
} else {
|
||||||
|
isMigrationTime = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'finalAmount': finalAmount,
|
||||||
|
'isMigrationTime': isMigrationTime,
|
||||||
|
'dateDelimiter': dateDelimiter ?? '',
|
||||||
|
'isDelimiter': isDelimiter,
|
||||||
|
'dateForm': dateForm,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
int weekNumber(DateTime date) {
|
||||||
|
int dayOfYear = int.parse(DateFormat("D").format(date));
|
||||||
|
return ((dayOfYear - date.weekday + 10) / 7).floor();
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ class SearchProvider with ChangeNotifier {
|
||||||
List searchResult = [];
|
List searchResult = [];
|
||||||
final cacheDuring = 20 * 60 * 1000; //First number is minutes
|
final cacheDuring = 20 * 60 * 1000; //First number is minutes
|
||||||
int cacheTime = 0;
|
int cacheTime = 0;
|
||||||
|
int resultLenght = 0;
|
||||||
|
|
||||||
void reload() {
|
void reload() {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
|
@ -180,8 +180,6 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, double>> getBalance(String address) async {
|
Future<Map<String, double>> getBalance(String address) async {
|
||||||
log.d('BALANCE: $address');
|
|
||||||
|
|
||||||
if (!nodeConnected) {
|
if (!nodeConnected) {
|
||||||
return {
|
return {
|
||||||
'transferableBalance': 0,
|
'transferableBalance': 0,
|
||||||
|
@ -220,6 +218,8 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
};
|
};
|
||||||
|
|
||||||
// log.i(finalBalances);
|
// log.i(finalBalances);
|
||||||
|
log.d(
|
||||||
|
'${getShortPubkey(address)} --- BALANCE: ${finalBalances['transferableBalance']}');
|
||||||
|
|
||||||
return finalBalances;
|
return finalBalances;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,29 +5,35 @@ 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/queries_indexer.dart';
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
import 'package:gecko/models/widgets_keys.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:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gecko/screens/wallet_view.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/page_route_no_transition.dart';
|
import 'package:gecko/widgets/transaction_tile.dart';
|
||||||
import 'package:graphql_flutter/graphql_flutter.dart';
|
import 'package:graphql_flutter/graphql_flutter.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
class ActivityScreen extends StatefulWidget 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 ScrollController scrollController = ScrollController();
|
|
||||||
final double avatarsSize = 80;
|
|
||||||
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;
|
FetchMore? fetchMore;
|
||||||
FetchMoreOptions? opts;
|
FetchMoreOptions? opts;
|
||||||
|
|
||||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -44,13 +50,15 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
||||||
),
|
),
|
||||||
bottomNavigationBar: const GeckoBottomAppBar(),
|
bottomNavigationBar: const GeckoBottomAppBar(),
|
||||||
body: Column(children: <Widget>[
|
body: Column(children: <Widget>[
|
||||||
HeaderProfile(address: address, username: username),
|
HeaderProfile(address: widget.address, username: widget.username),
|
||||||
historyQuery(context),
|
historyQuery(context),
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget historyQuery(context) {
|
Widget historyQuery(context) {
|
||||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||||
|
int nPage = 1;
|
||||||
|
int nRepositories = 20;
|
||||||
|
|
||||||
if (indexerEndpoint == '') {
|
if (indexerEndpoint == '') {
|
||||||
return Column(children: <Widget>[
|
return Column(children: <Widget>[
|
||||||
|
@ -85,7 +93,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
||||||
options: QueryOptions(
|
options: QueryOptions(
|
||||||
document: gql(getHistoryByAddressQ),
|
document: gql(getHistoryByAddressQ),
|
||||||
variables: <String, dynamic>{
|
variables: <String, dynamic>{
|
||||||
'address': address,
|
'address': widget.address,
|
||||||
'number': 20,
|
'number': 20,
|
||||||
'cursor': null
|
'cursor': null
|
||||||
},
|
},
|
||||||
|
@ -93,7 +101,9 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
||||||
builder: (QueryResult result, {fetchMore, refetch}) {
|
builder: (QueryResult result, {fetchMore, refetch}) {
|
||||||
if (result.isLoading && result.data == null) {
|
if (result.isLoading && result.data == null) {
|
||||||
return const Center(
|
return const Center(
|
||||||
child: CircularProgressIndicator(),
|
child: CircularProgressIndicator(
|
||||||
|
color: orangeC,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,8 +129,22 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.isNotLoading) {
|
if (result.isNotLoading) {
|
||||||
// log.d(result.data);
|
if (duniterIndexer.fetchMoreCursor == null) nPage = 1;
|
||||||
opts = duniterIndexer.checkQueryResult(result, opts, address);
|
|
||||||
|
// 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
|
// Build history list
|
||||||
|
@ -153,6 +177,11 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
||||||
|
|
||||||
Widget historyView(context, result) {
|
Widget historyView(context, result) {
|
||||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
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
|
return duniterIndexer.transBC == null
|
||||||
? Column(children: <Widget>[
|
? Column(children: <Widget>[
|
||||||
|
@ -163,7 +192,53 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
||||||
)
|
)
|
||||||
])
|
])
|
||||||
: Column(children: <Widget>[
|
: Column(children: <Widget>[
|
||||||
getTransactionTile(context, duniterIndexer),
|
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'])
|
if (result.isLoading && duniterIndexer.pageInfo!['hasPreviousPage'])
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
@ -183,196 +258,4 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget getTransactionTile(
|
|
||||||
BuildContext context, DuniterIndexer duniterIndexer) {
|
|
||||||
int keyID = 0;
|
|
||||||
String? dateDelimiter;
|
|
||||||
String? lastDateDelimiter;
|
|
||||||
const double avatarSize = 200;
|
|
||||||
|
|
||||||
bool isTody = false;
|
|
||||||
bool isYesterday = false;
|
|
||||||
bool isThisWeek = false;
|
|
||||||
bool isMigrationTime = false;
|
|
||||||
bool isMigrationTimePassed = false;
|
|
||||||
|
|
||||||
final Map<int, String> monthsInYear = {
|
|
||||||
1: "month1".tr(),
|
|
||||||
2: "month2".tr(),
|
|
||||||
3: "month3".tr(),
|
|
||||||
4: "month4".tr(),
|
|
||||||
5: "month5".tr(),
|
|
||||||
6: "month6".tr(),
|
|
||||||
7: "month7".tr(),
|
|
||||||
8: "month8".tr(),
|
|
||||||
9: "month9".tr(),
|
|
||||||
10: "month10".tr(),
|
|
||||||
11: "month11".tr(),
|
|
||||||
12: "month12".tr()
|
|
||||||
};
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
children: duniterIndexer.transBC!.map((repository) {
|
|
||||||
// log.d('bbbbbbbbbbbbbbbbbbbbbb: ' + repository.toString());
|
|
||||||
|
|
||||||
DateTime now = DateTime.now();
|
|
||||||
DateTime date = repository[0];
|
|
||||||
|
|
||||||
String dateForm;
|
|
||||||
if ({4, 10, 11, 12}.contains(date.month)) {
|
|
||||||
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 3)}.";
|
|
||||||
} else if ({1, 2, 7, 9}.contains(date.month)) {
|
|
||||||
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 4)}.";
|
|
||||||
} else {
|
|
||||||
dateForm = "${date.day} ${monthsInYear[date.month]}";
|
|
||||||
}
|
|
||||||
|
|
||||||
int weekNumber(DateTime date) {
|
|
||||||
int dayOfYear = int.parse(DateFormat("D").format(date));
|
|
||||||
return ((dayOfYear - date.weekday + 10) / 7).floor();
|
|
||||||
}
|
|
||||||
|
|
||||||
final transactionDate = DateTime(date.year, date.month, date.day);
|
|
||||||
final todayDate = DateTime(now.year, now.month, now.day);
|
|
||||||
final yesterdayDate = DateTime(now.year, now.month, now.day - 1);
|
|
||||||
|
|
||||||
if (transactionDate == todayDate && !isTody) {
|
|
||||||
dateDelimiter = lastDateDelimiter = "today".tr();
|
|
||||||
isTody = true;
|
|
||||||
} else if (transactionDate == yesterdayDate && !isYesterday) {
|
|
||||||
dateDelimiter = lastDateDelimiter = "yesterday".tr();
|
|
||||||
isYesterday = true;
|
|
||||||
} else if (weekNumber(date) == weekNumber(now) &&
|
|
||||||
date.year == now.year &&
|
|
||||||
lastDateDelimiter != "thisWeek".tr() &&
|
|
||||||
transactionDate != yesterdayDate &&
|
|
||||||
transactionDate != todayDate &&
|
|
||||||
!isThisWeek) {
|
|
||||||
dateDelimiter = lastDateDelimiter = "thisWeek".tr();
|
|
||||||
isThisWeek = true;
|
|
||||||
} else if (lastDateDelimiter != monthsInYear[date.month] &&
|
|
||||||
lastDateDelimiter != "${monthsInYear[date.month]} ${date.year}" &&
|
|
||||||
transactionDate != todayDate &&
|
|
||||||
transactionDate != yesterdayDate &&
|
|
||||||
!(weekNumber(date) == weekNumber(now) && date.year == now.year)) {
|
|
||||||
if (date.year == now.year) {
|
|
||||||
dateDelimiter = lastDateDelimiter = monthsInYear[date.month];
|
|
||||||
} else {
|
|
||||||
dateDelimiter =
|
|
||||||
lastDateDelimiter = "${monthsInYear[date.month]} ${date.year}";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dateDelimiter = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
|
||||||
late double amount;
|
|
||||||
late String finalAmount;
|
|
||||||
amount = repository[4] == 'RECEIVED' ? repository[3] : repository[3] * -1;
|
|
||||||
|
|
||||||
if (isUdUnit) {
|
|
||||||
amount = round(amount / balanceRatio);
|
|
||||||
finalAmount = 'ud'.tr(args: ['$amount ']);
|
|
||||||
} else {
|
|
||||||
finalAmount = '$amount $currencyName';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isMigrationTimePassed && date.compareTo(startBlockchainTime) < 0) {
|
|
||||||
isMigrationTimePassed = true;
|
|
||||||
isMigrationTime = true;
|
|
||||||
} else {
|
|
||||||
isMigrationTime = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (dateDelimiter != null)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 30),
|
|
||||||
child: Text(
|
|
||||||
dateDelimiter!,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 23, color: orangeC, fontWeight: FontWeight.w300),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 0),
|
|
||||||
child:
|
|
||||||
// Row(children: [Column(children: [],)],)
|
|
||||||
ListTile(
|
|
||||||
key: keyTransaction(keyID++),
|
|
||||||
contentPadding: const EdgeInsets.only(
|
|
||||||
left: 20, right: 30, top: 15, bottom: 15),
|
|
||||||
leading: ClipOval(
|
|
||||||
child: defaultAvatar(avatarSize),
|
|
||||||
),
|
|
||||||
title: Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 5),
|
|
||||||
child: Text(getShortPubkey(repository[1]),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 18, fontFamily: 'Monospace')),
|
|
||||||
),
|
|
||||||
subtitle: RichText(
|
|
||||||
text: TextSpan(
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.grey[700],
|
|
||||||
),
|
|
||||||
children: <TextSpan>[
|
|
||||||
TextSpan(
|
|
||||||
text: dateForm,
|
|
||||||
),
|
|
||||||
if (repository[2] != '')
|
|
||||||
TextSpan(
|
|
||||||
text: ' · ',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
color: Colors.grey[550],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
TextSpan(
|
|
||||||
text: repository[2],
|
|
||||||
style: TextStyle(
|
|
||||||
fontStyle: FontStyle.italic,
|
|
||||||
color: Colors.grey[600],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
trailing: Text(finalAmount,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 18, fontWeight: FontWeight.w500),
|
|
||||||
textAlign: TextAlign.justify),
|
|
||||||
dense: false,
|
|
||||||
isThreeLine: false,
|
|
||||||
onTap: () {
|
|
||||||
duniterIndexer.nPage = 1;
|
|
||||||
// _cesiumPlusProvider.avatarCancelToken.cancel('cancelled');
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
PageNoTransit(builder: (context) {
|
|
||||||
return WalletViewScreen(
|
|
||||||
address: repository[1],
|
|
||||||
username: username ?? '',
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
// Navigator.pop(context);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
}).toList());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,6 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
// sub.nodeConnected = false;
|
// sub.nodeConnected = false;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// TODO: fix random bad network status on startup
|
|
||||||
HomeProvider homeProvider =
|
HomeProvider homeProvider =
|
||||||
Provider.of<HomeProvider>(context, listen: false);
|
Provider.of<HomeProvider>(context, listen: false);
|
||||||
Connectivity()
|
Connectivity()
|
||||||
|
|
|
@ -58,8 +58,17 @@ class WalletsHome extends StatelessWidget {
|
||||||
ModalRoute.withName('/'),
|
ModalRoute.withName('/'),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
title: Text(currentChest.name!,
|
title: Row(
|
||||||
style: TextStyle(color: Colors.grey[850])),
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'assets/chests/${currentChest.imageName}',
|
||||||
|
height: 32,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 17),
|
||||||
|
Text(currentChest.name!,
|
||||||
|
style: TextStyle(color: Colors.grey[850])),
|
||||||
|
],
|
||||||
|
),
|
||||||
backgroundColor: const Color(0xffFFD58D),
|
backgroundColor: const Color(0xffFFD58D),
|
||||||
),
|
),
|
||||||
bottomNavigationBar: myWalletProvider.lastFlyBy == ''
|
bottomNavigationBar: myWalletProvider.lastFlyBy == ''
|
||||||
|
|
|
@ -2,18 +2,11 @@ import 'package:easy_localization/easy_localization.dart';
|
||||||
|
|
||||||
import 'package:gecko/globals.dart';
|
import 'package:gecko/globals.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gecko/models/wallet_data.dart';
|
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
|
||||||
import 'package:gecko/providers/cesium_plus.dart';
|
|
||||||
import 'package:gecko/models/g1_wallets_list.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/wallets_profiles.dart';
|
import 'package:gecko/providers/wallets_profiles.dart';
|
||||||
import 'package:gecko/screens/common_elements.dart';
|
import 'package:gecko/screens/common_elements.dart';
|
||||||
import 'package:gecko/screens/wallet_view.dart';
|
|
||||||
import 'package:gecko/widgets/balance.dart';
|
|
||||||
import 'package:gecko/widgets/bottom_app_bar.dart';
|
import 'package:gecko/widgets/bottom_app_bar.dart';
|
||||||
import 'package:gecko/widgets/name_by_address.dart';
|
import 'package:gecko/widgets/contacts_list.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class ContactsScreen extends StatelessWidget {
|
class ContactsScreen extends StatelessWidget {
|
||||||
|
@ -24,15 +17,9 @@ class ContactsScreen extends StatelessWidget {
|
||||||
WalletsProfilesProvider walletsProfilesClass =
|
WalletsProfilesProvider walletsProfilesClass =
|
||||||
Provider.of<WalletsProfilesProvider>(context, listen: true);
|
Provider.of<WalletsProfilesProvider>(context, listen: true);
|
||||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||||
|
|
||||||
double avatarSize = 55;
|
double avatarSize = 55;
|
||||||
|
|
||||||
final myContacts = contactsBox.toMap().values.toList();
|
final myContacts = contactsBox.toMap().values.toList();
|
||||||
|
|
||||||
// for (var element in myContacts) {
|
|
||||||
// log.d('yooo: ${element.pubkey} ${element.username}');
|
|
||||||
// }
|
|
||||||
|
|
||||||
myContacts.sort((p1, p2) {
|
myContacts.sort((p1, p2) {
|
||||||
return Comparable.compare(p1.username?.toLowerCase() ?? 'zz',
|
return Comparable.compare(p1.username?.toLowerCase() ?? 'zz',
|
||||||
p2.username?.toLowerCase() ?? 'zz');
|
p2.username?.toLowerCase() ?? 'zz');
|
||||||
|
@ -52,85 +39,11 @@ class ContactsScreen extends StatelessWidget {
|
||||||
bottomNavigationBar: const GeckoBottomAppBar(),
|
bottomNavigationBar: const GeckoBottomAppBar(),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Stack(children: [
|
child: Stack(children: [
|
||||||
Padding(
|
ContactsList(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
myContacts: myContacts,
|
||||||
child: Column(
|
avatarSize: avatarSize,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
walletsProfilesClass: walletsProfilesClass,
|
||||||
children: <Widget>[
|
duniterIndexer: duniterIndexer),
|
||||||
const SizedBox(height: 20),
|
|
||||||
if (myContacts.isEmpty)
|
|
||||||
Text('noContacts'.tr())
|
|
||||||
else
|
|
||||||
Expanded(
|
|
||||||
child: ListView(children: <Widget>[
|
|
||||||
for (G1WalletsList g1Wallet in myContacts)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
|
||||||
child: ListTile(
|
|
||||||
key: keySearchResult('keyID++'),
|
|
||||||
horizontalTitleGap: 40,
|
|
||||||
contentPadding: const EdgeInsets.all(5),
|
|
||||||
leading: defaultAvatar(avatarSize),
|
|
||||||
title: Row(children: <Widget>[
|
|
||||||
Text(getShortPubkey(g1Wallet.address),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
fontFamily: 'Monospace',
|
|
||||||
fontWeight: FontWeight.w500),
|
|
||||||
textAlign: TextAlign.center),
|
|
||||||
]),
|
|
||||||
trailing: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 110,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment:
|
|
||||||
MainAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
mainAxisAlignment:
|
|
||||||
MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Balance(
|
|
||||||
address:
|
|
||||||
g1Wallet.address,
|
|
||||||
size: 16),
|
|
||||||
]),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
subtitle: Row(children: <Widget>[
|
|
||||||
NameByAddress(
|
|
||||||
wallet:
|
|
||||||
WalletData(address: g1Wallet.address))
|
|
||||||
]),
|
|
||||||
dense: false,
|
|
||||||
isThreeLine: false,
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
walletsProfilesClass.address =
|
|
||||||
g1Wallet.address;
|
|
||||||
return WalletViewScreen(
|
|
||||||
address: g1Wallet.address,
|
|
||||||
username:
|
|
||||||
duniterIndexer.walletNameIndexer[
|
|
||||||
g1Wallet.address] ??
|
|
||||||
'',
|
|
||||||
avatar: g1WalletsBox
|
|
||||||
.get(g1Wallet.address)
|
|
||||||
?.avatar,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
CommonElements().offlineInfo(context),
|
CommonElements().offlineInfo(context),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:gecko/globals.dart';
|
import 'package:gecko/globals.dart';
|
||||||
|
@ -21,6 +23,8 @@ class SearchScreen extends StatefulWidget {
|
||||||
class _SearchScreenState extends State<SearchScreen> {
|
class _SearchScreenState extends State<SearchScreen> {
|
||||||
bool canPasteAddress = false;
|
bool canPasteAddress = false;
|
||||||
String pastedAddress = '';
|
String pastedAddress = '';
|
||||||
|
Timer? debounce;
|
||||||
|
final int debouneTime = 50;
|
||||||
|
|
||||||
Future getClipBoard() async {
|
Future getClipBoard() async {
|
||||||
final clipboard = await Clipboard.getData('text/plain');
|
final clipboard = await Clipboard.getData('text/plain');
|
||||||
|
@ -88,10 +92,12 @@ class _SearchScreenState extends State<SearchScreen> {
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
onChanged: (v) async => {
|
onChanged: (v) => {
|
||||||
await getClipBoard(),
|
if (debounce?.isActive ?? false) {debounce!.cancel()},
|
||||||
setState(() {}),
|
debounce = Timer(Duration(milliseconds: debouneTime), () {
|
||||||
searchProvider.reload()
|
getClipBoard();
|
||||||
|
searchProvider.reload();
|
||||||
|
})
|
||||||
},
|
},
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
filled: true,
|
filled: true,
|
||||||
|
@ -99,6 +105,23 @@ class _SearchScreenState extends State<SearchScreen> {
|
||||||
prefixIconConstraints: const BoxConstraints(
|
prefixIconConstraints: const BoxConstraints(
|
||||||
minHeight: 32,
|
minHeight: 32,
|
||||||
),
|
),
|
||||||
|
suffixIcon: searchProvider.searchController.text == ''
|
||||||
|
? null
|
||||||
|
: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: (() async => {
|
||||||
|
searchProvider.searchController.text = '',
|
||||||
|
await getClipBoard(),
|
||||||
|
searchProvider.reload(),
|
||||||
|
}),
|
||||||
|
icon: Icon(
|
||||||
|
Icons.close,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
size: 30,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
prefixIcon: const Padding(
|
prefixIcon: const Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 17),
|
padding: EdgeInsets.symmetric(horizontal: 17),
|
||||||
child: Image(
|
child: Image(
|
||||||
|
|
|
@ -2,19 +2,12 @@ import 'package:easy_localization/easy_localization.dart';
|
||||||
|
|
||||||
import 'package:gecko/globals.dart';
|
import 'package:gecko/globals.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gecko/models/wallet_data.dart';
|
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
|
||||||
import 'package:gecko/providers/cesium_plus.dart';
|
|
||||||
import 'package:gecko/models/g1_wallets_list.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/wallets_profiles.dart';
|
import 'package:gecko/providers/wallets_profiles.dart';
|
||||||
import 'package:gecko/providers/search.dart';
|
import 'package:gecko/providers/search.dart';
|
||||||
import 'package:gecko/screens/common_elements.dart';
|
import 'package:gecko/screens/common_elements.dart';
|
||||||
import 'package:gecko/screens/wallet_view.dart';
|
|
||||||
import 'package:gecko/widgets/balance.dart';
|
|
||||||
import 'package:gecko/widgets/bottom_app_bar.dart';
|
import 'package:gecko/widgets/bottom_app_bar.dart';
|
||||||
import 'package:gecko/widgets/name_by_address.dart';
|
import 'package:gecko/widgets/search_result_list.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class SearchResultScreen extends StatelessWidget {
|
class SearchResultScreen extends StatelessWidget {
|
||||||
|
@ -28,6 +21,13 @@ class SearchResultScreen extends StatelessWidget {
|
||||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||||
|
|
||||||
double avatarSize = 55;
|
double avatarSize = 55;
|
||||||
|
// List<G1WalletsList> myContacts = contactsBox.toMap().values.toList();
|
||||||
|
// myContacts = myContacts
|
||||||
|
// .where((map) =>
|
||||||
|
// (map.username ?? '').contains(searchProvider.searchController.text))
|
||||||
|
// .toList();
|
||||||
|
|
||||||
|
// final searchProvider.resultLenght.toString();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
|
@ -48,126 +48,42 @@ class SearchResultScreen extends StatelessWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
const SizedBox(height: 30),
|
const SizedBox(height: 30),
|
||||||
RichText(
|
Center(
|
||||||
text: TextSpan(
|
child: Column(
|
||||||
style: TextStyle(
|
children: <Widget>[
|
||||||
fontSize: 18,
|
Text(
|
||||||
color: Colors.grey[700],
|
"resultsFor".tr(),
|
||||||
),
|
style: TextStyle(color: Colors.grey[600]),
|
||||||
children: <TextSpan>[
|
|
||||||
TextSpan(
|
|
||||||
text: "resultsFor".tr(),
|
|
||||||
),
|
|
||||||
TextSpan(
|
|
||||||
text: '"${searchProvider.searchController.text}"',
|
|
||||||
style: const TextStyle(fontStyle: FontStyle.italic),
|
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
'"${searchProvider.searchController.text}"',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontStyle: FontStyle.italic, fontSize: 21),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
// const SizedBox(height: 40),
|
||||||
|
// Text(
|
||||||
|
// 'Dans mes contacts'.tr(args: [currencyName]),
|
||||||
|
// style: const TextStyle(fontSize: 20),
|
||||||
|
// ),
|
||||||
|
// ContactsList(
|
||||||
|
// myContacts: myContacts,
|
||||||
|
// avatarSize: avatarSize,
|
||||||
|
// walletsProfilesClass: walletsProfilesClass,
|
||||||
|
// duniterIndexer: duniterIndexer),
|
||||||
const SizedBox(height: 40),
|
const SizedBox(height: 40),
|
||||||
Text(
|
Text(
|
||||||
'inBlockchainResult'.tr(args: [currencyName]),
|
'inBlockchainResult'.tr(args: [currencyName]),
|
||||||
style: const TextStyle(fontSize: 20),
|
style: const TextStyle(fontSize: 20),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
FutureBuilder(
|
SearchResult(
|
||||||
future: searchProvider.searchAddress(),
|
searchProvider: searchProvider,
|
||||||
builder: (context, AsyncSnapshot<List?> snapshot) {
|
duniterIndexer: duniterIndexer,
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
avatarSize: avatarSize,
|
||||||
if (snapshot.data?.isEmpty ?? true) {
|
walletsProfilesClass: walletsProfilesClass),
|
||||||
return duniterIndexer.searchIdentity(
|
|
||||||
context, searchProvider.searchController.text);
|
|
||||||
// const Text('Aucun résultat');
|
|
||||||
} else {
|
|
||||||
return Expanded(
|
|
||||||
child: ListView(children: <Widget>[
|
|
||||||
for (G1WalletsList g1Wallet
|
|
||||||
in snapshot.data ?? [])
|
|
||||||
Padding(
|
|
||||||
padding:
|
|
||||||
const EdgeInsets.symmetric(horizontal: 5),
|
|
||||||
child: ListTile(
|
|
||||||
key: keySearchResult(g1Wallet.address),
|
|
||||||
horizontalTitleGap: 40,
|
|
||||||
contentPadding: const EdgeInsets.all(5),
|
|
||||||
leading: defaultAvatar(avatarSize),
|
|
||||||
title: Row(children: <Widget>[
|
|
||||||
Text(getShortPubkey(g1Wallet.address),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
fontFamily: 'Monospace',
|
|
||||||
fontWeight: FontWeight.w500),
|
|
||||||
textAlign: TextAlign.center),
|
|
||||||
]),
|
|
||||||
trailing: Column(
|
|
||||||
mainAxisAlignment:
|
|
||||||
MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 110,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment:
|
|
||||||
MainAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
mainAxisAlignment:
|
|
||||||
MainAxisAlignment
|
|
||||||
.center,
|
|
||||||
children: [
|
|
||||||
Balance(
|
|
||||||
address: g1Wallet
|
|
||||||
.address,
|
|
||||||
size: 16),
|
|
||||||
]),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
subtitle: Row(children: <Widget>[
|
|
||||||
NameByAddress(
|
|
||||||
wallet: WalletData(
|
|
||||||
address: g1Wallet.address),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
dense: false,
|
|
||||||
isThreeLine: false,
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
walletsProfilesClass.address =
|
|
||||||
g1Wallet.address;
|
|
||||||
return WalletViewScreen(
|
|
||||||
address: g1Wallet.address,
|
|
||||||
username: duniterIndexer
|
|
||||||
.walletNameIndexer[
|
|
||||||
g1Wallet.address] ??
|
|
||||||
'',
|
|
||||||
avatar: g1WalletsBox
|
|
||||||
.get(g1Wallet.address)
|
|
||||||
?.avatar,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return const Center(
|
|
||||||
heightFactor: 5,
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 3,
|
|
||||||
backgroundColor: yellowC,
|
|
||||||
color: orangeC,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
// Text(
|
|
||||||
// _searchProvider.searchResult.toString(),
|
|
||||||
// )
|
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
CommonElements().offlineInfo(context),
|
CommonElements().offlineInfo(context),
|
||||||
|
|
|
@ -162,8 +162,8 @@ class WalletViewScreen extends StatelessWidget {
|
||||||
builder: (context, AsyncSnapshot<Map<String, int>> snapshot) {
|
builder: (context, AsyncSnapshot<Map<String, int>> snapshot) {
|
||||||
if (snapshot.data == null) return const SizedBox();
|
if (snapshot.data == null) return const SizedBox();
|
||||||
String duration = '';
|
String duration = '';
|
||||||
log.d('certDelay ${snapshot.data!['certDelay']}');
|
log.d(
|
||||||
log.d('certRenewable ${snapshot.data!['certRenewable']}');
|
'${getShortPubkey(address)} --- certDelay ${snapshot.data!['certDelay']} --- certRenewable ${snapshot.data!['certRenewable']}');
|
||||||
|
|
||||||
if (snapshot.data!['certDelay'] != null ||
|
if (snapshot.data!['certDelay'] != null ||
|
||||||
snapshot.data!['certRenewable'] != null) {
|
snapshot.data!['certRenewable'] != null) {
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gecko/globals.dart';
|
||||||
|
import 'package:gecko/models/g1_wallets_list.dart';
|
||||||
|
import 'package:gecko/models/wallet_data.dart';
|
||||||
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
|
import 'package:gecko/providers/cesium_plus.dart';
|
||||||
|
import 'package:gecko/providers/duniter_indexer.dart';
|
||||||
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
|
import 'package:gecko/providers/wallets_profiles.dart';
|
||||||
|
import 'package:gecko/screens/wallet_view.dart';
|
||||||
|
import 'package:gecko/widgets/balance.dart';
|
||||||
|
import 'package:gecko/widgets/name_by_address.dart';
|
||||||
|
|
||||||
|
class ContactsList extends StatelessWidget {
|
||||||
|
const ContactsList({
|
||||||
|
Key? key,
|
||||||
|
required this.myContacts,
|
||||||
|
required this.avatarSize,
|
||||||
|
required this.walletsProfilesClass,
|
||||||
|
required this.duniterIndexer,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final List<G1WalletsList> myContacts;
|
||||||
|
final double avatarSize;
|
||||||
|
final WalletsProfilesProvider walletsProfilesClass;
|
||||||
|
final DuniterIndexer duniterIndexer;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
if (myContacts.isEmpty)
|
||||||
|
Text('noContacts'.tr())
|
||||||
|
else
|
||||||
|
Expanded(
|
||||||
|
child: ListView(children: <Widget>[
|
||||||
|
for (G1WalletsList g1Wallet in myContacts)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||||
|
child: ListTile(
|
||||||
|
key: keySearchResult('keyID++'),
|
||||||
|
horizontalTitleGap: 40,
|
||||||
|
contentPadding: const EdgeInsets.all(5),
|
||||||
|
leading: defaultAvatar(avatarSize),
|
||||||
|
title: Row(children: <Widget>[
|
||||||
|
Text(getShortPubkey(g1Wallet.address),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontFamily: 'Monospace',
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
textAlign: TextAlign.center),
|
||||||
|
]),
|
||||||
|
trailing: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 110,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Balance(
|
||||||
|
address: g1Wallet.address,
|
||||||
|
size: 16),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
subtitle: Row(children: <Widget>[
|
||||||
|
NameByAddress(
|
||||||
|
wallet: WalletData(address: g1Wallet.address))
|
||||||
|
]),
|
||||||
|
dense: false,
|
||||||
|
isThreeLine: false,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) {
|
||||||
|
walletsProfilesClass.address = g1Wallet.address;
|
||||||
|
return WalletViewScreen(
|
||||||
|
address: g1Wallet.address,
|
||||||
|
username: duniterIndexer.walletNameIndexer[
|
||||||
|
g1Wallet.address] ??
|
||||||
|
'',
|
||||||
|
avatar: g1WalletsBox
|
||||||
|
.get(g1Wallet.address)
|
||||||
|
?.avatar,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
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/cesium_plus.dart';
|
||||||
|
import 'package:gecko/providers/duniter_indexer.dart';
|
||||||
|
import 'package:gecko/providers/search.dart';
|
||||||
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
|
import 'package:gecko/providers/wallets_profiles.dart';
|
||||||
|
import 'package:gecko/screens/wallet_view.dart';
|
||||||
|
import 'package:gecko/widgets/balance.dart';
|
||||||
|
import 'package:graphql_flutter/graphql_flutter.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class SearchIdentityQuery extends StatelessWidget {
|
||||||
|
const SearchIdentityQuery({Key? key, required this.name}) : super(key: key);
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
WalletsProfilesProvider walletsProfiles =
|
||||||
|
Provider.of<WalletsProfilesProvider>(context, listen: false);
|
||||||
|
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||||
|
final searchProvider = Provider.of<SearchProvider>(context, listen: false);
|
||||||
|
if (indexerEndpoint == '') {
|
||||||
|
return const Text('Aucun résultat');
|
||||||
|
}
|
||||||
|
|
||||||
|
log.d(indexerEndpoint);
|
||||||
|
final httpLink = HttpLink(
|
||||||
|
'$indexerEndpoint/v1/graphql',
|
||||||
|
);
|
||||||
|
|
||||||
|
final client = ValueNotifier(
|
||||||
|
GraphQLClient(
|
||||||
|
cache: GraphQLCache(
|
||||||
|
store: HiveStore()), // 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.isLoading) {
|
||||||
|
return Text('loading'.tr());
|
||||||
|
}
|
||||||
|
|
||||||
|
final List identities = result.data?['search_identity'] ?? [];
|
||||||
|
|
||||||
|
if (identities.isEmpty) {
|
||||||
|
return Text('noResult'.tr());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map profile in identities) {
|
||||||
|
duniterIndexer.walletNameIndexer
|
||||||
|
.putIfAbsent(profile['pubkey'], () => profile['name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
searchProvider.resultLenght = identities.length;
|
||||||
|
// TODO: Find a way to reload a provider here, in Widget build...
|
||||||
|
|
||||||
|
double avatarSize = 55;
|
||||||
|
return Expanded(
|
||||||
|
child: ListView(children: <Widget>[
|
||||||
|
for (Map profile in identities)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||||
|
child: ListTile(
|
||||||
|
key: keySearchResult(profile['pubkey']),
|
||||||
|
horizontalTitleGap: 40,
|
||||||
|
contentPadding: const EdgeInsets.all(5),
|
||||||
|
leading: defaultAvatar(avatarSize),
|
||||||
|
title: Row(children: <Widget>[
|
||||||
|
Text(getShortPubkey(profile['pubkey']),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontFamily: 'Monospace',
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
textAlign: TextAlign.center),
|
||||||
|
]),
|
||||||
|
trailing: SizedBox(
|
||||||
|
width: 110,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Balance(
|
||||||
|
address: profile['pubkey'], size: 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['pubkey'];
|
||||||
|
return WalletViewScreen(
|
||||||
|
address: profile['pubkey'],
|
||||||
|
username: name,
|
||||||
|
avatar:
|
||||||
|
g1WalletsBox.get(profile['pubkey'])?.avatar,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gecko/globals.dart';
|
||||||
|
import 'package:gecko/models/g1_wallets_list.dart';
|
||||||
|
import 'package:gecko/models/wallet_data.dart';
|
||||||
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
|
import 'package:gecko/providers/cesium_plus.dart';
|
||||||
|
import 'package:gecko/providers/duniter_indexer.dart';
|
||||||
|
import 'package:gecko/providers/search.dart';
|
||||||
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
|
import 'package:gecko/providers/wallets_profiles.dart';
|
||||||
|
import 'package:gecko/screens/wallet_view.dart';
|
||||||
|
import 'package:gecko/widgets/balance.dart';
|
||||||
|
import 'package:gecko/widgets/name_by_address.dart';
|
||||||
|
import 'package:gecko/widgets/search_identity_query.dart';
|
||||||
|
|
||||||
|
class SearchResult extends StatelessWidget {
|
||||||
|
const SearchResult({
|
||||||
|
Key? key,
|
||||||
|
required this.searchProvider,
|
||||||
|
required this.duniterIndexer,
|
||||||
|
required this.avatarSize,
|
||||||
|
required this.walletsProfilesClass,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final SearchProvider searchProvider;
|
||||||
|
final DuniterIndexer duniterIndexer;
|
||||||
|
final double avatarSize;
|
||||||
|
final WalletsProfilesProvider walletsProfilesClass;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return FutureBuilder(
|
||||||
|
future: searchProvider.searchAddress(),
|
||||||
|
builder: (context, AsyncSnapshot<List?> snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
if (snapshot.data?.isEmpty ?? true) {
|
||||||
|
return SearchIdentityQuery(
|
||||||
|
name: searchProvider.searchController.text);
|
||||||
|
// const Text('Aucun résultat');
|
||||||
|
} else {
|
||||||
|
return Expanded(
|
||||||
|
child: ListView(children: <Widget>[
|
||||||
|
for (G1WalletsList g1Wallet in snapshot.data ?? [])
|
||||||
|
resultTile(g1Wallet, context),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return const Center(
|
||||||
|
heightFactor: 5,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 3,
|
||||||
|
backgroundColor: yellowC,
|
||||||
|
color: orangeC,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Padding resultTile(G1WalletsList g1Wallet, BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||||
|
child: ListTile(
|
||||||
|
key: keySearchResult(g1Wallet.address),
|
||||||
|
horizontalTitleGap: 40,
|
||||||
|
contentPadding: const EdgeInsets.all(5),
|
||||||
|
leading: defaultAvatar(avatarSize),
|
||||||
|
title: Row(children: <Widget>[
|
||||||
|
Text(getShortPubkey(g1Wallet.address),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontFamily: 'Monospace',
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
textAlign: TextAlign.center),
|
||||||
|
]),
|
||||||
|
trailing:
|
||||||
|
Column(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 110,
|
||||||
|
child: Row(mainAxisAlignment: MainAxisAlignment.end, children: [
|
||||||
|
Column(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||||
|
Balance(address: g1Wallet.address, size: 16),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
subtitle: Row(children: <Widget>[
|
||||||
|
NameByAddress(
|
||||||
|
wallet: WalletData(address: g1Wallet.address),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
dense: false,
|
||||||
|
isThreeLine: false,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) {
|
||||||
|
walletsProfilesClass.address = g1Wallet.address;
|
||||||
|
return WalletViewScreen(
|
||||||
|
address: g1Wallet.address,
|
||||||
|
username:
|
||||||
|
duniterIndexer.walletNameIndexer[g1Wallet.address] ?? '',
|
||||||
|
avatar: g1WalletsBox.get(g1Wallet.address)?.avatar,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
|
import 'package:gecko/providers/cesium_plus.dart';
|
||||||
|
import 'package:gecko/providers/duniter_indexer.dart';
|
||||||
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
|
import 'package:gecko/screens/activity.dart';
|
||||||
|
import 'package:gecko/screens/wallet_view.dart';
|
||||||
|
import 'package:gecko/widgets/page_route_no_transition.dart';
|
||||||
|
|
||||||
|
class TransactionTile extends StatelessWidget {
|
||||||
|
const TransactionTile({
|
||||||
|
Key? key,
|
||||||
|
required this.widget,
|
||||||
|
required this.keyID,
|
||||||
|
required this.avatarSize,
|
||||||
|
required this.repository,
|
||||||
|
required this.dateForm,
|
||||||
|
required this.finalAmount,
|
||||||
|
required this.duniterIndexer,
|
||||||
|
required this.context,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final ActivityScreen widget;
|
||||||
|
final int keyID;
|
||||||
|
final double avatarSize;
|
||||||
|
final List repository;
|
||||||
|
final String dateForm;
|
||||||
|
final String finalAmount;
|
||||||
|
final DuniterIndexer duniterIndexer;
|
||||||
|
final BuildContext context;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final newKey = keyID + 1;
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 0),
|
||||||
|
child: ListTile(
|
||||||
|
key: keyTransaction(newKey),
|
||||||
|
contentPadding:
|
||||||
|
const EdgeInsets.only(left: 20, right: 30, top: 15, bottom: 15),
|
||||||
|
leading: ClipOval(
|
||||||
|
child: defaultAvatar(avatarSize),
|
||||||
|
),
|
||||||
|
title: Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 5),
|
||||||
|
child: Text(getShortPubkey(repository[1]),
|
||||||
|
style: const TextStyle(fontSize: 18, fontFamily: 'Monospace')),
|
||||||
|
),
|
||||||
|
subtitle: RichText(
|
||||||
|
text: TextSpan(
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
color: Colors.grey[700],
|
||||||
|
),
|
||||||
|
children: <TextSpan>[
|
||||||
|
TextSpan(
|
||||||
|
text: dateForm,
|
||||||
|
),
|
||||||
|
if (repository[2] != '')
|
||||||
|
TextSpan(
|
||||||
|
text: ' · ',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
color: Colors.grey[550],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: repository[2],
|
||||||
|
style: TextStyle(
|
||||||
|
fontStyle: FontStyle.italic,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
trailing: Text(finalAmount,
|
||||||
|
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
|
||||||
|
textAlign: TextAlign.justify),
|
||||||
|
dense: false,
|
||||||
|
isThreeLine: false,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
PageNoTransit(builder: (context) {
|
||||||
|
return WalletViewScreen(
|
||||||
|
address: repository[1],
|
||||||
|
username: widget.username ?? '',
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
// Navigator.pop(context);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue