TF-4053 Add interactor/datasource/repository for move folder content action

This commit is contained in:
dab246
2025-10-29 13:19:25 +07:00
committed by Dat H. Pham
parent ccdbd798d9
commit 369316f50d
19 changed files with 695 additions and 188 deletions
@@ -4,3 +4,5 @@ class NotFoundInboxMailboxException implements Exception {}
class NotFoundMailboxException implements Exception {}
class NotFoundClearMailboxResponseException implements Exception {}
class CannotMoveAllEmailException implements Exception {}
@@ -0,0 +1,31 @@
import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_action.dart';
class MoveFolderContentRequest with EquatableMixin {
final MailboxId mailboxId;
final MoveAction moveAction;
final MailboxId destinationMailboxId;
final String destinationMailboxDisplayName;
final int totalEmails;
final bool markAsRead;
MoveFolderContentRequest({
required this.mailboxId,
required this.moveAction,
required this.destinationMailboxId,
required this.destinationMailboxDisplayName,
this.totalEmails = 0,
this.markAsRead = false,
});
@override
List<Object?> get props => [
mailboxId,
moveAction,
destinationMailboxId,
destinationMailboxDisplayName,
totalEmails,
markAsRead,
];
}
@@ -15,6 +15,7 @@ import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/get_mailbox_by_role_response.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_response.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_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_request.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/subscribe_mailbox_request.dart';
@@ -41,6 +42,13 @@ abstract class MailboxRepository {
Future<bool> moveMailbox(Session session, AccountId accountId, MoveMailboxRequest request);
Future<void> moveFolderContent({
required Session session,
required AccountId accountId,
required MoveFolderContentRequest request,
StreamController<dartz.Either<Failure, Success>>? onProgressController,
});
Future<State?> getMailboxState(Session session, AccountId accountId);
Future<bool> subscribeMailbox(Session session, AccountId accountId, SubscribeMailboxRequest request);
@@ -0,0 +1,38 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/move_folder_content_request.dart';
class MovingFolderContent extends LoadingState {}
class MoveFolderContentProgressState extends UIState {
final MailboxId mailboxId;
final int countEmailsCompleted;
final int totalEmails;
MoveFolderContentProgressState(
this.mailboxId,
this.countEmailsCompleted,
this.totalEmails,
);
@override
List<Object?> get props => [
mailboxId,
countEmailsCompleted,
totalEmails,
];
}
class MoveFolderContentSuccess extends UIState {
final MoveFolderContentRequest request;
MoveFolderContentSuccess(this.request);
@override
List<Object?> get props => [request];
}
class MoveFolderContentFailure extends FeatureFailure {
MoveFolderContentFailure(dynamic exception) : super(exception: exception);
}
@@ -0,0 +1,37 @@
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/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_mailbox_state.dart';
class MoveFolderContentInteractor {
final MailboxRepository _mailboxRepository;
MoveFolderContentInteractor(this._mailboxRepository);
Stream<void> execute({
required Session session,
required AccountId accountId,
required MoveFolderContentRequest request,
StreamController<Either<Failure, Success>>? onProgressController,
}) async* {
try {
yield Right<Failure, Success>(MovingFolderContent());
await _mailboxRepository.moveFolderContent(
session: session,
accountId: accountId,
request: request,
onProgressController: onProgressController,
);
yield Right<Failure, Success>(MoveFolderContentSuccess(request));
} catch (e) {
yield Left<Failure, Success>(MoveMailboxFailure(e));
}
}
}