TF-4053 Implement move folder content on mailbox list view

This commit is contained in:
dab246
2025-10-29 14:56:07 +07:00
committed by Dat H. Pham
parent ac99fccfb0
commit 58c05c38b2
19 changed files with 313 additions and 28 deletions
@@ -53,6 +53,10 @@ import 'package:tmail_ui_user/main/routes/route_navigation.dart';
typedef RenameMailboxActionCallback = void Function(PresentationMailbox mailbox, MailboxName newMailboxName); typedef RenameMailboxActionCallback = void Function(PresentationMailbox mailbox, MailboxName newMailboxName);
typedef MovingMailboxActionCallback = void Function(PresentationMailbox mailboxSelected, PresentationMailbox? destinationMailbox); typedef MovingMailboxActionCallback = void Function(PresentationMailbox mailboxSelected, PresentationMailbox? destinationMailbox);
typedef OnMoveFolderContentActionCallback = void Function(
PresentationMailbox currentMailbox,
PresentationMailbox destinationMailbox,
);
typedef DeleteMailboxActionCallback = void Function(PresentationMailbox mailbox); typedef DeleteMailboxActionCallback = void Function(PresentationMailbox mailbox);
typedef AllowSubaddressingActionCallback = void Function(MailboxId, Map<String, List<String>?>?, MailboxActions); typedef AllowSubaddressingActionCallback = void Function(MailboxId, Map<String, List<String>?>?, MailboxActions);
@@ -637,4 +641,33 @@ abstract class BaseMailboxController extends BaseController
triggerScrollWhenExpandFolder(newExpandMode, itemKey, scrollController); triggerScrollWhenExpandFolder(newExpandMode, itemKey, scrollController);
} }
} }
void moveFolderContentAction({
required BuildContext context,
required AccountId accountId,
required Session session,
required PresentationMailbox mailboxSelected,
required OnMoveFolderContentActionCallback onMoveFolderContentAction,
}) async {
final arguments = DestinationPickerArguments(
accountId,
MailboxActions.moveFolderContent,
session,
mailboxIdSelected: mailboxSelected.id,
);
final destinationMailbox = PlatformInfo.isWeb
? await DialogRouter.pushGeneralDialog(
routeName: AppRoutes.destinationPicker,
arguments: arguments,
)
: await push(AppRoutes.destinationPicker, arguments: arguments);
if (destinationMailbox is PresentationMailbox) {
log('$runtimeType::moveFolderContentAction: DestinationMailbox is ${destinationMailbox.name?.name}');
onMoveFolderContentAction(
mailboxSelected,
destinationMailbox,
);
}
}
} }
@@ -103,7 +103,9 @@ class DestinationPickerController extends BaseMailboxController {
void handleSuccessViewState(Success success) async { void handleSuccessViewState(Success success) async {
super.handleSuccessViewState(success); super.handleSuccessViewState(success);
if (success is GetAllMailboxSuccess) { if (success is GetAllMailboxSuccess) {
if (mailboxAction.value == MailboxActions.move && mailboxIdSelected != null) { if ((mailboxAction.value == MailboxActions.move ||
mailboxAction.value == MailboxActions.moveFolderContent) &&
mailboxIdSelected != null) {
await buildTree( await buildTree(
success.mailboxList.listSubscribedMailboxesAndDefaultMailboxes, success.mailboxList.listSubscribedMailboxesAndDefaultMailboxes,
mailboxIdSelected: mailboxIdSelected); mailboxIdSelected: mailboxIdSelected);
@@ -249,9 +251,11 @@ class DestinationPickerController extends BaseMailboxController {
void searchMailbox(BuildContext context, String value) { void searchMailbox(BuildContext context, String value) {
searchQuery.value = SearchQuery(value); searchQuery.value = SearchQuery(value);
final searchableMailboxList = mailboxAction.value == MailboxActions.moveEmail final searchableMailboxList =
? allMailboxes mailboxAction.value == MailboxActions.moveEmail ||
: allMailboxes.listPersonalMailboxes; mailboxAction.value == MailboxActions.moveFolderContent
? allMailboxes
: allMailboxes.listPersonalMailboxes;
final mailboxListWithDisplayName = searchableMailboxList final mailboxListWithDisplayName = searchableMailboxList
.map((mailbox) => mailbox.withDisplayName(mailbox.getDisplayName(context))) .map((mailbox) => mailbox.withDisplayName(mailbox.getDisplayName(context)))
@@ -296,8 +296,10 @@ class DestinationPickerView extends GetWidget<DestinationPickerController>
} }
}), }),
Obx(() { Obx(() {
if (controller.teamMailboxesIsNotEmpty if (controller.teamMailboxesIsNotEmpty &&
&& controller.mailboxAction.value == MailboxActions.moveEmail) { (controller.mailboxAction.value == MailboxActions.moveEmail ||
controller.mailboxAction.value ==
MailboxActions.moveFolderContent)) {
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@@ -158,6 +158,7 @@ class DestinationPickerSearchMailboxItemBuilder extends StatelessWidget {
( (
mailboxActions == MailboxActions.select || mailboxActions == MailboxActions.select ||
mailboxActions == MailboxActions.create || mailboxActions == MailboxActions.create ||
mailboxActions == MailboxActions.moveEmail mailboxActions == MailboxActions.moveEmail ||
mailboxActions == MailboxActions.moveFolderContent
); );
} }
@@ -8,14 +8,13 @@ import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/move_folder_content_request.dart'; import 'package:tmail_ui_user/features/mailbox/domain/model/move_folder_content_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart'; import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/move_folder_content_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/move_folder_content_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/move_mailbox_state.dart';
class MoveFolderContentInteractor { class MoveFolderContentInteractor {
final MailboxRepository _mailboxRepository; final MailboxRepository _mailboxRepository;
MoveFolderContentInteractor(this._mailboxRepository); MoveFolderContentInteractor(this._mailboxRepository);
Stream<void> execute({ Stream<Either<Failure, Success>> execute({
required Session session, required Session session,
required AccountId accountId, required AccountId accountId,
required MoveFolderContentRequest request, required MoveFolderContentRequest request,
@@ -23,6 +22,7 @@ class MoveFolderContentInteractor {
}) async* { }) async* {
try { try {
yield Right<Failure, Success>(MovingFolderContent()); yield Right<Failure, Success>(MovingFolderContent());
onProgressController?.add(Right(MovingFolderContent()));
await _mailboxRepository.moveFolderContent( await _mailboxRepository.moveFolderContent(
session: session, session: session,
accountId: accountId, accountId: accountId,
@@ -31,7 +31,7 @@ class MoveFolderContentInteractor {
); );
yield Right<Failure, Success>(MoveFolderContentSuccess(request)); yield Right<Failure, Success>(MoveFolderContentSuccess(request));
} catch (e) { } catch (e) {
yield Left<Failure, Success>(MoveMailboxFailure(e)); yield Left<Failure, Success>(MoveFolderContentFailure(e));
} }
} }
} }
@@ -0,0 +1,108 @@
import 'package:core/presentation/state/success.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter/cupertino.dart';
import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_action.dart';
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/move_folder_content_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/move_folder_content_state.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.dart';
extension HandleMoveFolderContentExtension on MailboxController {
void performMoveFolderContent({
required BuildContext context,
required PresentationMailbox mailboxSelected,
}) {
final accountId = mailboxDashBoardController.accountId.value;
final session = mailboxDashBoardController.sessionCurrent;
if (accountId == null || session == null) {
consumeState(
Stream.value(
Left(MoveFolderContentFailure(NotFoundAccountIdException())),
),
);
return;
}
moveFolderContentAction(
context: context,
accountId: accountId,
session: session,
mailboxSelected: mailboxSelected,
onMoveFolderContentAction: (currentMailbox, destinationMailbox) {
consumeState(mailboxActionReactor.moveFolderContent(
session: session,
accountId: accountId,
moveRequest: MoveFolderContentRequest(
moveAction: MoveAction.moving,
mailboxId: currentMailbox.id,
destinationMailboxId: destinationMailbox.id,
destinationMailboxDisplayName:
destinationMailbox.getDisplayName(context),
markAsRead: destinationMailbox.isSpam,
totalEmails: currentMailbox.countTotalEmails,
),
onProgressController:
mailboxDashBoardController.progressStateController,
));
},
);
}
void handleMoveFolderContentSuccess(MoveFolderContentSuccess success) {
mailboxDashBoardController.syncViewStateMailboxActionProgress(
newState: Right(UIState.idle),
);
final moveFolderRequest = success.request;
if (moveFolderRequest.moveAction == MoveAction.moving) {
toastManager.showMessageSuccessWithAction(
success: success,
onActionCallback: () {
_undoMoveFolderContentAction(
newMoveRequest: MoveFolderContentRequest(
moveAction: MoveAction.undo,
mailboxId: moveFolderRequest.destinationMailboxId,
destinationMailboxId: moveFolderRequest.mailboxId,
destinationMailboxDisplayName: '',
totalEmails: moveFolderRequest.totalEmails,
),
);
},
);
}
}
void _undoMoveFolderContentAction({
required MoveFolderContentRequest newMoveRequest,
}) {
final accountId = mailboxDashBoardController.accountId.value;
final session = mailboxDashBoardController.sessionCurrent;
if (accountId == null || session == null) {
consumeState(
Stream.value(
Left(MoveFolderContentFailure(NotFoundAccountIdException())),
),
);
return;
}
consumeState(mailboxActionReactor.moveFolderContent(
session: session,
accountId: accountId,
moveRequest: newMoveRequest,
onProgressController: mailboxDashBoardController.progressStateController,
));
}
void handleMoveFolderContentFailure(MoveFolderContentFailure failure) {
mailboxDashBoardController.syncViewStateMailboxActionProgress(
newState: Right(UIState.idle),
);
toastManager.showMessageFailure(failure);
}
}
@@ -20,6 +20,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_defaul
import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/delete_multiple_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/delete_multiple_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_folder_content_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart';
@@ -60,6 +61,7 @@ class MailboxBindings extends BaseBindings {
Get.find<SubscribeMultipleMailboxInteractor>(), Get.find<SubscribeMultipleMailboxInteractor>(),
Get.find<SubaddressingInteractor>(), Get.find<SubaddressingInteractor>(),
Get.find<CreateDefaultMailboxInteractor>(), Get.find<CreateDefaultMailboxInteractor>(),
Get.find<MoveFolderContentInteractor>(),
Get.find<TreeBuilder>(), Get.find<TreeBuilder>(),
Get.find<VerifyNameInteractor>(), Get.find<VerifyNameInteractor>(),
Get.find<GetAllMailboxInteractor>(), Get.find<GetAllMailboxInteractor>(),
@@ -111,6 +113,7 @@ class MailboxBindings extends BaseBindings {
Get.lazyPut(() => SubscribeMultipleMailboxInteractor(Get.find<MailboxRepository>())); Get.lazyPut(() => SubscribeMultipleMailboxInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => SubaddressingInteractor(Get.find<MailboxRepository>())); Get.lazyPut(() => SubaddressingInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => CreateDefaultMailboxInteractor(Get.find<MailboxRepository>())); Get.lazyPut(() => CreateDefaultMailboxInteractor(Get.find<MailboxRepository>()));
Get.lazyPut(() => MoveFolderContentInteractor(Get.find<MailboxRepository>()));
} }
@override @override
@@ -49,6 +49,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/state/create_new_mailbox_s
import 'package:tmail_ui_user/features/mailbox/domain/state/delete_multiple_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/delete_multiple_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/get_all_mailboxes_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/get_all_mailboxes_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/move_folder_content_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/move_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/move_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/refresh_all_mailboxes_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/refresh_all_mailboxes_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/refresh_changes_all_mailboxes_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/refresh_changes_all_mailboxes_state.dart';
@@ -60,6 +61,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_defaul
import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/delete_multiple_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/delete_multiple_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_folder_content_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart';
@@ -67,6 +69,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/subaddressing_int
import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multiple_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/subscribe_multiple_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/action/mailbox_ui_action.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/action/mailbox_ui_action.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/handle_move_folder_content_extension.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/mixin/mailbox_widget_mixin.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/mixin/mailbox_widget_mixin.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
@@ -74,6 +77,7 @@ import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_catego
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_builder.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/open_mailbox_view_event.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/model/open_mailbox_view_event.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_action_reactor.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_utils.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_utils.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart'; import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/mailbox_creator_arguments.dart'; import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/mailbox_creator_arguments.dart';
@@ -116,8 +120,10 @@ class MailboxController extends BaseMailboxController
final SubscribeMultipleMailboxInteractor _subscribeMultipleMailboxInteractor; final SubscribeMultipleMailboxInteractor _subscribeMultipleMailboxInteractor;
final SubaddressingInteractor _subaddressingInteractor; final SubaddressingInteractor _subaddressingInteractor;
final CreateDefaultMailboxInteractor _createDefaultMailboxInteractor; final CreateDefaultMailboxInteractor _createDefaultMailboxInteractor;
final MoveFolderContentInteractor _moveFolderContentInteractor;
IOSSharingManager? _iosSharingManager; IOSSharingManager? _iosSharingManager;
late MailboxActionReactor mailboxActionReactor;
final _activeScrollTop = RxBool(false); final _activeScrollTop = RxBool(false);
final _activeScrollBottom = RxBool(true); final _activeScrollBottom = RxBool(true);
@@ -147,6 +153,7 @@ class MailboxController extends BaseMailboxController
this._subscribeMultipleMailboxInteractor, this._subscribeMultipleMailboxInteractor,
this._subaddressingInteractor, this._subaddressingInteractor,
this._createDefaultMailboxInteractor, this._createDefaultMailboxInteractor,
this._moveFolderContentInteractor,
TreeBuilder treeBuilder, TreeBuilder treeBuilder,
VerifyNameInteractor verifyNameInteractor, VerifyNameInteractor verifyNameInteractor,
GetAllMailboxInteractor getAllMailboxInteractor, GetAllMailboxInteractor getAllMailboxInteractor,
@@ -162,6 +169,9 @@ class MailboxController extends BaseMailboxController
void onInit() { void onInit() {
_registerObxStreamListener(); _registerObxStreamListener();
_initWebSocketQueueHandler(); _initWebSocketQueueHandler();
mailboxActionReactor = MailboxActionReactor(
_moveFolderContentInteractor,
);
super.onInit(); super.onInit();
} }
@@ -186,7 +196,6 @@ class MailboxController extends BaseMailboxController
@override @override
void handleSuccessViewState(Success success) { void handleSuccessViewState(Success success) {
super.handleSuccessViewState(success);
if (success is GetAllMailboxSuccess) { if (success is GetAllMailboxSuccess) {
_handleGetAllMailboxSuccess(success); _handleGetAllMailboxSuccess(success);
} else if (success is CreateNewMailboxSuccess) { } else if (success is CreateNewMailboxSuccess) {
@@ -209,12 +218,15 @@ class MailboxController extends BaseMailboxController
handleSubAddressingSuccess(success); handleSubAddressingSuccess(success);
} else if (success is CreateDefaultMailboxAllSuccess) { } else if (success is CreateDefaultMailboxAllSuccess) {
_handleCreateDefaultFolderIfMissingSuccess(success); _handleCreateDefaultFolderIfMissingSuccess(success);
} else if (success is MoveFolderContentSuccess) {
handleMoveFolderContentSuccess(success);
} else {
super.handleSuccessViewState(success);
} }
} }
@override @override
void handleFailureViewState(Failure failure) { void handleFailureViewState(Failure failure) {
super.handleFailureViewState(failure);
if (failure is CreateNewMailboxFailure) { if (failure is CreateNewMailboxFailure) {
_createNewMailboxFailure(failure); _createNewMailboxFailure(failure);
} else if (failure is RenameMailboxFailure) { } else if (failure is RenameMailboxFailure) {
@@ -223,6 +235,10 @@ class MailboxController extends BaseMailboxController
_deleteMailboxFailure(failure); _deleteMailboxFailure(failure);
} else if (failure is SubaddressingFailure) { } else if (failure is SubaddressingFailure) {
handleSubAddressingFailure(failure); handleSubAddressingFailure(failure);
} else if (failure is MoveFolderContentFailure) {
handleMoveFolderContentFailure(failure);
} else {
super.handleFailureViewState(failure);
} }
} }
@@ -1178,6 +1194,8 @@ class MailboxController extends BaseMailboxController
mailboxDashBoardController.gotoEmailRecovery(); mailboxDashBoardController.gotoEmailRecovery();
break; break;
case MailboxActions.moveFolderContent: case MailboxActions.moveFolderContent:
performMoveFolderContent(context: context, mailboxSelected: mailbox);
mailboxDashBoardController.closeMailboxMenuDrawer();
break; break;
default: default:
break; break;
@@ -37,6 +37,7 @@ extension MailboxActionsExtension on MailboxActions {
return AppLocalizations.of(context).selectParentFolder; return AppLocalizations.of(context).selectParentFolder;
case MailboxActions.moveEmail: case MailboxActions.moveEmail:
case MailboxActions.move: case MailboxActions.move:
case MailboxActions.moveFolderContent:
return AppLocalizations.of(context).moveTo; return AppLocalizations.of(context).moveTo;
case MailboxActions.select: case MailboxActions.select:
case MailboxActions.selectForRuleAction: case MailboxActions.selectForRuleAction:
@@ -0,0 +1,29 @@
import 'dart:async';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/move_folder_content_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_folder_content_interactor.dart';
class MailboxActionReactor {
MailboxActionReactor(this._moveFolderContentInteractor);
final MoveFolderContentInteractor _moveFolderContentInteractor;
Stream<Either<Failure, Success>> moveFolderContent({
required Session session,
required AccountId accountId,
required MoveFolderContentRequest moveRequest,
StreamController<Either<Failure, Success>>? onProgressController,
}) {
return _moveFolderContentInteractor.execute(
session: session,
accountId: accountId,
request: moveRequest,
onProgressController: onProgressController,
);
}
}
@@ -317,9 +317,9 @@ class MailboxDashBoardController extends ReloadableController
Worker? searchInputFocusWorker; Worker? searchInputFocusWorker;
Worker? _downloadUIActionWorker; Worker? _downloadUIActionWorker;
final StreamController<Either<Failure, Success>> _progressStateController = final StreamController<Either<Failure, Success>> progressStateController =
StreamController<Either<Failure, Success>>.broadcast(); StreamController<Either<Failure, Success>>.broadcast();
Stream<Either<Failure, Success>> get progressState => _progressStateController.stream; Stream<Either<Failure, Success>> get progressState => progressStateController.stream;
final StreamController<RefreshActionViewEvent> _refreshActionEventController = final StreamController<RefreshActionViewEvent> _refreshActionEventController =
StreamController<RefreshActionViewEvent>.broadcast(); StreamController<RefreshActionViewEvent>.broadcast();
@@ -743,7 +743,8 @@ class MailboxDashBoardController extends ReloadableController
void _registerStreamListener() { void _registerStreamListener() {
progressState.listen((state) { progressState.listen((state) {
viewStateMailboxActionProgress.value = state; log('$runtimeType::_registerStreamListener: ViewStateMailboxActionProgress = ${state.runtimeType}');
syncViewStateMailboxActionProgress(newState: state);
}); });
_refreshActionEventController.stream _refreshActionEventController.stream
@@ -1760,13 +1761,19 @@ class MailboxDashBoardController extends ReloadableController
accountId, accountId,
trashMailboxId, trashMailboxId,
totalEmailsInTrash, totalEmailsInTrash,
_progressStateController, progressStateController,
)); ));
} }
} }
void syncViewStateMailboxActionProgress({
required Either<Failure, Success> newState,
}) {
viewStateMailboxActionProgress.value = newState;
}
void _emptyTrashFolderSuccess(EmptyTrashFolderSuccess success) { void _emptyTrashFolderSuccess(EmptyTrashFolderSuccess success) {
viewStateMailboxActionProgress.value = Right(UIState.idle); syncViewStateMailboxActionProgress(newState: Right(UIState.idle));
handleDeleteEmailsInMailbox( handleDeleteEmailsInMailbox(
emailIds: success.emailIds, emailIds: success.emailIds,
@@ -1902,11 +1909,11 @@ class MailboxDashBoardController extends ReloadableController
mailboxId, mailboxId,
mailboxDisplayName, mailboxDisplayName,
totalEmailsUnread, totalEmailsUnread,
_progressStateController)); progressStateController));
} }
void _markAsReadMailboxSuccess(Success success) { void _markAsReadMailboxSuccess(Success success) {
viewStateMailboxActionProgress.value = Right(UIState.idle); syncViewStateMailboxActionProgress(newState: Right(UIState.idle));
if (success is MarkAsMailboxReadAllSuccess) { if (success is MarkAsMailboxReadAllSuccess) {
if (currentContext != null && currentOverlayContext != null) { if (currentContext != null && currentOverlayContext != null) {
@@ -1926,7 +1933,7 @@ class MailboxDashBoardController extends ReloadableController
} }
void _markAsReadMailboxFailure(MarkAsMailboxReadFailure failure) { void _markAsReadMailboxFailure(MarkAsMailboxReadFailure failure) {
viewStateMailboxActionProgress.value = Right(UIState.idle); syncViewStateMailboxActionProgress(newState: Right(UIState.idle));
if (currentOverlayContext != null && currentContext != null) { if (currentOverlayContext != null && currentContext != null) {
appToast.showToastErrorMessage( appToast.showToastErrorMessage(
currentOverlayContext!, currentOverlayContext!,
@@ -1938,7 +1945,7 @@ class MailboxDashBoardController extends ReloadableController
} }
void _markAsReadMailboxAllFailure(MarkAsMailboxReadAllFailure failure) { void _markAsReadMailboxAllFailure(MarkAsMailboxReadAllFailure failure) {
viewStateMailboxActionProgress.value = Right(UIState.idle); syncViewStateMailboxActionProgress(newState: Right(UIState.idle));
if (currentOverlayContext != null && currentContext != null) { if (currentOverlayContext != null && currentContext != null) {
appToast.showToastErrorMessage( appToast.showToastErrorMessage(
currentOverlayContext!, currentOverlayContext!,
@@ -2694,13 +2701,13 @@ class MailboxDashBoardController extends ReloadableController
accountId, accountId,
spamFolderId, spamFolderId,
totalEmails, totalEmails,
_progressStateController, progressStateController,
)); ));
} }
} }
void _emptySpamFolderSuccess(EmptySpamFolderSuccess success) { void _emptySpamFolderSuccess(EmptySpamFolderSuccess success) {
viewStateMailboxActionProgress.value = Right(UIState.idle); syncViewStateMailboxActionProgress(newState: Right(UIState.idle));
handleDeleteEmailsInMailbox( handleDeleteEmailsInMailbox(
emailIds: success.emailIds, emailIds: success.emailIds,
@@ -3108,13 +3115,13 @@ class MailboxDashBoardController extends ReloadableController
} }
void _handleEmptySpamFolderFailure(EmptySpamFolderFailure failure) { void _handleEmptySpamFolderFailure(EmptySpamFolderFailure failure) {
viewStateMailboxActionProgress.value = Right(UIState.idle); syncViewStateMailboxActionProgress(newState: Right(UIState.idle));
toastManager.showMessageFailure(failure); toastManager.showMessageFailure(failure);
} }
void _handleEmptyTrashFolderFailure(EmptyTrashFolderFailure failure) { void _handleEmptyTrashFolderFailure(EmptyTrashFolderFailure failure) {
viewStateMailboxActionProgress.value = Right(UIState.idle); syncViewStateMailboxActionProgress(newState: Right(UIState.idle));
toastManager.showMessageFailure(failure); toastManager.showMessageFailure(failure);
} }
@@ -3325,7 +3332,7 @@ class MailboxDashBoardController extends ReloadableController
_emailReceiveManager.closeEmailReceiveManagerStream(); _emailReceiveManager.closeEmailReceiveManagerStream();
_deepLinkDataStreamSubscription?.cancel(); _deepLinkDataStreamSubscription?.cancel();
} }
_progressStateController.close(); progressStateController.close();
_refreshActionEventController.close(); _refreshActionEventController.close();
_notificationManager.closeStream(); _notificationManager.closeStream();
_fcmService.closeStream(); _fcmService.closeStream();
@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart'; import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/clear_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/clear_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/move_folder_content_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/styles/mark_mailbox_as_read_loading_banner_style.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/styles/mark_mailbox_as_read_loading_banner_style.dart';
import 'package:tmail_ui_user/features/thread/domain/state/empty_spam_folder_state.dart'; import 'package:tmail_ui_user/features/thread/domain/state/empty_spam_folder_state.dart';
@@ -29,6 +30,11 @@ class MarkMailboxAsReadLoadingBanner extends StatelessWidget with AppLoaderMixin
return _buildProgressBanner(success.countRead, success.totalUnread); return _buildProgressBanner(success.countRead, success.totalUnread);
} else if (success is EmptyingFolderState) { } else if (success is EmptyingFolderState) {
return _buildProgressBanner(success.countEmailsDeleted, success.totalEmails); return _buildProgressBanner(success.countEmailsDeleted, success.totalEmails);
} else if (success is MoveFolderContentProgressState) {
return _buildProgressBanner(
success.countEmailsCompleted,
success.totalEmails,
);
} else { } else {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
@@ -18,6 +18,7 @@ import 'package:tmail_ui_user/features/email/presentation/model/context_item_ema
import 'package:tmail_ui_user/features/email/presentation/model/popup_menu_item_email_action.dart'; import 'package:tmail_ui_user/features/email/presentation/model/popup_menu_item_email_action.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/clear_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/clear_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/move_folder_content_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_report_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_report_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_open_context_menu_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/handle_open_context_menu_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/extensions/open_and_close_composer_extension.dart';
@@ -793,6 +794,7 @@ class _MailboxActionProgressBanner extends StatelessWidget with AppLoaderMixin {
if (success is MarkAsMailboxReadLoading || if (success is MarkAsMailboxReadLoading ||
success is EmptySpamFolderLoading || success is EmptySpamFolderLoading ||
success is EmptyTrashFolderLoading || success is EmptyTrashFolderLoading ||
success is MovingFolderContent ||
success is ClearingMailbox) { success is ClearingMailbox) {
return Padding( return Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(
@@ -815,6 +817,12 @@ class _MailboxActionProgressBanner extends StatelessWidget with AppLoaderMixin {
success.countEmailsDeleted, success.countEmailsDeleted,
success.totalEmails, success.totalEmails,
); );
} else if (success is MoveFolderContentProgressState) {
return _buildProgressBanner(
context,
success.countEmailsCompleted,
success.totalEmails,
);
} }
return const SizedBox.shrink(); return const SizedBox.shrink();
}, },
+6
View File
@@ -5057,5 +5057,11 @@
"type": "text", "type": "text",
"placeholders_order": [], "placeholders_order": [],
"placeholders": {} "placeholders": {}
},
"moveFolderContentToastMessage": "Failed to move all emails from this folder to another folder.",
"@moveFolderContentToastMessage": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
} }
} }
+1 -1
View File
@@ -54,7 +54,7 @@ class CoreBindings extends Bindings {
void _bindingToast() { void _bindingToast() {
Get.put(AppToast()); Get.put(AppToast());
Get.put(ToastManager(Get.find<AppToast>())); Get.put(ToastManager(Get.find<AppToast>(), Get.find<ImagePaths>()));
} }
void _bindingDeviceManager() { void _bindingDeviceManager() {
@@ -5352,4 +5352,11 @@ class AppLocalizations {
name: 'moveFolderContent', name: 'moveFolderContent',
); );
} }
String get moveFolderContentToastMessage {
return Intl.message(
'Failed to move all emails from this folder to another folder.',
name: 'moveFolderContentToastMessage',
);
}
} }
+44 -1
View File
@@ -2,12 +2,16 @@ import 'dart:io';
import 'package:core/domain/exceptions/file_exception.dart'; import 'package:core/domain/exceptions/file_exception.dart';
import 'package:core/domain/exceptions/web_session_exception.dart'; import 'package:core/domain/exceptions/web_session_exception.dart';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart'; import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/utils/app_toast.dart'; import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/utils/app_logger.dart'; import 'package:core/utils/app_logger.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_appauth_web/authorization_exception.dart'; import 'package:flutter_appauth_web/authorization_exception.dart';
import 'package:flutter_svg/svg.dart';
import 'package:jmap_dart_client/jmap/core/error/method/error_method_response.dart'; import 'package:jmap_dart_client/jmap/core/error/method/error_method_response.dart';
import 'package:jmap_dart_client/jmap/core/error/method/exception/error_method_response_exception.dart'; import 'package:jmap_dart_client/jmap/core/error/method/exception/error_method_response_exception.dart';
import 'package:jmap_dart_client/jmap/core/error/set_error.dart'; import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
@@ -27,6 +31,7 @@ import 'package:tmail_ui_user/features/login/data/network/oidc_error.dart';
import 'package:tmail_ui_user/features/login/domain/exceptions/authentication_exception.dart'; import 'package:tmail_ui_user/features/login/domain/exceptions/authentication_exception.dart';
import 'package:tmail_ui_user/features/login/domain/exceptions/oauth_authorization_error.dart'; import 'package:tmail_ui_user/features/login/domain/exceptions/oauth_authorization_error.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/clear_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/clear_mailbox_state.dart';
import 'package:tmail_ui_user/features/mailbox/domain/state/move_folder_content_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/add_recipient_in_forwarding_state.dart'; import 'package:tmail_ui_user/features/manage_account/domain/state/add_recipient_in_forwarding_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/create_new_rule_filter_state.dart'; import 'package:tmail_ui_user/features/manage_account/domain/state/create_new_rule_filter_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/delete_recipient_in_forwarding_state.dart'; import 'package:tmail_ui_user/features/manage_account/domain/state/delete_recipient_in_forwarding_state.dart';
@@ -45,8 +50,9 @@ import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class ToastManager { class ToastManager {
final AppToast appToast; final AppToast appToast;
final ImagePaths imagePaths;
ToastManager(this.appToast); ToastManager(this.appToast, this.imagePaths);
String getDefaultMessageByException( String getDefaultMessageByException(
AppLocalizations appLocalizations, AppLocalizations appLocalizations,
@@ -187,6 +193,9 @@ class ToastManager {
} else if (failure is CalendarEventReplyFailure) { } else if (failure is CalendarEventReplyFailure) {
message = message ?? message = message ??
appLocalizations.eventReplyWasSentUnsuccessfully; appLocalizations.eventReplyWasSentUnsuccessfully;
} else if (failure is MoveFolderContentFailure) {
message = message ??
appLocalizations.moveFolderContentToastMessage;
} }
log('ToastManager::showMessageFailure: Message: $message'); log('ToastManager::showMessageFailure: Message: $message');
if (message?.trim().isNotEmpty == true) { if (message?.trim().isNotEmpty == true) {
@@ -256,4 +265,38 @@ class ToastManager {
appToast.showToastSuccessMessage(overlayContext, message!); appToast.showToastSuccessMessage(overlayContext, message!);
} }
} }
void showMessageSuccessWithAction({
required Success success,
required VoidCallback onActionCallback,
}) {
final context = currentContext;
final overlayContext = currentOverlayContext;
if (context == null || overlayContext == null) {
logError('$runtimeType::showMessageSuccessWithAction: Context or OverlayContext is null');
return;
}
String? message;
final appLocalizations = AppLocalizations.of(context);
if (success is MoveFolderContentSuccess) {
message = appLocalizations.movedToFolder(
success.request.destinationMailboxDisplayName,
);
}
log('$runtimeType::showMessageSuccessWithAction: Message: $message');
if (message?.trim().isNotEmpty == true) {
appToast.showToastMessage(
overlayContext,
message!,
actionName: appLocalizations.undo,
onActionClick: onActionCallback,
leadingSVGIcon: imagePaths.icFolderMailbox,
leadingSVGIconColor: Colors.white,
backgroundColor: AppColor.toastSuccessBackgroundColor,
textColor: Colors.white,
actionIcon: SvgPicture.asset(imagePaths.icUndo),
);
}
}
} }
@@ -49,6 +49,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_mailbo
import 'package:tmail_ui_user/features/mailbox/domain/usecases/delete_multiple_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/delete_multiple_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/mark_as_mailbox_read_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/mark_as_mailbox_read_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_folder_content_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart';
@@ -165,6 +166,7 @@ const fallbackGenerators = {
MockSpec<SubscribeMultipleMailboxInteractor>(), MockSpec<SubscribeMultipleMailboxInteractor>(),
MockSpec<SubaddressingInteractor>(), MockSpec<SubaddressingInteractor>(),
MockSpec<CreateDefaultMailboxInteractor>(), MockSpec<CreateDefaultMailboxInteractor>(),
MockSpec<MoveFolderContentInteractor>(),
MockSpec<TreeBuilder>(), MockSpec<TreeBuilder>(),
MockSpec<VerifyNameInteractor>(), MockSpec<VerifyNameInteractor>(),
MockSpec<GetAllMailboxInteractor>(), MockSpec<GetAllMailboxInteractor>(),
@@ -280,6 +282,7 @@ void main() {
final subscribeMultipleMailboxInteractor = MockSubscribeMultipleMailboxInteractor(); final subscribeMultipleMailboxInteractor = MockSubscribeMultipleMailboxInteractor();
final subaddressingInteractor = MockSubaddressingInteractor(); final subaddressingInteractor = MockSubaddressingInteractor();
final createDefaultMailboxInteractor = MockCreateDefaultMailboxInteractor(); final createDefaultMailboxInteractor = MockCreateDefaultMailboxInteractor();
final moveFolderContentInteractor = MockMoveFolderContentInteractor();
final treeBuilder = MockTreeBuilder(); final treeBuilder = MockTreeBuilder();
final verifyNameInteractor = MockVerifyNameInteractor(); final verifyNameInteractor = MockVerifyNameInteractor();
final getAllMailboxInteractor = MockGetAllMailboxInteractor(); final getAllMailboxInteractor = MockGetAllMailboxInteractor();
@@ -411,6 +414,7 @@ void main() {
subscribeMultipleMailboxInteractor, subscribeMultipleMailboxInteractor,
subaddressingInteractor, subaddressingInteractor,
createDefaultMailboxInteractor, createDefaultMailboxInteractor,
moveFolderContentInteractor,
treeBuilder, treeBuilder,
verifyNameInteractor, verifyNameInteractor,
getAllMailboxInteractor, getAllMailboxInteractor,
@@ -647,6 +651,7 @@ void main() {
subscribeMultipleMailboxInteractor, subscribeMultipleMailboxInteractor,
subaddressingInteractor, subaddressingInteractor,
createDefaultMailboxInteractor, createDefaultMailboxInteractor,
moveFolderContentInteractor,
treeBuilder, treeBuilder,
verifyNameInteractor, verifyNameInteractor,
getAllMailboxInteractor, getAllMailboxInteractor,
@@ -46,6 +46,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/usecases/create_new_mailbo
import 'package:tmail_ui_user/features/mailbox/domain/usecases/delete_multiple_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/delete_multiple_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/get_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/mark_as_mailbox_read_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/mark_as_mailbox_read_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_folder_content_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/move_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/refresh_all_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/mailbox/domain/usecases/rename_mailbox_interactor.dart';
@@ -166,6 +167,7 @@ const fallbackGenerators = {
MockSpec<SubscribeMultipleMailboxInteractor>(), MockSpec<SubscribeMultipleMailboxInteractor>(),
MockSpec<SubaddressingInteractor>(), MockSpec<SubaddressingInteractor>(),
MockSpec<CreateDefaultMailboxInteractor>(), MockSpec<CreateDefaultMailboxInteractor>(),
MockSpec<MoveFolderContentInteractor>(),
MockSpec<TreeBuilder>(), MockSpec<TreeBuilder>(),
MockSpec<VerifyNameInteractor>(), MockSpec<VerifyNameInteractor>(),
MockSpec<GetAllMailboxInteractor>(), MockSpec<GetAllMailboxInteractor>(),
@@ -266,6 +268,7 @@ void main() {
final subscribeMultipleMailboxInteractor = MockSubscribeMultipleMailboxInteractor(); final subscribeMultipleMailboxInteractor = MockSubscribeMultipleMailboxInteractor();
final subaddressingInteractor = MockSubaddressingInteractor(); final subaddressingInteractor = MockSubaddressingInteractor();
final createDefaultMailboxInteractor = MockCreateDefaultMailboxInteractor(); final createDefaultMailboxInteractor = MockCreateDefaultMailboxInteractor();
final moveFolderContentInteractor = MockMoveFolderContentInteractor();
final treeBuilder = MockTreeBuilder(); final treeBuilder = MockTreeBuilder();
final verifyNameInteractor = MockVerifyNameInteractor(); final verifyNameInteractor = MockVerifyNameInteractor();
final getAllMailboxInteractor = MockGetAllMailboxInteractor(); final getAllMailboxInteractor = MockGetAllMailboxInteractor();
@@ -400,6 +403,7 @@ void main() {
subscribeMultipleMailboxInteractor, subscribeMultipleMailboxInteractor,
subaddressingInteractor, subaddressingInteractor,
createDefaultMailboxInteractor, createDefaultMailboxInteractor,
moveFolderContentInteractor,
treeBuilder, treeBuilder,
verifyNameInteractor, verifyNameInteractor,
getAllMailboxInteractor, getAllMailboxInteractor,