TF-4301 Ensure that CreateNewLabelInteractor and EditLabelInteractor are always non-null before using them.

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2026-04-17 10:20:15 +07:00
committed by Dat H. Pham
parent 8ac68ed1a5
commit 5938df395c
3 changed files with 71 additions and 35 deletions
@@ -0,0 +1,31 @@
import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:labels/model/label.dart';
import 'package:tmail_ui_user/features/labels/domain/usecases/create_new_label_interactor.dart';
import 'package:tmail_ui_user/features/labels/domain/usecases/edit_label_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
class OpenEditLabelModalParams with EquatableMixin {
final Label selectedLabel;
final AccountId accountId;
final VerifyNameInteractor verifyNameInteractor;
final CreateNewLabelInteractor createNewLabelInteractor;
final EditLabelInteractor editLabelInteractor;
const OpenEditLabelModalParams({
required this.selectedLabel,
required this.accountId,
required this.verifyNameInteractor,
required this.createNewLabelInteractor,
required this.editLabelInteractor,
});
@override
List<Object?> get props => [
selectedLabel,
accountId,
verifyNameInteractor,
createNewLabelInteractor,
editLabelInteractor,
];
}
@@ -6,8 +6,11 @@ import 'package:labels/extensions/list_label_extension.dart';
import 'package:labels/model/label.dart'; import 'package:labels/model/label.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart'; import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart'; import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
import 'package:tmail_ui_user/features/labels/domain/model/open_edit_label_modal_params.dart';
import 'package:tmail_ui_user/features/labels/domain/state/delete_a_label_state.dart'; import 'package:tmail_ui_user/features/labels/domain/state/delete_a_label_state.dart';
import 'package:tmail_ui_user/features/labels/domain/state/edit_label_state.dart'; import 'package:tmail_ui_user/features/labels/domain/state/edit_label_state.dart';
import 'package:tmail_ui_user/features/labels/domain/usecases/create_new_label_interactor.dart';
import 'package:tmail_ui_user/features/labels/domain/usecases/edit_label_interactor.dart';
import 'package:tmail_ui_user/features/labels/presentation/label_controller.dart'; import 'package:tmail_ui_user/features/labels/presentation/label_controller.dart';
import 'package:tmail_ui_user/features/labels/presentation/models/label_action_type.dart'; import 'package:tmail_ui_user/features/labels/presentation/models/label_action_type.dart';
import 'package:tmail_ui_user/features/labels/presentation/widgets/create_new_label_modal.dart'; import 'package:tmail_ui_user/features/labels/presentation/widgets/create_new_label_modal.dart';
@@ -45,8 +48,15 @@ extension HandleLabelActionTypeExtension on LabelController {
required AccountId? accountId, required AccountId? accountId,
required Label label, required Label label,
}) async { }) async {
final createNewLabelInteractor = getBinding<CreateNewLabelInteractor>();
final editLabelInteractor = getBinding<EditLabelInteractor>();
final verifyNameInteractor = getBinding<VerifyNameInteractor>(); final verifyNameInteractor = getBinding<VerifyNameInteractor>();
if (verifyNameInteractor == null) {
final isInteractorsInitialized = createNewLabelInteractor != null &&
editLabelInteractor != null &&
verifyNameInteractor != null;
if (!isInteractorsInitialized) {
_handleEditLabelFailure(EditLabelFailure(const InteractorNotInitialized())); _handleEditLabelFailure(EditLabelFailure(const InteractorNotInitialized()));
return; return;
} }
@@ -57,9 +67,13 @@ extension HandleLabelActionTypeExtension on LabelController {
} }
final resultState = await openEditLabelModal( final resultState = await openEditLabelModal(
selectedLabel: label, params: OpenEditLabelModalParams(
accountId: accountId, selectedLabel: label,
verifyNameInteractor: verifyNameInteractor, accountId: accountId,
verifyNameInteractor: verifyNameInteractor,
createNewLabelInteractor: createNewLabelInteractor,
editLabelInteractor: editLabelInteractor,
),
); );
if (resultState is EditLabelSuccess) { if (resultState is EditLabelSuccess) {
@@ -10,6 +10,7 @@ import 'package:model/mailbox/expand_mode.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart'; import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart'; import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart';
import 'package:tmail_ui_user/features/labels/domain/model/open_edit_label_modal_params.dart';
import 'package:tmail_ui_user/features/labels/domain/state/create_new_label_state.dart'; import 'package:tmail_ui_user/features/labels/domain/state/create_new_label_state.dart';
import 'package:tmail_ui_user/features/labels/domain/state/delete_a_label_state.dart'; import 'package:tmail_ui_user/features/labels/domain/state/delete_a_label_state.dart';
import 'package:tmail_ui_user/features/labels/domain/state/get_all_label_state.dart'; import 'package:tmail_ui_user/features/labels/domain/state/get_all_label_state.dart';
@@ -42,9 +43,7 @@ class LabelController extends BaseController
final GlobalKey labelAppBarKey = GlobalKey(); final GlobalKey labelAppBarKey = GlobalKey();
GetAllLabelInteractor? _getAllLabelInteractor; GetAllLabelInteractor? _getAllLabelInteractor;
CreateNewLabelInteractor? _createNewLabelInteractor;
GetLabelSettingStateInteractor? _getLabelSettingStateInteractor; GetLabelSettingStateInteractor? _getLabelSettingStateInteractor;
EditLabelInteractor? _editLabelInteractor;
DeleteALabelInteractor? _deleteALabelInteractor; DeleteALabelInteractor? _deleteALabelInteractor;
GetLabelChangesInteractor? _getLabelChangesInteractor; GetLabelChangesInteractor? _getLabelChangesInteractor;
@@ -99,8 +98,6 @@ class LabelController extends BaseController
void injectLabelsBindings() { void injectLabelsBindings() {
LabelInteractorBindings().dependencies(); LabelInteractorBindings().dependencies();
_getAllLabelInteractor = getBinding<GetAllLabelInteractor>(); _getAllLabelInteractor = getBinding<GetAllLabelInteractor>();
_createNewLabelInteractor = getBinding<CreateNewLabelInteractor>();
_editLabelInteractor = getBinding<EditLabelInteractor>();
_deleteALabelInteractor = getBinding<DeleteALabelInteractor>(); _deleteALabelInteractor = getBinding<DeleteALabelInteractor>();
_getLabelChangesInteractor = getBinding<GetLabelChangesInteractor>(); _getLabelChangesInteractor = getBinding<GetLabelChangesInteractor>();
} }
@@ -147,6 +144,8 @@ class LabelController extends BaseController
Future<dynamic> openCreateNewLabelModal({ Future<dynamic> openCreateNewLabelModal({
required AccountId accountId, required AccountId accountId,
required VerifyNameInteractor verifyNameInteractor, required VerifyNameInteractor verifyNameInteractor,
required CreateNewLabelInteractor createNewLabelInteractor,
required EditLabelInteractor editLabelInteractor,
}) async { }) async {
return DialogRouter().openDialogModal( return DialogRouter().openDialogModal(
child: CreateNewLabelModal( child: CreateNewLabelModal(
@@ -155,29 +154,27 @@ class LabelController extends BaseController
accountId: accountId, accountId: accountId,
imagePaths: imagePaths, imagePaths: imagePaths,
verifyNameInteractor: verifyNameInteractor, verifyNameInteractor: verifyNameInteractor,
createNewLabelInteractor: _createNewLabelInteractor!, createNewLabelInteractor: createNewLabelInteractor,
editLabelInteractor: _editLabelInteractor!, editLabelInteractor: editLabelInteractor,
), ),
dialogLabel: 'create-new-label-modal', dialogLabel: 'create-new-label-modal',
); );
} }
Future<dynamic> openEditLabelModal({ Future<dynamic> openEditLabelModal({
required Label selectedLabel, required OpenEditLabelModalParams params,
required AccountId accountId,
required VerifyNameInteractor verifyNameInteractor,
}) async { }) async {
return DialogRouter().openDialogModal( return DialogRouter().openDialogModal(
child: CreateNewLabelModal( child: CreateNewLabelModal(
key: const Key('edit_label_modal'), key: const Key('edit_label_modal'),
labels: labels, labels: labels,
accountId: accountId, accountId: params.accountId,
imagePaths: imagePaths, imagePaths: imagePaths,
selectedLabel: selectedLabel, selectedLabel: params.selectedLabel,
actionType: LabelActionType.edit, actionType: LabelActionType.edit,
verifyNameInteractor: verifyNameInteractor, verifyNameInteractor: params.verifyNameInteractor,
createNewLabelInteractor: _createNewLabelInteractor!, createNewLabelInteractor: params.createNewLabelInteractor,
editLabelInteractor: _editLabelInteractor!, editLabelInteractor: params.editLabelInteractor,
), ),
dialogLabel: 'edit-label-modal', dialogLabel: 'edit-label-modal',
); );
@@ -188,18 +185,17 @@ class LabelController extends BaseController
OnLabelActionCallback? onLabelActionCallback, OnLabelActionCallback? onLabelActionCallback,
bool shouldPop = false, bool shouldPop = false,
}) async { }) async {
if (_createNewLabelInteractor == null || _editLabelInteractor == null) { final createNewLabelInteractor = getBinding<CreateNewLabelInteractor>();
_handleCreateNewLabelFailure( final editLabelInteractor = getBinding<EditLabelInteractor>();
failure: CreateNewLabelFailure(const InteractorNotInitialized()),
shouldPop: shouldPop,
);
return;
}
final verifyNameInteractor = getBinding<VerifyNameInteractor>(); final verifyNameInteractor = getBinding<VerifyNameInteractor>();
if (verifyNameInteractor == null) {
final isInteractorsInitialized = createNewLabelInteractor != null &&
editLabelInteractor != null &&
verifyNameInteractor != null;
if (!isInteractorsInitialized) {
_handleCreateNewLabelFailure( _handleCreateNewLabelFailure(
failure: CreateNewLabelFailure(const InteractorNotInitialized()), failure: CreateNewLabelFailure(const InteractorNotInitialized()),
shouldPop: shouldPop,
); );
return; return;
} }
@@ -207,7 +203,6 @@ class LabelController extends BaseController
if (accountId == null) { if (accountId == null) {
_handleCreateNewLabelFailure( _handleCreateNewLabelFailure(
failure: CreateNewLabelFailure(NotFoundAccountIdException()), failure: CreateNewLabelFailure(NotFoundAccountIdException()),
shouldPop: shouldPop,
); );
return; return;
} }
@@ -215,6 +210,8 @@ class LabelController extends BaseController
final resultState = await openCreateNewLabelModal( final resultState = await openCreateNewLabelModal(
accountId: accountId, accountId: accountId,
verifyNameInteractor: verifyNameInteractor, verifyNameInteractor: verifyNameInteractor,
createNewLabelInteractor: createNewLabelInteractor,
editLabelInteractor: editLabelInteractor,
); );
if (resultState is CreateNewLabelSuccess) { if (resultState is CreateNewLabelSuccess) {
@@ -224,10 +221,7 @@ class LabelController extends BaseController
shouldPop: shouldPop, shouldPop: shouldPop,
); );
} else if (resultState is CreateNewLabelFailure) { } else if (resultState is CreateNewLabelFailure) {
_handleCreateNewLabelFailure( _handleCreateNewLabelFailure(failure: resultState);
failure: resultState,
shouldPop: shouldPop,
);
} }
} }
@@ -250,7 +244,6 @@ class LabelController extends BaseController
void _handleCreateNewLabelFailure({ void _handleCreateNewLabelFailure({
required CreateNewLabelFailure failure, required CreateNewLabelFailure failure,
bool shouldPop = false,
}) { }) {
toastManager.showMessageFailure(failure); toastManager.showMessageFailure(failure);
} }
@@ -309,8 +302,6 @@ class LabelController extends BaseController
@override @override
void onClose() { void onClose() {
_getAllLabelInteractor = null; _getAllLabelInteractor = null;
_createNewLabelInteractor = null;
_editLabelInteractor = null;
_deleteALabelInteractor = null; _deleteALabelInteractor = null;
_getLabelSettingStateInteractor = null; _getLabelSettingStateInteractor = null;
_webSocketQueueHandler?.dispose(); _webSocketQueueHandler?.dispose();