TF-3123 Fix load more is irrelevant when filtering emails by unread

This commit is contained in:
dab246
2024-09-16 02:21:56 +07:00
committed by Dat H. Pham
parent 7daab0bb1a
commit 47c7cb9ee8
5 changed files with 107 additions and 74 deletions
@@ -1726,18 +1726,24 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
dispatchAction(StartSearchEmailAction()); dispatchAction(StartSearchEmailAction());
} }
bool isEmptyTrashBannerEnabledOnWeb(BuildContext context) { bool isEmptyTrashBannerEnabledOnWeb(
return selectedMailbox.value != null && BuildContext context,
selectedMailbox.value!.isTrash && PresentationMailbox? mailbox
selectedMailbox.value!.countTotalEmails > 0 && ) {
return mailbox != null &&
mailbox.isTrash &&
mailbox.countTotalEmails > 0 &&
!searchController.isSearchActive() && !searchController.isSearchActive() &&
responsiveUtils.isWebDesktop(context); responsiveUtils.isWebDesktop(context);
} }
bool isEmptyTrashBannerEnabledOnMobile(BuildContext context) { bool isEmptyTrashBannerEnabledOnMobile(
return selectedMailbox.value != null && BuildContext context,
selectedMailbox.value!.isTrash && PresentationMailbox? mailbox
selectedMailbox.value!.countTotalEmails > 0 && ) {
return mailbox != null &&
mailbox.isTrash &&
mailbox.countTotalEmails > 0 &&
!searchController.isSearchActive() && !searchController.isSearchActive() &&
!responsiveUtils.isWebDesktop(context); !responsiveUtils.isWebDesktop(context);
} }
@@ -2184,18 +2190,24 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
} }
} }
bool isEmptySpamBannerEnabledOnWeb(BuildContext context) { bool isEmptySpamBannerEnabledOnWeb(
return selectedMailbox.value != null && BuildContext context,
selectedMailbox.value!.isSpam && PresentationMailbox? mailbox
selectedMailbox.value!.countTotalEmails > 0 && ) {
return mailbox != null &&
mailbox.isSpam &&
mailbox.countTotalEmails > 0 &&
!searchController.isSearchActive() && !searchController.isSearchActive() &&
responsiveUtils.isWebDesktop(context); responsiveUtils.isWebDesktop(context);
} }
bool isEmptySpamBannerEnabledOnMobile(BuildContext context) { bool isEmptySpamBannerEnabledOnMobile(
return selectedMailbox.value != null && BuildContext context,
selectedMailbox.value!.isSpam && PresentationMailbox? mailbox
selectedMailbox.value!.countTotalEmails > 0 && ) {
return mailbox != null &&
mailbox.isSpam &&
mailbox.countTotalEmails > 0 &&
!searchController.isSearchActive() && !searchController.isSearchActive() &&
!responsiveUtils.isWebDesktop(context); !responsiveUtils.isWebDesktop(context);
} }
@@ -95,7 +95,8 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
), ),
_buildVacationNotificationMessage(context), _buildVacationNotificationMessage(context),
Obx(() { Obx(() {
if (controller.isEmptyTrashBannerEnabledOnWeb(context)) { final presentationMailbox = controller.selectedMailbox.value;
if (controller.isEmptyTrashBannerEnabledOnWeb(context, presentationMailbox)) {
return Padding( return Padding(
padding: const EdgeInsetsDirectional.only( padding: const EdgeInsetsDirectional.only(
top: BannerEmptyTrashStyles.webTopMargin, top: BannerEmptyTrashStyles.webTopMargin,
@@ -110,7 +111,8 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
} }
}), }),
Obx(() { Obx(() {
if (controller.isEmptySpamBannerEnabledOnWeb(context)) { final presentationMailbox = controller.selectedMailbox.value;
if (controller.isEmptySpamBannerEnabledOnWeb(context, presentationMailbox)) {
return Padding( return Padding(
padding: const EdgeInsetsDirectional.only( padding: const EdgeInsetsDirectional.only(
top: BannerDeleteAllSpamEmailsStyles.webTopMargin, top: BannerDeleteAllSpamEmailsStyles.webTopMargin,
@@ -277,6 +277,9 @@ class ThreadRepositoryImpl extends ThreadRepository {
properties: emailRequest.properties) properties: emailRequest.properties)
.then((response) { .then((response) {
final listEmails = response.emailList; final listEmails = response.emailList;
if (emailRequest.lastEmailId != null && listEmails?.isNotEmpty == true) {
listEmails?.removeWhere((email) => email.id == emailRequest.lastEmailId);
}
return EmailsResponse(emailList: listEmails, state: response.state); return EmailsResponse(emailList: listEmails, state: response.state);
}); });
@@ -1,10 +1,11 @@
import 'dart:async';
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/utils/app_logger.dart'; import 'package:core/utils/app_logger.dart';
import 'package:core/utils/platform_info.dart'; import 'package:core/utils/platform_info.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
@@ -110,6 +111,8 @@ class ThreadController extends BaseController with EmailActionController {
final FocusNode focusNodeKeyBoard = FocusNode(); final FocusNode focusNodeKeyBoard = FocusNode();
final latestEmailSelectedOrUnselected = Rxn<PresentationEmail>(); final latestEmailSelectedOrUnselected = Rxn<PresentationEmail>();
StreamSubscription<html.Event>? _resizeBrowserStreamSubscription;
AccountId? get _accountId => mailboxDashBoardController.accountId.value; AccountId? get _accountId => mailboxDashBoardController.accountId.value;
Session? get _session => mailboxDashBoardController.sessionCurrent; Session? get _session => mailboxDashBoardController.sessionCurrent;
@@ -154,6 +157,9 @@ class ThreadController extends BaseController with EmailActionController {
_currentEmailState = null; _currentEmailState = null;
listEmailController.dispose(); listEmailController.dispose();
focusNodeKeyBoard.dispose(); focusNodeKeyBoard.dispose();
if (PlatformInfo.isWeb) {
_resizeBrowserStreamSubscription?.cancel();
}
super.onClose(); super.onClose();
} }
@@ -230,6 +236,15 @@ class ThreadController extends BaseController with EmailActionController {
super.handleUrgentException(failure: failure, exception: exception); super.handleUrgentException(failure: failure, exception: exception);
} }
@override
void onDone() {
viewState.value.map((success) {
if (success is GetAllEmailSuccess) {
_handleOnDoneGetAllEmailSuccess(success);
}
});
}
void _resetLoadingMore() { void _resetLoadingMore() {
if (loadingMoreStatus.value == LoadingMoreStatus.running) { if (loadingMoreStatus.value == LoadingMoreStatus.running) {
loadingMoreStatus.value = LoadingMoreStatus.idle; loadingMoreStatus.value = LoadingMoreStatus.idle;
@@ -238,7 +253,7 @@ class ThreadController extends BaseController with EmailActionController {
void _registerObxStreamListener() { void _registerObxStreamListener() {
ever(mailboxDashBoardController.selectedMailbox, (mailbox) { ever(mailboxDashBoardController.selectedMailbox, (mailbox) {
log('ThreadController::_registerObxStreamListener:TEST: SelectedMailbox: ${mailbox?.id} - ${mailbox?.name} | CurrentMemoryMailboxId: $_currentMemoryMailboxId'); log('ThreadController::_registerObxStreamListener:SelectedMailbox: ${mailbox?.id} - ${mailbox?.name} | CurrentMemoryMailboxId: $_currentMemoryMailboxId');
if (mailbox is PresentationMailbox if (mailbox is PresentationMailbox
&& mailbox.mailboxId != _currentMemoryMailboxId) { && mailbox.mailboxId != _currentMemoryMailboxId) {
_currentMemoryMailboxId = mailbox.id; _currentMemoryMailboxId = mailbox.id;
@@ -381,23 +396,17 @@ class ThreadController extends BaseController with EmailActionController {
} }
void _registerBrowserResizeListener() { void _registerBrowserResizeListener() {
log('ThreadController::_registerBrowserResizeListener:'); _resizeBrowserStreamSubscription = html.window.onResize.listen((_) {
html.window.onResize.listen((_) => _measureBrowserHeight()); _validateBrowserHeight();
});
} }
void _initialMeasureBrowserHeight() { void _validateBrowserHeight() {
log('ThreadController::_initialMeasureBrowserHeight:');
_measureBrowserHeight();
}
void _measureBrowserHeight() {
final browserInnerHeight = html.window.innerHeight ?? 0; final browserInnerHeight = html.window.innerHeight ?? 0;
log('ThreadController::_measureBrowserHeight: BROWSER_INTER_HEIGHT = $browserInnerHeight');
final currentListEmails = mailboxDashBoardController.emailsInCurrentMailbox; final currentListEmails = mailboxDashBoardController.emailsInCurrentMailbox;
final totalHeightListEmails = currentListEmails.isEmpty final totalHeightListEmails = currentListEmails.isEmpty
? 0 ? 0
: currentListEmails.length * ThreadConstants.defaultMaxHeightEmailItemOnBrowser; : currentListEmails.length * ThreadConstants.defaultMaxHeightEmailItemOnBrowser;
log('ThreadController::_handleResizeBrowser: TOTAL_HEIGHT_LIST_EMAILS = $totalHeightListEmails');
if (browserInnerHeight >= ThreadConstants.defaultMaxHeightBrowser && if (browserInnerHeight >= ThreadConstants.defaultMaxHeightBrowser &&
totalHeightListEmails <= browserInnerHeight) { totalHeightListEmails <= browserInnerHeight) {
_performAutomaticallyLoadMoreEmails(); _performAutomaticallyLoadMoreEmails();
@@ -434,7 +443,7 @@ class ThreadController extends BaseController with EmailActionController {
mailboxDashBoardController.emailsInCurrentMailbox.clear(); mailboxDashBoardController.emailsInCurrentMailbox.clear();
mailboxDashBoardController.listEmailSelected.clear(); mailboxDashBoardController.listEmailSelected.clear();
mailboxDashBoardController.currentSelectMode.value = SelectMode.INACTIVE; mailboxDashBoardController.currentSelectMode.value = SelectMode.INACTIVE;
canLoadMore = false; canLoadMore = true;
loadingMoreStatus.value = LoadingMoreStatus.idle; loadingMoreStatus.value = LoadingMoreStatus.idle;
} }
@@ -457,17 +466,15 @@ class ThreadController extends BaseController with EmailActionController {
canLoadMore = newListEmail.length >= ThreadConstants.maxCountEmails; canLoadMore = newListEmail.length >= ThreadConstants.maxCountEmails;
SchedulerBinding.instance.addPostFrameCallback((_) { if (listEmailController.hasClients) {
if (listEmailController.hasClients) { listEmailController.jumpTo(0);
listEmailController.animateTo( }
0, }
duration: const Duration(milliseconds: 500),
curve: Curves.fastOutSlowIn); void _handleOnDoneGetAllEmailSuccess(GetAllEmailSuccess success) {
} if (PlatformInfo.isWeb) {
if (PlatformInfo.isWeb) { _validateBrowserHeight();
_initialMeasureBrowserHeight(); }
}
});
} }
void _refreshChangesAllEmailSuccess(RefreshChangesAllEmailSuccess success) { void _refreshChangesAllEmailSuccess(RefreshChangesAllEmailSuccess success) {
@@ -494,11 +501,12 @@ class ThreadController extends BaseController with EmailActionController {
if (mailboxDashBoardController.emailsInCurrentMailbox.isEmpty) { if (mailboxDashBoardController.emailsInCurrentMailbox.isEmpty) {
refreshAllEmail(); refreshAllEmail();
} else if (PlatformInfo.isWeb) { } else if (PlatformInfo.isWeb) {
_initialMeasureBrowserHeight(); _validateBrowserHeight();
} }
} }
void _getAllEmailAction() { void _getAllEmailAction() {
log('ThreadController::_getAllEmailAction:');
if (_session != null &&_accountId != null) { if (_session != null &&_accountId != null) {
consumeState(_getEmailsInMailboxInteractor.execute( consumeState(_getEmailsInMailboxInteractor.execute(
_session!, _session!,
@@ -598,11 +606,12 @@ class ThreadController extends BaseController with EmailActionController {
} }
void _loadMoreEmails() { void _loadMoreEmails() {
log('ThreadController::_loadMoreEmails()'); log('ThreadController::_loadMoreEmails()::canLoadMore = $canLoadMore');
if (canLoadMore && _session != null && _accountId != null) { if (canLoadMore && _session != null && _accountId != null) {
final oldestEmail = mailboxDashBoardController.emailsInCurrentMailbox.isNotEmpty final oldestEmail = mailboxDashBoardController.emailsInCurrentMailbox.isNotEmpty
? mailboxDashBoardController.emailsInCurrentMailbox.last ? mailboxDashBoardController.emailsInCurrentMailbox.last
: null; : null;
log('ThreadController::_loadMoreEmails: OldestEmailID = ${oldestEmail?.id?.asString}');
consumeState(_loadMoreEmailsInMailboxInteractor.execute( consumeState(_loadMoreEmailsInMailboxInteractor.execute(
GetEmailRequest( GetEmailRequest(
_session!, _session!,
@@ -619,8 +628,13 @@ class ThreadController extends BaseController with EmailActionController {
} }
} }
bool _validatePresentationEmail(PresentationEmail email) {
return _belongToCurrentMailboxId(email)
&& _notDuplicatedInCurrentList(email);
}
bool _belongToCurrentMailboxId(PresentationEmail email) { bool _belongToCurrentMailboxId(PresentationEmail email) {
return (email.mailboxIds != null && email.mailboxIds!.keys.contains(selectedMailboxId)); return email.mailboxIds != null && email.mailboxIds!.keys.contains(selectedMailboxId);
} }
bool _notDuplicatedInCurrentList(PresentationEmail email) { bool _notDuplicatedInCurrentList(PresentationEmail email) {
@@ -630,29 +644,31 @@ class ThreadController extends BaseController with EmailActionController {
} }
void _loadMoreEmailsSuccess(LoadMoreEmailsSuccess success) { void _loadMoreEmailsSuccess(LoadMoreEmailsSuccess success) {
log('ThreadController::_loadMoreEmailsSuccess: COUNT = ${success.emailList.length}'); canLoadMore = success.emailList.isNotEmpty;
if (success.emailList.isNotEmpty) {
final appendableList = success.emailList
.where(_belongToCurrentMailboxId)
.where(_notDuplicatedInCurrentList)
.toList()
.syncPresentationEmail(
mapMailboxById: mailboxDashBoardController.mapMailboxById,
selectedMailbox: selectedMailbox,
searchQuery: searchController.searchQuery,
isSearchEmailRunning: searchController.isSearchEmailRunning
);
mailboxDashBoardController.emailsInCurrentMailbox.addAll(appendableList);
canLoadMore = true;
} else {
canLoadMore = false;
}
loadingMoreStatus.value = LoadingMoreStatus.completed; loadingMoreStatus.value = LoadingMoreStatus.completed;
final appendableList = validateListEmailsLoadMore(success.emailList);
if (PlatformInfo.isWeb) { log('ThreadController::_loadMoreEmailsSuccess: emailList = ${success.emailList.length} | appendableList = ${appendableList.length}');
_initialMeasureBrowserHeight(); if (appendableList.isNotEmpty) {
mailboxDashBoardController.emailsInCurrentMailbox.addAll(appendableList);
} }
if (PlatformInfo.isWeb) {
_validateBrowserHeight();
}
}
List<PresentationEmail> validateListEmailsLoadMore(List<PresentationEmail> emailList) {
log('ThreadController::validateListEmailsLoadMore: BEFORE_EMAIL_LIST = ${emailList.length}');
final appendableList = emailList
.where(_validatePresentationEmail)
.toList()
.syncPresentationEmail(
mapMailboxById: mailboxDashBoardController.mapMailboxById,
selectedMailbox: selectedMailbox,
searchQuery: searchController.searchQuery,
isSearchEmailRunning: searchController.isSearchEmailRunning
);
log('ThreadController::validateListEmailsLoadMore: AFTER_EMAIL_LIST = ${appendableList.length}');
return appendableList;
} }
SelectMode getSelectMode(PresentationEmail presentationEmail, PresentationEmail? selectedEmail) { SelectMode getSelectMode(PresentationEmail presentationEmail, PresentationEmail? selectedEmail) {
@@ -787,9 +803,6 @@ class ThreadController extends BaseController with EmailActionController {
bool get isSearchActive => searchController.isSearchEmailRunning; bool get isSearchActive => searchController.isSearchEmailRunning;
bool get isAllSearchInActive => !searchController.isSearchActive() &&
searchController.isAdvancedSearchViewOpen.isFalse;
void clearTextSearch() { void clearTextSearch() {
searchController.clearTextSearch(); searchController.clearTextSearch();
} }
@@ -870,7 +883,7 @@ class ThreadController extends BaseController with EmailActionController {
canSearchMore = newEmailListSynced.length >= ThreadConstants.maxCountEmails; canSearchMore = newEmailListSynced.length >= ThreadConstants.maxCountEmails;
if (PlatformInfo.isWeb) { if (PlatformInfo.isWeb) {
_initialMeasureBrowserHeight(); _validateBrowserHeight();
} }
} }
@@ -929,7 +942,7 @@ class ThreadController extends BaseController with EmailActionController {
loadingMoreStatus.value = LoadingMoreStatus.completed; loadingMoreStatus.value = LoadingMoreStatus.completed;
if (PlatformInfo.isWeb) { if (PlatformInfo.isWeb) {
_initialMeasureBrowserHeight(); _validateBrowserHeight();
} }
} }
@@ -143,7 +143,8 @@ class ThreadView extends GetWidget<ThreadController>
)), )),
], ],
Obx(() { Obx(() {
if (controller.mailboxDashBoardController.isEmptyTrashBannerEnabledOnMobile(context)) { final presentationMailbox = controller.mailboxDashBoardController.selectedMailbox.value;
if (controller.mailboxDashBoardController.isEmptyTrashBannerEnabledOnMobile(context, presentationMailbox)) {
return Padding( return Padding(
padding: const EdgeInsetsDirectional.symmetric( padding: const EdgeInsetsDirectional.symmetric(
horizontal: BannerEmptyTrashStyles.mobileMargin horizontal: BannerEmptyTrashStyles.mobileMargin
@@ -157,7 +158,8 @@ class ThreadView extends GetWidget<ThreadController>
} }
}), }),
Obx(() { Obx(() {
if (controller.mailboxDashBoardController.isEmptySpamBannerEnabledOnMobile(context)) { final presentationMailbox = controller.mailboxDashBoardController.selectedMailbox.value;
if (controller.mailboxDashBoardController.isEmptySpamBannerEnabledOnMobile(context, presentationMailbox)) {
return Padding( return Padding(
padding: const EdgeInsetsDirectional.symmetric( padding: const EdgeInsetsDirectional.symmetric(
horizontal: BannerDeleteAllSpamEmailsStyles.mobileMargin horizontal: BannerDeleteAllSpamEmailsStyles.mobileMargin
@@ -305,7 +307,8 @@ class ThreadView extends GetWidget<ThreadController>
} }
return Obx(() { return Obx(() {
if (controller.isAllSearchInActive) { final isAdvancedSearchViewOpen = controller.searchController.isAdvancedSearchViewOpen.value;
if (controller.searchController.isSearchActive() && !isAdvancedSearchViewOpen) {
return Container( return Container(
padding: PlatformInfo.isMobile && controller.listEmailSelected.isNotEmpty padding: PlatformInfo.isMobile && controller.listEmailSelected.isNotEmpty
? EdgeInsets.only(bottom: controller.responsiveUtils.isTabletLarge(context) ? 85 : 70) ? EdgeInsets.only(bottom: controller.responsiveUtils.isTabletLarge(context) ? 85 : 70)