Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion lib/features/mailbox/presentation/mailbox_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ class MailboxController extends BaseMailboxController
mailboxDashBoardController.updateRefreshAllMailboxState(Right(RefreshAllMailboxSuccess()));
_handleCreateDefaultFolderIfMissing(mailboxDashBoardController.mapDefaultMailboxIdByRole);
_handleDataFromNavigationRouter();
mailboxDashBoardController.getSpamReportBanner();
mailboxDashBoardController.refreshSpamReportBanner();
if (PlatformInfo.isIOS) {
_updateMailboxIdsBlockNotificationToKeychain(success.mailboxList);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/unread_spa
abstract class SpamReportDataSource {
Future<void> storeLastTimeDismissedSpamReported(DateTime lastTimeDismissedSpamReported);

Future<DateTime> getLastTimeDismissedSpamReported();
Future<int> getLastTimeDismissedSpamReportedMilliseconds();

Future<void> deleteLastTimeDismissedSpamReported();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class HiveSpamReportDataSourceImpl extends SpamReportDataSource {
}

@override
Future<DateTime> getLastTimeDismissedSpamReported() {
Future<int> getLastTimeDismissedSpamReportedMilliseconds() {
throw UnimplementedError();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ class LocalSpamReportDataSourceImpl extends SpamReportDataSource {
);

@override
Future<DateTime> getLastTimeDismissedSpamReported() async {
Future<int> getLastTimeDismissedSpamReportedMilliseconds() async {
return Future.sync(() async {
final spamReportConfig = await _preferencesSettingManager.getSpamReportConfig();
return DateTime.fromMillisecondsSinceEpoch(
spamReportConfig.lastTimeDismissedMilliseconds,
);
return spamReportConfig.lastTimeDismissedMilliseconds;
}).catchError(_exceptionThrower.throwException);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class SpamReportRepositoryImpl extends SpamReportRepository {
SpamReportRepositoryImpl(this.mapDataSource);

@override
Future<DateTime> getLastTimeDismissedSpamReported() async {
return await mapDataSource[DataSourceType.local]!.getLastTimeDismissedSpamReported();
Future<int> getLastTimeDismissedSpamReportedMilliseconds() async {
return await mapDataSource[DataSourceType.local]!.getLastTimeDismissedSpamReportedMilliseconds();
}

@override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import 'package:core/domain/exceptions/app_base_exception.dart';

class NotFoundLastTimeDismissedSpamReportException extends AppBaseException {
NotFoundLastTimeDismissedSpamReportException([super.message]);
class SpamDismissCooldownActiveException extends AppBaseException {
SpamDismissCooldownActiveException([super.message]);

@override
String get exceptionName => 'NotFoundLastTimeDismissedSpamReportException';
String get exceptionName => 'SpamDismissCooldownActiveException';
}

class NotFoundSpamMailboxCachedException extends AppBaseException {
Expand All @@ -20,3 +20,10 @@ class NotFoundSpamMailboxException extends AppBaseException {
@override
String get exceptionName => 'NotFoundSpamMailboxException';
}

class NoUnreadSpamEmailsException extends AppBaseException {
NoUnreadSpamEmailsException([super.message]);

@override
String get exceptionName => 'NoUnreadSpamEmailsException';
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_repor
abstract class SpamReportRepository {
Future<void> storeLastTimeDismissedSpamReported(DateTime lastTimeDismissedSpamReported);

Future<DateTime> getLastTimeDismissedSpamReported();
Future<int> getLastTimeDismissedSpamReportedMilliseconds();

Future<void> deleteLastTimeDismissedSpamReported();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,3 @@ class GetSpamMailboxCachedFailure extends FeatureFailure {

GetSpamMailboxCachedFailure(exception) : super(exception: exception);
}

class InvalidSpamReportCondition extends FeatureFailure {}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@

import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/utils/app_logger.dart';
import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/exceptions/spam_report_exception.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/spam_report_repository.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_spam_mailbox_cached_state.dart';

class GetSpamMailboxCachedInteractor {
static const int spamReportBannerDisplayIntervalInHour = 12;
static const int spamReportBannerDisplayIntervalInHours = 24;

final SpamReportRepository _spamReportRepository;

Expand All @@ -19,25 +19,43 @@ class GetSpamMailboxCachedInteractor {
try {
yield Right<Failure, Success>(GetSpamMailboxCachedLoading());
if (await _validateIntervalToShowBanner()) {
final spamMailbox = await _spamReportRepository.getSpamMailboxCached(accountId, userName);
final spamMailbox = await _spamReportRepository.getSpamMailboxCached(accountId, userName);
final countUnreadSpamMailbox = spamMailbox.unreadEmails?.value.value.toInt() ?? 0;
if (countUnreadSpamMailbox > 0) {
yield Right<Failure, Success>(GetSpamMailboxCachedSuccess(spamMailbox));
} else {
yield Left<Failure, Success>(InvalidSpamReportCondition());
yield Left<Failure, Success>(
GetSpamMailboxCachedFailure(NoUnreadSpamEmailsException()),
);
}
} else {
yield Left<Failure, Success>(InvalidSpamReportCondition());
yield Left<Failure, Success>(
GetSpamMailboxCachedFailure(SpamDismissCooldownActiveException()),
);
}
} catch (e) {
yield Left<Failure, Success>(GetSpamMailboxCachedFailure(e));
}
}

Future<bool> _validateIntervalToShowBanner() async {
final lastTimeDismissedSpamReported = await _spamReportRepository.getLastTimeDismissedSpamReported();
final currentTime = DateTime.now().difference(lastTimeDismissedSpamReported);
log('GetSpamMailboxCachedInteractor::_compareSpamReportTime:lastTimeDismissedSpamReported: $lastTimeDismissedSpamReported | currentTime: $currentTime');
return currentTime.inHours > spamReportBannerDisplayIntervalInHour;
final lastTimeDismissedMs = await _spamReportRepository
.getLastTimeDismissedSpamReportedMilliseconds();

if (lastTimeDismissedMs <= 0) {
return true;
}

final lastTime = DateTime.fromMillisecondsSinceEpoch(lastTimeDismissedMs);
final now = DateTime.now();
final elapsed = now.difference(lastTime);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because elapsed can be negative (user change timezone, ...), so we should check also
if (elapsed.isNegative) return true;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

if (elapsed.isNegative) {
if (elapsed.abs() < const Duration(days: 1)) return false;
return true;
}
final isIntervalElapsed =
elapsed.inHours >= spamReportBannerDisplayIntervalInHours;

return isIntervalElapsed;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2525,24 +2525,6 @@ class MailboxDashBoardController extends ReloadableController

bool get enableSpamReport => spamReportController.enableSpamReport;

void getSpamReportBanner() {
if (enableSpamReport) {
final spamId = spamMailboxId;
if (spamId == null) {
spamReportController.setSpamPresentationMailbox(null);
return;
}

final spamMailbox = mapMailboxById[spamId];
final unreadEmails = spamMailbox?.unreadEmails?.value.value ?? 0;
if (unreadEmails > 0) {
spamReportController.setSpamPresentationMailbox(spamMailbox);
} else {
spamReportController.setSpamPresentationMailbox(null);
}
}
}

void refreshSpamReportBanner() {
if (enableSpamReport && sessionCurrent != null && accountId.value != null) {
spamReportController.getSpamMailboxCached(accountId.value!, sessionCurrent!.username);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/exceptions/spam_report_exception.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_report_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_spam_mailbox_cached_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_spam_report_state.dart';
Expand Down Expand Up @@ -75,7 +76,7 @@ class SpamReportController extends BaseController {
@override
void handleFailureViewState(Failure failure) {
if (failure is GetSpamMailboxCachedFailure) {
presentationSpamMailbox.value = null;
_validateSpamMailboxChanged(failure);
} else if (failure is GetSpamReportStateFailure) {
_spamReportLoaderStatus = LoaderStatus.completed;
} else {
Expand Down Expand Up @@ -147,6 +148,16 @@ class SpamReportController extends BaseController {
presentationSpamMailbox.value = spamMailbox;
}

void _validateSpamMailboxChanged(GetSpamMailboxCachedFailure failure) {
if (failure.exception is NoUnreadSpamEmailsException) {
final currentSpamMailbox = presentationSpamMailbox.value;
if (currentSpamMailbox != null && currentSpamMailbox.countUnreadEmails > 0) {
_storeLastTimeDismissedSpamReportedAction();
}
}
setSpamPresentationMailbox(null);
}

@override
void onClose() {
_appLifecycleListener?.dispose();
Expand Down
Loading
Loading