Skip to content
Snippets Groups Projects
Commit d9338e92 authored by poka's avatar poka
Browse files

feat: Can renew membership

parent efed633e
No related branches found
No related tags found
No related merge requests found
......@@ -238,5 +238,11 @@
"enterYourNewAddress": "Enter your new address {}",
"youCanMigrateThisIdentity": "You can migrate this identity !",
"identityMigrated": "Identity migrated",
"passwordTooSimple": "Your password is to simple"
}
\ No newline at end of file
"passwordTooSimple": "Your password is to simple",
"renewMembership": "Renew my membership",
"areYouSureYouWantToRenewMembership": "Are you sure you want to renew your membership ?",
"membershipExpiredOn": "Membership expired on {}",
"membershipExpiresOn": "Membership expires on {}",
"renewingMembership": "Renewing membership",
"membershipRenewalConfirmed": "Your membership renewal request has been registered and will be effective within a few minutes"
}
......@@ -239,5 +239,11 @@
"enterYourNewAddress": "Enter your new address {}",
"youCanMigrateThisIdentity": "You can migrate this identity !",
"identityMigrated": "Identity migrated",
"passwordTooSimple": "Your password is to simple"
}
\ No newline at end of file
"passwordTooSimple": "Your password is to simple",
"renewMembership": "Renovar mi adhésion",
"areYouSureYouWantToRenewMembership": "¿Estás seguro de que quieres renovar tu adhésion?",
"membershipExpiredOn": "Adhésion expirée el {}",
"membershipExpiresOn": "Adhésion expira el {}",
"renewingMembership": "Renovando adhésion",
"membershipRenewalConfirmed": "Su solicitud de renovación de membresía ha sido registrada y será efectiva en unos minutos"
}
......@@ -238,5 +238,11 @@
"enterYourNewAddress": "Entrez votre nouvelle adresse {}",
"youCanMigrateThisIdentity": "Vous pouvez migrer vers cette identité !",
"identityMigrated": "Identité migré",
"passwordTooSimple": "Votre code secret est trop simple"
}
\ No newline at end of file
"passwordTooSimple": "Votre code secret est trop simple",
"renewMembership": "Renouveler mon adhésion",
"areYouSureYouWantToRenewMembership": "Êtes-vous sûr de vouloir renouveler votre adhésion ?",
"membershipExpiredOn": "Adhésion expirée le {}",
"membershipExpiresOn": "Adhésion expire le {}",
"renewingMembership": "Renouvellement d'adhésion",
"membershipRenewalConfirmed": "Votre demande de renouvellement d'adhésion a bien été prise en compte et sera effective d'ici quelques minutes"
}
......@@ -105,7 +105,8 @@ const keyDropdownWallets = Key('keyDropdownKey');
Key keyTransaction(int keyId) => Key('keyTransaction$keyId');
Key keyMnemonicWord(String word) => Key('keyMnemonicWord$word');
Key keySearchResult(String address) => Key('keySearchResult$address');
Key keySelectDuniterNode(String endpoint) =>
Key('keySelectDuniterNode$endpoint');
Key keySelectDuniterNode(String endpoint) => Key('keySelectDuniterNode$endpoint');
Key keyOpenWallet(String address) => Key('keyOpenWallet$address');
Key keySelectThisWallet(String address) => Key('keySelectThisWallet$address');
const keyRenewMembership = Key('renewMembership');
......@@ -213,6 +213,20 @@ class SubstrateSdk with ChangeNotifier {
return certsCounterCache[address]!;
}
Future<DateTime?> membershipExpireIn(String address) async {
final idtyIndex = await _getIdentityIndexOf(address);
if (idtyIndex == null) return null;
final expireOnMap = await _getStorage('membership.membership($idtyIndex)') ?? {};
final expireOn = expireOnMap['expireOn'] as int;
// Calculate time difference from current block (6 seconds per block)
final blockDifference = expireOn - blocNumber;
// Returns expiration date by adding (or subtracting if expired) time from now
return DateTime.now().add(Duration(seconds: blockDifference * 6));
}
Future<int> getCertValidityPeriod(String from, String to) async {
final idtyIndexFrom = await _getIdentityIndexOf(from);
final idtyIndexTo = await _getIdentityIndexOf(to);
......@@ -1216,4 +1230,25 @@ newKeySig: $newKeySigType""");
void reload() {
notifyListeners();
}
Future<String> renewMembership(String address, String password) async {
final sender = await _setSender(address);
final txInfo = TxInfoData(
'distance',
'requestDistanceEvaluation',
sender,
);
final transactionId = const Uuid().v4();
final transactionContent = TransactionContent(
transactionId: transactionId,
status: TransactionStatus.sending,
from: address,
to: address,
amount: -1,
);
_executeCall(transactionContent, txInfo, [], password);
return transactionId;
}
}
......@@ -13,13 +13,6 @@ import 'package:gecko/screens/myWallets/migrate_identity.dart';
import 'package:gecko/screens/transaction_in_progress.dart';
import 'package:gecko/widgets/commons/top_appbar.dart';
import 'package:provider/provider.dart';
// import 'package:gecko/models/wallet_data.dart';
// import 'package:gecko/providers/my_wallets.dart';
// import 'package:gecko/providers/substrate_sdk.dart';
// import 'package:gecko/screens/common_elements.dart';
// import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
// import 'package:gecko/screens/transaction_in_progress.dart';
// import 'package:provider/provider.dart';
class ManageMembership extends StatelessWidget {
const ManageMembership({super.key, required this.address});
......@@ -30,50 +23,57 @@ class ManageMembership extends StatelessWidget {
final sub = Provider.of<SubstrateSdk>(context);
return Scaffold(
backgroundColor: backgroundColor,
appBar: GeckoAppBar('manageMembership'.tr()),
body: SafeArea(
child: Column(children: <Widget>[
ScaledSizedBox(height: 20),
migrateIdentity(context),
ScaledSizedBox(height: 10),
FutureBuilder(
future: sub.isSmith(address),
builder: (BuildContext context, AsyncSnapshot<bool> isSmith) {
if (isSmith.data ?? false) {
return ScaledSizedBox(
height: 75,
child: Row(
children: <Widget>[
ScaledSizedBox(width: 17),
Image.asset(
'assets/skull_Icon.png',
color: Colors.grey[500],
height: scaleSize(28),
),
ScaledSizedBox(width: 12),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('revokeMyIdentity'.tr(),
style: scaledTextStyle(
fontSize: 17,
color: Colors.grey[500])),
ScaledSizedBox(height: 2),
Text("youCannotRevokeThisIdentity".tr(),
style: scaledTextStyle(
fontSize: 12,
color: Colors.grey[500])),
]),
],
));
} else {
return revokeMyIdentity(context);
}
})
]),
));
backgroundColor: backgroundColor,
appBar: GeckoAppBar('manageMembership'.tr()),
body: SafeArea(
child: Column(children: <Widget>[
ScaledSizedBox(height: 20),
FutureBuilder<DateTime?>(
future: sub.membershipExpireIn(address),
builder: (context, snapshot) {
if (snapshot.hasData) {
return renewMembership(context, snapshot.data);
}
return const SizedBox.shrink();
},
),
migrateIdentity(context),
ScaledSizedBox(height: 10),
FutureBuilder(
future: sub.isSmith(address),
builder: (BuildContext context, AsyncSnapshot<bool> isSmith) {
if (isSmith.data ?? false) {
return ScaledSizedBox(
height: 75,
child: Row(
children: <Widget>[
ScaledSizedBox(width: 25),
Image.asset(
'assets/skull_Icon.png',
color: Colors.grey[500],
height: scaleSize(28),
),
ScaledSizedBox(width: 20),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('revokeMyIdentity'.tr(), style: scaledTextStyle(fontSize: 17, color: Colors.grey[500])),
ScaledSizedBox(height: 2),
Text("youCannotRevokeThisIdentity".tr(), style: scaledTextStyle(fontSize: 12, color: Colors.grey[500])),
],
),
],
),
);
} else {
return revokeMyIdentity(context);
}
},
),
]),
),
);
}
Widget migrateIdentity(BuildContext context) {
......@@ -90,9 +90,9 @@ class ManageMembership extends StatelessWidget {
child: ScaledSizedBox(
height: 55,
child: Row(children: <Widget>[
ScaledSizedBox(width: 16),
ScaledSizedBox(width: 20),
Icon(Icons.change_circle_outlined, size: scaleSize(32)),
ScaledSizedBox(width: 11.5),
ScaledSizedBox(width: 16),
Text('Migrer mon identité', style: scaledTextStyle(fontSize: 17)),
]),
),
......@@ -103,19 +103,15 @@ class ManageMembership extends StatelessWidget {
return InkWell(
key: keyRevokeIdty,
onTap: () async {
final answer = await confirmPopup(context,
'Êtes-vous certains de vouloir révoquer définitivement cette identité ?') ??
false;
final answer = await confirmPopup(context, 'areYouSureYouWantToRevokeIdentity'.tr()) ?? false;
if (!answer) return;
final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
final myWalletProvider = Provider.of<MyWalletsProvider>(context, listen: false);
final sub = Provider.of<SubstrateSdk>(context, listen: false);
if (!await myWalletProvider.askPinCode()) return;
final transactionId =
await sub.revokeIdentity(address, myWalletProvider.pinCode);
final transactionId = await sub.revokeIdentity(address, myWalletProvider.pinCode);
Navigator.pop(context);
......@@ -123,25 +119,97 @@ class ManageMembership extends StatelessWidget {
context,
MaterialPageRoute(builder: (context) {
return TransactionInProgress(
transactionId: transactionId,
transType: 'revokeIdty',
fromAddress: getShortPubkey(address),
toAddress: getShortPubkey(address));
transactionId: transactionId, transType: 'revokeIdty', fromAddress: getShortPubkey(address), toAddress: getShortPubkey(address));
}),
);
},
child: ScaledSizedBox(
height: 55,
child: Row(children: <Widget>[
ScaledSizedBox(width: 20),
ScaledSizedBox(width: 25),
Image.asset(
'assets/skull_Icon.png',
height: scaleSize(28),
),
ScaledSizedBox(width: 16),
Text('Révoquer mon adhésion', style: scaledTextStyle(fontSize: 17)),
ScaledSizedBox(width: 20),
Text('revokeMyIdentity'.tr(), style: scaledTextStyle(fontSize: 17)),
]),
),
);
}
Widget renewMembership(BuildContext context, DateTime? expireIn) {
final sub = Provider.of<SubstrateSdk>(context, listen: false);
if (expireIn == null) return const SizedBox.shrink();
final now = DateTime.now();
final twoMonthsFromNow = now.add(const Duration(days: 60));
final isExpired = expireIn.isBefore(now);
final canRenew = expireIn.isBefore(twoMonthsFromNow);
return ScaledSizedBox(
height: 75,
child: InkWell(
key: keyRenewMembership,
onTap: canRenew
? () async {
final answer = await confirmPopup(context, 'areYouSureYouWantToRenewMembership'.tr()) ?? false;
if (!answer) return;
final myWalletProvider = Provider.of<MyWalletsProvider>(context, listen: false);
if (!await myWalletProvider.askPinCode()) return;
final transactionId = await sub.renewMembership(address, myWalletProvider.pinCode);
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return TransactionInProgress(
transactionId: transactionId,
transType: 'renewMembership',
fromAddress: getShortPubkey(address),
toAddress: getShortPubkey(address),
);
}),
);
}
: null,
child: Row(
children: <Widget>[
ScaledSizedBox(width: 20),
Image.asset(
'assets/medal.png',
height: scaleSize(28),
color: canRenew ? null : Colors.grey[500],
),
ScaledSizedBox(width: 16),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'renewMembership'.tr(),
style: scaledTextStyle(
fontSize: 17,
color: canRenew ? null : Colors.grey[500],
),
),
Text(
isExpired
? 'membershipExpiredOn'.tr(args: [DateFormat('dd/MM/yyyy').format(expireIn)])
: 'membershipExpiresOn'.tr(args: [DateFormat('dd/MM/yyyy').format(expireIn)]),
style: scaledTextStyle(
fontSize: 12,
color: Colors.grey[500],
),
),
],
),
],
),
),
);
}
}
......@@ -89,7 +89,11 @@ class _TransactionInProgressState extends State<TransactionInProgress> {
}
if (txContent!.status == TransactionStatus.success) {
resultText = 'extrinsicValidated'.tr(args: [actionMap[widget.transType] ?? 'strangeTransaction'.tr()]);
if (widget.transType == 'renewMembership') {
resultText = 'membershipRenewalConfirmed'.tr();
} else {
resultText = 'extrinsicValidated'.tr(args: [actionMap[widget.transType] ?? 'strangeTransaction'.tr()]);
}
} else if (txContent!.status == TransactionStatus.failed) {
resultText = errorTransactionMap[txContent!.error] ?? txContent!.error!;
} else {
......
......@@ -17,6 +17,7 @@ Map<String, String> actionMap = {
'comfirmIdty': 'identityConfirm'.tr(),
'revokeIdty': 'revokeAdhesion'.tr(),
'identityMigration': 'identityMigration'.tr(),
'renewMembership': 'renewingMembership'.tr(),
};
Map<TransactionStatus, String> statusStatusMap = {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment