From 9431502cefcc019d6d5c42917d9dda89f31756f0 Mon Sep 17 00:00:00 2001 From: dab246 Date: Thu, 3 Oct 2024 14:47:18 +0700 Subject: [PATCH] TF-3002 [MOBILE] Fix `no result` screen still show during search is in progress --- .../presentation/search_email_controller.dart | 23 ++++++++ .../email/presentation/search_email_view.dart | 23 +++----- .../widgets/empty_search_email_widget.dart | 56 +++++++++++++++++++ .../search_email_loading_bar_widget.dart | 36 ++++++------ 4 files changed, 103 insertions(+), 35 deletions(-) create mode 100644 lib/features/search/email/presentation/widgets/empty_search_email_widget.dart diff --git a/lib/features/search/email/presentation/search_email_controller.dart b/lib/features/search/email/presentation/search_email_controller.dart index 72033b1098..dd566c167c 100644 --- a/lib/features/search/email/presentation/search_email_controller.dart +++ b/lib/features/search/email/presentation/search_email_controller.dart @@ -107,6 +107,7 @@ class SearchEmailController extends BaseController final selectionMode = Rx(SelectMode.INACTIVE); final emailSortOrderType = EmailSortOrderType.mostRecent.obs; final suggestionSearchViewState = Rx>(Right(UIState.idle)); + final resultSearchViewState = Rx>(Right(UIState.idle)); late Debouncer _deBouncerTime; late Worker dashBoardViewStateWorker; @@ -175,6 +176,8 @@ class SearchEmailController extends BaseController _searchMoreEmailsSuccess(success); } else if (success is RefreshChangesSearchEmailSuccess) { _refreshChangesSearchEmailsSuccess(success); + } else if (success is SearchingState) { + resultSearchViewState.value = Right(success); } } @@ -188,6 +191,22 @@ class SearchEmailController extends BaseController } } + @override + void handleUrgentExceptionOnMobile({Failure? failure, Exception? exception}) { + super.handleUrgentExceptionOnMobile(failure: failure, exception: exception); + if (failure is SearchEmailFailure) { + _searchEmailsFailure(failure); + } + } + + @override + void handleUrgentExceptionOnWeb({Failure? failure, Exception? exception}) { + super.handleUrgentExceptionOnWeb(failure: failure, exception: exception); + if (failure is SearchEmailFailure) { + _searchEmailsFailure(failure); + } + } + void _initializeDebounceTimeTextSearchChange() { _deBouncerTime = Debouncer( const Duration(milliseconds: 500), @@ -345,6 +364,7 @@ class SearchEmailController extends BaseController textInputSearchFocus.unfocus(); if (session != null && accountId != null) { + resultSearchViewState.value = Right(SearchingState()); canSearchMore = true; searchIsRunning.value = true; cancelSelectionMode(); @@ -400,6 +420,8 @@ class SearchEmailController extends BaseController isSearchEmailRunning: true ); + resultSearchViewState.value = Right(success); + if (resultSearchScrollController.hasClients) { resultSearchScrollController.animateTo( 0, @@ -410,6 +432,7 @@ class SearchEmailController extends BaseController void _searchEmailsFailure(SearchEmailFailure failure) { listResultSearch.clear(); + resultSearchViewState.value = Left(failure); } void searchMoreEmailsAction() { diff --git a/lib/features/search/email/presentation/search_email_view.dart b/lib/features/search/email/presentation/search_email_view.dart index 043dd8716d..6b29888a89 100644 --- a/lib/features/search/email/presentation/search_email_view.dart +++ b/lib/features/search/email/presentation/search_email_view.dart @@ -31,13 +31,12 @@ import 'package:tmail_ui_user/features/search/email/presentation/widgets/email_r import 'package:tmail_ui_user/features/search/email/presentation/widgets/email_receive_time_cupertino_action_sheet_action_builder.dart'; import 'package:tmail_ui_user/features/search/email/presentation/widgets/email_sort_by_action_tile_widget.dart'; import 'package:tmail_ui_user/features/search/email/presentation/widgets/email_sort_by_cupertino_action_sheet_action_builder.dart'; +import 'package:tmail_ui_user/features/search/email/presentation/widgets/empty_search_email_widget.dart'; import 'package:tmail_ui_user/features/search/email/presentation/widgets/search_email_loading_bar_widget.dart'; -import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart'; import 'package:tmail_ui_user/features/thread/domain/state/search_more_email_state.dart'; import 'package:tmail_ui_user/features/thread/presentation/styles/item_email_tile_styles.dart'; 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/empty_emails_widget.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class SearchEmailView extends GetWidget @@ -82,7 +81,7 @@ class SearchEmailView extends GetWidget _buildListSearchFilterAction(context), Obx(() => SearchEmailLoadingBarWidget( suggestionViewState: controller.suggestionSearchViewState.value, - resultSearchViewState: controller.viewState.value, + resultSearchViewState: controller.resultSearchViewState.value, )), Expanded(child: Obx(() { if (controller.searchIsRunning.isFalse) { @@ -110,7 +109,11 @@ class SearchEmailView extends GetWidget controller.listResultSearch ); } else { - return _buildEmptyEmail(context); + return Obx(() => EmptySearchEmailWidget( + suggestionViewState: controller.suggestionSearchViewState.value, + resultSearchViewState: controller.resultSearchViewState.value, + isNetworkConnectionAvailable: controller.networkConnectionController.isNetworkConnectionAvailable(), + )); } } })), @@ -613,18 +616,6 @@ class SearchEmailView extends GetWidget ); } - Widget _buildEmptyEmail(BuildContext context) { - return Obx(() => controller.viewState.value.fold( - (failure) => const SizedBox.shrink(), - (success) => success is! SearchingState - ? EmptyEmailsWidget( - key: const Key('empty_search_email_view'), - isNetworkConnectionAvailable: controller.networkConnectionController.isNetworkConnectionAvailable(), - isSearchActive: true) - : const SizedBox.shrink()) - ); - } - Widget _buildListEmailBody(BuildContext context, List listPresentationEmail) { return NotificationListener( onNotification: (ScrollNotification scrollInfo) { diff --git a/lib/features/search/email/presentation/widgets/empty_search_email_widget.dart b/lib/features/search/email/presentation/widgets/empty_search_email_widget.dart new file mode 100644 index 0000000000..0a82349c69 --- /dev/null +++ b/lib/features/search/email/presentation/widgets/empty_search_email_widget.dart @@ -0,0 +1,56 @@ + +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:flutter/material.dart'; +import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart'; +import 'package:tmail_ui_user/features/thread/presentation/widgets/empty_emails_widget.dart'; + +class EmptySearchEmailWidget extends StatelessWidget { + + final Either resultSearchViewState; + final Either suggestionViewState; + final bool isNetworkConnectionAvailable; + + const EmptySearchEmailWidget({ + super.key, + required this.resultSearchViewState, + required this.suggestionViewState, + required this.isNetworkConnectionAvailable, + }); + + @override + Widget build(BuildContext context) { + return resultSearchViewState.fold( + (failure) => _suggestionViewStateToUI(suggestionViewState), + (success) { + if (success is SearchingState) { + return const SizedBox.shrink(); + } else { + return _suggestionViewStateToUI(suggestionViewState); + } + } + ); + } + + Widget _suggestionViewStateToUI(Either viewState) { + return viewState.fold( + (failure) => EmptyEmailsWidget( + key: const Key('empty_search_email_view'), + isNetworkConnectionAvailable: isNetworkConnectionAvailable, + isSearchActive: true + ), + (success) { + if (success is LoadingState) { + return const SizedBox.shrink(); + } else { + return EmptyEmailsWidget( + key: const Key('empty_search_email_view'), + isNetworkConnectionAvailable: isNetworkConnectionAvailable, + isSearchActive: true + ); + } + } + ); + } +} \ No newline at end of file diff --git a/lib/features/search/email/presentation/widgets/search_email_loading_bar_widget.dart b/lib/features/search/email/presentation/widgets/search_email_loading_bar_widget.dart index d038405700..3319c59d82 100644 --- a/lib/features/search/email/presentation/widgets/search_email_loading_bar_widget.dart +++ b/lib/features/search/email/presentation/widgets/search_email_loading_bar_widget.dart @@ -20,17 +20,7 @@ class SearchEmailLoadingBarWidget extends StatelessWidget with AppLoaderMixin { @override Widget build(BuildContext context) { return resultSearchViewState.fold( - (failure) { - return suggestionViewState.fold( - (failure) => const SizedBox.shrink(), - (success) => success is LoadingState - ? Padding( - padding: const EdgeInsets.symmetric(vertical: 16), - child: loadingWidget - ) - : const SizedBox.shrink() - ); - }, + (failure) => _suggestionViewStateToUI(suggestionViewState), (success) { if (success is SearchingState) { return Padding( @@ -38,15 +28,23 @@ class SearchEmailLoadingBarWidget extends StatelessWidget with AppLoaderMixin { child: loadingWidget ); } else { - return suggestionViewState.fold( - (failure) => const SizedBox.shrink(), - (success) => success is LoadingState - ? Padding( - padding: const EdgeInsets.symmetric(vertical: 16), - child: loadingWidget - ) - : const SizedBox.shrink() + return _suggestionViewStateToUI(suggestionViewState); + } + } + ); + } + + Widget _suggestionViewStateToUI(Either viewState) { + return viewState.fold( + (failure) => const SizedBox.shrink(), + (success) { + if (success is LoadingState) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: loadingWidget ); + } else { + return const SizedBox.shrink(); } } );