From 50a95086670929f95cca4350d26b14a05169303e Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Thu, 4 Jul 2024 22:14:51 +0545 Subject: [PATCH] October (#2768) * fix: Solve different issues of token #2750 * feat: Support talao4eu wallet type #2765 * feat: Add option to reset if wallet attestation is revoked #2759 * fix: Add image in pin code blocked screen page #2742 * fix: Overflow issue in blockchain accounts list * feat: Add new wordings for did list #2707 * fix: Solve restoration failing in ios #2763 * feat: Set default theme value #2760 * fix: Update account name instantly #2667 * feat: Add auto in vcformat #2770 * linter update * feat: Implement app theme in chat #2767 --- lib/app/shared/constants/parameters.dart | 3 + lib/app/shared/enum/status/app_status.dart | 2 +- .../enum/type/profile/wallet_app_type.dart | 2 +- lib/chat_room/view/chat_room_view.dart | 74 +++++++++++++++++- .../widgets/manage_accounts_item.dart | 78 +++++++++---------- .../widgets/reveal_private_key_button.dart | 12 +-- .../widgets/see_address_button.dart | 12 +-- .../drawer/reset_wallet/reset_wallet.dart | 1 + .../reset_wallet/view/reset_wallet_menu.dart | 2 - .../manage_did/view/did/manage_did_page.dart | 3 +- .../manage_did_polygon_id_page.dart | 2 +- .../jwk_thumbprint_p256_key_page.dart | 2 +- .../view/restore_credential_page.dart | 14 +++- .../widgets/upload_file.dart | 16 ++-- .../cubit/token_amount_calculator_cubit.dart | 32 +++++--- .../cubit/token_amount_calculator_state.dart | 9 +++ .../widgets/token_amount_calculator.dart | 7 ++ lib/enterprise/cubit/enterprise_cubit.dart | 4 +- lib/enterprise/cubit/enterprise_state.dart | 2 +- lib/enterprise/enterprise.dart | 1 + .../widget/wallet_revoked_dialog.dart | 63 +++++++++++++++ lib/enterprise/widget/widget.dart | 1 + lib/l10n/arb/app_en.arb | 14 ++-- lib/pin_code/view/delete_my_wallet_page.dart | 26 +++---- lib/splash/bloclisteners/blocklisteners.dart | 7 ++ lib/theme/theme_repository.dart | 3 +- lib/theme/theme_state.dart | 5 +- lib/wallet/cubit/wallet_cubit.dart | 2 + packages/oidc4vc/lib/src/vc_format_type.dart | 9 +++ .../alert_message/alert_message_test.dart | 1 + test/app/shared/date/date_test.dart | 4 +- test/app/view/app_test.dart | 9 ++- .../drawer/src/view/drawer_page_test.dart | 3 +- test/lang/cubit/lang_cubit_test.dart | 24 +++--- 34 files changed, 322 insertions(+), 127 deletions(-) create mode 100644 lib/enterprise/widget/wallet_revoked_dialog.dart create mode 100644 lib/enterprise/widget/widget.dart diff --git a/lib/app/shared/constants/parameters.dart b/lib/app/shared/constants/parameters.dart index ddfd06ab3..c3ff799b8 100644 --- a/lib/app/shared/constants/parameters.dart +++ b/lib/app/shared/constants/parameters.dart @@ -102,4 +102,7 @@ class Parameters { static const Color seedColor = Color(0xff6600FF); // Talao // static const Color seedColor = Color(0xff1EAADC); + + // ThemeMode.light for talao + static const ThemeMode defaultTheme = ThemeMode.dark; } diff --git a/lib/app/shared/enum/status/app_status.dart b/lib/app/shared/enum/status/app_status.dart index f45e362df..e4d129104 100644 --- a/lib/app/shared/enum/status/app_status.dart +++ b/lib/app/shared/enum/status/app_status.dart @@ -8,5 +8,5 @@ enum AppStatus { success, idle, goBack, - //gotTokenReward, + revoked, } diff --git a/lib/app/shared/enum/type/profile/wallet_app_type.dart b/lib/app/shared/enum/type/profile/wallet_app_type.dart index 40fadef4c..cac833ffc 100644 --- a/lib/app/shared/enum/type/profile/wallet_app_type.dart +++ b/lib/app/shared/enum/type/profile/wallet_app_type.dart @@ -1 +1 @@ -enum WalletAppType { altme, talao } +enum WalletAppType { altme, talao, talao4eu } diff --git a/lib/chat_room/view/chat_room_view.dart b/lib/chat_room/view/chat_room_view.dart index 1080f8000..974c68bc5 100644 --- a/lib/chat_room/view/chat_room_view.dart +++ b/lib/chat_room/view/chat_room_view.dart @@ -51,6 +51,7 @@ class _ChatRoomViewState extends State { @override Widget build(BuildContext context) { final l10n = context.l10n; + final colorScheme = Theme.of(context).colorScheme; return BasePage( title: widget.appBarTitle, scrollView: false, @@ -103,7 +104,78 @@ class _ChatRoomViewState extends State { alignment: Alignment.topCenter, children: [ Chat( - theme: const DarkChatTheme(), + theme: DefaultChatTheme( + primaryColor: colorScheme.primaryContainer, + secondaryColor: colorScheme.secondaryContainer, + backgroundColor: colorScheme.surface, + inputBackgroundColor: colorScheme.secondaryContainer, + inputTextColor: colorScheme.onSurface, + errorColor: colorScheme.error, + sentMessageBodyTextStyle: TextStyle( + color: colorScheme.onPrimary, + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.5, + ), + sentMessageBodyBoldTextStyle: TextStyle( + color: colorScheme.onPrimary, + fontSize: 12, + fontWeight: FontWeight.w500, + height: 1.333, + ), + sentMessageDocumentIconColor: colorScheme.onPrimary, + sentMessageLinkTitleTextStyle: TextStyle( + color: colorScheme.onPrimary, + fontSize: 16, + fontWeight: FontWeight.w800, + height: 1.375, + ), + sentMessageCaptionTextStyle: TextStyle( + color: colorScheme.onPrimary, + fontSize: 12, + fontWeight: FontWeight.w500, + height: 1, + ), + systemMessageTheme: SystemMessageTheme( + margin: const EdgeInsets.only( + bottom: 24, + top: 8, + left: 8, + right: 8, + ), + textStyle: TextStyle( + color: colorScheme.onPrimary, + fontSize: 12, + fontWeight: FontWeight.w800, + height: 1.333, + ), + ), + receivedMessageBodyTextStyle: TextStyle( + color: colorScheme.onSurface, + fontSize: 16, + fontWeight: FontWeight.w500, + height: 1.5, + ), + receivedMessageCaptionTextStyle: TextStyle( + color: colorScheme.onSurface, + fontSize: 12, + fontWeight: FontWeight.w500, + height: 1.333, + ), + receivedMessageDocumentIconColor: colorScheme.onSurface, + receivedMessageLinkDescriptionTextStyle: TextStyle( + color: colorScheme.onSurface, + fontSize: 14, + fontWeight: FontWeight.w400, + height: 1.428, + ), + receivedMessageLinkTitleTextStyle: TextStyle( + color: colorScheme.onSurface, + fontSize: 16, + fontWeight: FontWeight.w800, + height: 1.375, + ), + ), messages: state.messages, onSendPressed: (partialText) { FocusManager.instance.primaryFocus?.unfocus(); diff --git a/lib/dashboard/drawer/blockchain_settings/manage_accounts/widgets/manage_accounts_item.dart b/lib/dashboard/drawer/blockchain_settings/manage_accounts/widgets/manage_accounts_item.dart index 9eb615476..34dea61b6 100644 --- a/lib/dashboard/drawer/blockchain_settings/manage_accounts/widgets/manage_accounts_item.dart +++ b/lib/dashboard/drawer/blockchain_settings/manage_accounts/widgets/manage_accounts_item.dart @@ -35,7 +35,6 @@ class ManageAccountsItem extends StatelessWidget { return BackgroundCard( child: Container( margin: const EdgeInsets.only(bottom: Sizes.spaceSmall), - padding: const EdgeInsets.symmetric(horizontal: Sizes.spaceSmall), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -114,50 +113,51 @@ class ManageAccountsItem extends StatelessWidget { Row( mainAxisSize: MainAxisSize.min, children: [ - SeeAddressButton( - onTap: () { - Navigator.of(context).push( - AccountPublicAddressPage.route( - accountName: accountName, - accountAddress: cryptoAccountData.walletAddress, - ), - ); - }, + Expanded( + child: SeeAddressButton( + onTap: () { + Navigator.of(context).push( + AccountPublicAddressPage.route( + accountName: accountName, + accountAddress: cryptoAccountData.walletAddress, + ), + ); + }, + ), ), const SizedBox(width: Sizes.spaceSmall), - RevealPrivateKeyButton( - onTap: () async { - final confirm = await showDialog( - context: context, - builder: (context) => ConfirmDialog( - title: l10n.warningDialogTitle, - subtitle: l10n.accountPrivateKeyAlert, - yes: l10n.showDialogYes, - no: l10n.showDialogNo, - ), - ) ?? - false; - - if (confirm) { - await securityCheck( - context: context, - localAuthApi: LocalAuthApi(), - onSuccess: () { - Navigator.of(context).push( - AccountPrivateKeyPage.route( - privateKey: cryptoAccountData.secretKey, + Expanded( + child: RevealPrivateKeyButton( + onTap: () async { + final confirm = await showDialog( + context: context, + builder: (context) => ConfirmDialog( + title: l10n.warningDialogTitle, + subtitle: l10n.accountPrivateKeyAlert, + yes: l10n.showDialogYes, + no: l10n.showDialogNo, ), - ); - }, - ); - } - }, + ) ?? + false; + + if (confirm) { + await securityCheck( + context: context, + localAuthApi: LocalAuthApi(), + onSuccess: () { + Navigator.of(context).push( + AccountPrivateKeyPage.route( + privateKey: cryptoAccountData.secretKey, + ), + ); + }, + ); + } + }, + ), ), ], ), - const SizedBox( - height: Sizes.spaceSmall, - ), ], ), ), diff --git a/lib/dashboard/drawer/blockchain_settings/manage_accounts/widgets/reveal_private_key_button.dart b/lib/dashboard/drawer/blockchain_settings/manage_accounts/widgets/reveal_private_key_button.dart index 8368b8cf6..939fb6f32 100644 --- a/lib/dashboard/drawer/blockchain_settings/manage_accounts/widgets/reveal_private_key_button.dart +++ b/lib/dashboard/drawer/blockchain_settings/manage_accounts/widgets/reveal_private_key_button.dart @@ -31,11 +31,13 @@ class RevealPrivateKeyButton extends StatelessWidget { width: Sizes.icon, color: Theme.of(context).colorScheme.onSurface, ), - Text( - l10n.revealPrivateKey.toUpperCase(), - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: Theme.of(context).colorScheme.onSurface, - ), + Expanded( + child: MyText( + l10n.revealPrivateKey.toUpperCase(), + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: Theme.of(context).colorScheme.onSurface, + ), + ), ), ], ), diff --git a/lib/dashboard/drawer/blockchain_settings/manage_accounts/widgets/see_address_button.dart b/lib/dashboard/drawer/blockchain_settings/manage_accounts/widgets/see_address_button.dart index 86cba1cf0..b2316e257 100644 --- a/lib/dashboard/drawer/blockchain_settings/manage_accounts/widgets/see_address_button.dart +++ b/lib/dashboard/drawer/blockchain_settings/manage_accounts/widgets/see_address_button.dart @@ -35,11 +35,13 @@ class SeeAddressButton extends StatelessWidget { color: Theme.of(context).colorScheme.onPrimaryContainer, ), ), - Text( - l10n.seeAddress.toUpperCase(), - style: Theme.of(context).textTheme.bodyMedium!.copyWith( - color: Theme.of(context).colorScheme.onPrimaryContainer, - ), + Expanded( + child: MyText( + l10n.seeAddress.toUpperCase(), + style: Theme.of(context).textTheme.bodyMedium!.copyWith( + color: Theme.of(context).colorScheme.onPrimaryContainer, + ), + ), ), ], ), diff --git a/lib/dashboard/drawer/reset_wallet/reset_wallet.dart b/lib/dashboard/drawer/reset_wallet/reset_wallet.dart index bc36d7c77..7da44926b 100644 --- a/lib/dashboard/drawer/reset_wallet/reset_wallet.dart +++ b/lib/dashboard/drawer/reset_wallet/reset_wallet.dart @@ -1,2 +1,3 @@ export 'cubit/reset_wallet_cubit.dart'; +export 'helper_functions/reset_wallet.dart'; export 'view/reset_wallet_menu.dart'; diff --git a/lib/dashboard/drawer/reset_wallet/view/reset_wallet_menu.dart b/lib/dashboard/drawer/reset_wallet/view/reset_wallet_menu.dart index 7738590e6..ea99fee3d 100644 --- a/lib/dashboard/drawer/reset_wallet/view/reset_wallet_menu.dart +++ b/lib/dashboard/drawer/reset_wallet/view/reset_wallet_menu.dart @@ -1,8 +1,6 @@ import 'package:altme/app/app.dart'; import 'package:altme/dashboard/dashboard.dart'; -import 'package:altme/dashboard/drawer/reset_wallet/helper_functions/reset_wallet.dart'; import 'package:altme/l10n/l10n.dart'; - import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/lib/dashboard/drawer/ssi/manage_did/view/did/manage_did_page.dart b/lib/dashboard/drawer/ssi/manage_did/view/did/manage_did_page.dart index 211ff0986..d4a065106 100644 --- a/lib/dashboard/drawer/ssi/manage_did/view/did/manage_did_page.dart +++ b/lib/dashboard/drawer/ssi/manage_did/view/did/manage_did_page.dart @@ -48,8 +48,9 @@ class _ManageDidEbsiPageState extends State { @override Widget build(BuildContext context) { final l10n = context.l10n; + final title = widget.didKeyType.getTitle(l10n); return BasePage( - title: l10n.decentralizedIDKey, + title: title, titleAlignment: Alignment.topCenter, scrollView: false, titleLeading: const BackLeadingButton(), diff --git a/lib/dashboard/drawer/ssi/manage_did/view/did_polygon_id/manage_did_polygon_id_page.dart b/lib/dashboard/drawer/ssi/manage_did/view/did_polygon_id/manage_did_polygon_id_page.dart index ab0174c63..090eb60dc 100644 --- a/lib/dashboard/drawer/ssi/manage_did/view/did_polygon_id/manage_did_polygon_id_page.dart +++ b/lib/dashboard/drawer/ssi/manage_did/view/did_polygon_id/manage_did_polygon_id_page.dart @@ -54,7 +54,7 @@ class ManageDidPolygonIdPage extends StatelessWidget { Widget build(BuildContext context) { final l10n = context.l10n; return BasePage( - title: l10n.polygonIdDecentralizedId, + title: l10n.polygonDecentralizedID, titleAlignment: Alignment.topCenter, scrollView: false, titleLeading: const BackLeadingButton(), diff --git a/lib/dashboard/drawer/ssi/manage_did/view/jwk_thumbprint_p256_key/jwk_thumbprint_p256_key_page.dart b/lib/dashboard/drawer/ssi/manage_did/view/jwk_thumbprint_p256_key/jwk_thumbprint_p256_key_page.dart index ba7aafe19..bfa876809 100644 --- a/lib/dashboard/drawer/ssi/manage_did/view/jwk_thumbprint_p256_key/jwk_thumbprint_p256_key_page.dart +++ b/lib/dashboard/drawer/ssi/manage_did/view/jwk_thumbprint_p256_key/jwk_thumbprint_p256_key_page.dart @@ -77,7 +77,7 @@ class _JWKThumbprintP256KeyPageState extends State mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - l10n.jwkThumbprintP256Key, + l10n.did, style: Theme.of(context).textTheme.headlineSmall, ), const SizedBox( diff --git a/lib/dashboard/drawer/ssi/restore/restore_credential/view/restore_credential_page.dart b/lib/dashboard/drawer/ssi/restore/restore_credential/view/restore_credential_page.dart index 5d63d03f4..e70098548 100644 --- a/lib/dashboard/drawer/ssi/restore/restore_credential/view/restore_credential_page.dart +++ b/lib/dashboard/drawer/ssi/restore/restore_credential/view/restore_credential_page.dart @@ -127,7 +127,7 @@ class _RestoreCredentialViewState extends State { UploadFile( filePath: state.backupFilePath, onTap: () async { - if (Platform.isAndroid) { + if (isAndroid) { final appDir = (await getTemporaryDirectory()).path; await Directory(appDir).delete(recursive: true); } @@ -159,15 +159,21 @@ class _RestoreCredentialViewState extends State { Future _pickRestoreFile() async { final l10n = context.l10n; final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); - final AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; /// storage permission has changed with android 13 late final PermissionStatus storagePermission; - if (int.parse(androidInfo.version.release) > 12) { - storagePermission = await Permission.photos.request(); + + if (isAndroid) { + final AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; + if (int.parse(androidInfo.version.release) > 12) { + storagePermission = await Permission.photos.request(); + } else { + storagePermission = await Permission.storage.request(); + } } else { storagePermission = await Permission.storage.request(); } + if (storagePermission.isDenied) { AlertMessage.showStateMessage( context: context, diff --git a/lib/dashboard/drawer/ssi/restore/restore_credential/widgets/upload_file.dart b/lib/dashboard/drawer/ssi/restore/restore_credential/widgets/upload_file.dart index f2e4ad094..50c9f509e 100644 --- a/lib/dashboard/drawer/ssi/restore/restore_credential/widgets/upload_file.dart +++ b/lib/dashboard/drawer/ssi/restore/restore_credential/widgets/upload_file.dart @@ -50,13 +50,15 @@ class UploadFile extends StatelessWidget { width: Sizes.icon, height: Sizes.icon, ), - const SizedBox( - width: Sizes.space2XSmall, - ), - MyText( - filePath == null ? l10n.uploadFile : filePath!.split('/').last, - minFontSize: 12, - style: Theme.of(context).textTheme.headlineSmall, + const SizedBox(width: Sizes.space2XSmall), + Expanded( + child: MyText( + filePath == null + ? l10n.uploadFile + : filePath!.split('/').last, + minFontSize: 12, + style: Theme.of(context).textTheme.bodyLarge, + ), ), ], ), diff --git a/lib/dashboard/home/tab_bar/tokens/insert_withdrawal_amount/cubit/token_amount_calculator_cubit.dart b/lib/dashboard/home/tab_bar/tokens/insert_withdrawal_amount/cubit/token_amount_calculator_cubit.dart index d3a466144..5d60f3458 100644 --- a/lib/dashboard/home/tab_bar/tokens/insert_withdrawal_amount/cubit/token_amount_calculator_cubit.dart +++ b/lib/dashboard/home/tab_bar/tokens/insert_withdrawal_amount/cubit/token_amount_calculator_cubit.dart @@ -1,4 +1,4 @@ -import 'package:altme/app/logger/logger.dart'; +import 'package:altme/app/app.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:bloc/bloc.dart'; import 'package:decimal/decimal.dart'; @@ -23,21 +23,35 @@ class TokenAmountCalculatorCubit extends Cubit { Decimal validAmount = Decimal.parse('0'); String insertedAmount = ''; try { - if (amount.isEmpty || amount == '0' || amount == '00') { + emit(state.loading()); + if (amount.isEmpty) { + validAmount = Decimal.parse('0'); + insertedAmount = ''; + } else if (amount == '0' || amount == '00') { validAmount = Decimal.parse('0'); insertedAmount = '0'; - } else if (amount.isEmpty || amount == '.') { + } else if (amount == '.') { validAmount = Decimal.parse('0.'); insertedAmount = '0.'; } else { - insertedAmount = amount.replaceAll(',', ''); - final bool isValid = - isValidateAmount(amount: amount, selectedToken: selectedToken); + String trimmedAmount = amount; + + // Check if the amount starts with zero(s) but not a decimal number + if (RegExp(r'^0+(\d+)').hasMatch(amount)) { + trimmedAmount = amount.replaceAll(RegExp('^0+'), ''); + } + + insertedAmount = trimmedAmount.replaceAll(',', ''); + final bool isValid = isValidateAmount( + amount: trimmedAmount, + selectedToken: selectedToken, + ); validAmount = isValid - ? Decimal.parse(amount.replaceAll(',', '')) + ? Decimal.parse(trimmedAmount.replaceAll(',', '')) : Decimal.parse('0'); } } catch (e, s) { + emit(state.copyWith(status: AppStatus.idle)); getLogger(runtimeType.toString()) .e('error in calculate amount,e: $e, s: $s'); } @@ -56,10 +70,10 @@ class TokenAmountCalculatorCubit extends Cubit { required String? amount, required TokenModel selectedToken, }) { - if (amount == null) return false; + if (amount == null || amount.isEmpty) return true; + // true => to avoid error => No balance try { final insertedAmount = Decimal.parse(amount.replaceAll(',', '')); - if (insertedAmount <= Decimal.parse('0.0')) return false; final maxAmount = Decimal.parse(selectedToken.calculatedBalance); if (insertedAmount > maxAmount) { return false; diff --git a/lib/dashboard/home/tab_bar/tokens/insert_withdrawal_amount/cubit/token_amount_calculator_state.dart b/lib/dashboard/home/tab_bar/tokens/insert_withdrawal_amount/cubit/token_amount_calculator_state.dart index e51fcc083..0c799fbe5 100644 --- a/lib/dashboard/home/tab_bar/tokens/insert_withdrawal_amount/cubit/token_amount_calculator_state.dart +++ b/lib/dashboard/home/tab_bar/tokens/insert_withdrawal_amount/cubit/token_amount_calculator_state.dart @@ -5,6 +5,7 @@ class TokenAmountCalculatorState extends Equatable { const TokenAmountCalculatorState({ this.validAmount = '0', this.insertedAmount = '', + this.status = AppStatus.idle, }); factory TokenAmountCalculatorState.fromJson(Map json) => @@ -12,12 +13,19 @@ class TokenAmountCalculatorState extends Equatable { final String validAmount; final String insertedAmount; + final AppStatus status; + + TokenAmountCalculatorState loading() { + return copyWith(status: AppStatus.loading); + } TokenAmountCalculatorState copyWith({ + AppStatus status = AppStatus.idle, String? validAmount, String? insertedAmount, }) { return TokenAmountCalculatorState( + status: status, insertedAmount: insertedAmount ?? this.insertedAmount, validAmount: validAmount ?? this.validAmount, ); @@ -27,6 +35,7 @@ class TokenAmountCalculatorState extends Equatable { @override List get props => [ + status, validAmount, insertedAmount, ]; diff --git a/lib/dashboard/home/tab_bar/tokens/insert_withdrawal_amount/widgets/token_amount_calculator.dart b/lib/dashboard/home/tab_bar/tokens/insert_withdrawal_amount/widgets/token_amount_calculator.dart index ac1e5be8f..ae81078a0 100644 --- a/lib/dashboard/home/tab_bar/tokens/insert_withdrawal_amount/widgets/token_amount_calculator.dart +++ b/lib/dashboard/home/tab_bar/tokens/insert_withdrawal_amount/widgets/token_amount_calculator.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:altme/app/app.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/l10n/l10n.dart'; +import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -57,6 +58,12 @@ class _TokenAmountCalculatorPageState extends State { Future _onPaste(TextSelectionDelegate value) async { final ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain); final text = data?.text ?? ''; + + final isValidAmount = Decimal.tryParse(text); + if (isValidAmount == null) { + return; + } + if (text.isEmpty) { return; } else { diff --git a/lib/enterprise/cubit/enterprise_cubit.dart b/lib/enterprise/cubit/enterprise_cubit.dart index aed347b72..9519fc0bc 100644 --- a/lib/enterprise/cubit/enterprise_cubit.dart +++ b/lib/enterprise/cubit/enterprise_cubit.dart @@ -382,9 +382,7 @@ class EnterpriseCubit extends Cubit { // active } else { // revoked - throw ResponseMessage( - message: ResponseString.RESPONSE_STRING_theWalletIsSuspended, - ); + emit(state.copyWith(status: AppStatus.revoked)); } } } diff --git a/lib/enterprise/cubit/enterprise_state.dart b/lib/enterprise/cubit/enterprise_state.dart index 226dd6145..a26c0e97a 100644 --- a/lib/enterprise/cubit/enterprise_state.dart +++ b/lib/enterprise/cubit/enterprise_state.dart @@ -28,7 +28,7 @@ class EnterpriseState extends Equatable { } EnterpriseState copyWith({ - required StateMessage? message, + StateMessage? message, AppStatus? status, }) { return EnterpriseState( diff --git a/lib/enterprise/enterprise.dart b/lib/enterprise/enterprise.dart index b261f2b65..c38d7e4e6 100644 --- a/lib/enterprise/enterprise.dart +++ b/lib/enterprise/enterprise.dart @@ -1 +1,2 @@ export 'cubit/enterprise_cubit.dart'; +export 'widget/widget.dart'; diff --git a/lib/enterprise/widget/wallet_revoked_dialog.dart b/lib/enterprise/widget/wallet_revoked_dialog.dart new file mode 100644 index 000000000..f18a2123e --- /dev/null +++ b/lib/enterprise/widget/wallet_revoked_dialog.dart @@ -0,0 +1,63 @@ +import 'package:altme/app/app.dart'; +import 'package:altme/dashboard/dashboard.dart'; +import 'package:altme/l10n/l10n.dart'; + +import 'package:flutter/material.dart'; + +class WalletRevokedDialog extends StatelessWidget { + const WalletRevokedDialog({super.key}); + + @override + Widget build(BuildContext context) { + final background = Theme.of(context).colorScheme.onSurface; + final textColor = Theme.of(context).colorScheme.surface; + + final l10n = context.l10n; + return AlertDialog( + backgroundColor: background, + surfaceTintColor: Colors.transparent, + contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(25)), + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 25), + Text( + l10n.theWalletIsSuspended, + style: Theme.of(context) + .textTheme + .headlineMedium! + .copyWith(color: textColor), + textAlign: TextAlign.center, + ), + const SizedBox(height: 24), + MyElevatedButton( + text: l10n.deleteMyWallet, + verticalSpacing: 14, + borderRadius: Sizes.smallRadius, + elevation: 0, + onPressed: () async { + Navigator.of(context).pop(); + await resetWallet(context); + }, + ), + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text( + l10n.skip.toUpperCase(), + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith(color: textColor), + textAlign: TextAlign.center, + ), + ), + ], + ), + ); + } +} diff --git a/lib/enterprise/widget/widget.dart b/lib/enterprise/widget/widget.dart new file mode 100644 index 000000000..68d6caf39 --- /dev/null +++ b/lib/enterprise/widget/widget.dart @@ -0,0 +1 @@ +export 'wallet_revoked_dialog.dart'; diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index c86a28d76..75aad955c 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -783,10 +783,10 @@ "transactionDoneDialogDescription": "The transfer may take a few minutes to complete", "withdrawalFailedMessage": "The account withdrawal was unsuccessful", "credentialRequiredMessage": "You must have the required credentials in your wallet to acquire this card:", - "keyDecentralizedIdEdSA": "Key Decentralized ID EdDSA", - "keyDecentralizedIDSecp256k1": "Key Decentralized ID Secp256k1", + "keyDecentralizedIdEdSA": "did:key EdDSA", + "keyDecentralizedIDSecp256k1": "did:key Secp256k1", "polygonIdDecentralizedId": "Polygon Decentralized ID", - "ebsiV3DecentralizedId": "EBSI V3 Decentralized ID", + "ebsiV3DecentralizedId": "did:key EBSI V3 P-256", "requiredCredentialNotFoundTitle": "We are unable to find the credential\nyou need in your wallet.", "requiredCredentialNotFoundSubTitle": "The required credential is not in your wallet", "requiredCredentialNotFoundDescription": "Please contact us on :", @@ -811,7 +811,7 @@ "livenessCardWhyGetThisCard": "Obtain verifiable proof of humanity, requested by most DeFi, GameFi protocols and Web3 dApps. Once obtained, you can mint a privacy-preserving, non-transferable NFT for on-chain verification without revealing personal data.", "livenessCardLongDescription": "This credential is a verifiable proof of humanity. Use it to prove you are not a bot when requested by DeFi protocols, Onchain games or Web3 dApps.", "chat": "Chat", - "polygonDecentralizedID": "Polygon Decentralized ID", + "polygonDecentralizedID": "PolygonID", "needMnemonicVerificatinoDescription": "You need to verify your wallet seed phrases to protect your assets!", "succesfullyAuthenticated": "Successfully Authenticated.", "authenticationFailed": "Authentication Failed.", @@ -956,8 +956,8 @@ "moreDetails": "More Details", "theCredentialOfferIsInvalid": "The credential offer is invalid", "dateOfRequest": "Date of Request", - "keyDecentralizedIDP256": "Key Decentralized ID P-256", - "jwkDecentralizedIDP256": "JWK Decentralized ID P-256", + "keyDecentralizedIDP256": "did:key P-256", + "jwkDecentralizedIDP256": "JWK Thumbprint P-256", "defaultDid": "Default DID", "selectOneOfTheDid": "Select one of the DIDs", "cryptographicHolderBinding": "Cryptographic Holder Binding", @@ -1057,7 +1057,7 @@ "theWalletIsSuspended": "The wallet is suspended.", "clientTypeTitle": "Wallet Client_id Scheme", "confidentialClient": "Confidential Client", - "jwkThumbprintP256Key": "JWK Thumbprint P-256 Key", + "jwkThumbprintP256Key": "did:jwk P-256", "walletBlockedPopupTitle": "Blockerd 10 minutes", "walletBlockedPopupDescription": "Too many failed attempts, your wallet is blocked for your security.\nYou can reset your wallet in order to use servives again.", "deleteMyWalletForWrontPincodeTitle": "Account blocked after 3 unsuccessful attempts", diff --git a/lib/pin_code/view/delete_my_wallet_page.dart b/lib/pin_code/view/delete_my_wallet_page.dart index ad2e67d74..3caac32f2 100644 --- a/lib/pin_code/view/delete_my_wallet_page.dart +++ b/lib/pin_code/view/delete_my_wallet_page.dart @@ -1,7 +1,6 @@ -import 'package:altme/app/shared/constants/image_strings.dart'; import 'package:altme/app/shared/constants/sizes.dart'; import 'package:altme/app/shared/widget/widget.dart'; -import 'package:altme/dashboard/drawer/reset_wallet/helper_functions/reset_wallet.dart'; +import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/l10n/l10n.dart'; import 'package:flutter/material.dart'; @@ -34,32 +33,25 @@ class DeleteMyWalletView extends StatelessWidget { scrollView: false, body: Column( children: [ - const Spacer( - flex: 8, - ), - Image.asset( - ImageStrings.cardMissing, - width: Sizes.icon, - ), - const SizedBox( - height: Sizes.spaceLarge, + const Spacer(flex: 6), + WalletLogo( + height: 90, + width: MediaQuery.of(context).size.shortestSide * 0.5, + showPoweredBy: true, ), + const SizedBox(height: Sizes.spaceLarge), Text( l10n.deleteMyWalletForWrontPincodeTitle, textAlign: TextAlign.center, style: Theme.of(context).textTheme.displaySmall, ), - const SizedBox( - height: Sizes.spaceXSmall, - ), + const SizedBox(height: Sizes.spaceXSmall), Text( l10n.deleteMyWalletForWrontPincodeDescription, textAlign: TextAlign.center, style: Theme.of(context).textTheme.labelMedium, ), - const Spacer( - flex: 14, - ), + const Spacer(flex: 15), MyElevatedButton( text: l10n.deleteMyWallet, onPressed: () async { diff --git a/lib/splash/bloclisteners/blocklisteners.dart b/lib/splash/bloclisteners/blocklisteners.dart index c928bb0bb..fd1344a12 100644 --- a/lib/splash/bloclisteners/blocklisteners.dart +++ b/lib/splash/bloclisteners/blocklisteners.dart @@ -869,6 +869,13 @@ final enterpriseBlocListener = BlocListener( Navigator.of(context).pop(); } + if (state.status == AppStatus.revoked) { + showDialog( + context: context, + builder: (_) => const WalletRevokedDialog(), + ); + } + if (state.message != null) { AlertMessage.showStateMessage( context: context, diff --git a/lib/theme/theme_repository.dart b/lib/theme/theme_repository.dart index af24c2d14..5836f2961 100644 --- a/lib/theme/theme_repository.dart +++ b/lib/theme/theme_repository.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:altme/app/app.dart'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -48,7 +49,7 @@ class ThemeRepository implements ThemePersistence { _controller.add(ThemeMode.dark); } } else { - _controller.add(ThemeMode.dark); + _controller.add(Parameters.defaultTheme); } } diff --git a/lib/theme/theme_state.dart b/lib/theme/theme_state.dart index 7670309c2..a00c9b9a9 100644 --- a/lib/theme/theme_state.dart +++ b/lib/theme/theme_state.dart @@ -1,8 +1,9 @@ part of 'theme_cubit.dart'; class ThemeState extends Equatable { - const ThemeState( - {this.themeMode = ThemeMode.dark,}); // Default theme = light theme + const ThemeState({ + this.themeMode = ThemeMode.dark, + }); // Default theme = light theme final ThemeMode themeMode; diff --git a/lib/wallet/cubit/wallet_cubit.dart b/lib/wallet/cubit/wallet_cubit.dart index 9294a8ec6..1b43de962 100644 --- a/lib/wallet/cubit/wallet_cubit.dart +++ b/lib/wallet/cubit/wallet_cubit.dart @@ -445,6 +445,8 @@ class WalletCubit extends Cubit { required BlockchainType blockchainType, required CredentialsCubit credentialsCubit, }) async { + emit(state.copyWith(status: WalletStatus.loading)); + final CryptoAccountData cryptoAccountData = state.cryptoAccount.data[index]; cryptoAccountData.name = newAccountName; diff --git a/packages/oidc4vc/lib/src/vc_format_type.dart b/packages/oidc4vc/lib/src/vc_format_type.dart index 93540f3eb..210ea3fc3 100644 --- a/packages/oidc4vc/lib/src/vc_format_type.dart +++ b/packages/oidc4vc/lib/src/vc_format_type.dart @@ -11,6 +11,8 @@ enum VCFormatType { jwtVcJsonLd, @JsonValue('vc+sd-jwt') vcSdJWT, + @JsonValue('auto') + auto, } extension VCFormatTypeX on VCFormatType { @@ -26,6 +28,8 @@ extension VCFormatTypeX on VCFormatType { return 'jwt_vc_json-ld'; case VCFormatType.vcSdJWT: return 'vc+sd-jwt'; + case VCFormatType.auto: + return 'auto'; } } @@ -41,6 +45,8 @@ extension VCFormatTypeX on VCFormatType { return 'jwt_vc_json-ld'; case VCFormatType.vcSdJWT: return 'vcsd-jwt'; + case VCFormatType.auto: + return 'auto'; } } @@ -52,6 +58,7 @@ extension VCFormatTypeX on VCFormatType { case VCFormatType.jwtVc: case VCFormatType.jwtVcJsonLd: case VCFormatType.vcSdJWT: + case VCFormatType.auto: return false; } } @@ -68,6 +75,8 @@ extension VCFormatTypeX on VCFormatType { return 'jwt_vp_json-ld'; case VCFormatType.vcSdJWT: return 'vc+sd-jwt'; + case VCFormatType.auto: + return 'auto'; } } } diff --git a/test/app/shared/alert_message/alert_message_test.dart b/test/app/shared/alert_message/alert_message_test.dart index 78c176835..c8e7817b3 100644 --- a/test/app/shared/alert_message/alert_message_test.dart +++ b/test/app/shared/alert_message/alert_message_test.dart @@ -163,6 +163,7 @@ void main() { stateMessage: StateMessage( messageHandler: ResponseMessage( message: ResponseString + // ignore: lines_longer_than_80_chars .RESPONSE_STRING_AN_ERROR_OCCURRED_WHILE_CONNECTING_TO_THE_SERVER, ), injectedMessage: null, diff --git a/test/app/shared/date/date_test.dart b/test/app/shared/date/date_test.dart index cb447be14..aa8a86cbe 100644 --- a/test/app/shared/date/date_test.dart +++ b/test/app/shared/date/date_test.dart @@ -47,8 +47,8 @@ void main() { }); test( - 'formatDateForCredentialCard returns formatted date for credential card', - () { + 'formatDateForCredentialCard returns ' + 'formatted date for credential card', () { const timestamp = '1643738400'; expect(UiDate.formatDateForCredentialCard(timestamp), '2022-02-01'); }); diff --git a/test/app/view/app_test.dart b/test/app/view/app_test.dart index 4c392141c..03333c79c 100644 --- a/test/app/view/app_test.dart +++ b/test/app/view/app_test.dart @@ -23,10 +23,11 @@ void main() { ); expect( - App( - themeRepository: themeRepository, - ).flavorMode, - FlavorMode.production); + App( + themeRepository: themeRepository, + ).flavorMode, + FlavorMode.production, + ); }); // testWidgets('renders SplashPage', (tester) async { diff --git a/test/dashboard/drawer/src/view/drawer_page_test.dart b/test/dashboard/drawer/src/view/drawer_page_test.dart index 71011e59e..f6b5cecc8 100644 --- a/test/dashboard/drawer/src/view/drawer_page_test.dart +++ b/test/dashboard/drawer/src/view/drawer_page_test.dart @@ -206,7 +206,8 @@ void main() { expect(find.text('Self-Sovereign Identity (DID)'), findsOneWidget); expect( find.text( - 'Manage your Decentralized ID and backup or restore your credentials'), + 'Manage your Decentralized ID and backup or restore your credentials', + ), findsOneWidget, ); diff --git a/test/lang/cubit/lang_cubit_test.dart b/test/lang/cubit/lang_cubit_test.dart index 3ede1cf10..8959da91e 100644 --- a/test/lang/cubit/lang_cubit_test.dart +++ b/test/lang/cubit/lang_cubit_test.dart @@ -38,9 +38,9 @@ void main() { test('emits new state with recorded language locale', () async { when(() => mockSecureStorageProvider.get(SecureStorageKeys.language)) .thenAnswer((_) async => 'es'); - when(() => - mockSecureStorageProvider.set(SecureStorageKeys.language, any())) - .thenAnswer((_) async {}); + when( + () => mockSecureStorageProvider.set(SecureStorageKeys.language, any()), + ).thenAnswer((_) async {}); await langCubit.checkLocale(); expect( @@ -52,9 +52,9 @@ void main() { test('returns LanguageType.phone when no recorded language', () async { when(() => mockSecureStorageProvider.get(SecureStorageKeys.language)) .thenAnswer((_) async => null); - when(() => - mockSecureStorageProvider.set(SecureStorageKeys.language, any())) - .thenAnswer((_) async {}); + when( + () => mockSecureStorageProvider.set(SecureStorageKeys.language, any()), + ).thenAnswer((_) async {}); final languageType = await langCubit.getRecordedLanguage(); expect(languageType, LanguageType.phone); @@ -80,15 +80,15 @@ void main() { test('calls secureStorageProvider.set with correct key and value', () async { - when(() => - mockSecureStorageProvider.set(SecureStorageKeys.language, any())) - .thenAnswer((_) async {}); + when( + () => mockSecureStorageProvider.set(SecureStorageKeys.language, any()), + ).thenAnswer((_) async {}); await langCubit.recordLanguage('fr'); - verify(() => - mockSecureStorageProvider.set(SecureStorageKeys.language, 'fr')) - .called(1); + verify( + () => mockSecureStorageProvider.set(SecureStorageKeys.language, 'fr'), + ).called(1); }); }); }