From a1f74e898853756aa95d79c2f743117932280f47 Mon Sep 17 00:00:00 2001 From: Thiago Carvalho Date: Wed, 6 Sep 2023 10:12:41 -0300 Subject: [PATCH 01/26] disable multi-select when showing a modal --- .../login/views/login_page.dart | 13 +++++++------ lib/blocs/pin_file/pin_file_bloc.dart | 14 ++++++++++++-- lib/components/create_manifest_form.dart | 3 ++- lib/components/create_snapshot_dialog.dart | 3 ++- lib/components/csv_export_dialog.dart | 3 ++- lib/components/drive_attach_form.dart | 7 ++++--- lib/components/drive_create_form.dart | 3 ++- lib/components/drive_detach_dialog.dart | 3 ++- lib/components/drive_rename_form.dart | 3 ++- lib/components/drive_share_dialog.dart | 3 ++- lib/components/feedback_survey.dart | 4 ++-- lib/components/file_download_dialog.dart | 7 ++++--- lib/components/file_share_dialog.dart | 3 ++- lib/components/folder_create_form.dart | 5 +++-- lib/components/fs_entry_move_form.dart | 5 +++-- lib/components/fs_entry_rename_form.dart | 5 +++-- lib/components/ghost_fixer_form.dart | 3 ++- lib/components/new_button/new_button.dart | 4 +--- lib/components/pin_file_dialog.dart | 7 ++++--- lib/components/progress_dialog.dart | 3 ++- lib/components/side_bar.dart | 3 ++- lib/components/upload_form.dart | 3 ++- .../views/cookie_policy_consent_modal.dart | 3 ++- lib/core/activity_tracker.dart | 14 +++++++++++++- lib/dev_tools/app_dev_tools.dart | 5 +++-- .../multiple_file_download_modal.dart | 3 ++- lib/main.dart | 4 +++- lib/pages/congestion_warning_wrapper.dart | 3 ++- .../components/drive_detail_data_list.dart | 3 ++- .../components/drive_file_drop_zone.dart | 5 +++-- lib/pages/drive_detail/drive_detail_page.dart | 1 + lib/pages/shared_file/shared_file_page.dart | 3 ++- .../biometric_permission_dialog.dart | 3 ++- lib/turbo/topup/views/topup_modal.dart | 3 ++- lib/turbo/topup/views/topup_payment_form.dart | 3 ++- lib/turbo/topup/views/topup_review_view.dart | 5 +++-- .../download_wallet_modal.dart | 5 +++-- lib/utils/show_general_dialog.dart | 19 +++++++++++++++++++ pubspec.lock | 2 +- pubspec.yaml | 1 + 40 files changed, 133 insertions(+), 59 deletions(-) create mode 100644 lib/utils/show_general_dialog.dart diff --git a/lib/authentication/login/views/login_page.dart b/lib/authentication/login/views/login_page.dart index 803a52fcea..b514a90114 100644 --- a/lib/authentication/login/views/login_page.dart +++ b/lib/authentication/login/views/login_page.dart @@ -19,6 +19,7 @@ import 'package:ardrive/utils/app_platform.dart'; import 'package:ardrive/utils/io_utils.dart'; import 'package:ardrive/utils/open_url.dart'; import 'package:ardrive/utils/pre_cache_assets.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive/utils/split_localizations.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:arweave/arweave.dart'; @@ -209,7 +210,7 @@ class _LoginPageScaffoldState extends State { // TODO: Verify if the error is `NoConnectionException` and show an appropriate message after validating with UI/UX if (state.error is WalletMismatchException) { - showAnimatedDialog( + showArDriveDialog( context, content: ArDriveIconModal( title: appLocalizationsOf(context).loginFailed, @@ -229,7 +230,7 @@ class _LoginPageScaffoldState extends State { return; } - showAnimatedDialog( + showArDriveDialog( context, content: ArDriveIconModal( title: appLocalizationsOf(context).loginFailed, @@ -924,7 +925,7 @@ class _CreatePasswordViewState extends State { final isValid = _formKey.currentState!.validateSync(); if (!isValid) { - showAnimatedDialog(context, + showArDriveDialog(context, content: ArDriveIconModal( icon: ArDriveIcons.triangle( size: 88, @@ -945,7 +946,7 @@ class _CreatePasswordViewState extends State { } if (_passwordController.text != _confirmPasswordController.text) { - showAnimatedDialog(context, + showArDriveDialog(context, content: ArDriveIconModal( icon: ArDriveIcons.triangle( size: 88, @@ -1430,7 +1431,7 @@ class _EnterSeedPhraseViewState extends State { bip39.validateMnemonic(_seedPhraseController.text); if (!isValid) { - showAnimatedDialog(context, + showArDriveDialog(context, content: ArDriveIconModal( icon: ArDriveIcons.triangle( size: 88, @@ -2201,7 +2202,7 @@ class CreateNewWalletViewState extends State { color: colors.themeErrorMuted, ) .copyWith(fontSize: 14))) - ]), + ]), shape: RoundedRectangleBorder( side: BorderSide( color: colors.themeErrorMuted, width: 1), diff --git a/lib/blocs/pin_file/pin_file_bloc.dart b/lib/blocs/pin_file/pin_file_bloc.dart index 5d089485b2..46d78828a3 100644 --- a/lib/blocs/pin_file/pin_file_bloc.dart +++ b/lib/blocs/pin_file/pin_file_bloc.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:ardrive/blocs/blocs.dart'; import 'package:ardrive/core/arfs/entities/arfs_entities.dart'; +import 'package:ardrive/core/crypto/crypto.dart'; import 'package:ardrive/entities/file_entity.dart'; import 'package:ardrive/entities/string_types.dart'; import 'package:ardrive/misc/misc.dart'; @@ -298,11 +299,20 @@ class PinFileBloc extends Bloc { .folderById(driveId: _driveId, folderId: _parentFolderId) .getSingle(); + final profile = _profileCubit.state as ProfileLoggedIn; + + final key = await _driveDao.getDriveKey( + _driveId, + profile.cipherKey, + ); + final crypto = ArDriveCrypto(); + final fileKey = await crypto.deriveFileKey(key!, newFileEntity.id!); + if (_turboUploadService.useTurboUpload) { final fileDataItem = await _arweave.prepareEntityDataItem( newFileEntity, profileState.wallet, - // TODO: key + key: fileKey, ); await _turboUploadService.postDataItem( @@ -314,7 +324,7 @@ class PinFileBloc extends Bloc { final fileDataItem = await _arweave.prepareEntityTx( newFileEntity, profileState.wallet, - null, // TODO: key + fileKey, ); await _arweave.postTx(fileDataItem); diff --git a/lib/components/create_manifest_form.dart b/lib/components/create_manifest_form.dart index f529df18b2..b7a81d292a 100644 --- a/lib/components/create_manifest_form.dart +++ b/lib/components/create_manifest_form.dart @@ -18,13 +18,14 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import '../utils/show_general_dialog.dart'; import 'components.dart'; Future promptToCreateManifest( BuildContext context, { required Drive drive, }) { - return showAnimatedDialog( + return showArDriveDialog( context, content: BlocProvider( create: (context) => CreateManifestCubit( diff --git a/lib/components/create_snapshot_dialog.dart b/lib/components/create_snapshot_dialog.dart index 50f6d18d72..b0951bddce 100644 --- a/lib/components/create_snapshot_dialog.dart +++ b/lib/components/create_snapshot_dialog.dart @@ -10,6 +10,7 @@ import 'package:ardrive/utils/app_localizations_wrapper.dart'; import 'package:ardrive/utils/filesize.dart'; import 'package:ardrive/utils/html/html_util.dart'; import 'package:ardrive/utils/logger/logger.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive/utils/split_localizations.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; @@ -21,7 +22,7 @@ Future promptToCreateSnapshot( BuildContext context, Drive drive, ) async { - return showAnimatedDialog( + return showArDriveDialog( context, barrierDismissible: false, content: BlocProvider( diff --git a/lib/components/csv_export_dialog.dart b/lib/components/csv_export_dialog.dart index 5d21cfb6d7..b571f94b2a 100644 --- a/lib/components/csv_export_dialog.dart +++ b/lib/components/csv_export_dialog.dart @@ -6,6 +6,7 @@ import 'package:ardrive/models/models.dart'; import 'package:ardrive/services/services.dart'; import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_io/ardrive_io.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; @@ -15,7 +16,7 @@ Future promptToExportCSVData({ required BuildContext context, required String driveId, }) => - showAnimatedDialog( + showArDriveDialog( context, content: BlocProvider( create: (_) { diff --git a/lib/components/drive_attach_form.dart b/lib/components/drive_attach_form.dart index cc2a7d0db9..b4b6173c99 100644 --- a/lib/components/drive_attach_form.dart +++ b/lib/components/drive_attach_form.dart @@ -12,6 +12,7 @@ import 'package:cryptography/cryptography.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import '../utils/show_general_dialog.dart'; import 'components.dart'; Future attachDrive({ @@ -25,7 +26,7 @@ Future attachDrive({ profileState is ProfileLoggedIn ? profileState.cipherKey : null; return showModalDialog( context, - () => showAnimatedDialog( + () => showArDriveDialog( context, content: BlocProvider( create: (context) => DriveAttachCubit( @@ -87,7 +88,7 @@ class _DriveAttachFormState extends State { return BlocConsumer( listener: (context, state) { if (state is DriveAttachInvalidDriveKey) { - showAnimatedDialog( + showArDriveDialog( context, content: ArDriveStandardModal( title: appLocalizationsOf(context).error, @@ -95,7 +96,7 @@ class _DriveAttachFormState extends State { ), ); } else if (state is DriveAttachDriveNotFound) { - showAnimatedDialog( + showArDriveDialog( context, content: ArDriveStandardModal( title: appLocalizationsOf(context).error, diff --git a/lib/components/drive_create_form.dart b/lib/components/drive_create_form.dart index 0645db6002..29dcad9559 100644 --- a/lib/components/drive_create_form.dart +++ b/lib/components/drive_create_form.dart @@ -6,6 +6,7 @@ import 'package:ardrive/services/services.dart'; import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/turbo/services/upload_service.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive/utils/validate_folder_name.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; @@ -17,7 +18,7 @@ import 'components.dart'; Future promptToCreateDrive(BuildContext context) => showCongestionDependentModalDialog( context, - () => showAnimatedDialog( + () => showArDriveDialog( context, content: BlocProvider( create: (_) => DriveCreateCubit( diff --git a/lib/components/drive_detach_dialog.dart b/lib/components/drive_detach_dialog.dart index 3582a1ed7a..6de59f36c0 100644 --- a/lib/components/drive_detach_dialog.dart +++ b/lib/components/drive_detach_dialog.dart @@ -1,6 +1,7 @@ import 'package:ardrive/blocs/drives/drives_cubit.dart'; import 'package:ardrive/entities/string_types.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -10,7 +11,7 @@ Future showDetachDriveDialog({ required DriveID driveID, required String driveName, }) => - showAnimatedDialog( + showArDriveDialog( context, content: ArDriveStandardModal( title: appLocalizationsOf(context).detachDrive, diff --git a/lib/components/drive_rename_form.dart b/lib/components/drive_rename_form.dart index 9d9f7897e5..3fa9e865e2 100644 --- a/lib/components/drive_rename_form.dart +++ b/lib/components/drive_rename_form.dart @@ -6,6 +6,7 @@ import 'package:ardrive/services/services.dart'; import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/turbo/services/upload_service.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive/utils/validate_folder_name.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; @@ -20,7 +21,7 @@ Future promptToRenameDrive( }) => showCongestionDependentModalDialog( context, - () => showAnimatedDialog( + () => showArDriveDialog( context, content: MultiBlocProvider( providers: [ diff --git a/lib/components/drive_share_dialog.dart b/lib/components/drive_share_dialog.dart index 7d198abfb7..2ea093a187 100644 --- a/lib/components/drive_share_dialog.dart +++ b/lib/components/drive_share_dialog.dart @@ -4,6 +4,7 @@ import 'package:ardrive/components/details_panel.dart'; import 'package:ardrive/models/models.dart'; import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -12,7 +13,7 @@ Future promptToShareDrive({ required BuildContext context, required Drive drive, }) => - showAnimatedDialog( + showArDriveDialog( context, content: BlocProvider( create: (_) => DriveShareCubit( diff --git a/lib/components/feedback_survey.dart b/lib/components/feedback_survey.dart index 722d08f535..fc67c0da9b 100644 --- a/lib/components/feedback_survey.dart +++ b/lib/components/feedback_survey.dart @@ -3,12 +3,12 @@ import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; import 'package:ardrive/utils/open_url_utils.dart'; import 'package:ardrive/utils/screen_sizes.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -Future openFeedbackSurveyModal(BuildContext context) => - showAnimatedDialog( +Future openFeedbackSurveyModal(BuildContext context) => showArDriveDialog( context, content: const FeedbackSurveyModal(), ); diff --git a/lib/components/file_download_dialog.dart b/lib/components/file_download_dialog.dart index ac289c10a4..16c3b6d4f1 100644 --- a/lib/components/file_download_dialog.dart +++ b/lib/components/file_download_dialog.dart @@ -12,6 +12,7 @@ import 'package:ardrive/services/services.dart'; import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; import 'package:ardrive/utils/filesize.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_io/ardrive_io.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:cryptography/cryptography.dart'; @@ -41,7 +42,7 @@ Future promptToDownloadProfileFile({ driveDao: context.read(), arweave: arweave, )..download(cipherKey); - return showAnimatedDialog( + return showArDriveDialog( context, barrierDismissible: false, content: BlocProvider.value( @@ -76,7 +77,7 @@ Future promptToDownloadFileRevision({ arweave: arweave, )..download(cipherKey); - return showAnimatedDialog( + return showArDriveDialog( context, barrierDismissible: false, content: BlocProvider.value( @@ -97,7 +98,7 @@ Future promptToDownloadSharedFile({ fileKey: fileKey, arweave: context.read(), ); - return showAnimatedDialog( + return showArDriveDialog( context, barrierDismissible: false, content: BlocProvider.value( diff --git a/lib/components/file_share_dialog.dart b/lib/components/file_share_dialog.dart index 70be996c60..6c38d2d859 100644 --- a/lib/components/file_share_dialog.dart +++ b/lib/components/file_share_dialog.dart @@ -3,6 +3,7 @@ import 'package:ardrive/components/details_panel.dart'; import 'package:ardrive/models/models.dart'; import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -14,7 +15,7 @@ Future promptToShareFile({ required String driveId, required String fileId, }) => - showAnimatedDialog( + showArDriveDialog( context, content: BlocProvider( create: (_) => FileShareCubit( diff --git a/lib/components/folder_create_form.dart b/lib/components/folder_create_form.dart index aa81c5da52..39a64b3854 100644 --- a/lib/components/folder_create_form.dart +++ b/lib/components/folder_create_form.dart @@ -5,6 +5,7 @@ import 'package:ardrive/services/services.dart'; import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/turbo/services/upload_service.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive/utils/validate_folder_name.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; @@ -19,7 +20,7 @@ Future promptToCreateFolder( }) => showCongestionDependentModalDialog( context, - () => showAnimatedDialog( + () => showArDriveDialog( context, content: BlocProvider( create: (context) => FolderCreateCubit( @@ -40,7 +41,7 @@ Future promptToCreateFolderWithoutCongestionWarning( required String driveId, required String parentFolderId, }) => - showAnimatedDialog( + showArDriveDialog( context, content: BlocProvider( create: (context) => FolderCreateCubit( diff --git a/lib/components/fs_entry_move_form.dart b/lib/components/fs_entry_move_form.dart index 9b18009e52..138421480e 100644 --- a/lib/components/fs_entry_move_form.dart +++ b/lib/components/fs_entry_move_form.dart @@ -5,6 +5,7 @@ import 'package:ardrive/services/services.dart'; import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/turbo/services/upload_service.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -17,7 +18,7 @@ Future promptToMove( required String driveId, required List selectedItems, }) { - return showAnimatedDialog( + return showArDriveDialog( context, content: MultiBlocProvider( providers: [ @@ -284,7 +285,7 @@ class FsEntryMoveForm extends StatelessWidget { text: appLocalizationsOf(context) .createFolderEmphasized, onPressed: () { - showAnimatedDialog( + showArDriveDialog( context, content: BlocProvider( create: (context) => FolderCreateCubit( diff --git a/lib/components/fs_entry_rename_form.dart b/lib/components/fs_entry_rename_form.dart index ec1a74dbb9..8cc7217c8a 100644 --- a/lib/components/fs_entry_rename_form.dart +++ b/lib/components/fs_entry_rename_form.dart @@ -6,6 +6,7 @@ import 'package:ardrive/services/services.dart'; import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/turbo/services/upload_service.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive/utils/validate_folder_name.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; @@ -18,7 +19,7 @@ void promptToRenameModal( String? fileId, required String initialName, }) { - showAnimatedDialog( + showArDriveDialog( context, content: MultiBlocProvider( providers: [ @@ -95,7 +96,7 @@ class _FsEntryRenameFormState extends State { } else if (state is FsEntryRenameInitialized) { _nameController.text = widget.entryName; } else if (state is EntityAlreadyExists) { - showAnimatedDialog( + showArDriveDialog( context, content: ArDriveStandardModal( title: appLocalizationsOf(context).error, diff --git a/lib/components/ghost_fixer_form.dart b/lib/components/ghost_fixer_form.dart index bac6ffb364..482a9d107b 100644 --- a/lib/components/ghost_fixer_form.dart +++ b/lib/components/ghost_fixer_form.dart @@ -6,6 +6,7 @@ import 'package:ardrive/pages/pages.dart'; import 'package:ardrive/services/services.dart'; import 'package:ardrive/turbo/services/upload_service.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive/utils/validate_folder_name.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; @@ -17,7 +18,7 @@ import 'components.dart'; Future promptToReCreateFolder(BuildContext context, {required FolderDataTableItem ghostFolder}) { if (ghostFolder.parentFolderId != null) { - return showAnimatedDialog( + return showArDriveDialog( context, content: BlocProvider( create: (context) => GhostFixerCubit( diff --git a/lib/components/new_button/new_button.dart b/lib/components/new_button/new_button.dart index 9a572e3dd0..5325a60b4b 100644 --- a/lib/components/new_button/new_button.dart +++ b/lib/components/new_button/new_button.dart @@ -405,9 +405,7 @@ class NewButton extends StatelessWidget { name: appLocalizations.newFolder, icon: ArDriveIcons.iconNewFolder1(size: defaultIconSize), ), - if (context.read().config.enablePins && - drive != null && - drive?.privacy == 'public') + if (context.read().config.enablePins && drive != null) ArDriveNewButtonItem( name: appLocalizationsOf(context).newFilePin, icon: ArDriveIcons.pinWithCircle(size: defaultIconSize), diff --git a/lib/components/pin_file_dialog.dart b/lib/components/pin_file_dialog.dart index b193cbc43e..1265a94426 100644 --- a/lib/components/pin_file_dialog.dart +++ b/lib/components/pin_file_dialog.dart @@ -8,6 +8,7 @@ import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/turbo/services/upload_service.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; import 'package:ardrive/utils/logger/logger.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -29,7 +30,7 @@ Future showPinFileDialog({ return showModalDialog( context, - () => showAnimatedDialog( + () => showArDriveDialog( context, content: BlocProvider( create: (context) { @@ -68,7 +69,7 @@ class PinFileDialog extends StatelessWidget { if (state is PinFileAbort || state is PinFileSuccess) { Navigator.of(context).pop(); } else if (state is PinFileError) { - showAnimatedDialog( + showArDriveDialog( context, content: _errorDialog( context, @@ -78,7 +79,7 @@ class PinFileDialog extends StatelessWidget { ); } else if (state is PinFileFieldsValidationError) { if (state.networkError) { - showAnimatedDialog( + showArDriveDialog( context, content: _errorDialog( context, diff --git a/lib/components/progress_dialog.dart b/lib/components/progress_dialog.dart index 25b61bb2b3..e0cf571255 100644 --- a/lib/components/progress_dialog.dart +++ b/lib/components/progress_dialog.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; @@ -8,7 +9,7 @@ Future showProgressDialog( required String title, List? actions, }) => - showAnimatedDialog( + showArDriveDialog( context, barrierDismissible: false, content: ProgressDialog( diff --git a/lib/components/side_bar.dart b/lib/components/side_bar.dart index 58fb8d4c2e..797d8f53f6 100644 --- a/lib/components/side_bar.dart +++ b/lib/components/side_bar.dart @@ -10,6 +10,7 @@ import 'package:ardrive/utils/app_localizations_wrapper.dart'; import 'package:ardrive/utils/app_platform.dart'; import 'package:ardrive/utils/logger/logger.dart'; import 'package:ardrive/utils/open_url.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive/utils/size_constants.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/foundation.dart'; @@ -463,7 +464,7 @@ class _AppSideBarState extends State { return HoverWidget( child: GestureDetector( onTap: () { - showAnimatedDialog( + showArDriveDialog( context, content: ArDriveStandardModal( hasCloseButton: true, diff --git a/lib/components/upload_form.dart b/lib/components/upload_form.dart index 17ba6d9706..eeb9b1b43c 100644 --- a/lib/components/upload_form.dart +++ b/lib/components/upload_form.dart @@ -21,6 +21,7 @@ import 'package:ardrive/turbo/turbo.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; import 'package:ardrive/utils/filesize.dart'; import 'package:ardrive/utils/logger/logger.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive/utils/upload_plan_utils.dart'; import 'package:ardrive_io/ardrive_io.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; @@ -67,7 +68,7 @@ Future promptToUpload( // ignore: use_build_context_synchronously await showCongestionDependentModalDialog( context, - () => showAnimatedDialog( + () => showArDriveDialog( context, content: BlocProvider( create: (context) => UploadCubit( diff --git a/lib/cookie_policy_consent/views/cookie_policy_consent_modal.dart b/lib/cookie_policy_consent/views/cookie_policy_consent_modal.dart index ca90dc0be4..1753e44280 100644 --- a/lib/cookie_policy_consent/views/cookie_policy_consent_modal.dart +++ b/lib/cookie_policy_consent/views/cookie_policy_consent_modal.dart @@ -3,6 +3,7 @@ import 'package:ardrive/cookie_policy_consent/cookie_policy_consent.dart'; import 'package:ardrive/misc/resources.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; import 'package:ardrive/utils/open_url.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; @@ -17,7 +18,7 @@ Future showCookiePolicyConsentModal( ArDriveCookiePolicyConsent(), )..add(VerifyCookiePolicyConsent()); - return showAnimatedDialog( + return showArDriveDialog( context, barrierDismissible: false, content: BlocProvider( diff --git a/lib/core/activity_tracker.dart b/lib/core/activity_tracker.dart index 83049441c5..b68fbffd21 100644 --- a/lib/core/activity_tracker.dart +++ b/lib/core/activity_tracker.dart @@ -1,5 +1,8 @@ -class ActivityTracker { +import 'package:flutter/foundation.dart'; + +class ActivityTracker extends ChangeNotifier { bool _isToppingUp = false; + bool _isShowingAnyDialog = false; // getters bool get isToppingUp => _isToppingUp; @@ -8,7 +11,16 @@ class ActivityTracker { _isToppingUp = value; } + void setShowingAnyDialog(bool value) { + _isShowingAnyDialog = value; + notifyListeners(); + } + bool get isSyncAllowed { return !isToppingUp; } + + bool get isMultiSelectEnabled { + return !_isShowingAnyDialog; + } } diff --git a/lib/dev_tools/app_dev_tools.dart b/lib/dev_tools/app_dev_tools.dart index 4a6c7e7d62..b14fe8d8d8 100644 --- a/lib/dev_tools/app_dev_tools.dart +++ b/lib/dev_tools/app_dev_tools.dart @@ -513,6 +513,7 @@ class DraggableWindow extends HookWidget { windowPos.value += details.delta; }, child: ArDriveCard( + elevation: 5, contentPadding: EdgeInsets.zero, boxShadow: BoxShadowCard.shadow100, width: windowSize.value.width, @@ -522,7 +523,7 @@ class DraggableWindow extends HookWidget { Padding( padding: const EdgeInsets.only(top: 32.0), child: child), Container( - height: 32, + height: 64, color: ArDriveTheme.of(context).themeData.colors.themeFgDefault, child: Row( @@ -545,7 +546,7 @@ class DraggableWindow extends HookWidget { child: Text( value, key: ValueKey(value), - style: ArDriveTypography.body.bodyRegular( + style: ArDriveTypography.body.bodyBold( color: ArDriveTheme.of(context) .themeData .colors diff --git a/lib/download/multiple_file_download_modal.dart b/lib/download/multiple_file_download_modal.dart index 04e4af834f..f2fcdc51d5 100644 --- a/lib/download/multiple_file_download_modal.dart +++ b/lib/download/multiple_file_download_modal.dart @@ -7,6 +7,7 @@ import 'package:ardrive/download/multiple_download_bloc.dart'; import 'package:ardrive/pages/pages.dart'; import 'package:ardrive/services/arweave/arweave_service.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -21,7 +22,7 @@ promptToDownloadMultipleFiles( .map((item) => ARFSFactory().getARFSFileFromFileDataItemTable(item)) .toList(); - showAnimatedDialog( + showArDriveDialog( context, barrierDismissible: false, content: BlocProvider( diff --git a/lib/main.dart b/lib/main.dart index 94a6ef9f37..b218517b07 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -44,6 +44,7 @@ import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:local_auth/local_auth.dart'; +import 'package:provider/provider.dart'; import 'blocs/blocs.dart'; import 'firebase_options.dart'; @@ -180,7 +181,8 @@ class AppState extends State { Widget build(BuildContext context) { return MultiRepositoryProvider( providers: [ - RepositoryProvider(create: (_) => ActivityTracker()), + ChangeNotifierProvider( + create: (_) => ActivityTracker()), RepositoryProvider(create: (_) => _arweave), // repository provider for UploadFileChecker RepositoryProvider( diff --git a/lib/pages/congestion_warning_wrapper.dart b/lib/pages/congestion_warning_wrapper.dart index d3be98d0c3..691c3c73fd 100644 --- a/lib/pages/congestion_warning_wrapper.dart +++ b/lib/pages/congestion_warning_wrapper.dart @@ -3,6 +3,7 @@ import 'package:ardrive/pages/user_interaction_wrapper.dart'; import 'package:ardrive/services/services.dart'; import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -24,7 +25,7 @@ Future showCongestionDependentModalDialog( return await showModalDialog(context, () async { if (warnAboutCongestion) { bool shouldShowDialog = false; - await showAnimatedDialog( + await showArDriveDialog( context, content: ArDriveStandardModal( title: appLocalizationsOf(context).warningEmphasized, diff --git a/lib/pages/drive_detail/components/drive_detail_data_list.dart b/lib/pages/drive_detail/components/drive_detail_data_list.dart index eb23a1166c..0adffed7e2 100644 --- a/lib/pages/drive_detail/components/drive_detail_data_list.dart +++ b/lib/pages/drive_detail/components/drive_detail_data_list.dart @@ -149,7 +149,8 @@ Widget _buildDataListContent( return LayoutBuilder(builder: (context, constraints) { return ArDriveDataTable( key: ValueKey(folder.id), - lockMultiSelect: context.watch().state is SyncInProgress, + lockMultiSelect: context.watch().state is SyncInProgress || + !context.watch().isMultiSelectEnabled, rowsPerPageText: appLocalizationsOf(context).rowsPerPage, maxItemsPerPage: 100, pageItemsDivisorFactor: 25, diff --git a/lib/pages/drive_detail/components/drive_file_drop_zone.dart b/lib/pages/drive_detail/components/drive_file_drop_zone.dart index 5443341623..9778bd556e 100644 --- a/lib/pages/drive_detail/components/drive_file_drop_zone.dart +++ b/lib/pages/drive_detail/components/drive_file_drop_zone.dart @@ -15,6 +15,7 @@ import 'package:ardrive/turbo/services/payment_service.dart'; import 'package:ardrive/turbo/services/upload_service.dart'; import 'package:ardrive/turbo/turbo.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive/utils/upload_plan_utils.dart'; import 'package:ardrive_io/ardrive_io.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; @@ -66,7 +67,7 @@ class DriveFileDropZoneState extends State { ), onError: (e) async { if (e is DropzoneWrongInputException) { - await showAnimatedDialog( + await showArDriveDialog( context, content: ArDriveStandardModal( title: appLocalizationsOf(context).error, @@ -115,7 +116,7 @@ class DriveFileDropZoneState extends State { // ignore: use_build_context_synchronously await showCongestionDependentModalDialog( context, - () => showAnimatedDialog( + () => showArDriveDialog( context, content: BlocProvider( create: (context) => UploadCubit( diff --git a/lib/pages/drive_detail/drive_detail_page.dart b/lib/pages/drive_detail/drive_detail_page.dart index 878123842b..e0ef316aef 100644 --- a/lib/pages/drive_detail/drive_detail_page.dart +++ b/lib/pages/drive_detail/drive_detail_page.dart @@ -11,6 +11,7 @@ import 'package:ardrive/components/drive_detach_dialog.dart'; import 'package:ardrive/components/drive_rename_form.dart'; import 'package:ardrive/components/new_button/new_button.dart'; import 'package:ardrive/components/side_bar.dart'; +import 'package:ardrive/core/activity_tracker.dart'; import 'package:ardrive/download/multiple_file_download_modal.dart'; import 'package:ardrive/entities/entities.dart' as entities; import 'package:ardrive/l11n/l11n.dart'; diff --git a/lib/pages/shared_file/shared_file_page.dart b/lib/pages/shared_file/shared_file_page.dart index dccda08a40..dc9dbbdadb 100644 --- a/lib/pages/shared_file/shared_file_page.dart +++ b/lib/pages/shared_file/shared_file_page.dart @@ -7,6 +7,7 @@ import 'package:ardrive/theme/theme.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; import 'package:ardrive/utils/filesize.dart'; import 'package:ardrive/utils/open_url.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -31,7 +32,7 @@ class SharedFilePage extends StatelessWidget { }, listener: (context, state) { if (state is SharedFileKeyInvalid) { - showAnimatedDialog( + showArDriveDialog( context, content: ArDriveStandardModal( title: appLocalizationsOf(context).error, diff --git a/lib/services/authentication/biometric_permission_dialog.dart b/lib/services/authentication/biometric_permission_dialog.dart index f57506c793..4b72f64619 100644 --- a/lib/services/authentication/biometric_permission_dialog.dart +++ b/lib/services/authentication/biometric_permission_dialog.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:ardrive/services/authentication/biometric_authentication.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -107,7 +108,7 @@ Future showBiometricExceptionDialog( void Function()? action, void Function()? cancelAction, }) async { - return showAnimatedDialog( + return showArDriveDialog( context, content: ArDriveStandardModal( title: appLocalizationsOf(context).enableBiometricLogin, diff --git a/lib/turbo/topup/views/topup_modal.dart b/lib/turbo/topup/views/topup_modal.dart index 85ee309899..b468de3cf4 100644 --- a/lib/turbo/topup/views/topup_modal.dart +++ b/lib/turbo/topup/views/topup_modal.dart @@ -14,6 +14,7 @@ import 'package:ardrive/turbo/topup/views/topup_success_view.dart'; import 'package:ardrive/turbo/topup/views/turbo_error_view.dart'; import 'package:ardrive/turbo/turbo.dart'; import 'package:ardrive/utils/logger/logger.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -249,7 +250,7 @@ class _TurboModalState extends State with TickerProviderStateMixin { } void _showSuccessDialog() { - showAnimatedDialog( + showArDriveDialog( context, content: const ArDriveStandardModal( width: 575, diff --git a/lib/turbo/topup/views/topup_payment_form.dart b/lib/turbo/topup/views/topup_payment_form.dart index 97dcdd611e..24b8fa50cd 100644 --- a/lib/turbo/topup/views/topup_payment_form.dart +++ b/lib/turbo/topup/views/topup_payment_form.dart @@ -10,6 +10,7 @@ import 'package:ardrive/turbo/topup/views/turbo_error_view.dart'; import 'package:ardrive/turbo/utils/utils.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; import 'package:ardrive/utils/logger/logger.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive/utils/split_localizations.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; @@ -114,7 +115,7 @@ class TurboPaymentFormViewState extends State { return BlocListener( listener: (context, state) { if (state is PaymentFormError) { - showAnimatedDialog( + showArDriveDialog( context, barrierDismissible: false, content: ArDriveStandardModal( diff --git a/lib/turbo/topup/views/topup_review_view.dart b/lib/turbo/topup/views/topup_review_view.dart index f60d5b449a..332d75272b 100644 --- a/lib/turbo/topup/views/topup_review_view.dart +++ b/lib/turbo/topup/views/topup_review_view.dart @@ -8,6 +8,7 @@ import 'package:ardrive/turbo/topup/views/topup_payment_form.dart'; import 'package:ardrive/turbo/topup/views/turbo_error_view.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; import 'package:ardrive/utils/open_url.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive/utils/split_localizations.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/gestures.dart'; @@ -65,7 +66,7 @@ class _TurboReviewViewState extends State { .read() .add(const TurboTopUpShowSuccessView()); } else if (state is PaymentReviewPaymentError) { - showAnimatedDialog( + showArDriveDialog( context, content: ArDriveStandardModal( width: 575, @@ -92,7 +93,7 @@ class _TurboReviewViewState extends State { .withOpacity(0.9), ); } else if (state is PaymentReviewErrorLoadingPaymentModel) { - showAnimatedDialog( + showArDriveDialog( context, content: ArDriveStandardModal( width: 575, diff --git a/lib/user/download_wallet/download_wallet_modal.dart b/lib/user/download_wallet/download_wallet_modal.dart index d4e8d2b127..51a13f2281 100644 --- a/lib/user/download_wallet/download_wallet_modal.dart +++ b/lib/user/download_wallet/download_wallet_modal.dart @@ -4,12 +4,13 @@ import 'package:ardrive/user/download_wallet/bloc/download_wallet_bloc.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; import 'package:ardrive/utils/io_utils.dart'; import 'package:ardrive/utils/open_url.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; void showDownloadWalletModal(BuildContext context) { - showAnimatedDialog( + showArDriveDialog( context, content: BlocProvider( create: (_) => DownloadWalletBloc( @@ -33,7 +34,7 @@ class DownloadWalletModal extends StatelessWidget { if (state is DownloadWalletSuccess) { Navigator.of(context).pop(); } else if (state is DownloadWalletFailure) { - showAnimatedDialog( + showArDriveDialog( context, content: ArDriveStandardModal( title: appLocalizationsOf(context).error, diff --git a/lib/utils/show_general_dialog.dart b/lib/utils/show_general_dialog.dart new file mode 100644 index 0000000000..2385b93851 --- /dev/null +++ b/lib/utils/show_general_dialog.dart @@ -0,0 +1,19 @@ +import 'package:ardrive/core/activity_tracker.dart'; +import 'package:ardrive_ui/ardrive_ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +Future showArDriveDialog( + BuildContext context, { + bool barrierDismissible = true, + required Widget content, + Color? barrierColor, +}) async { + context.read().setShowingAnyDialog(true); + return showAnimatedDialog( + context, + content: content, + barrierColor: barrierColor, + barrierDismissible: barrierDismissible, + ).then((value) => context.read().setShowingAnyDialog(false)); +} diff --git a/pubspec.lock b/pubspec.lock index f7fb6f6580..86adc31c49 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1528,7 +1528,7 @@ packages: source: hosted version: "4.2.4" provider: - dependency: transitive + dependency: "direct main" description: name: provider sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f diff --git a/pubspec.yaml b/pubspec.yaml index 8b0113854f..c4339d1e2c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -119,6 +119,7 @@ dependencies: tuple: ^2.0.2 share_plus: ^6.3.4 flutter_email_sender: ^6.0.1 + provider: ^6.0.5 dependency_overrides: ardrive_io: From 2752e38534935c71cebb2dda96a3705a78fef1bd Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 26 Sep 2023 13:26:36 -0300 Subject: [PATCH 02/26] feat(app shell): makes it not to show the wallet switch dialog when not using arconnect PE-4477 --- lib/app_shell.dart | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/app_shell.dart b/lib/app_shell.dart index 813c167871..de17d4de1e 100644 --- a/lib/app_shell.dart +++ b/lib/app_shell.dart @@ -2,6 +2,7 @@ import 'package:ardrive/components/profile_card.dart'; import 'package:ardrive/components/side_bar.dart'; import 'package:ardrive/pages/drive_detail/components/hover_widget.dart'; import 'package:ardrive/utils/html/html_util.dart'; +import 'package:ardrive/utils/logger/logger.dart'; import 'package:ardrive/utils/size_constants.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; @@ -31,17 +32,27 @@ class AppShellState extends State { bool _showProfileOverlay = false; bool _showWalletSwitchDialog = true; @override - Widget build(BuildContext context) => BlocBuilder( + Widget build(BuildContext context) => BlocBuilder( builder: (context, state) { onArConnectWalletSwitch(() { - if (_showWalletSwitchDialog) { - showDialog( - context: context, - builder: (context) => const WalletSwitchDialog(), - ); - } - //Used to prevent the dialog being shown multiple times. - _showWalletSwitchDialog = false; + context + .read() + .isCurrentProfileArConnect() + .then((isCurrentProdileArConnect) { + if (_showWalletSwitchDialog) { + if (isCurrentProdileArConnect) { + showDialog( + context: context, + builder: (context) => const WalletSwitchDialog(), + ); + } else { + logger.d('Wallet switch detected while not logged in' + ' to ArConnect. Ignoring.'); + } + } + //Used to prevent the dialog being shown multiple times. + _showWalletSwitchDialog = false; + }); }); Widget buildPage(scaffold) => Material( From 27b35037e95cd31991f1dd82a6569a1fa5fa7286 Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 26 Sep 2023 13:29:21 -0300 Subject: [PATCH 03/26] chore(auth, login bloc, profile add cubit): removes unnecessary null type; formatting PE-4477 --- lib/authentication/ardrive_auth.dart | 2 +- .../login/blocs/login_bloc.dart | 44 ++++++++++++++----- lib/blocs/profile_add/profile_add_cubit.dart | 2 +- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/lib/authentication/ardrive_auth.dart b/lib/authentication/ardrive_auth.dart index f1fb6d1837..233853a35a 100644 --- a/lib/authentication/ardrive_auth.dart +++ b/lib/authentication/ardrive_auth.dart @@ -26,7 +26,7 @@ abstract class ArDriveAuth { Future unlockWithBiometrics({required String localizedReason}); Future unlockUser({required String password}); Future logout(); - User? get currentUser; + User get currentUser; Stream onAuthStateChanged(); Future isBiometricsEnabled(); diff --git a/lib/authentication/login/blocs/login_bloc.dart b/lib/authentication/login/blocs/login_bloc.dart index cdd2f90653..07f6ac7cd0 100644 --- a/lib/authentication/login/blocs/login_bloc.dart +++ b/lib/authentication/login/blocs/login_bloc.dart @@ -77,7 +77,9 @@ class LoginBloc extends Bloc { } Future _handleUnlockUserWithBiometricsEvent( - UnLockWithBiometrics event, Emitter emit) async { + UnLockWithBiometrics event, + Emitter emit, + ) async { final previousState = state; try { @@ -107,7 +109,9 @@ class LoginBloc extends Bloc { } Future _handleAddWalletFileEvent( - AddWalletFile event, Emitter emit) async { + AddWalletFile event, + Emitter emit, + ) async { final previousState = state; try { @@ -130,7 +134,9 @@ class LoginBloc extends Bloc { } Future _handleLoginWithPasswordEvent( - LoginWithPassword event, Emitter emit) async { + LoginWithPassword event, + Emitter emit, + ) async { final previousState = state; try { @@ -150,7 +156,9 @@ class LoginBloc extends Bloc { } Future _handleCheckIfUserIsLoggedInEvent( - CheckIfUserIsLoggedIn event, Emitter emit) async { + CheckIfUserIsLoggedIn event, + Emitter emit, + ) async { emit(LoginLoading()); if (await _arDriveAuth.isUserLoggedIn()) { @@ -172,7 +180,9 @@ class LoginBloc extends Bloc { } Future _handleUnlockUserWithPasswordEvent( - UnlockUserWithPassword event, Emitter emit) async { + UnlockUserWithPassword event, + Emitter emit, + ) async { final previousState = state; emit(LoginLoading()); @@ -192,7 +202,9 @@ class LoginBloc extends Bloc { } Future _handleCreatePasswordEvent( - CreatePassword event, Emitter emit) async { + CreatePassword event, + Emitter emit, + ) async { final previousState = state; emit(LoginLoading()); @@ -212,7 +224,9 @@ class LoginBloc extends Bloc { } Future _handleAddWalletFromArConnectEvent( - AddWalletFromArConnect event, Emitter emit) async { + AddWalletFromArConnect event, + Emitter emit, + ) async { final previousState = state; try { @@ -343,7 +357,9 @@ class LoginBloc extends Bloc { } Future _handleEnterSeedPhrase( - EnterSeedPhrase event, Emitter emit) async { + EnterSeedPhrase event, + Emitter emit, + ) async { emit(LoginEnterSeedPhrase()); } @@ -358,7 +374,9 @@ class LoginBloc extends Bloc { } Future _handleAddWalletFromCompleterEvent( - AddWalletFromCompleter event, Emitter emit) async { + AddWalletFromCompleter event, + Emitter emit, + ) async { profileType = ProfileType.json; Completer completer = event.walletCompleter; @@ -380,14 +398,18 @@ class LoginBloc extends Bloc { } Future _handleCreateNewWalletEvent( - CreateNewWallet event, Emitter emit) async { + CreateNewWallet event, + Emitter emit, + ) async { profileType = ProfileType.json; final mnemonic = bip39.generateMnemonic(); emit(LoginCreateNewWallet(mnemonic)); } Future _handleCompleteWalletGenerationEvent( - CompleteWalletGeneration event, Emitter emit) async { + CompleteWalletGeneration event, + Emitter emit, + ) async { final previousState = state; final wallet = event.wallet; diff --git a/lib/blocs/profile_add/profile_add_cubit.dart b/lib/blocs/profile_add/profile_add_cubit.dart index 5dc8b47cb1..eec59b71e3 100644 --- a/lib/blocs/profile_add/profile_add_cubit.dart +++ b/lib/blocs/profile_add/profile_add_cubit.dart @@ -52,7 +52,7 @@ class ProfileAddCubit extends Cubit { return arconnect.isExtensionPresent(); } - ProfileType? getProfileType() => _profileType; + ProfileType getProfileType() => _profileType; Future promptForWallet() async { if (_profileType == ProfileType.arConnect) { From 286f8ac81ae9af35b2adbf6e1b3f55ef5ca08ac2 Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 26 Sep 2023 13:31:27 -0300 Subject: [PATCH 04/26] feat(ardrive auth): makes it be aware of the profile being logged out before triggeering the wallet switch event PE-4477 --- lib/authentication/ardrive_auth.dart | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/authentication/ardrive_auth.dart b/lib/authentication/ardrive_auth.dart index 233853a35a..5e38328fd5 100644 --- a/lib/authentication/ardrive_auth.dart +++ b/lib/authentication/ardrive_auth.dart @@ -216,25 +216,15 @@ class ArDriveAuthImpl implements ArDriveAuth { try { if (_currentUser != null) { - if (currentUser.profileType == ProfileType.arConnect) { - try { - await _arConnectService.disconnect(); - } catch (e) { - logger.e('Failed to disconnect from ArConnect', e); - } - } - - _secureKeyValueStore.remove('password'); - _secureKeyValueStore.remove('biometricEnabled'); - + await _secureKeyValueStore.remove('password'); + await _secureKeyValueStore.remove('biometricEnabled'); currentUser = null; firstPrivateDriveTxId = null; - + await _disconnectFromArConnecct(); _userStreamController.add(null); } await _databaseHelpers.deleteAllTables(); - (await _metadataCache).clear(); } catch (e) { logger.e('Failed to logout user', e); @@ -242,6 +232,17 @@ class ArDriveAuthImpl implements ArDriveAuth { } } + Future _disconnectFromArConnecct() async { + final hasArConnectPermissions = await _arConnectService.checkPermissions(); + if (hasArConnectPermissions) { + try { + await _arConnectService.disconnect(); + } catch (e) { + logger.e('Failed to disconnect from ArConnect', e); + } + } + } + @override Future isBiometricsEnabled() { return _biometricAuthentication.isEnabled(); From 0b3d6d5c9a7dddca0b10701060d81a502de7277b Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 26 Sep 2023 13:32:18 -0300 Subject: [PATCH 05/26] feat(login bloc): removes unnecessary repeated code PE-4477 --- lib/authentication/login/blocs/login_bloc.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/authentication/login/blocs/login_bloc.dart b/lib/authentication/login/blocs/login_bloc.dart index 07f6ac7cd0..b10e30bfef 100644 --- a/lib/authentication/login/blocs/login_bloc.dart +++ b/lib/authentication/login/blocs/login_bloc.dart @@ -274,10 +274,6 @@ class LoginBloc extends Bloc { await _arDriveAuth.logout(); } - if (_isArConnectWallet()) { - await _arConnectService.disconnect(); - } - emit(LoginInitial(_arConnectService.isExtensionPresent())); } From 76fe12a778d7fe3b8ae1608edc83da19cc7ade7a Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 26 Sep 2023 13:34:45 -0300 Subject: [PATCH 06/26] feat(login): makes it not to notify the wallet mismatch when not using arconnect PE-4477 --- lib/authentication/login/blocs/login_bloc.dart | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/authentication/login/blocs/login_bloc.dart b/lib/authentication/login/blocs/login_bloc.dart index b10e30bfef..c2fc309c40 100644 --- a/lib/authentication/login/blocs/login_bloc.dart +++ b/lib/authentication/login/blocs/login_bloc.dart @@ -322,7 +322,13 @@ class LoginBloc extends Bloc { return; } - onArConnectWalletSwitch(() { + onArConnectWalletSwitch(() async { + final isUserLoggedIng = await _arDriveAuth.isUserLoggedIn(); + if (isUserLoggedIng && !_isArConnectWallet()) { + logger.d('Wallet switch detected. Is current profile ArConnect: false'); + return; + } + if (ignoreNextWaletSwitch) { ignoreNextWaletSwitch = false; return; From 43198539ebf401f940a93b2234e87d0da674abf2 Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 26 Sep 2023 13:35:14 -0300 Subject: [PATCH 07/26] feat(login): awaits for unawaited promise PE-4477 --- lib/authentication/login/blocs/login_bloc.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/authentication/login/blocs/login_bloc.dart b/lib/authentication/login/blocs/login_bloc.dart index c2fc309c40..1df9402f70 100644 --- a/lib/authentication/login/blocs/login_bloc.dart +++ b/lib/authentication/login/blocs/login_bloc.dart @@ -338,7 +338,7 @@ class LoginBloc extends Bloc { // ignore: invalid_use_of_visible_for_testing_member emit(const LoginFailure(WalletMismatchException())); - _arDriveAuth.logout(); + await _arDriveAuth.logout(); // ignore: invalid_use_of_visible_for_testing_member emit(const LoginInitial(true)); From d3381a01931d4085510c0374679f7cd1db07d419 Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 26 Sep 2023 13:50:06 -0300 Subject: [PATCH 08/26] feat(app shel): reverts unnecessary change PE-4477 --- lib/app_shell.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/app_shell.dart b/lib/app_shell.dart index de17d4de1e..96ebc893b9 100644 --- a/lib/app_shell.dart +++ b/lib/app_shell.dart @@ -32,8 +32,8 @@ class AppShellState extends State { bool _showProfileOverlay = false; bool _showWalletSwitchDialog = true; @override - Widget build(BuildContext context) => BlocBuilder( - builder: (context, state) { + Widget build(BuildContext context) => BlocBuilder( + builder: (context, _) { onArConnectWalletSwitch(() { context .read() From 75991d6152d6bc8099a493a025c0c0bf873225fa Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 26 Sep 2023 13:51:34 -0300 Subject: [PATCH 09/26] chore(app shell): variable typo PE-4477 --- lib/app_shell.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/app_shell.dart b/lib/app_shell.dart index 96ebc893b9..dc80c88e0e 100644 --- a/lib/app_shell.dart +++ b/lib/app_shell.dart @@ -38,9 +38,9 @@ class AppShellState extends State { context .read() .isCurrentProfileArConnect() - .then((isCurrentProdileArConnect) { + .then((isCurrentProfileArConnect) { if (_showWalletSwitchDialog) { - if (isCurrentProdileArConnect) { + if (isCurrentProfileArConnect) { showDialog( context: context, builder: (context) => const WalletSwitchDialog(), From 37dfde5b3b518d42e5bcc56b805a5938e09177e8 Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 26 Sep 2023 14:02:32 -0300 Subject: [PATCH 10/26] chore(user): removes unnecessary null check PE-4477 --- lib/blocs/upload/upload_cubit.dart | 10 +++++----- lib/components/upload_form.dart | 2 +- lib/core/upload/uploader.dart | 2 +- .../drive_detail/components/drive_file_drop_zone.dart | 2 +- lib/turbo/topup/views/topup_modal.dart | 4 ++-- .../download_wallet/bloc/download_wallet_bloc.dart | 2 +- lib/utils/user_utils.dart | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/blocs/upload/upload_cubit.dart b/lib/blocs/upload/upload_cubit.dart index eae65f7968..006d8d0817 100644 --- a/lib/blocs/upload/upload_cubit.dart +++ b/lib/blocs/upload/upload_cubit.dart @@ -321,7 +321,7 @@ class UploadCubit extends Cubit { try { final uploadPreparation = await _arDriveUploadManager.prepareUpload( params: UploadParams( - user: _auth.currentUser!, + user: _auth.currentUser, files: files, targetFolder: _targetFolder, targetDrive: _targetDrive, @@ -351,7 +351,7 @@ class UploadCubit extends Cubit { 'UploadPlan For AR: ${uploadPreparation.uploadPaymentInfo.arCostEstimate.toString()}\n' 'UploadPlan For Turbo: ${uploadPreparation.uploadPlansPreparation.uploadPlanForTurbo.toString()}\n' 'Turbo Balance: ${uploadPreparation.uploadPaymentInfo.turboBalance}\n' - 'AR Balance: ${_auth.currentUser!.walletBalance}\n' + 'AR Balance: ${_auth.currentUser.walletBalance}\n' 'Is Turbo Upload Possible: ${paymentInfo.isUploadEligibleToTurbo}\n' 'Is Zero Balance: $isTurboZeroBalance\n', ); @@ -396,7 +396,7 @@ class UploadCubit extends Cubit { costEstimateTurbo: paymentInfo.turboCostEstimate, credits: literalBalance, arBalance: - convertCreditsToLiteralString(_auth.currentUser!.walletBalance), + convertCreditsToLiteralString(_auth.currentUser.walletBalance), uploadIsPublic: _targetDrive.isPublic, sufficientArBalance: profile.walletBalance >= paymentInfo.arCostEstimate.totalCost, @@ -530,7 +530,7 @@ class UploadCubit extends Cubit { } ArDriveUploader _getUploader() { - final wallet = _auth.currentUser!.wallet; + final wallet = _auth.currentUser.wallet; final turboUploader = TurboUploader(_turbo, wallet); final arweaveUploader = ArweaveBundleUploader(_arweave.client); @@ -558,7 +558,7 @@ class UploadCubit extends Cubit { arweaveService: _arweave, turboUploadService: _turbo, pstService: _pst, - wallet: _auth.currentUser!.wallet, + wallet: _auth.currentUser.wallet, isArConnect: await _profileCubit.isCurrentProfileArConnect(), useTurbo: _uploadMethod == UploadMethod.turbo, ); diff --git a/lib/components/upload_form.dart b/lib/components/upload_form.dart index 52d8d7c215..3db59b232f 100644 --- a/lib/components/upload_form.dart +++ b/lib/components/upload_form.dart @@ -80,7 +80,7 @@ Future promptToUpload( ), turboUploadCostCalculator: TurboUploadCostCalculator( priceEstimator: TurboPriceEstimator( - wallet: context.read().currentUser!.wallet, + wallet: context.read().currentUser.wallet, costCalculator: TurboCostCalculator( paymentService: context.read(), ), diff --git a/lib/core/upload/uploader.dart b/lib/core/upload/uploader.dart index c319edf7a1..94cd53eae3 100644 --- a/lib/core/upload/uploader.dart +++ b/lib/core/upload/uploader.dart @@ -357,7 +357,7 @@ class UploadPaymentEvaluator { /// If we can't get the balance, turbo won't be available try { turboBalance = - await _turboBalanceRetriever.getBalance(_auth.currentUser!.wallet); + await _turboBalanceRetriever.getBalance(_auth.currentUser.wallet); logger.i('Turbo balance: $turboBalance'); } catch (e, stacktrace) { diff --git a/lib/pages/drive_detail/components/drive_file_drop_zone.dart b/lib/pages/drive_detail/components/drive_file_drop_zone.dart index 91ebd84650..b944676791 100644 --- a/lib/pages/drive_detail/components/drive_file_drop_zone.dart +++ b/lib/pages/drive_detail/components/drive_file_drop_zone.dart @@ -128,7 +128,7 @@ class DriveFileDropZoneState extends State { ), turboUploadCostCalculator: TurboUploadCostCalculator( priceEstimator: TurboPriceEstimator( - wallet: context.read().currentUser!.wallet, + wallet: context.read().currentUser.wallet, costCalculator: TurboCostCalculator( paymentService: context.read(), ), diff --git a/lib/turbo/topup/views/topup_modal.dart b/lib/turbo/topup/views/topup_modal.dart index f2434310eb..805b85a8f9 100644 --- a/lib/turbo/topup/views/topup_modal.dart +++ b/lib/turbo/topup/views/topup_modal.dart @@ -32,7 +32,7 @@ void showTurboModal(BuildContext context, {Function()? onSuccess}) { ); final priceEstimator = TurboPriceEstimator( - wallet: context.read().currentUser!.wallet, + wallet: context.read().currentUser.wallet, paymentService: context.read(), costCalculator: costCalculator, ); @@ -51,7 +51,7 @@ void showTurboModal(BuildContext context, {Function()? onSuccess}) { balanceRetriever: balanceRetriever, priceEstimator: priceEstimator, paymentProvider: turboPaymentProvider, - wallet: context.read().currentUser!.wallet, + wallet: context.read().currentUser.wallet, supportedCountriesRetriever: turboSupportedCountriesRetriever, ); diff --git a/lib/user/download_wallet/bloc/download_wallet_bloc.dart b/lib/user/download_wallet/bloc/download_wallet_bloc.dart index e53b178afe..2fe6953f02 100644 --- a/lib/user/download_wallet/bloc/download_wallet_bloc.dart +++ b/lib/user/download_wallet/bloc/download_wallet_bloc.dart @@ -28,7 +28,7 @@ class DownloadWalletBloc return; } try { - final wallet = _ardriveAuth.currentUser!.wallet; + final wallet = _ardriveAuth.currentUser.wallet; await _ardriveIOUtils.downloadWalletAsJsonFile( wallet: wallet, diff --git a/lib/utils/user_utils.dart b/lib/utils/user_utils.dart index fa2353dfaf..e070f51eb0 100644 --- a/lib/utils/user_utils.dart +++ b/lib/utils/user_utils.dart @@ -4,7 +4,7 @@ import 'package:ardrive/user/user.dart'; bool isDriveOwner(ArDriveAuth auth, String driveOwner) { User user; try { - user = auth.currentUser!; + user = auth.currentUser; } catch (e) { return false; } From 26f5c0a42de2002edf833054275e249f6a916a8e Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 26 Sep 2023 14:03:28 -0300 Subject: [PATCH 11/26] test(user utils): fixes unit test PE-4477 --- test/utils/user_utils.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/utils/user_utils.dart b/test/utils/user_utils.dart index 9fc96b60ba..cd0fd68a99 100644 --- a/test/utils/user_utils.dart +++ b/test/utils/user_utils.dart @@ -59,7 +59,7 @@ void main() { test('should return false when the current user is null', () { // arrange - when(() => auth.currentUser).thenReturn(null); + when(() => auth.currentUser).thenThrow(Exception()); // act final result = isDriveOwner(auth, 'other address'); From 543e2e4c308c735647aef617cb055e0db0edb9fd Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 26 Sep 2023 14:23:40 -0300 Subject: [PATCH 12/26] test(ardrive auth test): fixes unit test PE-4477 --- test/authentication/ardrive_auth_test.dart | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/authentication/ardrive_auth_test.dart b/test/authentication/ardrive_auth_test.dart index b99a7c9876..5a80824b04 100644 --- a/test/authentication/ardrive_auth_test.dart +++ b/test/authentication/ardrive_auth_test.dart @@ -55,6 +55,13 @@ void main() { id: 'some_id', rootFolderId: 'some_id', )); + + when(() => mockArConnectService.checkPermissions()).thenAnswer( + (invocation) => Future.value(true), + ); + when(() => mockArConnectService.disconnect()).thenAnswer( + (invocation) => Future.value(null), + ); }); // test `ArDriveAuth` @@ -643,7 +650,7 @@ void main() { when(() => mockArweaveService.getFirstPrivateDriveTxId(wallet, maxRetries: any(named: 'maxRetries'))) .thenAnswer((_) async => 'some_id'); - // mock cripto derive drive key + // mock crypto derive drive key when( () => mockArDriveCrypto.deriveDriveKey( wallet, From dd5d0e57d0ccb7bbdc392c249bcbc1cad99d8f87 Mon Sep 17 00:00:00 2001 From: Mati Date: Wed, 27 Sep 2023 15:38:07 -0300 Subject: [PATCH 13/26] feat(topup dialog): makes the dropdown overlay match the with of the field PE-4397 --- lib/turbo/topup/views/topup_payment_form.dart | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/turbo/topup/views/topup_payment_form.dart b/lib/turbo/topup/views/topup_payment_form.dart index 49e690b5c6..f86dc07940 100644 --- a/lib/turbo/topup/views/topup_payment_form.dart +++ b/lib/turbo/topup/views/topup_payment_form.dart @@ -1017,11 +1017,29 @@ class InputDropdownMenu extends StatefulWidget { class _InputDropdownMenuState extends State> { T? _selectedItem; + final GlobalKey _childKey = GlobalKey(); + double? _childWidth; + double get childWidth => _childWidth ?? 200; + + void _refreshChildWidth() { + final currentContext = _childKey.currentContext; + if (currentContext == null) { + return; + } + + final RenderBox renderBox = + _childKey.currentContext!.findRenderObject() as RenderBox; + + setState(() { + _childWidth = renderBox.size.width; + }); + } @override initState() { super.initState(); _selectedItem = widget.selectedItem; + WidgetsBinding.instance.addPostFrameCallback((_) => _refreshChildWidth()); } @override @@ -1031,13 +1049,12 @@ class _InputDropdownMenuState showScrollbars: true, onClick: widget.onClick, maxHeight: 275, - width: 200, anchor: widget.anchor, items: widget.items .map( (e) => ArDriveDropdownItem( content: Container( - width: 200, + width: _childWidth, alignment: Alignment.center, height: 44, color: widget.backgroundColor ?? @@ -1071,6 +1088,7 @@ class _InputDropdownMenuState ) .toList(), child: Column( + key: _childKey, mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, From bce579c7f47ed5f05bd46f51f199e0601b6613b8 Mon Sep 17 00:00:00 2001 From: Mati Date: Wed, 27 Sep 2023 15:41:37 -0300 Subject: [PATCH 14/26] chore(cleanup): removes unused arguments PE-4397 --- lib/pages/drive_detail/components/drive_explorer_item_tile.dart | 1 - lib/pages/drive_detail/drive_detail_page.dart | 2 -- 2 files changed, 3 deletions(-) diff --git a/lib/pages/drive_detail/components/drive_explorer_item_tile.dart b/lib/pages/drive_detail/components/drive_explorer_item_tile.dart index 3242497593..8bd3d40751 100644 --- a/lib/pages/drive_detail/components/drive_explorer_item_tile.dart +++ b/lib/pages/drive_detail/components/drive_explorer_item_tile.dart @@ -434,7 +434,6 @@ class EntityActionsMenu extends StatelessWidget { @override Widget build(BuildContext context) { return ArDriveDropdown( - width: item is DriveDataItem ? 240 : 160, height: isMobile(context) ? 44 : 60, anchor: alignment, items: _getItems(item, context, withInfo), diff --git a/lib/pages/drive_detail/drive_detail_page.dart b/lib/pages/drive_detail/drive_detail_page.dart index 6da5fa614d..3e77689bb2 100644 --- a/lib/pages/drive_detail/drive_detail_page.dart +++ b/lib/pages/drive_detail/drive_detail_page.dart @@ -268,7 +268,6 @@ class _DriveDetailPageState extends State { tooltip: appLocalizationsOf(context).showMenu, child: ArDriveDropdown( - width: 260, anchor: const Aligned( follower: Alignment.topRight, target: Alignment.bottomRight, @@ -774,7 +773,6 @@ class MobileFolderNavigation extends StatelessWidget { state.currentDrive.ownerAddress); return ArDriveDropdown( - width: 240, anchor: const Aligned( follower: Alignment.topRight, target: Alignment.bottomRight, From 731ef3bd31256b13e854878e6569c4ac021c839b Mon Sep 17 00:00:00 2001 From: Mati Date: Wed, 27 Sep 2023 15:42:38 -0300 Subject: [PATCH 15/26] feat(deps): update the ArDrive UI dep PE-4397 --- pubspec.lock | 6 +++--- pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index c9157fd185..15c1e7020f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -79,11 +79,11 @@ packages: dependency: "direct main" description: path: "." - ref: "v1.10.0" - resolved-ref: "72cd21de7cbd52067924cefac579cdb9d7ef39b7" + ref: PE-4397 + resolved-ref: "2d51239f7850b331daaf540464f6f94e902a5b4e" url: "https://github.com/ar-io/ardrive_ui.git" source: git - version: "1.10.0" + version: "1.11.0" args: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1c09bc37a7..f172dc6485 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -39,7 +39,7 @@ dependencies: ardrive_ui: git: url: https://github.com/ar-io/ardrive_ui.git - ref: v1.10.0 + ref: PE-4397 artemis: ^7.0.0-beta.13 arweave: git: From 9cfad0132f2b82250016a60bcef204e83c8177e6 Mon Sep 17 00:00:00 2001 From: Mati Date: Wed, 27 Sep 2023 16:00:33 -0300 Subject: [PATCH 16/26] feat(topup modal): moves the country dropdown just below the credit card field PE-4397 --- lib/turbo/topup/views/topup_payment_form.dart | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/turbo/topup/views/topup_payment_form.dart b/lib/turbo/topup/views/topup_payment_form.dart index f86dc07940..2cd9fb3878 100644 --- a/lib/turbo/topup/views/topup_payment_form.dart +++ b/lib/turbo/topup/views/topup_payment_form.dart @@ -429,13 +429,6 @@ class TurboPaymentFormViewState extends State { nameOnCardTextField(), ], ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - countryTextField(theme), - ], - ), - const SizedBox(height: 16), Padding( padding: const EdgeInsets.only(bottom: 4, right: 16), child: Align( @@ -492,6 +485,13 @@ class TurboPaymentFormViewState extends State { ), ), const SizedBox(height: 16), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + countryTextField(theme), + ], + ), + const SizedBox(height: 16), Row(children: [promoCodeLabel()]), ScreenTypeLayout.builder( mobile: (context) => Row(children: [ From 632deb1989406c00686eca0c3cff714947e62b2e Mon Sep 17 00:00:00 2001 From: Mati Date: Wed, 27 Sep 2023 18:22:19 -0300 Subject: [PATCH 17/26] feat(app version widget): factors it out into its own source file PE-4533 --- lib/components/app_version_widget.dart | 37 ++++++++++++++++++++++++++ lib/components/side_bar.dart | 31 +-------------------- 2 files changed, 38 insertions(+), 30 deletions(-) create mode 100644 lib/components/app_version_widget.dart diff --git a/lib/components/app_version_widget.dart b/lib/components/app_version_widget.dart new file mode 100644 index 0000000000..47b2ab4d7b --- /dev/null +++ b/lib/components/app_version_widget.dart @@ -0,0 +1,37 @@ +import 'package:ardrive/utils/app_localizations_wrapper.dart'; +import 'package:ardrive/utils/logger/logger.dart'; +import 'package:ardrive_ui/ardrive_ui.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:package_info_plus/package_info_plus.dart'; + +class AppVersionWidget extends StatelessWidget { + const AppVersionWidget({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return FutureBuilder( + future: PackageInfo.fromPlatform(), + builder: (BuildContext context, AsyncSnapshot snapshot) { + final info = snapshot.data; + if (info == null) { + logger.d('PackageInfo is null'); + return const SizedBox( + height: 32, + width: 32, + ); + } + final literalVersion = + kIsWeb ? info.version : '${info.version}+${info.buildNumber}'; + logger.d('Version: $literalVersion'); + return Text( + appLocalizationsOf(context).appVersion(literalVersion), + style: ArDriveTypography.body.buttonNormalRegular( + color: Colors.grey, + ), + textAlign: TextAlign.center, + ); + }, + ); + } +} diff --git a/lib/components/side_bar.dart b/lib/components/side_bar.dart index 58fb8d4c2e..ca0888f060 100644 --- a/lib/components/side_bar.dart +++ b/lib/components/side_bar.dart @@ -1,6 +1,7 @@ import 'package:ardrive/blocs/drive_detail/drive_detail_cubit.dart'; import 'package:ardrive/blocs/drives/drives_cubit.dart'; import 'package:ardrive/blocs/profile/profile_cubit.dart'; +import 'package:ardrive/components/app_version_widget.dart'; import 'package:ardrive/components/new_button/new_button.dart'; import 'package:ardrive/components/theme_switcher.dart'; import 'package:ardrive/misc/resources.dart'; @@ -15,7 +16,6 @@ import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:package_info_plus/package_info_plus.dart'; import 'package:responsive_builder/responsive_builder.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -718,32 +718,3 @@ class HelpButton extends StatelessWidget { ); } } - -class AppVersionWidget extends StatelessWidget { - const AppVersionWidget({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return FutureBuilder( - future: PackageInfo.fromPlatform(), - builder: (BuildContext context, AsyncSnapshot snapshot) { - final info = snapshot.data; - if (info == null) { - return const SizedBox( - height: 32, - width: 32, - ); - } - final literalVersion = - kIsWeb ? info.version : '${info.version}+${info.buildNumber}'; - return Text( - appLocalizationsOf(context).appVersion(literalVersion), - style: ArDriveTypography.body.buttonNormalRegular( - color: Colors.grey, - ), - textAlign: TextAlign.center, - ); - }, - ); - } -} From 30709149b5a612105079c21e3ae2f986d7ee28d8 Mon Sep 17 00:00:00 2001 From: Mati Date: Wed, 27 Sep 2023 18:24:57 -0300 Subject: [PATCH 18/26] feat(login page): adds the version on the bottom of the login page for both desktop and mobile views PE-4533 --- .../login/views/login_page.dart | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/lib/authentication/login/views/login_page.dart b/lib/authentication/login/views/login_page.dart index ae010ac371..a44ed0ee5f 100644 --- a/lib/authentication/login/views/login_page.dart +++ b/lib/authentication/login/views/login_page.dart @@ -8,6 +8,7 @@ import 'package:ardrive/authentication/login/blocs/login_bloc.dart'; import 'package:ardrive/authentication/login/blocs/stub_web_wallet.dart' // stub implementation if (dart.library.html) 'package:ardrive/authentication/login/blocs/web_wallet.dart'; import 'package:ardrive/blocs/profile/profile_cubit.dart'; +import 'package:ardrive/components/app_version_widget.dart'; import 'package:ardrive/misc/resources.dart'; import 'package:ardrive/pages/drive_detail/components/hover_widget.dart'; import 'package:ardrive/services/arconnect/arconnect.dart'; @@ -98,10 +99,20 @@ class _LoginPageScaffoldState extends State { child: Row( children: [ Expanded( - child: _buildIllustration( - context, - // verify theme light - Resources.images.login.gridImage), + child: Stack( + children: [ + _buildIllustration( + context, + // verify theme light + Resources.images.login.gridImage, + ), + const Positioned( + bottom: 16, + left: 16, + child: AppVersionWidget(), + ), + ], + ), ), Expanded( child: FractionallySizedBox( @@ -122,7 +133,24 @@ class _LoginPageScaffoldState extends State { horizontal: 16, vertical: 8, ), - child: Center(child: _buildContent(context)), + child: Stack( + children: [ + Center( + child: Column( + children: [ + _buildContent(context), + ], + ), + ), + Positioned( + bottom: 16, + child: SizedBox( + width: MediaQuery.of(context).size.width - 32, + child: const AppVersionWidget(), + ), + ), + ], + ), ), ), ), From 3ced38521bb5e9201f18fa3767fe5fe830511d98 Mon Sep 17 00:00:00 2001 From: Professional Date: Thu, 28 Sep 2023 09:26:44 -0300 Subject: [PATCH 19/26] feat(share file): allow to share file when the file is pending --- lib/blocs/file_share/file_share_cubit.dart | 4 +-- lib/blocs/file_share/file_share_state.dart | 3 +++ lib/components/file_share_dialog.dart | 30 ++++++++++++++++++++-- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/lib/blocs/file_share/file_share_cubit.dart b/lib/blocs/file_share/file_share_cubit.dart index 93fcac5bd0..02a1136ffe 100644 --- a/lib/blocs/file_share/file_share_cubit.dart +++ b/lib/blocs/file_share/file_share_cubit.dart @@ -45,9 +45,6 @@ class FileShareCubit extends Cubit { if (dataTxStatus == TransactionStatus.failed) { emit(FileShareLoadedFailedFile()); return; - } else if (dataTxStatus == TransactionStatus.pending) { - emit(FileShareLoadedPendingFile()); - return; } late Uri fileShareLink; @@ -87,6 +84,7 @@ class FileShareCubit extends Cubit { fileName: file.name, fileShareLink: fileShareLink, isPublicFile: drive.isPublic, + isPending: dataTxStatus == TransactionStatus.pending, ), ); } diff --git a/lib/blocs/file_share/file_share_state.dart b/lib/blocs/file_share/file_share_state.dart index 6bab74e769..5fb13bd996 100644 --- a/lib/blocs/file_share/file_share_state.dart +++ b/lib/blocs/file_share/file_share_state.dart @@ -25,10 +25,13 @@ class FileShareLoadSuccess extends FileShareState { /// Whether or not this file is public ie. not encrypted on the network. final bool isPublicFile; + final bool isPending; + const FileShareLoadSuccess({ required this.fileName, required this.fileShareLink, required this.isPublicFile, + required this.isPending, }); @override diff --git a/lib/components/file_share_dialog.dart b/lib/components/file_share_dialog.dart index 70be996c60..8b6883236b 100644 --- a/lib/components/file_share_dialog.dart +++ b/lib/components/file_share_dialog.dart @@ -58,9 +58,35 @@ class FileShareDialogState extends State { const Center(child: CircularProgressIndicator()) else if (state is FileShareLoadedFailedFile) Text(appLocalizationsOf(context).shareFailedFile) - else if (state is FileShareLoadedPendingFile) - Text(appLocalizationsOf(context).sharePendingFile) else if (state is FileShareLoadSuccess) ...{ + if (state.isPending) + Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: Row( + children: [ + ArDriveIcons.triangle( + color: ArDriveTheme.of(context) + .themeData + .colors + .themeWarningEmphasis, + ), + const SizedBox( + width: 8, + ), + Flexible( + child: Text( + 'Warning: This file is currently pending and may not be immediately accessible.', + style: ArDriveTypography.body.buttonNormalBold( + color: ArDriveTheme.of(context) + .themeData + .colors + .themeWarningEmphasis, + ), + ), + ), + ], + ), + ), Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ From 0d025a0d9eecde35ea464b00d2c377aa66aff374 Mon Sep 17 00:00:00 2001 From: Thiago Carvalho Date: Thu, 28 Sep 2023 10:00:12 -0300 Subject: [PATCH 20/26] feat(share file): fix lint warning --- .../components/biometric_toggle.dart | 1 + .../multiple_file_download_modal.dart | 1 + pubspec.lock | 46 ++++++++----------- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/lib/authentication/components/biometric_toggle.dart b/lib/authentication/components/biometric_toggle.dart index 21f4c2b691..7cfe56d238 100644 --- a/lib/authentication/components/biometric_toggle.dart +++ b/lib/authentication/components/biometric_toggle.dart @@ -91,6 +91,7 @@ class _BiometricToggleState extends State { } catch (e) { widget.onError?.call(); if (e is BiometricException) { + // ignore: use_build_context_synchronously showBiometricExceptionDialogForException( context, e, diff --git a/lib/download/multiple_file_download_modal.dart b/lib/download/multiple_file_download_modal.dart index 9f429310ea..f14c78e308 100644 --- a/lib/download/multiple_file_download_modal.dart +++ b/lib/download/multiple_file_download_modal.dart @@ -9,6 +9,7 @@ import 'package:ardrive/pages/pages.dart'; import 'package:ardrive/services/arweave/arweave_service.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; import 'package:ardrive/utils/filesize.dart'; +import 'package:ardrive/utils/show_general_dialog.dart'; import 'package:ardrive_io/ardrive_io.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/material.dart'; diff --git a/pubspec.lock b/pubspec.lock index 28bc53ad4e..1edbf211e3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -321,10 +321,10 @@ packages: dependency: "direct main" description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.17.1" connectivity_plus: dependency: "direct main" description: @@ -1123,10 +1123,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.18.0" io: dependency: transitive description: @@ -1283,18 +1283,18 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.15" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.2.0" meta: dependency: transitive description: @@ -1768,10 +1768,10 @@ packages: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.9.1" sqflite: dependency: transitive description: @@ -1930,26 +1930,26 @@ packages: dependency: "direct dev" description: name: test - sha256: "13b41f318e2a5751c3169137103b60c584297353d4b1761b66029bae6411fe46" + sha256: "3dac9aecf2c3991d09b9cdde4f98ded7b30804a88a0d7e4e7e1678e78d6b97f4" url: "https://pub.dev" source: hosted - version: "1.24.3" + version: "1.24.1" test_api: dependency: transitive description: name: test_api - sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "0.5.1" test_core: dependency: transitive description: name: test_core - sha256: "99806e9e6d95c7b059b7a0fc08f07fc53fabe54a829497f0d9676299f1e8637e" + sha256: "5138dbffb77b2289ecb12b81c11ba46036590b72a64a7a90d6ffb880f1a29e93" url: "https://pub.dev" source: hosted - version: "0.5.3" + version: "0.5.1" timeago: dependency: "direct main" description: @@ -2130,10 +2130,10 @@ packages: dependency: transitive description: name: vm_service - sha256: c620a6f783fa22436da68e42db7ebbf18b8c44b9a46ab911f666ff09ffd9153f + sha256: f6deed8ed625c52864792459709183da231ebf66ff0cf09e69b573227c377efe url: "https://pub.dev" source: hosted - version: "11.7.1" + version: "11.3.0" watcher: dependency: transitive description: @@ -2142,14 +2142,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" - web: - dependency: transitive - description: - name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 - url: "https://pub.dev" - source: hosted - version: "0.1.4-beta" web_socket_channel: dependency: transitive description: @@ -2207,5 +2199,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.0.0 <4.0.0" flutter: ">=3.10.0" From b48646f6611919dc984c9361ba67cd80ae67d8b8 Mon Sep 17 00:00:00 2001 From: Mati Date: Thu, 28 Sep 2023 11:47:18 -0300 Subject: [PATCH 21/26] chore(ardrive auth): corrects typo PE-4477 --- lib/authentication/ardrive_auth.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/authentication/ardrive_auth.dart b/lib/authentication/ardrive_auth.dart index 5e38328fd5..1a9b45cd13 100644 --- a/lib/authentication/ardrive_auth.dart +++ b/lib/authentication/ardrive_auth.dart @@ -220,7 +220,7 @@ class ArDriveAuthImpl implements ArDriveAuth { await _secureKeyValueStore.remove('biometricEnabled'); currentUser = null; firstPrivateDriveTxId = null; - await _disconnectFromArConnecct(); + await _disconnectFromArConnect(); _userStreamController.add(null); } @@ -232,7 +232,7 @@ class ArDriveAuthImpl implements ArDriveAuth { } } - Future _disconnectFromArConnecct() async { + Future _disconnectFromArConnect() async { final hasArConnectPermissions = await _arConnectService.checkPermissions(); if (hasArConnectPermissions) { try { From 791a44210a9255276d1cbf957f658f6bf79f2a95 Mon Sep 17 00:00:00 2001 From: Mati Date: Thu, 28 Sep 2023 11:57:25 -0300 Subject: [PATCH 22/26] feat(app version widget): makes the version component have the color based on the theme PE-4533 --- lib/authentication/login/views/login_page.dart | 16 +++++++++++++--- lib/components/app_version_widget.dart | 9 +++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/lib/authentication/login/views/login_page.dart b/lib/authentication/login/views/login_page.dart index a44ed0ee5f..0f7ee0a981 100644 --- a/lib/authentication/login/views/login_page.dart +++ b/lib/authentication/login/views/login_page.dart @@ -106,10 +106,15 @@ class _LoginPageScaffoldState extends State { // verify theme light Resources.images.login.gridImage, ), - const Positioned( + Positioned( bottom: 16, left: 16, - child: AppVersionWidget(), + child: AppVersionWidget( + color: ArDriveTheme.of(context) + .themeData + .colors + .themeFgDefault, + ), ), ], ), @@ -146,7 +151,12 @@ class _LoginPageScaffoldState extends State { bottom: 16, child: SizedBox( width: MediaQuery.of(context).size.width - 32, - child: const AppVersionWidget(), + child: AppVersionWidget( + color: ArDriveTheme.of(context) + .themeData + .colors + .themeFgDefault, + ), ), ), ], diff --git a/lib/components/app_version_widget.dart b/lib/components/app_version_widget.dart index 47b2ab4d7b..f905a66c21 100644 --- a/lib/components/app_version_widget.dart +++ b/lib/components/app_version_widget.dart @@ -6,7 +6,12 @@ import 'package:flutter/material.dart'; import 'package:package_info_plus/package_info_plus.dart'; class AppVersionWidget extends StatelessWidget { - const AppVersionWidget({Key? key}) : super(key: key); + final Color color; + + const AppVersionWidget({ + Key? key, + this.color = Colors.grey, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -27,7 +32,7 @@ class AppVersionWidget extends StatelessWidget { return Text( appLocalizationsOf(context).appVersion(literalVersion), style: ArDriveTypography.body.buttonNormalRegular( - color: Colors.grey, + color: color, ), textAlign: TextAlign.center, ); From d2f279cd87b85986a5f75da262579d4326401557 Mon Sep 17 00:00:00 2001 From: Mati Date: Thu, 28 Sep 2023 13:15:08 -0300 Subject: [PATCH 23/26] chore(app version widget): removes unnecessary log statements PE-4533 --- lib/components/app_version_widget.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/components/app_version_widget.dart b/lib/components/app_version_widget.dart index f905a66c21..24a1611a36 100644 --- a/lib/components/app_version_widget.dart +++ b/lib/components/app_version_widget.dart @@ -1,5 +1,4 @@ import 'package:ardrive/utils/app_localizations_wrapper.dart'; -import 'package:ardrive/utils/logger/logger.dart'; import 'package:ardrive_ui/ardrive_ui.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -20,7 +19,6 @@ class AppVersionWidget extends StatelessWidget { builder: (BuildContext context, AsyncSnapshot snapshot) { final info = snapshot.data; if (info == null) { - logger.d('PackageInfo is null'); return const SizedBox( height: 32, width: 32, @@ -28,7 +26,6 @@ class AppVersionWidget extends StatelessWidget { } final literalVersion = kIsWeb ? info.version : '${info.version}+${info.buildNumber}'; - logger.d('Version: $literalVersion'); return Text( appLocalizationsOf(context).appVersion(literalVersion), style: ArDriveTypography.body.buttonNormalRegular( From 80347232ee6079ae28ca297a546feccee92f70c2 Mon Sep 17 00:00:00 2001 From: Mati Date: Thu, 28 Sep 2023 17:16:29 -0300 Subject: [PATCH 24/26] feat(pubspec): bumps version of ardrive-io PE-4397 --- pubspec.lock | 4 ++-- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 15c1e7020f..399c8eb5b1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -79,8 +79,8 @@ packages: dependency: "direct main" description: path: "." - ref: PE-4397 - resolved-ref: "2d51239f7850b331daaf540464f6f94e902a5b4e" + ref: "v1.11.0" + resolved-ref: "357ce9113b6c90eb00d3ae4528112a8228d9d11f" url: "https://github.com/ar-io/ardrive_ui.git" source: git version: "1.11.0" diff --git a/pubspec.yaml b/pubspec.yaml index f172dc6485..8d6fba7ebd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -39,7 +39,7 @@ dependencies: ardrive_ui: git: url: https://github.com/ar-io/ardrive_ui.git - ref: PE-4397 + ref: v1.11.0 artemis: ^7.0.0-beta.13 arweave: git: From ae143b7e17cd2a4893843446bcad48583817256a Mon Sep 17 00:00:00 2001 From: Thiago Carvalho Date: Thu, 28 Sep 2023 17:17:15 -0300 Subject: [PATCH 25/26] bump version --- android/fastlane/metadata/android/en-US/changelogs/65.txt | 5 +++++ pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 android/fastlane/metadata/android/en-US/changelogs/65.txt diff --git a/android/fastlane/metadata/android/en-US/changelogs/65.txt b/android/fastlane/metadata/android/en-US/changelogs/65.txt new file mode 100644 index 0000000000..becfd3b8ae --- /dev/null +++ b/android/fastlane/metadata/android/en-US/changelogs/65.txt @@ -0,0 +1,5 @@ +- Add app version number on login page +- Disables multi-select option when a modal is open +- Pending files now can be shared +- Improvements on country dropdown of Turbo payment form +- Fixed issue where switching ArConnect wallets redirected users to initial unlock screen. \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index b3e977405e..c5ec896f0b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: Secure, permanent storage publish_to: 'none' -version: 2.16.0 +version: 2.17.0 environment: sdk: '>=2.18.5 <3.0.0' From 9248e9ef4471ace9fd03da80cb12110ef9302d54 Mon Sep 17 00:00:00 2001 From: Thiago Carvalho Date: Thu, 28 Sep 2023 17:22:21 -0300 Subject: [PATCH 26/26] improve release notes --- android/fastlane/metadata/android/en-US/changelogs/65.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/fastlane/metadata/android/en-US/changelogs/65.txt b/android/fastlane/metadata/android/en-US/changelogs/65.txt index becfd3b8ae..3aa682b840 100644 --- a/android/fastlane/metadata/android/en-US/changelogs/65.txt +++ b/android/fastlane/metadata/android/en-US/changelogs/65.txt @@ -1,5 +1,5 @@ - Add app version number on login page - Disables multi-select option when a modal is open - Pending files now can be shared -- Improvements on country dropdown of Turbo payment form +- Layout improvements to the country dropdown on the Turbo payment form - Fixed issue where switching ArConnect wallets redirected users to initial unlock screen. \ No newline at end of file