TF-1362: [Presentation] : Implement StoreLastTimeDismissed and show detail for spam report banner

This commit is contained in:
HuyNguyen
2023-01-13 12:45:30 +07:00
committed by Dat Vu
parent 46b50842ce
commit cd04a1b8d0
22 changed files with 335 additions and 225 deletions
@@ -269,6 +269,8 @@ class MailboxController extends BaseMailboxController {
refreshMailboxChanges();
}
mailboxDashBoardController.clearMailboxUIAction();
} else if (action is OpenSpamMailboxAction){
openMailbox(action.context, action.presentationMailbox);
}
});
}
@@ -6,11 +6,11 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/share_prefer
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/unread_spam_emails_response.dart';
import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart';
class LocalSpamReportDataSourceImpl extends SpamReportDataSource {
class SharePreferenceSpamReportDataSourceImpl extends SpamReportDataSource {
final SharePreferenceSpamReportDataSource _sharePreferenceSpamReportDataSource;
final ExceptionThrower _exceptionThrower;
LocalSpamReportDataSourceImpl(this._sharePreferenceSpamReportDataSource, this._exceptionThrower);
SharePreferenceSpamReportDataSourceImpl(this._sharePreferenceSpamReportDataSource, this._exceptionThrower);
@override
Future<DateTime> getLastTimeDismissedSpamReported() async {
return Future.sync(() async {
@@ -27,7 +27,7 @@ class SpamReportDataSourceImpl extends SpamReportDataSource {
}
) {
return Future.sync(() async {
final _unreadSpamEmailsResponse = await _spamReportApi.findNumberOfUnreadSpamEmails(
final _unreadSpamEmailsResponse = await _spamReportApi.getUnreadSpamEmailbox(
accountId, mailboxFilterCondition: mailboxFilterCondition, limit: limit);
return _unreadSpamEmailsResponse;
}).catchError((error) {
@@ -20,7 +20,7 @@ class SharePreferenceSpamReportDataSource extends SpamReportDataSource {
@override
Future<bool> storeLastTimeDismissedSpamReported(DateTime lastTimeDismissedSpamReported) async {
final _timeStamp = lastTimeDismissedSpamReported.microsecondsSinceEpoch;
final _timeStamp = lastTimeDismissedSpamReported.millisecondsSinceEpoch;
return await _sharedPreferences.setInt(MailboxDashboardConstant.keyLastTimeDismissedSpamReported,_timeStamp);
}
@@ -1,4 +1,3 @@
import 'package:jmap_dart_client/http/http_client.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/request/reference_path.dart';
@@ -12,10 +11,11 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/unread_spa
class SpamReportApi {
final HttpClient _httpClient;
static const int _deafaultLimit = 1;
SpamReportApi(this._httpClient);
Future<UnreadSpamEmailsResponse> findNumberOfUnreadSpamEmails(
Future<UnreadSpamEmailsResponse> getUnreadSpamEmailbox(
AccountId accountId,
{
MailboxFilterCondition? mailboxFilterCondition,
@@ -24,11 +24,11 @@ class SpamReportApi {
) async {
final processingInvocation = ProcessingInvocation();
final requestBuilder = JmapRequestBuilder(_httpClient, processingInvocation);
final spamReportQueryMethod = QueryMailboxMethod(accountId)..addLimit(limit ?? UnsignedInt(_deafaultLimit));
final spamReportQueryMethod = QueryMailboxMethod(accountId)..addLimit(limit ?? UnsignedInt(1));
if(mailboxFilterCondition != null) spamReportQueryMethod.addFilters(mailboxFilterCondition);
final spamReportQueryMethodInvocation = requestBuilder.invocation(spamReportQueryMethod);
final getMailBoxMethod = GetMailboxMethod(accountId)
..addReferenceIds(processingInvocation.createResultReference(
spamReportQueryMethodInvocation.methodCallId,
@@ -42,11 +42,10 @@ class SpamReportApi {
final _mailboxResponse = result
.parse<GetMailboxResponse>(getMailboxInvocation.methodCallId, GetMailboxResponse.deserialize);
final _unreadSpamEmailNumber = _mailboxResponse?.list.first.unreadEmails?.value.value.toInt();
return Future.sync(() async {
return UnreadSpamEmailsResponse(unreadSpamEmailNumber: _unreadSpamEmailNumber);
final _unreadSpamMailbox = _mailboxResponse?.list.first;
return UnreadSpamEmailsResponse(unreadSpamMailbox: _unreadSpamMailbox);
}).catchError((error) {
throw error;
});
@@ -27,7 +27,7 @@ class SpamReportRepositoryImpl extends SpamReportRepository {
}
@override
Future<UnreadSpamEmailsResponse> findNumberOfUnreadSpamEmails(
Future<UnreadSpamEmailsResponse> getUnreadSpamMailbox(
AccountId accountId,
{
MailboxFilterCondition? mailboxFilterCondition,
@@ -35,6 +35,8 @@ class SpamReportRepositoryImpl extends SpamReportRepository {
}
) {
return mapDataSource[DataSourceType.network]!.findNumberOfUnreadSpamEmails(
accountId, mailboxFilterCondition: mailboxFilterCondition, limit: limit);
accountId,
mailboxFilterCondition: mailboxFilterCondition,
limit: limit);
}
}
@@ -1,13 +1,14 @@
import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
class UnreadSpamEmailsResponse with EquatableMixin {
final int? unreadSpamEmailNumber;
final Mailbox? unreadSpamMailbox;
UnreadSpamEmailsResponse({
this.unreadSpamEmailNumber,
this.unreadSpamMailbox,
});
@override
List<Object?> get props => [unreadSpamEmailNumber];
List<Object?> get props => [unreadSpamMailbox];
}
@@ -10,7 +10,7 @@ abstract class SpamReportRepository {
Future<void> deleteLastTimeDismissedSpamReported();
Future<UnreadSpamEmailsResponse> findNumberOfUnreadSpamEmails(
Future<UnreadSpamEmailsResponse> getUnreadSpamMailbox(
AccountId accountId,
{
MailboxFilterCondition? mailboxFilterCondition,
@@ -1,15 +1,16 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
class GetNumberOfUnreadSpamEmailsLoading extends UIState {}
class GetUnreadSpamMailboxLoading extends UIState {}
class GetNumberOfUnreadSpamEmailsSuccess extends UIState {
final int unreadSpamEmailNumber;
class GetUnreadSpamMailboxSuccess extends UIState {
final Mailbox unreadSpamMailbox;
GetNumberOfUnreadSpamEmailsSuccess(this.unreadSpamEmailNumber);
GetUnreadSpamMailboxSuccess(this.unreadSpamMailbox);
@override
List<Object> get props => [unreadSpamEmailNumber];
List<Object> get props => [unreadSpamMailbox];
}
class InvalidSpamReportCondition extends FeatureFailure {
@@ -17,10 +18,10 @@ class InvalidSpamReportCondition extends FeatureFailure {
List<Object?> get props => [];
}
class GetNumberOfUnreadSpamEmailsFailure extends FeatureFailure {
class GetUnreadSpamMailboxFailure extends FeatureFailure {
final dynamic exception;
GetNumberOfUnreadSpamEmailsFailure(this.exception);
GetUnreadSpamMailboxFailure(this.exception);
@override
List<Object> get props => [exception];
@@ -8,11 +8,11 @@ import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox_filter_condition.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_number_of_unread_spam_emails_state.dart';
class GetNumberOfUnreadSpamEmails {
class GetUnreadSpamMailboxInteractor {
static const int conditionsForDisplayingSpamReportBanner = 4;
final SpamReportRepository _spamReportRepository;
GetNumberOfUnreadSpamEmails(this._spamReportRepository);
GetUnreadSpamMailboxInteractor(this._spamReportRepository);
Stream<Either<Failure, Success>> execute(
AccountId accountId,
@@ -22,22 +22,22 @@ class GetNumberOfUnreadSpamEmails {
}
) async* {
try {
yield Right(GetNumberOfUnreadSpamEmailsLoading());
yield Right(GetUnreadSpamMailboxLoading());
final _lastTimeDissmissedSpamReported = await _spamReportRepository.getLastTimeDismissedSpamReported();
final _timeLast = DateTime.now().difference(_lastTimeDissmissedSpamReported);
final _checkTimeCondition = (_lastTimeDissmissedSpamReported.hour - DateTime.now().hour) > conditionsForDisplayingSpamReportBanner;
final _checkTimeCondition = (_timeLast.inHours > 0) && (_timeLast.inHours > conditionsForDisplayingSpamReportBanner);
if (_checkTimeCondition) {
final _response = await _spamReportRepository.findNumberOfUnreadSpamEmails(accountId, mailboxFilterCondition: mailboxFilterCondition, limit: limit);
final _unreadSpamEmailNumber = _response.unreadSpamEmailNumber ?? 0;
final _response = await _spamReportRepository.getUnreadSpamMailbox(accountId, mailboxFilterCondition: mailboxFilterCondition, limit: limit);
final _unreadSpamMailbox = _response.unreadSpamMailbox;
yield Right(GetNumberOfUnreadSpamEmailsSuccess(_unreadSpamEmailNumber));
yield Right(GetUnreadSpamMailboxSuccess(_unreadSpamMailbox!));
} else {
yield Left(InvalidSpamReportCondition());
}
} catch (e) {
yield Left(GetNumberOfUnreadSpamEmailsFailure(e));
yield Left(GetUnreadSpamMailboxFailure(e));
}
}
}
@@ -2,6 +2,7 @@
import 'package:flutter/cupertino.dart';
import 'package:model/email/email_action_type.dart';
import 'package:model/email/presentation_email.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
import 'package:tmail_ui_user/main/routes/navigation_router.dart';
@@ -123,4 +124,14 @@ class SearchEmailByQueryAction extends DashBoardAction {
@override
List<Object?> get props => [navigationRouter];
}
class OpenSpamMailboxAction extends DashBoardAction {
final BuildContext context;
final PresentationMailbox presentationMailbox;
OpenSpamMailboxAction(this.context, this.presentationMailbox);
@override
List<Object?> get props => [context, presentationMailbox];
}
@@ -58,10 +58,12 @@ import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_controller.d
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/search_datasource.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/session_storage_composer_datasource.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/spam_report_datasource.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/local_spam_report_datasource_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/share_preference_spam_report_data_source_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/search_datasource_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/session_storage_composer_datasoure_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/spam_report_datasource_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/share_preference_spam_report_data_source.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/network/spam_report_api.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/repository/composer_cache_repository_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/repository/search_repository_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/repository/spam_report_repository_impl.dart';
@@ -71,11 +73,13 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/spam_
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_all_recent_search_latest_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_app_dashboard_configuration_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_composer_cache_on_web_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_unread_spam_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/quick_search_email_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_on_web_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_composer_cache_on_web_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/save_recent_search_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_last_time_dismissed_spam_reported_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/advanced_filter_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/download/download_controller.dart';
@@ -127,7 +131,11 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.find<SaveRecentSearchInteractor>(),
Get.find<GetAllRecentSearchLatestInteractor>(),
));
Get.put(SpamReportController());
Get.put(SpamReportController(
Get.find<StoreSpamReportInteractor>(),
Get.find<GetUnreadSpamMailboxInteractor>(),
));
Get.put(MailboxDashBoardController(
Get.find<LogoutOidcInteractor>(),
Get.find<DeleteAuthorityOidcInteractor>(),
@@ -160,7 +168,7 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.lazyPut<AccountDatasource>(() => Get.find<HiveAccountDatasourceImpl>());
Get.lazyPut<AuthenticationOIDCDataSource>(() => Get.find<AuthenticationOIDCDataSourceImpl>());
Get.lazyPut<SessionStorageComposerDatasource>(() => Get.find<SessionStorageComposerDatasourceImpl>());
Get.lazyPut<SpamReportDataSource>(() => Get.find<LocalSpamReportDataSourceImpl>());
Get.lazyPut<SpamReportDataSource>(() => Get.find<SpamReportDataSourceImpl>());
}
@override
@@ -199,7 +207,11 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.find<RemoteExceptionThrower>(),
));
Get.lazyPut(() => SessionStorageComposerDatasourceImpl());
Get.lazyPut(() => LocalSpamReportDataSourceImpl(
Get.lazyPut(() => SpamReportDataSourceImpl(
Get.find<SpamReportApi>(),
Get.find<RemoteExceptionThrower>(),
));
Get.lazyPut(() => SharePreferenceSpamReportDataSourceImpl(
Get.find<SharePreferenceSpamReportDataSource>(),
Get.find<CacheExceptionThrower>(),
));
@@ -271,6 +283,10 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.lazyPut(() => GetEmailByIdInteractor(
Get.find<ThreadRepository>()));
Get.lazyPut(() => UpdateAuthenticationAccountInteractor(Get.find<AccountRepository>()));
Get.lazyPut(() => StoreSpamReportInteractor(
Get.find<SpamReportRepository>()));
Get.lazyPut(() => GetUnreadSpamMailboxInteractor(
Get.find<SpamReportRepository>()));
}
@override
@@ -314,7 +330,7 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.lazyPut(() => SpamReportRepositoryImpl(
{
DataSourceType.network: Get.find<SpamReportDataSource>(),
DataSourceType.local: Get.find<LocalSpamReportDataSourceImpl>()
DataSourceType.local: Get.find<SharePreferenceSpamReportDataSourceImpl>()
},
));
}
@@ -416,6 +416,7 @@ class MailboxDashBoardController extends ReloadableController {
} else {
dispatchRoute(DashboardRoutes.thread);
}
spamReportController.getUnreadSpamMailboxAction(accountId.value!);
} else {
dispatchRoute(DashboardRoutes.thread);
reload();
@@ -1520,6 +1521,10 @@ class MailboxDashBoardController extends ReloadableController {
void updateEmailList(List<PresentationEmail> newEmailList) {
emailsInCurrentMailbox.value = newEmailList;
}
void openSpamMailboxAction(BuildContext context, PresentationMailbox presentationMailbox){
dispatchAction(OpenSpamMailboxAction(context, presentationMailbox));
}
@override
void onClose() {
@@ -1,14 +1,64 @@
import 'package:get/get_rx/get_rx.dart';
import 'package:core/utils/app_logger.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox_filter_condition.dart';
import 'package:model/extensions/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_dashboard/domain/state/get_number_of_unread_spam_emails_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/store_last_time_dismissed_spam_reported_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_unread_spam_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/store_last_time_dismissed_spam_reported_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
class SpamReportController extends BaseController {
final StoreSpamReportInteractor _storeSpamReportInteractor;
final GetUnreadSpamMailboxInteractor _getNumberOfUnreadSpamEmailsInteractor;
final dismissedSpamReported = RxBool(false);
final _presentationSpamMailbox = Rxn<PresentationMailbox>();
SpamReportController(this._storeSpamReportInteractor, this._getNumberOfUnreadSpamEmailsInteractor);
@override
void onDone() {}
void onDone() {
viewState.value.fold(
(failure) {
logError('SpamReportController::onDone(): failure: $failure');
},
(success) {
if(success is GetUnreadSpamMailboxSuccess){
_presentationSpamMailbox.value = success.unreadSpamMailbox.toPresentationMailbox();
log('SpamReportController::GetNumberOfUnreadSpamEmailsSuccess():success $success');
} else if(success is StoreLastTimeDismissedSpamReportSuccess){
_presentationSpamMailbox.value = null;
log('SpamReportController::StoreLastTimeDismissedSpamReportSuccess():success $success');
}
},
);
}
void dismissSpamReportAction() {
dismissedSpamReported.value = true;
_storeLastTimeDismissedSpamReportedAction();
}
void getUnreadSpamMailboxAction(AccountId accountId){
final _mailboxFilterCondition = MailboxFilterCondition(role: Role('Spam'));
consumeState(_getNumberOfUnreadSpamEmailsInteractor.execute(accountId,mailboxFilterCondition: _mailboxFilterCondition));
}
void _storeLastTimeDismissedSpamReportedAction() {
consumeState(_storeSpamReportInteractor.execute(DateTime.now()));
}
bool get notShowSpamReportBanner => _presentationSpamMailbox.value == null;
int get numberOfUnreadSpamEmails => (_presentationSpamMailbox.value?.unreadEmails?.value.value ?? 0).toInt();
void openMailbox(BuildContext context) {
final _mailboxDashBoardController = Get.find<MailboxDashBoardController>();
dismissSpamReportAction();
_mailboxDashBoardController.openSpamMailboxAction(context, _presentationSpamMailbox.value!);
}
}
@@ -22,6 +22,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/ad
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/advanced_search/icon_open_advanced_search_widget.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/download/download_task_item_widget.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/search_input_form_widget.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/spam_report_banner_web_widget.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/top_bar_thread_selection.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart';
@@ -42,7 +43,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
final SearchController searchController = Get.find<SearchController>();
final AppGridDashboardController appGridDashboardController = Get.find<AppGridDashboardController>();
final mailBoxDashboardController = Get.find<MailboxDashBoardController>();
final spamReportController = Get.find<SpamReportController>();
final SpamReportController spamReportController = Get.find<SpamReportController>();
@override
Widget build(BuildContext context) {
@@ -107,7 +108,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
children: [
SizedBox(child: MailboxView(), width: responsiveUtils.defaultSizeMenu),
Expanded(child: Column(children: [
_buildSpamReportBoxWebWidget(context),
const SpamReportBannerWebWidget(),
_buildEmptyTrashButton(context),
const QuotasWarningBannerWidget(
margin: EdgeInsets.only(right: 16, top: 8),
@@ -695,76 +696,4 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
}
});
}
Widget _buildSpamReportBoxWebWidget(BuildContext context) {
return Obx(() {
if (spamReportController.dismissedSpamReported.value) {
return const SizedBox(
height: 8,
);
}
return Container(
height: 84,
margin: const EdgeInsets.only(right: 16, top: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColor.colorBorderBodyThread, width: 1),
color: AppColor.colorSpamReportBox.withOpacity(0.12)),
child: Stack(
alignment: AlignmentDirectional.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
SvgPicture.asset(
imagePaths.icInfoCircleOutline,
width: 28,
height: 28,
color: AppColor.primaryColor,
),
const SizedBox(
width: 8,
),
Text(
AppLocalizations.of(context).countNewSpamEmails(5),
style: const TextStyle(
fontSize: 16,
color: AppColor.primaryColor,
fontWeight: FontWeight.w500),
),
],
),
Padding(
padding: const EdgeInsets.only(
left: 32,
),
child: buildTextButton(
AppLocalizations.of(context).showDetails,
height: 36,
width: 115,
textStyle: const TextStyle(
fontSize: 15,
color: AppColor.primaryColor,
fontWeight: FontWeight.w400),
backgroundColor: AppColor.colorCreateNewIdentityButton,
radius: 10,
),
),
],
),
Positioned(
top: 16,
right: 16,
child: buildSVGIconButton(
icon: imagePaths.icCloseComposer,
onTap: () => spamReportController.dismissSpamReportAction(),
),
),
],
),
);
});
}
}
@@ -0,0 +1,87 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/spam_report_controller.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class SpamReportBannerWebWidget extends StatelessWidget {
const SpamReportBannerWebWidget({ Key? key }) : super(key: key);
@override
Widget build(BuildContext context){
final _spamReportController = Get.find<SpamReportController>();
final _imagePaths = Get.find<ImagePaths>();
return Obx(() {
if (_spamReportController.notShowSpamReportBanner) {
return const SizedBox(
height: 8,
);
}
return Container(
height: 84,
margin: const EdgeInsets.only(right: 16, top: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColor.colorBorderBodyThread, width: 1),
color: AppColor.colorSpamReportBox.withOpacity(0.12)),
child: Stack(
alignment: AlignmentDirectional.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
SvgPicture.asset(
_imagePaths.icInfoCircleOutline,
width: 28,
height: 28,
color: AppColor.primaryColor,
),
const SizedBox(width: 8),
Text(
AppLocalizations.of(context).countNewSpamEmails(
_spamReportController.numberOfUnreadSpamEmails),
style: const TextStyle(
fontSize: 16,
color: AppColor.primaryColor,
fontWeight: FontWeight.w500),
),
],
),
Padding(
padding: const EdgeInsets.only(
left: 32,
),
child: buildTextButton(
AppLocalizations.of(context).showDetails,
height: 36,
width: 115,
textStyle: const TextStyle(
fontSize: 15,
color: AppColor.primaryColor,
fontWeight: FontWeight.w400),
backgroundColor: AppColor.colorCreateNewIdentityButton,
radius: 10,
onTap: () => _spamReportController.openMailbox(context),
),
),
],
),
Positioned(
top: 16,
right: 16,
child: buildSVGIconButton(
icon: _imagePaths.icCloseComposer,
onTap: () => _spamReportController.dismissSpamReportAction(),
),
),
],
),
);
});
}
}
@@ -34,7 +34,6 @@ import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/search_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/spam_report_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_routes.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart';
import 'package:tmail_ui_user/features/search/presentation/search_email_bindings.dart';
@@ -118,10 +117,6 @@ class ThreadController extends BaseController with EmailActionController {
SearchQuery? get searchQuery => searchController.searchEmailFilter.value.text;
RxList<PresentationEmail> get emailList => mailboxDashBoardController.emailsInCurrentMailbox;
SpamReportController get spamReportController => mailboxDashBoardController.spamReportController;
ThreadController(
this._getEmailsInMailboxInteractor,
this._refreshChangesEmailsInMailboxInteractor,
@@ -24,6 +24,7 @@ import 'package:tmail_ui_user/features/thread/presentation/widgets/bottom_bar_th
import 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_builder.dart'
if (dart.library.html) 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_web_builder.dart';
import 'package:tmail_ui_user/features/thread/presentation/widgets/filter_message_cupertino_action_sheet_action_builder.dart';
import 'package:tmail_ui_user/features/thread/presentation/widgets/spam_report_banner_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
@@ -61,7 +62,7 @@ class ThreadView extends GetWidget<ThreadController>
... [
_buildAppBarNormal(context),
_buildSearchBarView(context),
_buildSpamReportBoxWidget(context),
const SpamReportBannerWidget(),
const QuotasWarningBannerWidget(),
_buildVacationNotificationMessage(context),
],
@@ -655,101 +656,4 @@ class ThreadView extends GetWidget<ThreadController>
});
});
}
Widget _buildSpamReportBoxWidget(BuildContext context) {
return Obx(() {
if (controller.spamReportController.dismissedSpamReported.value) {
return const SizedBox.shrink();
}
return Container(
height: 124,
margin: const EdgeInsets.only(right: 16, top: 16, left: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColor.colorBorderBodyThread, width: 1),
color: AppColor.colorSpamReportBox.withOpacity(0.12)),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(top: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
_imagePaths.icInfoCircleOutline,
width: 28,
height: 28,
color: AppColor.primaryColor,
),
const SizedBox(
width: 8,
),
Text(
AppLocalizations.of(context).countNewSpamEmails(5),
style: const TextStyle(
fontSize: 16,
color: AppColor.primaryColor,
fontWeight: FontWeight.w500),
),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
child: Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: _spamReportButtonAction(
context,
AppLocalizations.of(context).showDetails,
AppColor.primaryColor,
() {}),
),
const SizedBox(
width: 8,
),
Expanded(
child: _spamReportButtonAction(
context,
AppLocalizations.of(context).dismiss,
AppColor.textFieldErrorBorderColor,
() => controller.spamReportController
.dismissSpamReportAction()),
),
],
),
),
),
],
),
);
});
}
Widget _spamReportButtonAction(BuildContext context, String title, Color colorText, Function()? onTap) {
return GestureDetector(
onTap: onTap,
child: Container(
height: 36,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: AppColor.colorCreateNewIdentityButton),
child: Expanded(
child: Center(
child: Text(
title,
style: TextStyle(
fontSize: 15,
color: colorText,
fontWeight: FontWeight.w400),
),
),
),
),
);
}
}
@@ -0,0 +1,109 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/spam_report_controller.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class SpamReportBannerWidget extends StatelessWidget {
const SpamReportBannerWidget({ Key? key }) : super(key: key);
@override
Widget build(BuildContext context){
final _spamReportController = Get.find<SpamReportController>();
final _imagePaths = Get.find<ImagePaths>();
return Obx(() {
if (_spamReportController.notShowSpamReportBanner) {
return const SizedBox.shrink();
}
return Container(
height: 124,
margin: const EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColor.colorBorderBodyThread, width: 1),
color: AppColor.colorSpamReportBox.withOpacity(0.12)),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(top: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
_imagePaths.icInfoCircleOutline,
width: 28,
height: 28,
color: AppColor.primaryColor,
),
const SizedBox(
width: 8,
),
Text(
AppLocalizations.of(context).countNewSpamEmails(5),
style: const TextStyle(
fontSize: 16,
color: AppColor.primaryColor,
fontWeight: FontWeight.w500),
),
],
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: _spamReportButtonAction(
context,
AppLocalizations.of(context).showDetails,
AppColor.primaryColor,
() => _spamReportController.openMailbox(context)),
),
const SizedBox(
width: 8,
),
Expanded(
child: _spamReportButtonAction(
context,
AppLocalizations.of(context).dismiss,
AppColor.textFieldErrorBorderColor,
() => _spamReportController
.dismissSpamReportAction()),
),
],
),
),
),
],
),
);
});
}
Widget _spamReportButtonAction(BuildContext context, String title, Color colorText, Function()? onTap) {
return GestureDetector(
onTap: onTap,
child: Container(
height: 36,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: AppColor.colorCreateNewIdentityButton),
child: Center(
child: Text(
title,
style: TextStyle(
fontSize: 15, color: colorText, fontWeight: FontWeight.w400),
),
),
),
);
}
}
@@ -22,6 +22,7 @@ import 'package:tmail_ui_user/features/login/data/local/encryption_key_cache_man
import 'package:tmail_ui_user/features/login/data/local/oidc_configuration_cache_manager.dart';
import 'package:tmail_ui_user/features/login/data/local/token_oidc_cache_manager.dart';
import 'package:tmail_ui_user/features/mailbox/data/local/mailbox_cache_manager.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/share_preference_spam_report_data_source.dart';
import 'package:tmail_ui_user/features/manage_account/data/local/language_cache_manager.dart';
import 'package:tmail_ui_user/features/push_notification/data/local/fcm_cache_manager.dart';
import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart';
@@ -68,6 +69,7 @@ class LocalBindings extends Bindings {
Get.find<FCMCacheManager>(),
Get.find<FCMSubscriptionCacheClient>(),
));
Get.put(SharePreferenceSpamReportDataSource(Get.find<SharedPreferences>()));
}
void _bindingException() {
@@ -17,6 +17,7 @@ import 'package:tmail_ui_user/features/login/data/network/config/authorization_i
import 'package:tmail_ui_user/features/login/data/network/oidc_http_client.dart';
import 'package:tmail_ui_user/features/login/data/utils/library_platform/app_auth_plugin/app_auth_plugin.dart';
import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_api.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/network/spam_report_api.dart';
import 'package:tmail_ui_user/features/manage_account/data/network/forwarding_api.dart';
import 'package:tmail_ui_user/features/manage_account/data/network/identity_api.dart';
import 'package:tmail_ui_user/features/manage_account/data/network/rule_filter_api.dart';
@@ -90,6 +91,7 @@ class NetworkBindings extends Bindings {
Get.put(ForwardingAPI(Get.find<JmapHttpClient.HttpClient>()));
Get.put(QuotasAPI(Get.find<JmapHttpClient.HttpClient>()));
Get.put(FcmApi(Get.find<JmapHttpClient.HttpClient>()));
Get.put(SpamReportApi(Get.find<JmapHttpClient.HttpClient>()));
}
void _bindingConnection() {