Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@ import 'package:flutter/material.dart';
class DefaultCloseButtonWidget extends StatelessWidget {
final String iconClose;
final VoidCallback onTapActionCallback;
final bool isAlignTopEnd;

const DefaultCloseButtonWidget({
super.key,
required this.iconClose,
required this.onTapActionCallback,
this.isAlignTopEnd = true,
});

@override
Widget build(BuildContext context) {
return PositionedDirectional(
top: 4,
end: 4,
end: isAlignTopEnd ? 4 : null,
start: isAlignTopEnd ? null : 4,
child: TMailButtonWidget.fromIcon(
icon: iconClose,
iconSize: 24,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,42 @@ import 'package:core/presentation/state/success.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';

typedef OnSyncListLabelForListEmail = void Function(
List<EmailId> emailIds,
List<KeyWordIdentifier> labelKeywords,
{bool shouldRemove}
);

class AddingListLabelsToListEmails extends LoadingState {}

class AddListLabelsToListEmailsSuccess extends UIState {
final List<EmailId> emailIds;
final List<KeyWordIdentifier> labelKeywords;
final List<String> labelDisplays;
final OnSyncListLabelForListEmail? onSync;

AddListLabelsToListEmailsSuccess(
this.emailIds,
this.labelKeywords,
this.labelDisplays,
);
this.labelDisplays, {
this.onSync,
});

@override
List<Object> get props => [emailIds, labelKeywords, labelDisplays];
List<Object?> get props => [emailIds, labelKeywords, labelDisplays];
}

class AddListLabelsToListEmailsHasSomeFailure
extends AddListLabelsToListEmailsSuccess {
AddListLabelsToListEmailsHasSomeFailure(
super.emailIds,
super.labelKeywords,
super.labelDisplays,
);
super.labelDisplays, {
super.onSync,
});

@override
List<Object> get props => [...super.props, 'hasSomeFailure'];
List<Object?> get props => [...super.props, 'hasSomeFailure'];
}

class AddListLabelsToListEmailsFailure extends FeatureFailure {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ 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:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:tmail_ui_user/features/composer/domain/exceptions/set_method_exception.dart';
import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart';
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
import 'package:tmail_ui_user/features/email/domain/state/labels/add_list_label_to_list_email_state.dart';
import 'package:tmail_ui_user/features/labels/domain/model/add_list_labels_to_list_emails_params.dart';

class AddListLabelToListEmailsInteractor {
final EmailRepository _emailRepository;
Expand All @@ -18,49 +17,49 @@ class AddListLabelToListEmailsInteractor {
Stream<Either<Failure, Success>> execute(
Session session,
AccountId accountId,
List<EmailId> emailIds,
List<KeyWordIdentifier> labelKeywords,
List<String> labelDisplays,
AddListLabelsToListEmailsParams params,
) async* {
try {
if (emailIds.isEmpty) {
if (params.emailIds.isEmpty) {
yield Left(AddListLabelsToListEmailsFailure(
exception: EmailIdsSuccessIsEmptyException(),
labelDisplays: labelDisplays,
labelDisplays: params.labelDisplays,
));
return;
}
yield Right(AddingListLabelsToListEmails());
final result = await _emailRepository.addListLabelToListEmail(
session,
accountId,
emailIds,
labelKeywords,
params.emailIds,
params.labelKeywords,
);
if (emailIds.length == result.emailIdsSuccess.length) {
if (params.emailIds.length == result.emailIdsSuccess.length) {
yield Right(AddListLabelsToListEmailsSuccess(
result.emailIdsSuccess,
labelKeywords,
labelDisplays,
params.labelKeywords,
params.labelDisplays,
onSync: params.onSync,
));
} else if (result.emailIdsSuccess.isEmpty) {
yield Left(AddListLabelsToListEmailsFailure(
exception: result.mapErrors.isNotEmpty
? SetMethodException(result.mapErrors)
: EmailIdsSuccessIsEmptyException(),
labelDisplays: labelDisplays,
labelDisplays: params.labelDisplays,
));
} else {
yield Right(AddListLabelsToListEmailsHasSomeFailure(
result.emailIdsSuccess,
labelKeywords,
labelDisplays,
params.labelKeywords,
params.labelDisplays,
onSync: params.onSync,
));
}
} catch (e) {
yield Left(AddListLabelsToListEmailsFailure(
exception: e,
labelDisplays: labelDisplays,
labelDisplays: params.labelDisplays,
));
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:labels/extensions/list_label_extension.dart';
import 'package:labels/model/label.dart';
import 'package:tmail_ui_user/features/email/domain/state/labels/add_list_label_to_list_email_state.dart';

class AddListLabelsToListEmailsParams extends Equatable {
final List<Label> labels;
final List<EmailId> emailIds;
final OnSyncListLabelForListEmail onSync;

const AddListLabelsToListEmailsParams({
required this.labels,
required this.emailIds,
required this.onSync,
});

List<KeyWordIdentifier> get labelKeywords => labels.keywords;

List<String> get labelDisplays => labels.displayNameNotNullList;

@override
List<Object?> get props => [labels, emailIds, onSync];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:flutter/material.dart';
import 'package:model/email/presentation_email.dart';
import 'package:model/extensions/list_presentation_email_extension.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/email/domain/state/labels/add_list_label_to_list_email_state.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/labels/add_list_label_to_list_emails_interactor.dart';
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
import 'package:tmail_ui_user/features/labels/domain/exceptions/label_exceptions.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:tmail_ui_user/features/labels/domain/model/add_list_labels_to_list_emails_params.dart';
import 'package:tmail_ui_user/features/labels/presentation/label_controller.dart';
import 'package:tmail_ui_user/features/labels/presentation/widgets/choose_label_modal.dart';
import 'package:tmail_ui_user/main/routes/dialog_router.dart';

class AddListLabelToListEmailsDelegate extends BaseController {
final LabelController _labelController;
final AddListLabelToListEmailsInteractor _interactor;

AddListLabelToListEmailsDelegate(this._labelController, this._interactor);

Future<void> openChooseLabelModal({
required List<PresentationEmail> selectedEmails,
required ImagePaths imagePaths,
required VoidCallback onCancel,
required OnSyncListLabelForListEmail onSync,
}) async {
if (_labelController.labels.isEmpty) return;

await DialogRouter().openDialogModal(
child: ChooseLabelModal(
labels: _labelController.labels,
onLabelAsToEmailsAction: (labels) {
onCancel();
_addLabels(
AddListLabelsToListEmailsParams(
labels: labels,
emailIds: selectedEmails.listEmailIds,
onSync: onSync,
),
);
},
imagePaths: imagePaths,
),
dialogLabel: 'choose-label-modal',
);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

void _addLabels(
AddListLabelsToListEmailsParams params,
) {
final session = _labelController.session;
final accountId = _labelController.accountId;

final exception = _validateParams(params.labelKeywords);
if (exception != null) {
emitFailure(
controller: this,
failure: AddListLabelsToListEmailsFailure(
exception: exception,
labelDisplays: params.labelDisplays,
),
);
return;
}

consumeState(_interactor.execute(session!, accountId!, params));
}

Exception? _validateParams(List<KeyWordIdentifier> keywords) {
if (_labelController.session == null) return NotFoundSessionException();
if (_labelController.accountId == null) return NotFoundAccountIdException();
if (keywords.isEmpty) return const LabelKeywordIsNull();
return null;
}

@override
void handleSuccessViewState(Success success) {
if (success is AddListLabelsToListEmailsSuccess) {
Comment thread
hoangdat marked this conversation as resolved.
toastManager.showMessageSuccess(success);
success.onSync?.call(success.emailIds, success.labelKeywords, shouldRemove: false);
}
Comment thread
dab246 marked this conversation as resolved.
}

@override
void handleFailureViewState(Failure failure) {
if (failure is AddListLabelsToListEmailsFailure) {
toastManager.showMessageFailure(failure);
}
}
}
Loading
Loading