refacto: walletData idtyStatus enum type

This commit is contained in:
poka 2023-11-19 13:41:24 +01:00
parent 08ea8445ad
commit 6f2d33b76e
14 changed files with 313 additions and 211 deletions

View File

@ -8,10 +8,11 @@ import 'package:hive_flutter/hive_flutter.dart';
import 'package:logger/logger.dart';
// Version of box data
const int dataVersion = 6;
const int dataVersion = 7;
late String appVersion;
const int pinLength = 5;
const int maxWalletsInSafe = 30;
const String appLang = 'english';
late Box<WalletData> walletBox;

View File

@ -68,6 +68,7 @@ Future<void> main() async {
Hive.registerAdapter(ChestDataAdapter());
Hive.registerAdapter(G1WalletsListAdapter());
Hive.registerAdapter(IdAdapter());
Hive.registerAdapter(IdtyStatusAdapter());
chestBox = await Hive.openBox<ChestData>("chestBox");

View File

@ -28,18 +28,27 @@ class WalletData extends HiveObject {
bool isOwned;
@HiveField(8)
bool isMember;
IdtyStatus identityStatus;
WalletData(
{required this.address,
this.chest,
this.number,
this.name,
this.derivation,
this.imageDefaultPath,
this.imageCustomPath,
this.isOwned = false,
this.isMember = false});
@HiveField(9)
double balance;
@HiveField(10)
List<int>? certs;
WalletData({
required this.address,
this.chest,
this.number,
this.name,
this.derivation,
this.imageDefaultPath,
this.imageCustomPath,
this.isOwned = false,
this.identityStatus = IdtyStatus.unknown,
this.balance = 0,
this.certs,
});
// representation of WalletData when debugging
@override
@ -58,9 +67,23 @@ class WalletData extends HiveObject {
}
}
class NewWallet {
final String address;
final String password;
@HiveType(typeId: 5)
enum IdtyStatus {
@HiveField(0)
none,
NewWallet._(this.address, this.password);
@HiveField(1)
created,
@HiveField(2)
confirmed,
@HiveField(3)
validated,
@HiveField(4)
expired,
@HiveField(5)
unknown
}

View File

@ -25,14 +25,16 @@ class WalletDataAdapter extends TypeAdapter<WalletData> {
imageDefaultPath: fields[5] as String?,
imageCustomPath: fields[6] as String?,
isOwned: fields[7] as bool,
isMember: fields[8] as bool,
identityStatus: fields[8] as IdtyStatus,
balance: fields[9] as double,
certs: (fields[10] as List?)?.cast<int>(),
);
}
@override
void write(BinaryWriter writer, WalletData obj) {
writer
..writeByte(9)
..writeByte(11)
..writeByte(0)
..write(obj.address)
..writeByte(1)
@ -50,7 +52,11 @@ class WalletDataAdapter extends TypeAdapter<WalletData> {
..writeByte(7)
..write(obj.isOwned)
..writeByte(8)
..write(obj.isMember);
..write(obj.identityStatus)
..writeByte(9)
..write(obj.balance)
..writeByte(10)
..write(obj.certs);
}
@override
@ -63,3 +69,62 @@ class WalletDataAdapter extends TypeAdapter<WalletData> {
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class IdtyStatusAdapter extends TypeAdapter<IdtyStatus> {
@override
final int typeId = 5;
@override
IdtyStatus read(BinaryReader reader) {
switch (reader.readByte()) {
case 0:
return IdtyStatus.none;
case 1:
return IdtyStatus.created;
case 2:
return IdtyStatus.confirmed;
case 3:
return IdtyStatus.validated;
case 4:
return IdtyStatus.expired;
case 5:
return IdtyStatus.unknown;
default:
return IdtyStatus.none;
}
}
@override
void write(BinaryWriter writer, IdtyStatus obj) {
switch (obj) {
case IdtyStatus.none:
writer.writeByte(0);
break;
case IdtyStatus.created:
writer.writeByte(1);
break;
case IdtyStatus.confirmed:
writer.writeByte(2);
break;
case IdtyStatus.validated:
writer.writeByte(3);
break;
case IdtyStatus.expired:
writer.writeByte(4);
break;
case IdtyStatus.unknown:
writer.writeByte(5);
break;
}
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is IdtyStatusAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@ -16,7 +16,6 @@ class DuniterIndexer with ChangeNotifier {
List? transBC;
List listIndexerEndpoints = [];
bool isLoadingIndexer = false;
Map<String, String> idtyStatusCache = {};
void reload() {
notifyListeners();

View File

@ -15,8 +15,6 @@ import "package:unorm_dart/unorm_dart.dart" as unorm;
class GenerateWalletsProvider with ChangeNotifier {
GenerateWalletsProvider();
// NewWallet generatedWallet;
durt.NewWallet? actualWallet;
final walletNameFocus = FocusNode();
Color? askedWordColor = Colors.black;
@ -171,7 +169,6 @@ class GenerateWalletsProvider with ChangeNotifier {
void resetCesiumImportView() {
cesiumID.text = cesiumPWD.text = cesiumPubkey.text = pin.text = '';
canImport = isCesiumIDVisible = isCesiumPWDVisible = false;
actualWallet = null;
notifyListeners();
}

View File

@ -312,9 +312,9 @@ class SubstrateSdk with ChangeNotifier {
}
Future<bool> isMember(String address) async {
final isMember = await idtyStatus(address) == 'Validated';
final isMember = await idtyStatus(address) == IdtyStatus.validated;
final walletData = walletBox.get(address) ?? WalletData(address: address);
walletData.isMember = isMember;
walletData.identityStatus = IdtyStatus.validated;
walletBox.put(address, walletData);
// notifyListeners();
return isMember;
@ -350,9 +350,9 @@ class SubstrateSdk with ChangeNotifier {
} else if (nextIssuableOn > blocNumber) {
final certDelayDuration = (nextIssuableOn - blocNumber) * 6;
result.putIfAbsent('certDelay', () => certDelayDuration);
} else if (toStatus == 'Created') {
} else if (toStatus == IdtyStatus.created) {
result.putIfAbsent('toStatus', () => 1);
} else if (toStatus == 'noid') {
} else if (toStatus == IdtyStatus.none) {
result.putIfAbsent('toStatus', () => 2);
result.putIfAbsent('canCert', () => 0);
} else {
@ -397,28 +397,34 @@ class SubstrateSdk with ChangeNotifier {
return startBlockchainTime.add(Duration(seconds: blocNumber * 6));
}
Future<String> idtyStatus(String address) async {
Future<IdtyStatus> idtyStatus(String address) async {
// final walletOptions =
// Provider.of<WalletOptionsProvider>(homeContext, listen: false);
var idtyIndex = await _getIdentityIndexOf(address);
if (idtyIndex == null) {
return 'noid';
return IdtyStatus.none;
}
final idtyStatus = await _getStorage('identity.identities($idtyIndex)');
if (idtyStatus != null) {
final String status = idtyStatus['status'];
switch (idtyStatus['status']) {
case 'Created':
return IdtyStatus.created;
// if (address == walletOptions.address.text && status == 'Validated') {
// walletOptions.reloadBuild();
// }
case 'ConfirmedByOwner':
return IdtyStatus.confirmed;
return (status);
case 'Validated':
return IdtyStatus.validated;
default:
return IdtyStatus.unknown;
}
} else {
return 'expired';
return IdtyStatus.expired;
}
}
@ -970,7 +976,7 @@ class SubstrateSdk with ChangeNotifier {
final fromIndex = await _getIdentityIndexOf(fromAddress);
final toIndex = await _getIdentityIndexOf(destAddress);
if (myIdtyStatus != 'Validated') {
if (myIdtyStatus != IdtyStatus.validated) {
transactionStatus = 'notMember';
notifyListeners();
return 'notMember';
@ -988,17 +994,17 @@ class SubstrateSdk with ChangeNotifier {
log.d(
"debug toCert: ${toCerts?[0]} --- ${currencyParameters['minCertForMembership']!} --- $toIdtyStatus");
if (toIdtyStatus == 'noid') {
if (toIdtyStatus == IdtyStatus.none) {
txInfo = TxInfoData(
'identity',
'createIdentity',
sender,
);
txOptions = [destAddress];
} else if (toIdtyStatus == 'Validated' ||
toIdtyStatus == 'ConfirmedByOwner') {
} else if (toIdtyStatus == IdtyStatus.validated ||
toIdtyStatus == IdtyStatus.confirmed) {
if (toCerts![0] >= currencyParameters['minCertForMembership']! - 1 &&
toIdtyStatus != 'Validated') {
toIdtyStatus != IdtyStatus.validated) {
log.i('Batch cert and membership validation');
txInfo = TxInfoData(
'utility',

View File

@ -29,7 +29,6 @@ class WalletOptionsProvider with ChangeNotifier {
TextEditingController nameController = TextEditingController();
late bool isDefaultWallet;
bool canValidateNameBool = false;
Future<NewWallet>? get badWallet => null;
Map<String, double> balanceCache = {};
int getPinLenght(walletNbr) {

View File

@ -25,7 +25,6 @@ class RestoreChest extends StatelessWidget {
final genW = Provider.of<GenerateWalletsProvider>(context, listen: false);
final sub = Provider.of<SubstrateSdk>(context, listen: false);
genW.actualWallet = null;
if (genW.isSentenceComplete(context)) {
genW.generatedMnemonic =
'${genW.cellController0.text} ${genW.cellController1.text} ${genW.cellController2.text} ${genW.cellController3.text} ${genW.cellController4.text} ${genW.cellController5.text} ${genW.cellController6.text} ${genW.cellController7.text} ${genW.cellController8.text} ${genW.cellController9.text} ${genW.cellController10.text} ${genW.cellController11.text}';

View File

@ -145,7 +145,8 @@ class WalletOptions extends StatelessWidget {
wallet: wallet,
size: 29,
color: Colors.black,
fontWeight: wallet.isMember
fontWeight: wallet.identityStatus ==
IdtyStatus.validated
? FontWeight.w500
: FontWeight.w400,
fontStyle: FontStyle.normal);

View File

@ -1,11 +1,11 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:flutter/material.dart';
@ -14,13 +14,11 @@ import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/screens/myWallets/chest_options.dart';
import 'package:gecko/screens/myWallets/import_g1_v1.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/myWallets/wallet_options.dart';
import 'package:gecko/widgets/balance.dart';
import 'package:gecko/widgets/bottom_app_bar.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
import 'package:gecko/widgets/commons/smooth_transition.dart';
import 'package:gecko/widgets/name_by_address.dart';
import 'package:gecko/widgets/payment_popup.dart';
import 'package:gecko/widgets/wallet_tile.dart';
import 'package:provider/provider.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
@ -99,6 +97,7 @@ class _WalletsHomeState extends State<WalletsHome> {
Widget dragInfo(BuildContext context) {
final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
final walletDataFrom =
myWalletProvider.getWalletDataByAddress(myWalletProvider.dragAddress);
@ -109,6 +108,14 @@ class _WalletsHomeState extends State<WalletsHome> {
myWalletProvider.dragAddress == myWalletProvider.lastFlyBy;
final screenWidth = MediaQuery.of(homeContext).size.width;
final fromName =
duniterIndexer.walletNameIndexer[walletDataFrom!.address] ??
walletDataFrom.name;
final toName = duniterIndexer.walletNameIndexer[walletDataTo!.address] ??
walletDataTo.name;
return Container(
color: yellowC,
width: screenWidth,
@ -118,10 +125,9 @@ class _WalletsHomeState extends State<WalletsHome> {
children: [
const SizedBox(height: 5),
Text('${'executeATransfer'.tr()}:'),
MarkdownBody(data: '${'from'.tr()} **${walletDataFrom!.name}**'),
MarkdownBody(data: '${'from'.tr()} **$fromName**'),
if (isSameAddress) Text('chooseATargetWallet'.tr()),
if (!isSameAddress)
MarkdownBody(data: 'Vers: **${walletDataTo!.name}**'),
if (!isSameAddress) MarkdownBody(data: 'Vers: **$toName**'),
],
)),
);
@ -359,116 +365,16 @@ class _WalletsHomeState extends State<WalletsHome> {
List<dynamic> accepted,
List<dynamic> rejected,
) {
return Padding(
padding: const EdgeInsets.all(16),
child: GestureDetector(
key: keyOpenWallet(repository.address),
onTap: () {
walletOptions.getAddress(
currentChestNumber, repository.derivation!);
Navigator.push(
context,
SmoothTransition(
page: WalletOptions(
wallet: repository,
),
),
);
},
child: SizedBox(
key: repository.number == 1
? keyDragAndDrop
: const Key('nothing'),
child: ClipOvalShadow(
shadow: const Shadow(
color: Colors.transparent,
offset: Offset(0, 0),
blurRadius: 5,
),
clipper: CustomClipperOval(),
child: ClipRRect(
borderRadius:
const BorderRadius.all(Radius.circular(12)),
child: Column(children: <Widget>[
Expanded(
child: Container(
width: double.infinity,
height: double.infinity,
decoration: const BoxDecoration(
gradient: RadialGradient(
radius: 0.8,
colors: [
Color.fromARGB(255, 255, 255, 211),
yellowC,
],
),
),
child:
// SvgPicture.asset('assets/chopp-gecko2.png',
// semanticsLabel: 'Gecko', height: 48),
repository.imageCustomPath == null ||
repository.imageCustomPath == ''
? Image.asset(
'assets/avatars/${repository.imageDefaultPath}',
alignment:
Alignment.bottomCenter,
scale: 0.5,
)
: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.transparent,
image: DecorationImage(
fit: BoxFit.fitHeight,
image: FileImage(
File(repository
.imageCustomPath!),
),
),
),
),
)),
Stack(children: <Widget>[
BalanceBuilder(
address: repository.address,
isDefault: repository.address ==
defaultWallet.address),
Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Column(
children: [
const SizedBox(height: 7),
Opacity(
opacity: 0.7,
child: NameByAddress(
wallet: repository,
size: 20,
color:
defaultWallet.address ==
repository.address
? Colors.white
: Colors.black,
fontWeight: FontWeight.w600,
fontStyle: FontStyle.normal,
))
],
),
],
),
]),
]),
),
),
),
),
);
return WalletTile(
repository: repository,
walletOptions: walletOptions,
defaultWallet: defaultWallet,
currentChestNumber: currentChestNumber);
}),
),
Consumer<SubstrateSdk>(builder: (context, sub, _) {
return sub.nodeConnected &&
myWalletProvider.listWallets.length < 30
myWalletProvider.listWallets.length < maxWalletsInSafe
? addNewDerivation(context)
: const Text('');
}),

View File

@ -2,7 +2,6 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/widgets/commons/animated_text.dart';
import 'package:gecko/widgets/name_by_address.dart';
@ -21,75 +20,58 @@ class IdentityStatus extends StatelessWidget {
@override
Widget build(BuildContext context) {
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
final walletData = walletBox.get(address) ?? WalletData(address: address);
return Consumer<SubstrateSdk>(builder: (context, sub, _) {
return FutureBuilder(
future: sub.idtyStatus(address),
initialData: '',
builder: (context, snapshot) {
duniterIndexer.idtyStatusCache[address] = snapshot.data.toString();
switch (snapshot.data.toString()) {
case 'noid':
walletData.isMember = false;
walletBox.put(address, walletData);
{
return showText('noIdentity'.tr());
}
case 'Created':
walletData.isMember = false;
walletBox.put(address, walletData);
{
return showText('identityCreated'.tr());
}
case 'ConfirmedByOwner':
walletData.isMember = false;
walletBox.put(address, walletData);
{
return isOwner
? showText('identityConfirmed'.tr())
: NameByAddress(
wallet: WalletData(address: address),
size: 20,
color: Colors.grey[700]!,
fontWeight: FontWeight.w500,
fontStyle: FontStyle.italic);
}
case 'Validated':
walletData.isMember = true;
walletBox.put(address, walletData);
{
return isOwner
? showText('memberValidated'.tr(), 18, true)
: NameByAddress(
wallet: WalletData(address: address),
size: 24,
color: Colors.black,
fontWeight: FontWeight.w600,
fontStyle: FontStyle.normal);
}
case 'expired':
walletData.isMember = false;
walletBox.put(address, walletData);
{
return showText('identityExpired'.tr());
}
initialData: walletData.identityStatus,
builder: (context, AsyncSnapshot<IdtyStatus> snapshot) {
final resStatus = snapshot.data!;
walletData.identityStatus = resStatus;
walletBox.put(address, walletData);
if (!isOwner) {
if (resStatus == IdtyStatus.confirmed) {
return NameByAddress(
wallet: WalletData(address: address),
size: 20,
color: Colors.grey[700]!,
fontWeight: FontWeight.w500,
fontStyle: FontStyle.italic);
} else if (resStatus == IdtyStatus.validated) {
return NameByAddress(
wallet: WalletData(address: address),
size: 24,
color: Colors.black,
fontWeight: FontWeight.w600,
fontStyle: FontStyle.normal);
}
}
final Map<IdtyStatus, String> statusText = {
IdtyStatus.none: 'noIdentity'.tr(),
IdtyStatus.created: 'identityCreated'.tr(),
IdtyStatus.confirmed: 'identityConfirmed'.tr(),
IdtyStatus.validated: 'memberValidated'.tr(),
IdtyStatus.expired: 'identityExpired'.tr(),
IdtyStatus.unknown: ''
};
return SizedBox(
child: showText('', 18, false, false),
child: showText(statusText[resStatus]!,
bold: resStatus == IdtyStatus.validated ? true : false),
);
});
});
}
AnimatedFadeOutIn showText(String text,
[double size = 18, bool bold = false, bool smooth = true]) {
{double size = 18, bool bold = false}) {
// log.d('$address $text');
return AnimatedFadeOutIn<String>(
data: text,
duration: Duration(milliseconds: smooth ? 200 : 0),
duration: const Duration(milliseconds: 150),
builder: (value) => Text(
value,
textAlign: TextAlign.center,

View File

@ -0,0 +1,123 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/screens/myWallets/wallet_options.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart';
import 'package:gecko/widgets/commons/smooth_transition.dart';
import 'package:gecko/widgets/name_by_address.dart';
class WalletTile extends StatelessWidget {
const WalletTile(
{Key? key,
required this.repository,
required this.walletOptions,
required this.defaultWallet,
required this.currentChestNumber})
: super(key: key);
final WalletData repository;
final WalletOptionsProvider walletOptions;
final WalletData defaultWallet;
final int currentChestNumber;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16),
child: GestureDetector(
key: keyOpenWallet(repository.address),
onTap: () {
walletOptions.getAddress(currentChestNumber, repository.derivation!);
Navigator.push(
context,
SmoothTransition(
page: WalletOptions(
wallet: repository,
),
),
);
},
child: SizedBox(
key: repository.number == 1 ? keyDragAndDrop : const Key('nothing'),
child: ClipOvalShadow(
shadow: const Shadow(
color: Colors.transparent,
offset: Offset(0, 0),
blurRadius: 5,
),
clipper: CustomClipperOval(),
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(12)),
child: Column(children: <Widget>[
Expanded(
child: Container(
width: double.infinity,
height: double.infinity,
decoration: const BoxDecoration(
gradient: RadialGradient(
radius: 0.8,
colors: [
Color.fromARGB(255, 255, 255, 211),
yellowC,
],
),
),
child: repository.imageCustomPath == null ||
repository.imageCustomPath == ''
? Image.asset(
'assets/avatars/${repository.imageDefaultPath}',
alignment: Alignment.bottomCenter,
scale: 0.5,
)
: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.transparent,
image: DecorationImage(
fit: BoxFit.fitHeight,
image: FileImage(
File(repository.imageCustomPath!),
),
),
),
),
)),
Stack(children: <Widget>[
BalanceBuilder(
address: repository.address,
isDefault: repository.address == defaultWallet.address),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [
const SizedBox(height: 7),
Opacity(
opacity: 0.7,
child: NameByAddress(
wallet: repository,
size: 20,
color:
defaultWallet.address == repository.address
? Colors.white
: Colors.black,
fontWeight: FontWeight.w600,
fontStyle: FontStyle.normal,
))
],
),
],
),
]),
]),
),
),
),
),
);
}
}

View File

@ -1,4 +1,4 @@
#!/bin/bash
flutter packages pub run build_runner build --delete-conflicting-outputs
dart run build_runner build --delete-conflicting-outputs