import 'dart:async'; import 'package:core/utils/app_logger.dart'; import 'package:dartz/dartz.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/core/user_name.dart'; import 'package:jmap_dart_client/jmap/core/utc_date.dart'; import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart'; import 'package:labels/model/label.dart'; import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:tmail_ui_user/features/base/base_controller.dart'; import 'package:tmail_ui_user/features/base/mixin/date_range_picker_mixin.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_all_recent_search_latest_state.dart'; 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/quick_search_email_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/presentation/extensions/handle_keyboard_shortcut_actions_extension.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_sort_order_type.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/quick_search_filter.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/search_email_filter.dart'; import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/search_state.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/search_status.dart'; class SearchController extends BaseController with DateRangePickerMixin { final QuickSearchEmailInteractor quickSearchEmailInteractor; final SaveRecentSearchInteractor _saveRecentSearchInteractor; final GetAllRecentSearchLatestInteractor _getAllRecentSearchLatestInteractor; final searchInputController = TextEditingController(); final searchEmailFilter = SearchEmailFilter.initial().obs; final searchState = SearchState.initial().obs; final isAdvancedSearchViewOpen = false.obs; final listFilterOnSuggestionForm = RxList(); final simpleSearchIsActivated = RxBool(false); final advancedSearchIsActivated = RxBool(false); final isSearchInputFocused = RxBool(false); SearchQuery? get searchQuery => searchEmailFilter.value.text; FocusNode searchFocus = FocusNode(); FocusNode? keyboardFocusNode; String currentSearchText = ''; SearchController( this.quickSearchEmailInteractor, this._saveRecentSearchInteractor, this._getAllRecentSearchLatestInteractor, ); @override void onInit() { super.onInit(); searchFocus.addListener(_onSearchFocusChanged); onKeyboardShortcutInit(); } void _onSearchFocusChanged() { log('SearchController::_onSearchFocusChanged: ${searchFocus.hasFocus}'); isSearchInputFocused.value = searchFocus.hasFocus; if (searchFocus.hasFocus) { refocusKeyboardShortcutFocus(); } else { clearKeyboardShortcutFocus(); } } void openAdvanceSearch() { isAdvancedSearchViewOpen.value = true; } void closeAdvanceSearch() { isAdvancedSearchViewOpen.value = false; } void clearSearchFilter({EmailSortOrderType? sortOrderType}) { searchEmailFilter.value = SearchEmailFilter.withSortOrder( sortOrderType ?? searchEmailFilter.value.sortOrderType, ); } void synchronizeSearchFilter(SearchEmailFilter searchFilter) { searchEmailFilter.value = searchFilter; } void addQuickSearchFilterToSuggestionSearchView(QuickSearchFilter searchFilter) { if (!listFilterOnSuggestionForm.contains(searchFilter)) { listFilterOnSuggestionForm.add(searchFilter); } } void deleteQuickSearchFilterFromSuggestionSearchView(QuickSearchFilter searchFilter) { listFilterOnSuggestionForm.remove(searchFilter); } void applyFilterSuggestionToSearchFilter(String currentUserEmail) { final receiveTime = listFilterOnSuggestionForm.contains(QuickSearchFilter.last7Days) ? EmailReceiveTimeType.last7Days : null; final hasAttachment = listFilterOnSuggestionForm.contains(QuickSearchFilter.hasAttachment) ? true : null; var listFromAddress = searchEmailFilter.value.from; if (currentUserEmail.isNotEmpty && listFilterOnSuggestionForm.contains(QuickSearchFilter.fromMe)) { listFromAddress.add(currentUserEmail); } final listHasKeyword = listFilterOnSuggestionForm.contains(QuickSearchFilter.starred) ? {KeyWordIdentifier.emailFlagged.value} : null; updateFilterEmail( emailReceiveTimeTypeOption: receiveTime != null ? Some(receiveTime) : null, hasAttachmentOption: hasAttachment != null ? Some(hasAttachment) : null, fromOption: Some(listFromAddress), hasKeywordOption: listHasKeyword != null ? Some(listHasKeyword) : null, ); clearFilterSuggestion(); } void clearFilterSuggestion() { listFilterOnSuggestionForm.clear(); } void updateFilterEmail({ Option>? fromOption, Option>? toOption, Option? textOption, Option? subjectOption, Option>? notKeywordOption, Option>? hasKeywordOption, Option? mailboxOption, Option? emailReceiveTimeTypeOption, Option? hasAttachmentOption, Option? unreadOption, Option? beforeOption, Option? startDateOption, Option? endDateOption, Option? positionOption, Option? sortOrderTypeOption, Option