diff --git a/lib/globals.dart b/lib/globals.dart index e5a1055d5f913ed9df168535523c5b9a9060a45d..8fa51264fc8352725e9a85f55d83b1d744fbf2a9 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -43,6 +43,7 @@ const Color orangeC = Color(0xffd07316); const Color yellowC = Color(0xffFFD68E); const Color floattingYellow = Color(0xffEFEFBF); const Color backgroundColor = Color(0xFFF5F5F5); +const Color headerColor = Color(0xFFFFF3E0); // Substrate settings const String currencyName = 'ĞD'; diff --git a/lib/providers/wallet_options.dart b/lib/providers/wallet_options.dart index ff3cf5a75a95425f40ee95bf7a0a3cc903e46691..f0d1bb8d954b9fb8c8758b76c715026e721f50bc 100644 --- a/lib/providers/wallet_options.dart +++ b/lib/providers/wallet_options.dart @@ -29,7 +29,7 @@ class WalletOptionsProvider with ChangeNotifier { bool isEditing = false; bool isBalanceBlur = false; final nameController = TextEditingController(); - late bool isDefaultWallet; + bool isDefaultWallet = false; bool canValidateNameBool = false; Map<String, double> balanceCache = {}; diff --git a/lib/screens/myWallets/chest_options.dart b/lib/screens/myWallets/chest_options.dart index d3e61eb382890740e9abe61b30c970237a6a02a3..6d8a965b8064fdce10cae89c8c77b07cbf3230ed 100644 --- a/lib/screens/myWallets/chest_options.dart +++ b/lib/screens/myWallets/chest_options.dart @@ -33,7 +33,10 @@ class ChestOptions extends StatelessWidget { child: Column( children: [ ScaledSizedBox(height: 20), - ChestOptionsContent(), + Padding( + padding: EdgeInsets.only(left: scaleSize(16)), + child: ChestOptionsContent(), + ), ], ), ), @@ -45,9 +48,7 @@ class ChestOptions extends StatelessWidget { } class ChestOptionsContent extends StatelessWidget { - const ChestOptionsContent({ - super.key, - }); + const ChestOptionsContent({super.key}); @override Widget build(BuildContext context) { @@ -56,144 +57,137 @@ class ChestOptionsContent extends StatelessWidget { final currentChest = chestBox.get(configBox.get('currentChest'))!; final isAlone = myWalletProvider.listWallets.length == 1; - return Column(children: <Widget>[ - InkWell( - key: keyShowSeed, - onTap: () async { - if (!await myWalletProvider.askPinCode()) return; - - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return ShowSeed( - walletName: currentChest.name, - walletProvider: myWalletProvider, - ); - }), - ); - }, - child: ScaledSizedBox( - height: 60, - child: Row(children: <Widget>[ - ScaledSizedBox(width: 20), - Image.asset( - 'assets/onBoarding/phrase_de_restauration_flou.png', - width: scaleSize(60), - ), - ScaledSizedBox(width: 13), - ScaledSizedBox( - width: 270, - child: Text( - 'displayMnemonic'.tr(), - style: scaledTextStyle( - fontSize: 16, - color: orangeC, + return Column( + children: [ + InkWell( + key: keyShowSeed, + onTap: () async { + if (!await myWalletProvider.askPinCode()) return; + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ShowSeed( + walletName: currentChest.name, + walletProvider: myWalletProvider, + )), + ); + }, + child: Container( + height: scaleSize(48), + padding: EdgeInsets.symmetric(horizontal: scaleSize(16)), + child: Row( + children: [ + Icon( + Icons.vpn_key_outlined, + size: scaleSize(24), + color: Colors.black87, ), - ), + ScaledSizedBox(width: 16), + Text( + 'displayMnemonic'.tr(), + style: scaledTextStyle( + fontSize: 16, + color: Colors.black87, + ), + ), + ], ), - ]), + ), ), - ), - ScaledSizedBox(height: 2), - Consumer<SubstrateSdk>(builder: (context, sub, _) { - return InkWell( - key: keyChangePin, - onTap: null, - // sub.nodeConnected - // ? () async { - // // await _chestProvider.changePin(context, cesiumWallet); - // String? pinResult = await Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) { - // return ChangePinScreen( - // walletName: currentChest.name, - // walletProvider: walletProvider, - // ); - // }, - // ), - // ); - - // if (pinResult != null) { - // walletProvider.pinCode = pinResult; - // } - // } - // : null, - child: ScaledSizedBox( - height: 60, - child: Row(children: <Widget>[ - ScaledSizedBox(width: 30), - Image.asset( - 'assets/chests/secret_code.png', - height: scaleSize(22), - ), - ScaledSizedBox(width: 18), - Text( - 'changePassword'.tr(), - style: scaledTextStyle(fontSize: 16, color: sub.nodeConnected ? Colors.grey[500] : Colors.grey[500]), + Consumer<SubstrateSdk>( + builder: (context, sub, _) { + return InkWell( + key: keyChangePin, + onTap: null, + child: Container( + height: scaleSize(48), + padding: EdgeInsets.symmetric(horizontal: scaleSize(16)), + child: Row( + children: [ + Icon( + Icons.lock_outline, + size: scaleSize(24), + color: Colors.grey[400], + ), + ScaledSizedBox(width: 16), + Text( + 'changePassword'.tr(), + style: scaledTextStyle( + fontSize: 16, + color: Colors.grey[500], + ), + ), + ], ), - ])), - ); - }), - ScaledSizedBox(height: 2), - if (!isAlone) - Consumer<SubstrateSdk>(builder: (context, sub, _) { - return InkWell( - key: keycreateRootDerivation, - onTap: sub.nodeConnected - ? () async { - await Navigator.push( - context, - MaterialPageRoute( - builder: (context) { - return const CustomDerivation(); - }, + ), + ); + }, + ), + if (!isAlone) + Consumer<SubstrateSdk>( + builder: (context, sub, _) { + return InkWell( + key: keycreateRootDerivation, + onTap: sub.nodeConnected + ? () async { + await Navigator.push( + context, + MaterialPageRoute(builder: (context) => const CustomDerivation()), + ); + } + : null, + child: Container( + height: scaleSize(48), + padding: EdgeInsets.symmetric(horizontal: scaleSize(16)), + child: Row( + children: [ + Icon( + Icons.manage_accounts, + size: scaleSize(24), + color: sub.nodeConnected ? Colors.black87 : Colors.grey[400], ), - ); - } - : null, - child: ScaledSizedBox( - height: 60, - child: Row(children: <Widget>[ - ScaledSizedBox(width: 37), - Icon( - Icons.manage_accounts, - size: scaleSize(31), + ScaledSizedBox(width: 16), + Text( + 'createDerivation'.tr(), + style: scaledTextStyle( + fontSize: 16, + color: sub.nodeConnected ? Colors.black87 : Colors.grey[500], + ), + ), + ], + ), ), - ScaledSizedBox(width: 23), + ); + }, + ), + InkWell( + key: keyDeleteChest, + onTap: () async { + await chestProvider.deleteChest(context, currentChest); + }, + child: Container( + height: scaleSize(48), + padding: EdgeInsets.symmetric(horizontal: scaleSize(16)), + child: Row( + children: [ + Image.asset( + 'assets/walletOptions/trash.png', + height: scaleSize(24), + color: const Color(0xffD80000), + ), + ScaledSizedBox(width: 16), Text( - 'createDerivation'.tr(), - style: scaledTextStyle(fontSize: 16, color: sub.nodeConnected ? Colors.black : Colors.grey[500]), + 'deleteChest'.tr(), + style: scaledTextStyle( + fontSize: 16, + color: const Color(0xffD80000), + ), ), - ]), - ), - ); - }), - ScaledSizedBox(height: 2), - InkWell( - key: keyDeleteChest, - onTap: () async { - await chestProvider.deleteChest(context, currentChest); - }, - child: ScaledSizedBox( - height: 60, - child: Row(children: <Widget>[ - ScaledSizedBox(width: 32), - Image.asset( - 'assets/walletOptions/trash.png', - height: scaleSize(38), - ), - ScaledSizedBox(width: 22), - Text( - 'deleteChest'.tr(), - style: scaledTextStyle( - fontSize: 16, - color: const Color(0xffD80000), - ), + ], ), - ]), + ), ), - ), - ]); + ], + ); } } diff --git a/lib/screens/myWallets/wallet_options.dart b/lib/screens/myWallets/wallet_options.dart index 686be096d0ee57d34b9ce67859733b435c5a7f96..487aa3b937d471a5b4cff4b90557e3b407009ea8 100644 --- a/lib/screens/myWallets/wallet_options.dart +++ b/lib/screens/myWallets/wallet_options.dart @@ -61,196 +61,227 @@ class WalletOptions extends StatelessWidget { myWalletProvider.reload(); }, child: Scaffold( - backgroundColor: backgroundColor, - resizeToAvoidBottomInset: false, + backgroundColor: Colors.white, appBar: AppBar( - toolbarHeight: scaleSize(57), + backgroundColor: headerColor, elevation: 0, title: Consumer<WalletOptionsProvider>(builder: (context, walletProvider, _) { return Text( isWalletNameIndexed ? duniterIndexer.walletNameIndexer[walletOptions.address.text]! : wallet.name!, - style: scaledTextStyle(fontSize: 18), + style: scaledTextStyle( + fontSize: 18, + fontWeight: FontWeight.w500, + color: Colors.black87, + ), ); }), actions: [ - InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return QrCodeFullscreen( - walletOptions.address.text, - ); - }), - ); - }, - child: QrImageView( - data: walletOptions.address.text, - version: QrVersions.auto, - size: scaleSize(70), + Padding( + padding: EdgeInsets.symmetric(horizontal: scaleSize(16)), + child: InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => QrCodeFullscreen(walletOptions.address.text)), + ); + }, + child: QrImageView( + data: walletOptions.address.text, + version: QrVersions.auto, + size: scaleSize(45), + backgroundColor: Colors.white, + ), ), ), ], ), - bottomNavigationBar: const GeckoBottomAppBar(), - body: Stack(children: [ - SafeArea( - child: Column(children: <Widget>[ - Container( - height: 5, - color: yellowC, - ), - Consumer<WalletOptionsProvider>(builder: (context, walletProvider, _) { - return Container( - decoration: const BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - yellowC, - backgroundColor, - ], - )), - child: Row(children: <Widget>[ - const Spacer(flex: 1), - ScaledSizedBox(width: 15), - avatar(walletProvider), - const Spacer(flex: 1), - Column(crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ - Stack(children: [ - ScaledSizedBox( - width: 230, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Consumer<WalletOptionsProvider>(builder: (context, walletProvider, _) { - return NameByAddress( - wallet: wallet, + body: Stack( + children: [ + Column( + children: [ + // En-tête avec avatar et informations + Container( + color: headerColor, + padding: EdgeInsets.symmetric( + horizontal: scaleSize(16), + vertical: scaleSize(16), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildAvatarSection(walletOptions), + SizedBox(width: scaleSize(20)), + Expanded( + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: scaleSize(26), + child: Consumer<WalletOptionsProvider>( + builder: (context, walletProvider, _) { + return Row( + children: [ + NameByAddress( + wallet: wallet, + size: 20, + color: Colors.black87, + fontWeight: wallet.identityStatus == IdtyStatus.member ? FontWeight.w600 : FontWeight.w400, + ), + if (duniterIndexer.walletNameIndexer[wallet.address] == null) + IconButton( + padding: EdgeInsets.zero, + constraints: const BoxConstraints(), + icon: Icon( + walletProvider.isEditing ? Icons.check : Icons.edit, + size: scaleSize(18), + ), + onPressed: () async { + await walletProvider.editWalletName(context, wallet.id()); + }, + ), + ], + ); + }, + ), + ), + if (!wallet.hasIdentity()) const SizedBox(height: 16), + Balance( + address: walletOptions.address.text, size: 24, - color: Colors.black, - fontWeight: wallet.identityStatus == IdtyStatus.member ? FontWeight.w500 : FontWeight.w400, - fontStyle: FontStyle.normal); - }) - ], - ), - ), - ScaledSizedBox(width: 10), - if (duniterIndexer.walletNameIndexer[wallet.address] == null) - Positioned( - right: 0, - child: InkWell( - key: keyRenameWallet, - onTap: () async { - await walletOptions.editWalletName(context, wallet.id()); - await Future.delayed(const Duration(milliseconds: 30)); - }, - child: ClipRRect( - child: Image.asset(walletOptions.isEditing ? 'assets/walletOptions/android-checkmark.png' : 'assets/walletOptions/edit.png', - width: scaleSize(23), height: scaleSize(23)), + ), + if (wallet.hasIdentity()) ...[ + SizedBox(height: scaleSize(12)), + InkWell( + onTap: () => sub.certsCounterCache[walletOptions.address.text] != null + ? Navigator.push( + context, + PageNoTransit( + builder: (context) => CertificationsScreen( + address: walletOptions.address.text, + username: duniterIndexer.walletNameIndexer[walletOptions.address.text] ?? '', + ), + ), + ) + : null, + child: Row( + children: [ + IdentityStatus( + address: walletOptions.address.text, + isOwner: true, + color: orangeC, + ), + SizedBox(width: scaleSize(8)), + Certifications( + address: walletOptions.address.text, + size: 16, + ), + ], + ), + ), + ], + ], ), ), - ), - ]), - ScaledSizedBox(height: 5), - Balance(address: walletProvider.address.text, size: 20), - ScaledSizedBox(width: 30), - InkWell( - onTap: () => sub.certsCounterCache[walletProvider.address.text] != null - ? { - Navigator.push( - context, - PageNoTransit(builder: (context) { - return CertificationsScreen( - address: walletProvider.address.text, username: duniterIndexer.walletNameIndexer[walletProvider.address.text] ?? ''); - }), - ), - } - : null, - child: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [ - IdentityStatus(address: walletOptions.address.text, isOwner: true, color: orangeC), - Certifications(address: walletProvider.address.text, size: 17) - ]), + ], + ), ), - ScaledSizedBox(height: 10), - ]), - const Spacer(flex: 2), - ]), - ); - }), - Expanded( - child: SingleChildScrollView( - child: Column(crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ - ScaledSizedBox(height: 25), - Consumer<WalletOptionsProvider>(builder: (context, walletProvider, _) { - final defaultWallet = myWalletProvider.getDefaultWallet(); - walletProvider.isDefaultWallet = walletOptions.address.text == defaultWallet.address; - return Column(children: [ - confirmIdentityButton(walletProvider), - if (wallet.isMembre()) renewMembershipButton(walletProvider), - pubkeyWidget(walletProvider, context), - ScaledSizedBox(height: 11), - activityWidget(context, historyProvider, walletProvider), - ScaledSizedBox(height: 11), - if (!isAlone) ...[ - setDefaultWalletWidget(context, walletProvider, myWalletProvider, walletOptions, currentChest), - ScaledSizedBox(height: 11), + ], + ), + ), + + // Corps avec les options + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: scaleSize(20)), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + ScaledSizedBox(height: 24), + Consumer<WalletOptionsProvider>( + builder: (context, walletProvider, _) { + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + buildConfirmIdentitySection(walletProvider), + if (wallet.isMembre()) buildRenewMembershipSection(walletProvider), + buildOptionsSection(context, walletProvider, historyProvider), + if (!isAlone) buildDefaultWalletSection(context, walletProvider, myWalletProvider, walletOptions, currentChest), + buildDangerZone(context, walletProvider, currentChest), + if (isAlone) aloneWalletOptions(), + ], + ); + }, + ), ], - Column(children: [ - if (!walletProvider.isDefaultWallet && !wallet.isMembre()) deleteWallet(context, walletProvider, currentChest), - const ManageMembershipButton(), - ]), - if (isAlone) aloneWalletOptions() - ]); - }), - ]), + ), + ), + ), ), - ), - ]), - ), - const OfflineInfo(), - ]), + ], + ), + const OfflineInfo(), + ], + ), + bottomNavigationBar: const GeckoBottomAppBar(), ), ); } - Widget avatar(WalletOptionsProvider walletProvider) { + Widget buildAvatarSection(WalletOptionsProvider walletProvider) { return Stack( - children: <Widget>[ - InkWell( - onTap: () async { - await (walletProvider.changeAvatar()); - }, - child: wallet.imageCustomPath == null || wallet.imageCustomPath == '' - ? Image.asset( - 'assets/avatars/${wallet.imageDefaultPath}', - width: scaleSize(122), - ) - : Container( - width: scaleSize(122), - height: scaleSize(122), - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Colors.transparent, - image: DecorationImage( - fit: BoxFit.cover, - image: FileImage( - File(wallet.imageCustomPath!), - ), - ), + alignment: Alignment.center, + children: [ + Container( + width: scaleSize(100), + height: scaleSize(100), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: ClipOval( + child: wallet.imageCustomPath == null || wallet.imageCustomPath == '' + ? Image.asset( + 'assets/avatars/${wallet.imageDefaultPath}', + fit: BoxFit.cover, + ) + : Image.file( + File(wallet.imageCustomPath!), + fit: BoxFit.cover, ), - ), + ), ), Positioned( right: 0, - top: 0, - child: InkWell( - onTap: () async { - wallet.imageCustomPath = await (walletProvider.changeAvatar()); - walletProvider.reload(); - }, - child: Image.asset( - 'assets/walletOptions/camera.png', - height: scaleSize(38), + bottom: 0, + child: Container( + padding: EdgeInsets.all(scaleSize(8)), + decoration: const BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + ), + child: InkWell( + onTap: () async { + wallet.imageCustomPath = await walletProvider.changeAvatar(); + walletProvider.reload(); + }, + child: Icon( + Icons.camera_alt, + size: scaleSize(20), + color: Colors.black54, + ), ), ), ), @@ -258,98 +289,44 @@ class WalletOptions extends StatelessWidget { ); } - Widget confirmIdentityButton(WalletOptionsProvider walletProvider) { - return Consumer<SubstrateSdk>(builder: (context, sub, _) { - return FutureBuilder( - future: sub.idtyStatus([walletProvider.address.text]), - initialData: const [IdtyStatus.unknown], - builder: (BuildContext context, AsyncSnapshot<List<IdtyStatus>> snapshot) { - if (!snapshot.hasData || snapshot.hasError) { - return const SizedBox.shrink(); - } - if (snapshot.data!.first == IdtyStatus.unconfirmed) { - return Column(children: [ - ScaledSizedBox( - width: 290, - height: 50, - child: ElevatedButton( - key: keyConfirmIdentity, - style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, - elevation: 4, - backgroundColor: orangeC, - ), - onPressed: () { - walletProvider.confirmIdentityPopup(context); - }, - child: Text( - 'confirmMyIdentity'.tr(), - style: scaledTextStyle(fontSize: 20, fontWeight: FontWeight.w600), - ), - ), - ), - ScaledSizedBox(height: 7), - Text( - "someoneCreatedYourIdentity".tr(args: [currencyName]), - style: scaledTextStyle( - fontSize: 15, - color: Colors.grey[600], - fontStyle: FontStyle.italic, - ), - ), - ScaledSizedBox(height: 40), - ]); - } else { - return ScaledSizedBox(); - } - }); - }); - } - Widget pubkeyWidget(WalletOptionsProvider walletProvider, BuildContext ctx) { final shortPubkey = getShortPubkey(walletProvider.address.text); - return GestureDetector( - key: keyCopyAddress, - onTap: () { - Clipboard.setData(ClipboardData(text: walletProvider.address.text)); - snackCopyKey(ctx); - }, - child: ScaledSizedBox( - height: 50, - child: Row(children: <Widget>[ - ScaledSizedBox(width: 26), + return Container( + height: scaleSize(48), + padding: EdgeInsets.symmetric(horizontal: scaleSize(16)), + child: Row( + children: [ Image.asset( 'assets/walletOptions/key.png', - height: scaleSize(42), + height: scaleSize(24), + color: Colors.black87, ), - ScaledSizedBox(width: 19), - Text(shortPubkey, style: scaledTextStyle(fontSize: 18, fontWeight: FontWeight.w800, fontFamily: 'Monospace', color: Colors.black)), - const Spacer(), - ScaledSizedBox( - height: 35, - child: ElevatedButton( - style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - backgroundColor: orangeC, - elevation: 1, + ScaledSizedBox(width: 16), + Expanded( + child: Text( + shortPubkey, + style: scaledTextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + fontFamily: 'Monospace', + color: Colors.black87, ), - onPressed: () { - Clipboard.setData(ClipboardData(text: walletProvider.address.text)); - snackCopyKey(ctx); - }, - child: Row(children: <Widget>[ - Image.asset( - 'assets/walletOptions/copy-white.png', - height: scaleSize(23), - ), - ]), ), ), - const Spacer(), - ]), + IconButton( + padding: EdgeInsets.zero, + constraints: const BoxConstraints(), + icon: Icon( + Icons.copy, + size: scaleSize(20), + color: Colors.black87, + ), + onPressed: () { + Clipboard.setData(ClipboardData(text: walletProvider.address.text)); + snackCopyKey(ctx); + }, + ), + ], ), ); } @@ -360,61 +337,31 @@ class WalletOptions extends StatelessWidget { onTap: () { Navigator.push( context, - PageNoTransit(builder: (context) { - return ActivityScreen(address: walletProvider.address.text); - }), + PageNoTransit(builder: (context) => ActivityScreen(address: walletProvider.address.text)), ); }, - child: ScaledSizedBox( - height: 50, - child: Row(children: <Widget>[ - ScaledSizedBox(width: 26), - Image.asset( - 'assets/walletOptions/clock.png', - height: scaleSize(42), - ), - ScaledSizedBox(width: 20), - Text("displayActivity".tr(), style: scaledTextStyle(fontSize: 17)), - ]), - ), - ); - } - - Widget setDefaultWalletWidget(BuildContext context, WalletOptionsProvider walletProvider, final myWalletProvider, final walletOptions, int currentChest) { - return Consumer<MyWalletsProvider>(builder: (context, myWalletProvider, _) { - WalletData defaultWallet = myWalletProvider.getDefaultWallet(); - walletOptions.isDefaultWallet = (defaultWallet.number == wallet.id()[1]); - return InkWell( - key: keySetDefaultWallet, - onTap: !walletProvider.isDefaultWallet - ? () async { - await setDefaultWallet(context, currentChest); - } - : null, - child: ScaledSizedBox( - height: 60, - child: Row(children: <Widget>[ - ScaledSizedBox(width: isTall ? 28 : 23), - ScaledSizedBox( - height: 42, - child: CircleAvatar( - backgroundColor: Colors.grey[walletProvider.isDefaultWallet ? 300 : 500], - child: Image.asset( - 'assets/walletOptions/android-checkmark.png', - height: scaleSize(23), - ), - ), + child: Container( + height: scaleSize(48), + padding: EdgeInsets.symmetric(horizontal: scaleSize(16)), + child: Row( + children: [ + Image.asset( + 'assets/walletOptions/clock.png', + height: scaleSize(24), + color: Colors.black87, ), - ScaledSizedBox(width: isTall ? 21 : 18), - ScaledSizedBox( - width: 250, - child: Text(walletProvider.isDefaultWallet ? 'thisWalletIsDefault'.tr() : 'defineWalletAsDefault'.tr(), - style: scaledTextStyle(fontSize: 17, color: walletProvider.isDefaultWallet ? Colors.grey[500] : Colors.black)), + ScaledSizedBox(width: 16), + Text( + "displayActivity".tr(), + style: scaledTextStyle( + fontSize: 16, + color: Colors.black87, + ), ), - ]), + ], ), - ); - }); + ), + ); } Future setDefaultWallet(BuildContext context, int currentChest) async { @@ -438,7 +385,7 @@ class WalletOptions extends StatelessWidget { future: sub.hasAccountConsumers(wallet.address), builder: (BuildContext context, AsyncSnapshot<bool> hasConsumers) { if (hasConsumers.connectionState != ConnectionState.done || hasConsumers.hasError || !hasConsumers.hasData) { - return const Text(''); + return const SizedBox.shrink(); } final double balance = walletOptions.balanceCache[walletOptions.address.text] ?? -1; final bool canDelete = !isDefaultWallet && !hasConsumers.data! && (balance > 2 || balance == 0) && !wallet.hasIdentity(); @@ -454,57 +401,192 @@ class WalletOptions extends StatelessWidget { } : null, child: canDelete - ? Row(children: <Widget>[ - ScaledSizedBox(width: 27), - Image.asset( - 'assets/walletOptions/trash.png', - height: scaleSize(42), + ? Container( + height: scaleSize(48), + padding: EdgeInsets.symmetric(horizontal: scaleSize(16)), + child: Row( + children: [ + Image.asset( + 'assets/walletOptions/trash.png', + height: scaleSize(24), + color: const Color(0xffD80000), + ), + ScaledSizedBox(width: 16), + Text( + 'deleteThisWallet'.tr(), + style: scaledTextStyle( + fontSize: 16, + color: const Color(0xffD80000), + ), + ), + ], ), - ScaledSizedBox(width: 19), - Text('deleteThisWallet'.tr(), style: scaledTextStyle(fontSize: 17, color: const Color(0xffD80000))), - ]) - : ScaledSizedBox(width: 30), + ) + : const SizedBox.shrink(), ); }); } - Widget renewMembershipButton(WalletOptionsProvider walletProvider) { + Widget buildRenewMembershipSection(WalletOptionsProvider walletProvider) { + return Consumer<SubstrateSdk>( + builder: (context, sub, _) { + return FutureBuilder<MembershipStatus>( + future: sub.getMembershipStatus(walletProvider.address.text), + builder: (context, snapshot) { + if (!snapshot.hasData || snapshot.hasError) { + return const SizedBox.shrink(); + } + + final info = MembershipRenewal.calculateRenewalInfo( + snapshot.data!, + sub.currencyParameters['membershipRenewalPeriod']!, + ); + + if (!info.canRenew) return const SizedBox.shrink(); + + return Container( + margin: EdgeInsets.only(bottom: scaleSize(24)), + child: Column( + children: [ + SizedBox( + width: double.infinity, + height: scaleSize(50), + child: ElevatedButton( + key: keyRenewMembership, + style: ElevatedButton.styleFrom( + backgroundColor: orangeC, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + onPressed: () => MembershipRenewal.executeRenewal(context, walletProvider.address.text), + child: Text( + 'renewMembership'.tr(), + style: scaledTextStyle(fontSize: 16, color: Colors.white), + ), + ), + ), + ScaledSizedBox(height: 8), + MembershipRenewal.buildExpirationText(info, width: 250), + ], + ), + ); + }, + ); + }, + ); + } + + Widget buildOptionsSection(BuildContext context, WalletOptionsProvider walletProvider, WalletsProfilesProvider historyProvider) { + return Column( + children: [ + pubkeyWidget(walletProvider, context), + ScaledSizedBox(height: 4), + activityWidget(context, historyProvider, walletProvider), + ScaledSizedBox(height: 4), + ], + ); + } + + Widget buildDefaultWalletSection( + BuildContext context, WalletOptionsProvider walletProvider, MyWalletsProvider myWalletProvider, WalletOptionsProvider walletOptions, int currentChest) { + return Consumer<MyWalletsProvider>( + builder: (context, myWalletProvider, _) { + WalletData defaultWallet = myWalletProvider.getDefaultWallet(); + walletOptions.isDefaultWallet = (defaultWallet.number == wallet.id()[1]); + return InkWell( + key: keySetDefaultWallet, + onTap: !walletProvider.isDefaultWallet + ? () async { + await setDefaultWallet(context, currentChest); + } + : null, + child: Container( + height: scaleSize(48), + padding: EdgeInsets.symmetric(horizontal: scaleSize(16)), + child: Row( + children: [ + Icon( + Icons.check_circle_outline, + size: scaleSize(24), + color: walletProvider.isDefaultWallet + ? Colors.grey[400] // Garde la couleur grise pour l'état désactivé + : Colors.black87, // Plus foncé pour l'état actif + ), + ScaledSizedBox(width: 16), + Text( + walletProvider.isDefaultWallet ? 'thisWalletIsDefault'.tr() : 'defineWalletAsDefault'.tr(), + style: scaledTextStyle( + fontSize: 16, + color: walletProvider.isDefaultWallet + ? Colors.grey[500] // Un peu plus foncé pour le texte désactivé + : Colors.black87, // Plus foncé pour le texte actif + ), + ), + ], + ), + ), + ); + }, + ); + } + + Widget buildDangerZone(BuildContext context, WalletOptionsProvider walletProvider, int currentChest) { + return Container( + margin: EdgeInsets.symmetric(vertical: scaleSize(8)), + child: Column( + children: [ + if (!walletProvider.isDefaultWallet && !wallet.hasIdentity()) deleteWallet(context, walletProvider, currentChest), + if (wallet.hasIdentity()) const ManageMembershipButton(), + ], + ), + ); + } + + Widget buildConfirmIdentitySection(WalletOptionsProvider walletProvider) { return Consumer<SubstrateSdk>(builder: (context, sub, _) { - return FutureBuilder<MembershipStatus>( - future: sub.getMembershipStatus(walletProvider.address.text), - builder: (context, snapshot) { + return FutureBuilder( + future: sub.idtyStatus([walletProvider.address.text]), + initialData: const [IdtyStatus.unknown], + builder: (BuildContext context, AsyncSnapshot<List<IdtyStatus>> snapshot) { if (!snapshot.hasData || snapshot.hasError) { return const SizedBox.shrink(); } - - final info = MembershipRenewal.calculateRenewalInfo( - snapshot.data!, - sub.currencyParameters['membershipRenewalPeriod']!, - ); - - if (info.canRenew) return const SizedBox.shrink(); - - return Column(children: [ - ScaledSizedBox( - width: 290, - height: 50, - child: ElevatedButton( - key: keyRenewMembership, - style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: orangeC, + if (snapshot.data!.first == IdtyStatus.unconfirmed) { + return Column(children: [ + SizedBox( + width: double.infinity, + height: scaleSize(50), + child: ElevatedButton( + key: keyConfirmIdentity, + style: ElevatedButton.styleFrom( + backgroundColor: orangeC, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + onPressed: () => walletProvider.confirmIdentityPopup(context), + child: Text( + 'confirmMyIdentity'.tr(), + style: scaledTextStyle(fontSize: 16, color: Colors.white), + ), ), - onPressed: () => MembershipRenewal.executeRenewal(context, walletProvider.address.text), - child: Text( - 'renewMembership'.tr(), - style: scaledTextStyle(fontSize: 17), + ), + ScaledSizedBox(height: 8), + Text( + "someoneCreatedYourIdentity".tr(args: [currencyName]), + style: scaledTextStyle( + fontSize: 15, + color: Colors.grey[600], + fontStyle: FontStyle.italic, ), ), - ), - ScaledSizedBox(height: 7), - MembershipRenewal.buildExpirationText(info, width: 250), - ScaledSizedBox(height: 40), - ]); + ScaledSizedBox(height: 24), + ]); + } + return const SizedBox.shrink(); }, ); }); @@ -514,46 +596,40 @@ class WalletOptions extends StatelessWidget { Widget aloneWalletOptions() { return Column( children: [ - ChestOptionsContent(), + const ChestOptionsContent(), Consumer<SubstrateSdk>( builder: (context, sub, _) { final myWalletProvider = Provider.of<MyWalletsProvider>(context); - return Column( - children: [ - InkWell( - onTap: () async { - if (!myWalletProvider.isNewDerivationLoading) { - if (!await myWalletProvider.askPinCode()) return; - - String newDerivationName = '${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}'; - await myWalletProvider.generateNewDerivation(context, newDerivationName); - - Navigator.pushReplacementNamed(context, '/mywallets'); - } - }, - child: ScaledSizedBox( - height: 60, - child: Row( - children: <Widget>[ - ScaledSizedBox(width: 37), - Icon( - Icons.add_circle_outline, - size: scaleSize(31), - color: sub.nodeConnected ? Colors.black : Colors.grey[500], - ), - ScaledSizedBox(width: 23), - Text( - 'createNewWallet'.tr(), - style: scaledTextStyle( - fontSize: 16, - color: sub.nodeConnected ? Colors.black : Colors.grey[500], - ), - ), - ], + return InkWell( + onTap: () async { + if (!myWalletProvider.isNewDerivationLoading) { + if (!await myWalletProvider.askPinCode()) return; + String newDerivationName = '${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}'; + await myWalletProvider.generateNewDerivation(context, newDerivationName); + Navigator.pushReplacementNamed(context, '/mywallets'); + } + }, + child: Container( + height: scaleSize(48), + padding: EdgeInsets.symmetric(horizontal: scaleSize(16)), + child: Row( + children: [ + Icon( + Icons.add_circle_outline, + size: scaleSize(24), + color: sub.nodeConnected ? Colors.black87 : Colors.grey[400], ), - ), + ScaledSizedBox(width: 16), + Text( + 'createNewWallet'.tr(), + style: scaledTextStyle( + fontSize: 16, + color: sub.nodeConnected ? Colors.black87 : Colors.grey[500], + ), + ), + ], ), - ], + ), ); }, ), @@ -561,27 +637,24 @@ Widget aloneWalletOptions() { onTap: () async { Navigator.push( homeContext, - MaterialPageRoute(builder: (context) { - return const ImportG1v1(); - }), + MaterialPageRoute(builder: (context) => const ImportG1v1()), ); }, - child: ScaledSizedBox( - height: 60, + child: Container( + height: scaleSize(48), + padding: EdgeInsets.symmetric(horizontal: scaleSize(16)), child: Row( - children: <Widget>[ - ScaledSizedBox(width: 37), + children: [ SvgPicture.asset( 'assets/cesium_bw2.svg', - semanticsLabel: 'CS', - height: scaleSize(31), + height: scaleSize(24), ), - ScaledSizedBox(width: 23), + ScaledSizedBox(width: 16), Text( 'importG1v1'.tr(), style: scaledTextStyle( fontSize: 16, - color: Colors.black, + color: Colors.black87, ), ), ], diff --git a/lib/screens/transaction_in_progress.dart b/lib/screens/transaction_in_progress.dart index 22d3bd2c1430bb48cfbd7e0ff0696a1eebb4ad4b..0a45881aafd28b1c74254cd3004f4bb6190d4a00 100644 --- a/lib/screens/transaction_in_progress.dart +++ b/lib/screens/transaction_in_progress.dart @@ -106,7 +106,7 @@ class _TransactionInProgressState extends State<TransactionInProgress> { return Scaffold( backgroundColor: Colors.white, appBar: AppBar( - backgroundColor: const Color(0xFFFFF3E0), + backgroundColor: headerColor, elevation: 0, automaticallyImplyLeading: false, centerTitle: true, @@ -123,7 +123,7 @@ class _TransactionInProgressState extends State<TransactionInProgress> { children: [ Container( width: double.infinity, - color: const Color(0xFFFFF3E0), + color: headerColor, padding: EdgeInsets.symmetric( horizontal: scaleSize(24), vertical: scaleSize(16), diff --git a/lib/widgets/balance.dart b/lib/widgets/balance.dart index bb02cb85b37b5b6c59a038de11c5ed732a31af30..1ccfa18b2119a30c231e836212e79dfafd0b62dd 100644 --- a/lib/widgets/balance.dart +++ b/lib/widgets/balance.dart @@ -6,60 +6,46 @@ import 'package:gecko/widgets/ud_unit_display.dart'; import 'package:provider/provider.dart'; class Balance extends StatelessWidget { - const Balance( - {super.key, - required this.address, - required this.size, - this.color = Colors.black}); + const Balance({super.key, required this.address, required this.size, this.color = Colors.black}); final String address; final double size; final Color color; @override Widget build(BuildContext context) { - final walletOptions = - Provider.of<WalletOptionsProvider>(context, listen: false); + final walletOptions = Provider.of<WalletOptionsProvider>(context, listen: false); return Consumer<SubstrateSdk>(builder: (context, sdk, _) { - return ScaledSizedBox( - height: size * 1.4, - child: FutureBuilder( - future: sdk.getBalance(address), - builder: (BuildContext context, - AsyncSnapshot<Map<String, double>> globalBalance) { - if (globalBalance.connectionState != ConnectionState.done || - globalBalance.hasError || - !globalBalance.hasData) { - if (walletOptions.balanceCache[address] != null && - walletOptions.balanceCache[address] != -1) { - return Row(children: [ - Text(walletOptions.balanceCache[address]!.toString(), - style: scaledTextStyle(fontSize: size, color: color)), - ScaledSizedBox(width: 5), - UdUnitDisplay(size: scaleSize(size), color: color), - ]); - } else { - return const SizedBox.shrink(); - } - } - walletOptions.balanceCache[address] = - globalBalance.data!['transferableBalance']!; - if (walletOptions.balanceCache[address] != -1) { - return Row(children: [ + return FutureBuilder( + future: sdk.getBalance(address), + builder: (BuildContext context, AsyncSnapshot<Map<String, double>> globalBalance) { + if (globalBalance.connectionState != ConnectionState.done || globalBalance.hasError || !globalBalance.hasData) { + if (walletOptions.balanceCache[address] != null && walletOptions.balanceCache[address] != -1) { + return Row(mainAxisSize: MainAxisSize.min, children: [ Text( walletOptions.balanceCache[address]!.toString(), - style: scaledTextStyle( - fontSize: size, - color: color, - ), + style: scaledTextStyle(fontSize: size, color: color), ), ScaledSizedBox(width: 5), UdUnitDisplay(size: scaleSize(size), color: color), ]); } else { - return const Text(''); + return const SizedBox.shrink(); } - }), - ); + } + walletOptions.balanceCache[address] = globalBalance.data!['transferableBalance']!; + if (walletOptions.balanceCache[address] != -1) { + return Row(mainAxisSize: MainAxisSize.min, children: [ + Text( + walletOptions.balanceCache[address]!.toString(), + style: scaledTextStyle(fontSize: size, color: color), + ), + ScaledSizedBox(width: 5), + UdUnitDisplay(size: scaleSize(size), color: color), + ]); + } else { + return const Text(''); + } + }); }); } } diff --git a/lib/widgets/buttons/manage_membership_button.dart b/lib/widgets/buttons/manage_membership_button.dart index 6477aee501227ba79f9cfdd3f0ece40590fc7bad..2eeb99f18a3ea3eeb95f28e4549b60e7f256b8a8 100644 --- a/lib/widgets/buttons/manage_membership_button.dart +++ b/lib/widgets/buttons/manage_membership_button.dart @@ -1,43 +1,43 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/models/scale_functions.dart'; -import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/screens/myWallets/manage_membership.dart'; import 'package:provider/provider.dart'; class ManageMembershipButton extends StatelessWidget { - const ManageMembershipButton({ - super.key, - }); + const ManageMembershipButton({super.key}); @override Widget build(BuildContext context) { - final walletOptions = - Provider.of<WalletOptionsProvider>(context, listen: false); + final walletOptions = Provider.of<WalletOptionsProvider>(context, listen: false); return InkWell( - key: keyManageMembership, onTap: () { Navigator.push( context, - MaterialPageRoute(builder: (context) { - return ManageMembership( - address: walletOptions.address.text, - ); - }), + MaterialPageRoute(builder: (context) => ManageMembership(address: walletOptions.address.text)), ); }, - child: ScaledSizedBox( - height: 40, - child: Row(children: <Widget>[ - ScaledSizedBox(width: 28), - Image.asset( - 'assets/medal.png', - height: scaleSize(42), - ), - ScaledSizedBox(width: 20), - Text('manageMembership'.tr(), style: scaledTextStyle(fontSize: 17)), - ]), + child: Container( + height: scaleSize(48), + padding: EdgeInsets.symmetric(horizontal: scaleSize(16)), + child: Row( + children: [ + Icon( + Icons.workspace_premium_outlined, + size: scaleSize(24), + color: Colors.black87, + ), + ScaledSizedBox(width: 16), + Text( + 'manageMembership'.tr(), + style: scaledTextStyle( + fontSize: 16, + color: Colors.black87, + ), + ), + ], + ), ), ); } diff --git a/lib/widgets/name_by_address.dart b/lib/widgets/name_by_address.dart index c814c8ecae076a7aa7eda480c59985b6febcab88..19395aa462cd3fb7f1751607fe82d2f1fdf937e5 100644 --- a/lib/widgets/name_by_address.dart +++ b/lib/widgets/name_by_address.dart @@ -14,12 +14,7 @@ import 'package:truncate/truncate.dart'; class NameByAddress extends StatelessWidget { const NameByAddress( - {super.key, - required this.wallet, - this.size = 20, - this.color = Colors.black, - this.fontWeight = FontWeight.w400, - this.fontStyle = FontStyle.italic}); + {super.key, required this.wallet, this.size = 20, this.color = Colors.black, this.fontWeight = FontWeight.w400, this.fontStyle = FontStyle.italic}); final WalletData wallet; final Color color; final double size; @@ -43,8 +38,7 @@ class NameByAddress extends StatelessWidget { 'address': wallet.address, }, ), - builder: (QueryResult result, - {VoidCallback? refetch, FetchMore? fetchMore}) { + builder: (QueryResult result, {VoidCallback? refetch, FetchMore? fetchMore}) { if (kDebugMode) { if (result.hasException) { return Text(result.exception.toString()); @@ -56,18 +50,11 @@ class NameByAddress extends StatelessWidget { } final edges = result.data?['identityConnection']['edges']; - final name = edges != null && edges.isNotEmpty - ? edges[0]['node']['name'] - : null; + final name = edges != null && edges.isNotEmpty ? edges[0]['node']['name'] : null; duniterIndexer.walletNameIndexer[wallet.address] = name; - g1WalletsBox.put( - wallet.address, - G1WalletsList( - address: wallet.address, - username: - duniterIndexer.walletNameIndexer[wallet.address])); + g1WalletsBox.put(wallet.address, G1WalletsList(address: wallet.address, username: duniterIndexer.walletNameIndexer[wallet.address])); if (duniterIndexer.walletNameIndexer[wallet.address] == null) { return WalletName(wallet: wallet, size: size, color: color); @@ -76,8 +63,7 @@ class NameByAddress extends StatelessWidget { return Text( color == Colors.grey[700]! ? '(${duniterIndexer.walletNameIndexer[wallet.address]!})' - : truncate( - duniterIndexer.walletNameIndexer[wallet.address]!, 20), + : truncate(duniterIndexer.walletNameIndexer[wallet.address]!, 19), style: scaledTextStyle( fontSize: size, color: color, diff --git a/lib/widgets/wallet_name.dart b/lib/widgets/wallet_name.dart index b2213b44f3457874acfa31192a009c9ebac057d6..219cf177176a8a2a6ca7f34a9f79d1e708813390 100644 --- a/lib/widgets/wallet_name.dart +++ b/lib/widgets/wallet_name.dart @@ -4,11 +4,7 @@ import 'package:gecko/models/wallet_data.dart'; import 'package:truncate/truncate.dart'; class WalletName extends StatelessWidget { - const WalletName( - {super.key, - required this.wallet, - this.size = 20, - this.color = Colors.black}); + const WalletName({super.key, required this.wallet, this.size = 20, this.color = Colors.black}); final WalletData wallet; final double size; final Color color; @@ -17,7 +13,7 @@ class WalletName extends StatelessWidget { Widget build(BuildContext context) { return Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( - truncate(wallet.name ?? '', 20), + truncate(wallet.name ?? '', 19), textAlign: TextAlign.center, style: scaledTextStyle( fontSize: size,