TF-3699 Thread Detail Next previous actions (#3843)

This commit is contained in:
Dat Dang
2025-07-16 17:15:17 +07:00
committed by Dat H. Pham
parent 4d9a44df66
commit 7332b731dc
28 changed files with 581 additions and 241 deletions
@@ -1,3 +1,4 @@
import 'package:debounce_throttle/debounce_throttle.dart';
import 'package:flutter/material.dart';
import 'dart:async';
@@ -38,20 +39,17 @@ import 'package:tmail_ui_user/features/network_connection/presentation/network_c
import 'package:tmail_ui_user/features/search/email/presentation/search_email_controller.dart';
import 'package:tmail_ui_user/features/thread_detail/domain/state/get_thread_by_id_state.dart';
import 'package:tmail_ui_user/features/thread_detail/domain/state/get_emails_by_ids_state.dart';
import 'package:tmail_ui_user/features/thread_detail/domain/state/get_thread_detail_status_state.dart';
import 'package:tmail_ui_user/features/thread_detail/domain/usecases/get_thread_by_id_interactor.dart';
import 'package:tmail_ui_user/features/thread_detail/domain/usecases/get_emails_by_ids_interactor.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/action/thread_detail_ui_action.dart';
import 'package:tmail_ui_user/features/thread_detail/domain/usecases/get_thread_detail_status_interactor.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/handle_email_moved_action.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/handle_get_email_ids_by_thread_id_success.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/handle_get_emails_by_ids_success.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/handle_get_thread_by_id_failure.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/handle_refresh_thread_detail_action.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/initialize_thread_detail_emails.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/refresh_thread_detail_on_setting_changed.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/thread_detail_on_selected_email_updated.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/model/thread_detail_setting_status.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_manager.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/handle_collapsed_email_download_states.dart';
@@ -60,7 +58,6 @@ import 'package:tmail_ui_user/features/thread_detail/presentation/extension/mark
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/quick_create_rule_from_collapsed_email_success.dart';
class ThreadDetailController extends BaseController {
final GetThreadDetailStatusInteractor _getThreadDetailStatusInteractor;
final GetThreadByIdInteractor _getEmailIdsByThreadIdInteractor;
final GetEmailsByIdsInteractor getEmailsByIdsInteractor;
final MarkAsEmailReadInteractor _markAsEmailReadInteractor;
@@ -70,7 +67,6 @@ class ThreadDetailController extends BaseController {
final DownloadAttachmentForWebInteractor _downloadAttachmentForWebInteractor;
ThreadDetailController(
this._getThreadDetailStatusInteractor,
this._getEmailIdsByThreadIdInteractor,
this.getEmailsByIdsInteractor,
this._markAsEmailReadInteractor,
@@ -90,18 +86,34 @@ class ThreadDetailController extends BaseController {
IndividualHeaderIdentifier.listUnsubscribeHeader.value,
});
final cachedEmailLoaded = <EmailId, EmailLoaded>{};
late final _threadGetDebouncer = Debouncer<ThreadId?>(
const Duration(milliseconds: 500),
initialValue: null,
checkEquality: true,
onChanged: (threadId) {
if (_validateLoadThread(threadId)) {
consumeState(_getEmailIdsByThreadIdInteractor.execute(
threadId!,
session!,
accountId!,
sentMailboxId!,
ownEmailAddress!,
selectedEmailId: mailboxDashBoardController.selectedEmail.value?.id,
));
}
},
);
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
final searchEmailController = Get.find<SearchEmailController>();
final networkConnectionController = Get.find<NetworkConnectionController>();
final threadDetailManager = Get.find<ThreadDetailManager>();
final downloadManager = Get.find<DownloadManager>();
final downloadProgressState = StreamController<Either<Failure, Success>>();
ScrollController? scrollController;
CreateNewEmailRuleFilterInteractor? _createNewEmailRuleFilterInteractor;
AppLifecycleListener? appLifecycleListener;
ThreadDetailSettingStatus threadDetailSettingStatus = ThreadDetailSettingStatus.loading;
bool threadDetailWasEnabled = true;
bool loadThreadOnThreadChanged = false;
AccountId? get accountId => mailboxDashBoardController.accountId.value;
Session? get session => mailboxDashBoardController.sessionCurrent;
@@ -121,21 +133,11 @@ class ThreadDetailController extends BaseController {
bool get networkConnected =>
networkConnectionController.isNetworkConnectionAvailable();
bool get isThreadDetailEnabled =>
threadDetailSettingStatus == ThreadDetailSettingStatus.enabled;
threadDetailManager.isThreadDetailEnabled;
@override
void onInit() {
super.onInit();
consumeState(_getThreadDetailStatusInteractor.execute());
appLifecycleListener = AppLifecycleListener(
onResume: () {
if (threadDetailSettingStatus == ThreadDetailSettingStatus.loading) {
return;
}
consumeState(_getThreadDetailStatusInteractor.execute());
},
);
ever(mailboxDashBoardController.accountId, (accountId) {
if (accountId == null) return;
@@ -172,22 +174,10 @@ class ThreadDetailController extends BaseController {
})
..listUnsubscribeHeader?.clear();
}
} else if (action is UpdatedThreadDetailSettingAction) {
consumeState(_getThreadDetailStatusInteractor.execute());
} else if (action is EmailMovedAction) {
handleEmailMovedAction(action);
} else if (action is LoadThreadDetailAfterSelectedEmailAction) {
if (_validateLoadThread(action)) {
scrollController = ScrollController();
consumeState(_getEmailIdsByThreadIdInteractor.execute(
action.threadId,
session!,
accountId!,
sentMailboxId!,
ownEmailAddress!,
selectedEmailId: mailboxDashBoardController.selectedEmail.value?.id,
));
}
_threadGetDebouncer.value = action.threadId;
}
// Reset [threadDetailUIAction] to original value
mailboxDashBoardController.dispatchThreadDetailUIAction(
@@ -205,9 +195,9 @@ class ThreadDetailController extends BaseController {
});
}
bool _validateLoadThread(LoadThreadDetailAfterSelectedEmailAction action) {
bool _validateLoadThread(ThreadId? threadId) {
return mailboxDashBoardController.selectedEmail.value?.threadId != null &&
action.threadId == mailboxDashBoardController.selectedEmail.value?.threadId &&
threadId == mailboxDashBoardController.selectedEmail.value?.threadId &&
session != null &&
accountId != null &&
sentMailboxId != null &&
@@ -223,6 +213,7 @@ class ThreadDetailController extends BaseController {
currentExpandedEmailId.value = null;
currentEmailLoaded.value = null;
cachedEmailLoaded.clear();
_threadGetDebouncer.value = null;
}
@override
@@ -240,13 +231,6 @@ class ThreadDetailController extends BaseController {
quickCreateRuleFromCollapsedEmailSuccess(success);
} else if (success is DownloadAttachmentForWebSuccess) {
handleDownloadSuccess(success);
} else if (success is GetThreadDetailStatusSuccess) {
threadDetailSettingStatus = success.threadDetailEnabled
? ThreadDetailSettingStatus.enabled
: ThreadDetailSettingStatus.disabled;
refreshThreadDetailOnSettingChanged();
} else if (success is GettingThreadDetailStatus) {
threadDetailSettingStatus = ThreadDetailSettingStatus.loading;
} else {
super.handleSuccessViewState(success);
}
@@ -266,10 +250,6 @@ class ThreadDetailController extends BaseController {
handleDownloadFailure(failure);
return;
}
if (failure is GetThreadDetailStatusFailure) {
threadDetailSettingStatus = ThreadDetailSettingStatus.enabled;
refreshThreadDetailOnSettingChanged();
}
if (failure is PrintEmailFailure) {
if (currentOverlayContext != null && currentContext != null) {
appToast.showToastErrorMessage(