Search is working (WIP performance improvements)

This commit is contained in:
poka 2021-11-26 08:56:20 +01:00
parent 2ecf10eb03
commit 616801e6fe
9 changed files with 382 additions and 102 deletions

View File

@ -1,6 +1,7 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:hive/hive.dart';
import 'package:logger/logger.dart';
@ -16,9 +17,10 @@ int ramSys;
Box<WalletData> walletBox;
Box<ChestData> chestBox;
Box configBox;
Box<G1WalletsList> g1WalletsBox;
// String cesiumPod = "https://g1.data.le-sou.org";
String cesiumPod = "https://g1.data.e-is.pro";
String cesiumPod = "https://g1.data.le-sou.org";
// String cesiumPod = "https://g1.data.e-is.pro";
// Responsive ratios
bool isTall;

View File

@ -23,6 +23,7 @@ import 'package:gecko/models/cesium_plus.dart';
import 'package:gecko/models/change_pin.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/chest_provider.dart';
import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/models/generate_wallets.dart';
import 'package:gecko/models/history.dart';
import 'package:gecko/models/home.dart';
@ -58,9 +59,12 @@ Future<void> main() async {
await Hive.initFlutter(appPath.path);
Hive.registerAdapter(WalletDataAdapter());
Hive.registerAdapter(ChestDataAdapter());
Hive.registerAdapter(G1WalletsListAdapter());
Hive.registerAdapter(IdAdapter());
walletBox = await Hive.openBox<WalletData>("walletBox");
chestBox = await Hive.openBox<ChestData>("chestBox");
configBox = await Hive.openBox("configBox");
g1WalletsBox = await Hive.openBox<G1WalletsList>("g1WalletsBox");
// final HiveStore _store =
// await HiveStore.open(path: '${appPath.path}/gqlCache');

View File

@ -0,0 +1,53 @@
import 'package:hive_flutter/hive_flutter.dart';
part 'g1_wallets_list.g.dart';
@HiveType(typeId: 2)
class G1WalletsList {
@HiveField(0)
String pubkey;
@HiveField(1)
double balance;
@HiveField(3)
Id id;
G1WalletsList({this.pubkey, this.balance, this.id});
G1WalletsList.fromJson(Map<String, dynamic> json) {
pubkey = json['pubkey'];
balance = json['balance'];
id = json['id'] != null ? Id.fromJson(json['id']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['pubkey'] = pubkey;
data['balance'] = balance;
if (id != null) {
data['id'] = id.toJson();
}
return data;
}
}
@HiveType(typeId: 3)
class Id {
bool isMember;
String username;
Id({this.isMember, this.username});
Id.fromJson(Map<String, dynamic> json) {
isMember = json['isMember'];
username = json['username'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['isMember'] = isMember;
data['username'] = username;
return data;
}
}

View File

@ -0,0 +1,72 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'g1_wallets_list.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class G1WalletsListAdapter extends TypeAdapter<G1WalletsList> {
@override
final int typeId = 2;
@override
G1WalletsList read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return G1WalletsList(
pubkey: fields[0] as String,
balance: fields[1] as double,
id: fields[3] as Id,
);
}
@override
void write(BinaryWriter writer, G1WalletsList obj) {
writer
..writeByte(3)
..writeByte(0)
..write(obj.pubkey)
..writeByte(1)
..write(obj.balance)
..writeByte(3)
..write(obj.id);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is G1WalletsListAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class IdAdapter extends TypeAdapter<Id> {
@override
final int typeId = 3;
@override
Id read(BinaryReader reader) {
return Id();
}
@override
void write(BinaryWriter writer, Id obj) {
writer.writeByte(0);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is IdAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@ -1,12 +1,61 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/g1_wallets_list.dart';
import 'package:http/http.dart' as http;
class SearchProvider with ChangeNotifier {
TextEditingController searchController = TextEditingController();
List searchResult = [];
final cacheDuring = 60 * 60 * 1000; //First number is minutes
int cacheTime = 0;
void rebuildWidget() {
notifyListeners();
}
void searchPubkey() {}
Future<List> searchBlockchain() async {
searchResult.clear();
int searchTime = DateTime.now().millisecondsSinceEpoch;
if (cacheTime + cacheDuring <= searchTime) {
var url = Uri.parse('https://g1-stats.axiom-team.fr/data/forbes.json');
var response = await http.get(url);
// print('Response body: ${response.body}');
List<G1WalletsList> _listWallets =
await compute(_parseG1Wallets, response.body);
for (G1WalletsList element in _listWallets) {
await g1WalletsBox.put(element.pubkey, element);
}
cacheTime = DateTime.now().millisecondsSinceEpoch;
}
g1WalletsBox.toMap().forEach((key, value) {
if ((value.id != null &&
value.id.username != null &&
value.id.username.contains(searchController.text)) ||
value.pubkey.contains(searchController.text)) {
searchResult.add(value);
return;
}
});
return searchResult;
// notifyListeners();
// log.i(g1WalletsBox
// .get('1N18iwCfzLYd7u6DTKafVrzs9bPyeYTGHoc5SsLMcfv')
// .balance);
}
}
List<G1WalletsList> _parseG1Wallets(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed
.map<G1WalletsList>((json) => G1WalletsList.fromJson(json))
.toList();
}

View File

@ -34,14 +34,15 @@ class CommonElements {
margin: const BubbleEdges.fromLTRB(10, 0, 20, 10),
// nip: BubbleNip.leftTop,
child: RichText(
key: textKey,
text: TextSpan(
style: const TextStyle(
fontSize: 18.0,
color: Colors.black,
),
children: text,
)),
key: textKey,
text: TextSpan(
style: const TextStyle(
fontSize: 18.0,
color: Colors.black,
),
children: text,
),
),
);
}

View File

@ -187,47 +187,48 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
children: [
if (_isFirstExec)
Container(
padding: const EdgeInsets.fromLTRB(
20, 0, 30, 0),
child: FutureBuilder(
future:
_cesiumPlusProvider.getAvatar(
_historyProvider.pubkey),
initialData: [
File(appPath.path +
'/default_avatar.png')
],
builder: (BuildContext context,
AsyncSnapshot<List> _avatar) {
cesiumData = _avatar.data;
// _cesiumPlusProvider.isComplete = true;
if (_avatar.connectionState !=
ConnectionState.done) {
return Image.file(
File(appPath.path +
'/default_avatar.png'),
height: avatarsSize);
}
if (_avatar.hasError) {
return Image.file(
File(appPath.path +
'/default_avatar.png'),
height: avatarsSize);
}
if (_avatar.hasData) {
return SingleChildScrollView(
padding:
const EdgeInsets.all(
0.0),
child: Image.file(
_avatar.data[0],
height: avatarsSize));
}
padding: const EdgeInsets.fromLTRB(
20, 0, 30, 0),
child: FutureBuilder(
future:
_cesiumPlusProvider.getAvatar(
_historyProvider.pubkey),
initialData: [
File(appPath.path +
'/default_avatar.png')
],
builder: (BuildContext context,
AsyncSnapshot<List> _avatar) {
cesiumData = _avatar.data;
// _cesiumPlusProvider.isComplete = true;
if (_avatar.connectionState !=
ConnectionState.done) {
return Image.file(
File(appPath.path +
'/default_avatar.png'),
height: avatarsSize);
})),
}
if (_avatar.hasError) {
return Image.file(
File(appPath.path +
'/default_avatar.png'),
height: avatarsSize);
}
if (_avatar.hasData) {
return SingleChildScrollView(
padding:
const EdgeInsets.all(
0.0),
child: Image.file(
_avatar.data[0],
height: avatarsSize));
}
return Image.file(
File(appPath.path +
'/default_avatar.png'),
height: avatarsSize);
}),
),
GestureDetector(
key: const Key('copyPubkey'),
onTap: () {
@ -270,18 +271,19 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.fromLTRB(
0, 0, 0, 0),
// padding: const EdgeInsets.,
child: FutureBuilder(
future: _cesiumPlusProvider.getName(
_historyProvider.pubkey),
initialData: '...',
builder: (context, snapshot) {
return Text(snapshot.data ?? '-',
style: const TextStyle(
fontSize: 20));
}))
padding:
const EdgeInsets.fromLTRB(0, 0, 0, 0),
// padding: const EdgeInsets.,
child: FutureBuilder(
future: _cesiumPlusProvider
.getName(_historyProvider.pubkey),
initialData: '...',
builder: (context, snapshot) {
return Text(snapshot.data ?? '-',
style: const TextStyle(
fontSize: 20));
}),
)
]),
const SizedBox(height: 18),
if (_isFirstExec)
@ -420,32 +422,33 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
: Column(children: <Widget>[
for (var repository in _historyProvider.transBC)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5.0),
child: ListTile(
key: Key('transaction${keyID++}'),
contentPadding: const EdgeInsets.all(5.0),
leading: Text(repository[1].toString(),
style: TextStyle(
fontSize: 12,
color: Colors.grey[800],
fontWeight: FontWeight.w700),
textAlign: TextAlign.center),
title: Text(repository[3],
style: const TextStyle(
fontSize: 15.0, fontFamily: 'Monospace'),
textAlign: TextAlign.center),
subtitle: Text(repository[6] != '' ? repository[6] : '-',
style: const TextStyle(fontSize: 12.0),
textAlign: TextAlign.center),
trailing: Text("${repository[4]} Ğ1",
style: const TextStyle(fontSize: 14.0),
textAlign: TextAlign.justify),
dense: true,
isThreeLine: false,
onTap: () {
// this._outputPubkey.text = repository[2];
_historyProvider.isPubkey(context, repository[2]);
})),
padding: const EdgeInsets.symmetric(horizontal: 5.0),
child: ListTile(
key: Key('transaction${keyID++}'),
contentPadding: const EdgeInsets.all(5.0),
leading: Text(repository[1].toString(),
style: TextStyle(
fontSize: 12,
color: Colors.grey[800],
fontWeight: FontWeight.w700),
textAlign: TextAlign.center),
title: Text(repository[3],
style: const TextStyle(
fontSize: 15.0, fontFamily: 'Monospace'),
textAlign: TextAlign.center),
subtitle: Text(repository[6] != '' ? repository[6] : '-',
style: const TextStyle(fontSize: 12.0),
textAlign: TextAlign.center),
trailing: Text("${repository[4]} Ğ1",
style: const TextStyle(fontSize: 14.0),
textAlign: TextAlign.justify),
dense: true,
isThreeLine: false,
onTap: () {
// this._outputPubkey.text = repository[2];
_historyProvider.isPubkey(context, repository[2]);
}),
),
if (result.isLoading)
Row(
mainAxisAlignment: MainAxisAlignment.center,

View File

@ -1,6 +1,11 @@
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:flutter/material.dart';
import 'package:gecko/models/cesium_plus.dart';
import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/models/history.dart';
import 'package:gecko/models/search.dart';
import 'package:provider/provider.dart';
@ -11,7 +16,16 @@ class SearchResultScreen extends StatelessWidget {
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SearchProvider _searchProvider = Provider.of<SearchProvider>(context);
int nbrResult = 0;
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context);
HistoryProvider _historyClass =
Provider.of<HistoryProvider>(context, listen: false);
// int nbrResult = 0;
int keyID = 0;
const double avatarsSize = 50;
// _searchProvider.searchPubkey();
return Scaffold(
appBar: AppBar(
@ -24,20 +38,102 @@ class SearchResultScreen extends StatelessWidget {
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 30),
Text(
'$nbrResult résultats pour "${_searchProvider.searchController.text}"',
style: TextStyle(fontSize: 18, color: Colors.grey[700]),
child:
Column(crossAxisAlignment: CrossAxisAlignment.start, children: <
Widget>[
const SizedBox(height: 30),
RichText(
text: TextSpan(
style: TextStyle(
fontSize: 18,
color: Colors.grey[700],
),
const SizedBox(height: 40),
const Text(
'Dans la blockchain Ğ1',
style: TextStyle(fontSize: 20),
)
]),
children: <TextSpan>[
const TextSpan(
text: "Résultats pour ",
),
TextSpan(
text: '"${_searchProvider.searchController.text}"',
style: const TextStyle(fontStyle: FontStyle.italic),
),
],
),
),
const SizedBox(height: 40),
const Text(
'Dans la blockchain Ğ1',
style: TextStyle(fontSize: 20),
),
const SizedBox(height: 20),
FutureBuilder(
future: _searchProvider.searchBlockchain(),
initialData: const [],
builder: (context, snapshot) {
return Expanded(
child: ListView(children: <Widget>[
for (G1WalletsList g1Wallet in snapshot.data)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: ListTile(
key: Key('searchResult${keyID++}'),
contentPadding: const EdgeInsets.all(5),
leading: FutureBuilder(
future: _cesiumPlusProvider
.getAvatar(g1Wallet.pubkey),
initialData: [
File(appPath.path + '/default_avatar.png')
],
builder: (BuildContext context,
AsyncSnapshot<List> _avatar) {
if (_avatar.connectionState !=
ConnectionState.done) {
return Image.file(
File(appPath.path +
'/default_avatar.png'),
height: avatarsSize);
}
if (_avatar.hasError) {
return Image.file(
File(appPath.path +
'/default_avatar.png'),
height: avatarsSize);
}
if (_avatar.hasData) {
return SingleChildScrollView(
padding: const EdgeInsets.all(0.0),
child: Image.file(_avatar.data.single,
height: avatarsSize));
}
return Image.file(
File(appPath.path +
'/default_avatar.png'),
height: avatarsSize);
}),
title: Text(
_historyClass.getShortPubkey(g1Wallet.pubkey),
style: const TextStyle(
fontSize: 15.0, fontFamily: 'Monospace'),
textAlign: TextAlign.center),
subtitle: Text(g1Wallet?.id?.username ?? '',
style: const TextStyle(fontSize: 12.0),
textAlign: TextAlign.center),
trailing: Text("${g1Wallet.balance} Ğ1",
style: const TextStyle(fontSize: 14.0),
textAlign: TextAlign.justify),
dense: false,
isThreeLine: false,
onTap: () {
_historyClass.isPubkey(
context, g1Wallet.pubkey);
}),
),
]),
);
}),
// Text(
// _searchProvider.searchResult.toString(),
// )
]),
),
),
);

View File

@ -5,7 +5,7 @@ description: Pay with G1.
# 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
version: 0.0.3+3
version: 0.0.3+5
environment:
sdk: ">=2.7.0 <3.0.0"
@ -26,7 +26,7 @@ dependencies:
graphql_flutter: ^5.0.0
hive: ^2.0.4
hive_flutter: ^1.1.0
http: ^0.13.0
http: ^0.13.4
image_gallery_saver: ^1.6.9
image_picker: ^0.8.4
intl: ^0.17.0