TF-3002 [WEB] Add delete button in search filters
This commit is contained in:
@@ -18,7 +18,10 @@ typedef ItemBuilder<T> = Widget Function(BuildContext context, T itemData);
|
|||||||
typedef SuggestionSelectionCallback<T> = void Function(T suggestion);
|
typedef SuggestionSelectionCallback<T> = void Function(T suggestion);
|
||||||
typedef RecentSelectionCallback<R> = void Function(R recent);
|
typedef RecentSelectionCallback<R> = void Function(R recent);
|
||||||
typedef ErrorBuilder = Widget Function(BuildContext context, Object? error);
|
typedef ErrorBuilder = Widget Function(BuildContext context, Object? error);
|
||||||
typedef ButtonActionBuilder = Widget Function(BuildContext context, dynamic action);
|
typedef ButtonActionBuilder = Widget Function(
|
||||||
|
BuildContext context,
|
||||||
|
dynamic action,
|
||||||
|
SuggestionsListState suggestionsListState);
|
||||||
typedef ButtonActionCallback = void Function(dynamic action);
|
typedef ButtonActionCallback = void Function(dynamic action);
|
||||||
|
|
||||||
typedef AnimationTransitionBuilder = Widget Function(
|
typedef AnimationTransitionBuilder = Widget Function(
|
||||||
@@ -315,8 +318,8 @@ class TypeAheadFieldQuickSearch<T, P, R> extends StatefulWidget {
|
|||||||
|
|
||||||
final QuickSearchSuggestionsBoxDecoration suggestionsBoxDecoration;
|
final QuickSearchSuggestionsBoxDecoration suggestionsBoxDecoration;
|
||||||
|
|
||||||
/// Used to control the `_SuggestionsBox`. Allows manual control to
|
/// Used to control the `SuggestionsBox`. Allows manual control to
|
||||||
/// open, close, toggle, or resize the `_SuggestionsBox`.
|
/// open, close, toggle, or resize the `SuggestionsBox`.
|
||||||
final QuickSearchSuggestionsBoxController? suggestionsBoxController;
|
final QuickSearchSuggestionsBoxController? suggestionsBoxController;
|
||||||
|
|
||||||
/// The duration to wait after the user stops typing before calling
|
/// The duration to wait after the user stops typing before calling
|
||||||
@@ -590,7 +593,7 @@ class _TypeAheadFieldQuickSearchState<T, P, R> extends State<TypeAheadFieldQuick
|
|||||||
with WidgetsBindingObserver {
|
with WidgetsBindingObserver {
|
||||||
FocusNode? _focusNode;
|
FocusNode? _focusNode;
|
||||||
TextEditingController? _textEditingController;
|
TextEditingController? _textEditingController;
|
||||||
_SuggestionsBox? _suggestionsBox;
|
SuggestionsBox? _suggestionsBox;
|
||||||
late TextDirection _textDirection;
|
late TextDirection _textDirection;
|
||||||
|
|
||||||
TextEditingController? get _effectiveController =>
|
TextEditingController? get _effectiveController =>
|
||||||
@@ -648,7 +651,7 @@ class _TypeAheadFieldQuickSearchState<T, P, R> extends State<TypeAheadFieldQuick
|
|||||||
_focusNode = FocusNode();
|
_focusNode = FocusNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
_suggestionsBox = _SuggestionsBox(
|
_suggestionsBox = SuggestionsBox(
|
||||||
context,
|
context,
|
||||||
widget.direction,
|
widget.direction,
|
||||||
widget.autoFlipDirection,
|
widget.autoFlipDirection,
|
||||||
@@ -721,7 +724,7 @@ class _TypeAheadFieldQuickSearchState<T, P, R> extends State<TypeAheadFieldQuick
|
|||||||
|
|
||||||
void _initOverlayEntry() {
|
void _initOverlayEntry() {
|
||||||
_suggestionsBox!._overlayEntry = OverlayEntry(builder: (context) {
|
_suggestionsBox!._overlayEntry = OverlayEntry(builder: (context) {
|
||||||
final suggestionsList = _SuggestionsList<T, P, R>(
|
final suggestionsList = SuggestionsList<T, P, R>(
|
||||||
suggestionsBox: _suggestionsBox,
|
suggestionsBox: _suggestionsBox,
|
||||||
decoration: widget.suggestionsBoxDecoration,
|
decoration: widget.suggestionsBoxDecoration,
|
||||||
debounceDuration: widget.debounceDuration,
|
debounceDuration: widget.debounceDuration,
|
||||||
@@ -905,8 +908,8 @@ class _TypeAheadFieldQuickSearchState<T, P, R> extends State<TypeAheadFieldQuick
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SuggestionsList<T, P, R> extends StatefulWidget {
|
class SuggestionsList<T, P, R> extends StatefulWidget {
|
||||||
final _SuggestionsBox? suggestionsBox;
|
final SuggestionsBox? suggestionsBox;
|
||||||
final TextEditingController? controller;
|
final TextEditingController? controller;
|
||||||
final bool getImmediateSuggestions;
|
final bool getImmediateSuggestions;
|
||||||
final SuggestionSelectionCallback<T>? onSuggestionSelected;
|
final SuggestionSelectionCallback<T>? onSuggestionSelected;
|
||||||
@@ -942,7 +945,8 @@ class _SuggestionsList<T, P, R> extends StatefulWidget {
|
|||||||
final SuggestionsCallback<P>? contactSuggestionCallback;
|
final SuggestionsCallback<P>? contactSuggestionCallback;
|
||||||
final SuggestionSelectionCallback<P>? onContactSuggestionSelected;
|
final SuggestionSelectionCallback<P>? onContactSuggestionSelected;
|
||||||
|
|
||||||
const _SuggestionsList({
|
const SuggestionsList({
|
||||||
|
super.key,
|
||||||
required this.suggestionsBox,
|
required this.suggestionsBox,
|
||||||
this.controller,
|
this.controller,
|
||||||
this.getImmediateSuggestions = false,
|
this.getImmediateSuggestions = false,
|
||||||
@@ -981,10 +985,10 @@ class _SuggestionsList<T, P, R> extends StatefulWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_SuggestionsListState<T, P, R> createState() => _SuggestionsListState<T, P, R>();
|
SuggestionsListState<T, P, R> createState() => SuggestionsListState<T, P, R>();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SuggestionsListState<T, P, R> extends State<_SuggestionsList<T, P, R>>
|
class SuggestionsListState<T, P, R> extends State<SuggestionsList<T, P, R>>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
Iterable<T>? _suggestions;
|
Iterable<T>? _suggestions;
|
||||||
Iterable<R>? _recentItems;
|
Iterable<R>? _recentItems;
|
||||||
@@ -998,7 +1002,7 @@ class _SuggestionsListState<T, P, R> extends State<_SuggestionsList<T, P, R>>
|
|||||||
late final ScrollController _scrollController =
|
late final ScrollController _scrollController =
|
||||||
widget.scrollController ?? ScrollController();
|
widget.scrollController ?? ScrollController();
|
||||||
|
|
||||||
_SuggestionsListState() {
|
SuggestionsListState() {
|
||||||
_controllerListener = () async {
|
_controllerListener = () async {
|
||||||
// If we came here because of a change in selected text, not because of
|
// If we came here because of a change in selected text, not because of
|
||||||
// actual change in text
|
// actual change in text
|
||||||
@@ -1015,7 +1019,7 @@ class _SuggestionsListState<T, P, R> extends State<_SuggestionsList<T, P, R>>
|
|||||||
recentItems = await widget.fetchRecentActionCallback!(widget.controller!.text);
|
recentItems = await widget.fetchRecentActionCallback!(widget.controller!.text);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError('_SuggestionsListState::_SuggestionsListState(): $e');
|
logError('SuggestionsListState::SuggestionsListState(): $e');
|
||||||
}
|
}
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -1046,7 +1050,7 @@ class _SuggestionsListState<T, P, R> extends State<_SuggestionsList<T, P, R>>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didUpdateWidget(_SuggestionsList<T, P, R> oldWidget) {
|
void didUpdateWidget(SuggestionsList<T, P, R> oldWidget) {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
widget.controller!.addListener(_controllerListener);
|
widget.controller!.addListener(_controllerListener);
|
||||||
_getSuggestions();
|
_getSuggestions();
|
||||||
@@ -1215,7 +1219,7 @@ class _SuggestionsListState<T, P, R> extends State<_SuggestionsList<T, P, R>>
|
|||||||
if (listActionWidget != null) listActionWidget,
|
if (listActionWidget != null) listActionWidget,
|
||||||
if (loadingWidget != null) loadingWidget,
|
if (loadingWidget != null) loadingWidget,
|
||||||
if (widget.buttonShowAllResult != null && widget.controller?.text.isNotEmpty == true)
|
if (widget.buttonShowAllResult != null && widget.controller?.text.isNotEmpty == true)
|
||||||
widget.buttonShowAllResult!(context, widget.controller?.text),
|
widget.buttonShowAllResult!(context, widget.controller?.text, this),
|
||||||
if (listItemContactWidget.isNotEmpty)
|
if (listItemContactWidget.isNotEmpty)
|
||||||
... listItemContactWidget,
|
... listItemContactWidget,
|
||||||
if (listItemContactWidget.isNotEmpty && listItemSuggestionWidget.isNotEmpty)
|
if (listItemContactWidget.isNotEmpty && listItemSuggestionWidget.isNotEmpty)
|
||||||
@@ -1253,7 +1257,7 @@ class _SuggestionsListState<T, P, R> extends State<_SuggestionsList<T, P, R>>
|
|||||||
if (listActionWidget != null) listActionWidget,
|
if (listActionWidget != null) listActionWidget,
|
||||||
if (loadingWidget != null) loadingWidget,
|
if (loadingWidget != null) loadingWidget,
|
||||||
if (widget.buttonShowAllResult != null && widget.controller?.text.isNotEmpty == true)
|
if (widget.buttonShowAllResult != null && widget.controller?.text.isNotEmpty == true)
|
||||||
widget.buttonShowAllResult!(context, widget.controller?.text),
|
widget.buttonShowAllResult!(context, widget.controller?.text, this),
|
||||||
if (_recentItems?.isNotEmpty == true && widget.itemRecentBuilder != null && widget.titleHeaderRecent != null)
|
if (_recentItems?.isNotEmpty == true && widget.itemRecentBuilder != null && widget.titleHeaderRecent != null)
|
||||||
widget.titleHeaderRecent!,
|
widget.titleHeaderRecent!,
|
||||||
if (listItemRecent.isNotEmpty)
|
if (listItemRecent.isNotEmpty)
|
||||||
@@ -1294,14 +1298,14 @@ class _SuggestionsListState<T, P, R> extends State<_SuggestionsList<T, P, R>>
|
|||||||
widget.buttonActionCallback?.call(action);
|
widget.buttonActionCallback?.call(action);
|
||||||
invalidateSuggestions();
|
invalidateSuggestions();
|
||||||
},
|
},
|
||||||
child: widget.actionButtonBuilder!(context, action),
|
child: widget.actionButtonBuilder!(context, action, this),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsetsDirectional.only(end: 8, bottom: 8),
|
padding: const EdgeInsetsDirectional.only(end: 8, bottom: 8),
|
||||||
child: widget.actionButtonBuilder!(context, action)
|
child: widget.actionButtonBuilder!(context, action, this)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -1732,7 +1736,7 @@ class QuickSearchTextFieldConfiguration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SuggestionsBox {
|
class SuggestionsBox {
|
||||||
static const int waitMetricsTimeoutMillis = 1000;
|
static const int waitMetricsTimeoutMillis = 1000;
|
||||||
static const double minOverlaySpace = 64.0;
|
static const double minOverlaySpace = 64.0;
|
||||||
|
|
||||||
@@ -1751,7 +1755,7 @@ class _SuggestionsBox {
|
|||||||
double textBoxHeight = 100.0;
|
double textBoxHeight = 100.0;
|
||||||
late double directionUpOffset;
|
late double directionUpOffset;
|
||||||
|
|
||||||
_SuggestionsBox(
|
SuggestionsBox(
|
||||||
this.context,
|
this.context,
|
||||||
this.direction,
|
this.direction,
|
||||||
this.autoFlipDirection,
|
this.autoFlipDirection,
|
||||||
@@ -1950,7 +1954,7 @@ class _SuggestionsBox {
|
|||||||
/// Supply an instance of this class to the [TypeAhead.suggestionsBoxController]
|
/// Supply an instance of this class to the [TypeAhead.suggestionsBoxController]
|
||||||
/// property to manually control the suggestions box
|
/// property to manually control the suggestions box
|
||||||
class QuickSearchSuggestionsBoxController {
|
class QuickSearchSuggestionsBoxController {
|
||||||
_SuggestionsBox? _suggestionsBox;
|
SuggestionsBox? _suggestionsBox;
|
||||||
FocusNode? _effectiveFocusNode;
|
FocusNode? _effectiveFocusNode;
|
||||||
|
|
||||||
/// Opens the suggestions box
|
/// Opens the suggestions box
|
||||||
|
|||||||
+12
-4
@@ -446,13 +446,21 @@ class AdvancedFilterController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _updateFromField() {
|
void _updateFromField() {
|
||||||
listFromEmailAddress = List.from(
|
if (searchEmailFilter.from.isNotEmpty) {
|
||||||
searchEmailFilter.from.map((address) => EmailAddress(null, address)));
|
listFromEmailAddress = List.from(
|
||||||
|
searchEmailFilter.from.map((address) => EmailAddress(null, address)));
|
||||||
|
} else {
|
||||||
|
listFromEmailAddress.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateToField() {
|
void _updateToField() {
|
||||||
listToEmailAddress= List.from(
|
if (searchEmailFilter.to.isNotEmpty) {
|
||||||
searchEmailFilter.to.map((address) => EmailAddress(null, address)));
|
listToEmailAddress = List.from(
|
||||||
|
searchEmailFilter.to.map((address) => EmailAddress(null, address)));
|
||||||
|
} else {
|
||||||
|
listToEmailAddress.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onSearchAction(BuildContext context) {
|
void onSearchAction(BuildContext context) {
|
||||||
|
|||||||
+70
-5
@@ -1579,10 +1579,6 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
|
|||||||
_getAllIdentities();
|
_getAllIdentities();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addFilterToSuggestionForm(QuickSearchFilter filter) {
|
|
||||||
searchController.addFilterToSuggestionForm(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<PresentationEmail>> quickSearchEmails(String query) async {
|
Future<List<PresentationEmail>> quickSearchEmails(String query) async {
|
||||||
if (sessionCurrent != null && accountId.value != null) {
|
if (sessionCurrent != null && accountId.value != null) {
|
||||||
return searchController.quickSearchEmails(
|
return searchController.quickSearchEmails(
|
||||||
@@ -1733,7 +1729,7 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
|
|||||||
: const None()
|
: const None()
|
||||||
);
|
);
|
||||||
|
|
||||||
dispatchAction(StartSearchEmailAction(filter: QuickSearchFilter.folder));
|
dispatchAction(StartSearchEmailAction());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1777,6 +1773,75 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
|
|||||||
dispatchAction(StartSearchEmailAction());
|
dispatchAction(StartSearchEmailAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _deleteDateTimeSearchFilter() {
|
||||||
|
dispatchAction(ClearDateRangeToAdvancedSearch(EmailReceiveTimeType.allTime));
|
||||||
|
searchController.updateFilterEmail(
|
||||||
|
emailReceiveTimeType: EmailReceiveTimeType.allTime,
|
||||||
|
startDateOption: const None(),
|
||||||
|
endDateOption: const None(),
|
||||||
|
beforeOption: const None()
|
||||||
|
);
|
||||||
|
dispatchAction(StartSearchEmailAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
void _deleteSortOrderSearchFilter() {
|
||||||
|
searchController.sortOrderFiltered.value = EmailSortOrderType.mostRecent;
|
||||||
|
searchController.updateFilterEmail(
|
||||||
|
sortOrderOption: EmailSortOrderType.mostRecent.getSortOrder());
|
||||||
|
dispatchAction(StartSearchEmailAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
void _deleteFromSearchFilter() {
|
||||||
|
searchController.updateFilterEmail(fromOption: const None());
|
||||||
|
dispatchAction(StartSearchEmailAction(filter: QuickSearchFilter.from));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _deleteToSearchFilter() {
|
||||||
|
searchController.updateFilterEmail(toOption: const None());
|
||||||
|
dispatchAction(StartSearchEmailAction(filter: QuickSearchFilter.to));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _deleteHasAttachmentSearchFilter() {
|
||||||
|
searchController.updateFilterEmail(hasAttachment: false);
|
||||||
|
dispatchAction(StartSearchEmailAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
void _deleteFolderSearchFilter() {
|
||||||
|
searchController.updateFilterEmail(
|
||||||
|
mailboxOption: const None(),
|
||||||
|
beforeOption: const None(),
|
||||||
|
positionOption: searchController.sortOrderFiltered.value.isScrollByPosition()
|
||||||
|
? const Some(0)
|
||||||
|
: const None()
|
||||||
|
);
|
||||||
|
dispatchAction(StartSearchEmailAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDeleteSearchFilterAction(QuickSearchFilter searchFilter) {
|
||||||
|
switch(searchFilter) {
|
||||||
|
case QuickSearchFilter.dateTime:
|
||||||
|
_deleteDateTimeSearchFilter();
|
||||||
|
break;
|
||||||
|
case QuickSearchFilter.sortBy:
|
||||||
|
_deleteSortOrderSearchFilter();
|
||||||
|
break;
|
||||||
|
case QuickSearchFilter.from:
|
||||||
|
_deleteFromSearchFilter();
|
||||||
|
break;
|
||||||
|
case QuickSearchFilter.hasAttachment:
|
||||||
|
_deleteHasAttachmentSearchFilter();
|
||||||
|
break;
|
||||||
|
case QuickSearchFilter.to:
|
||||||
|
_deleteToSearchFilter();
|
||||||
|
break;
|
||||||
|
case QuickSearchFilter.folder:
|
||||||
|
_deleteFolderSearchFilter();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool isEmptyTrashBannerEnabledOnWeb(
|
bool isEmptyTrashBannerEnabledOnWeb(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
PresentationMailbox? mailbox
|
PresentationMailbox? mailbox
|
||||||
|
|||||||
@@ -70,14 +70,16 @@ class SearchController extends BaseController with DateRangePickerMixin {
|
|||||||
searchEmailFilter.value = SearchEmailFilter.initial();
|
searchEmailFilter.value = SearchEmailFilter.initial();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addFilterToSuggestionForm(QuickSearchFilter filter) {
|
void addQuickSearchFilterToSuggestionSearchView(QuickSearchFilter searchFilter) {
|
||||||
if (listFilterOnSuggestionForm.contains(filter)) {
|
if (!listFilterOnSuggestionForm.contains(searchFilter)) {
|
||||||
listFilterOnSuggestionForm.remove(filter);
|
listFilterOnSuggestionForm.add(searchFilter);
|
||||||
} else {
|
|
||||||
listFilterOnSuggestionForm.add(filter);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void deleteQuickSearchFilterFromSuggestionSearchView(QuickSearchFilter searchFilter) {
|
||||||
|
listFilterOnSuggestionForm.remove(searchFilter);
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<PresentationEmail>> quickSearchEmails({
|
Future<List<PresentationEmail>> quickSearchEmails({
|
||||||
required Session session,
|
required Session session,
|
||||||
required AccountId accountId,
|
required AccountId accountId,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dash
|
|||||||
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_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/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/quick_search_filter.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/styles/mailbox_dashboard_view_web_style.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/download/download_task_item_widget.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/mark_mailbox_as_read_loading_banner.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/mark_mailbox_as_read_loading_banner.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/navigation_bar/navigation_bar_widget.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/navigation_bar/navigation_bar_widget.dart';
|
||||||
@@ -460,15 +461,15 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
|||||||
controller: controller.listSearchFilterScrollController!,
|
controller: controller.listSearchFilterScrollController!,
|
||||||
children: [
|
children: [
|
||||||
_buildQuickSearchFilterButton(context, QuickSearchFilter.folder),
|
_buildQuickSearchFilterButton(context, QuickSearchFilter.folder),
|
||||||
const SizedBox(width: 8),
|
MailboxDashboardViewWebStyle.searchFilterSizeBoxMargin,
|
||||||
_buildQuickSearchFilterButton(context, QuickSearchFilter.from),
|
_buildQuickSearchFilterButton(context, QuickSearchFilter.from),
|
||||||
const SizedBox(width: 8),
|
MailboxDashboardViewWebStyle.searchFilterSizeBoxMargin,
|
||||||
_buildQuickSearchFilterButton(context, QuickSearchFilter.to),
|
_buildQuickSearchFilterButton(context, QuickSearchFilter.to),
|
||||||
const SizedBox(width: 8),
|
MailboxDashboardViewWebStyle.searchFilterSizeBoxMargin,
|
||||||
_buildQuickSearchFilterButton(context, QuickSearchFilter.dateTime),
|
_buildQuickSearchFilterButton(context, QuickSearchFilter.dateTime),
|
||||||
const SizedBox(width: 8),
|
MailboxDashboardViewWebStyle.searchFilterSizeBoxMargin,
|
||||||
_buildQuickSearchFilterButton(context, QuickSearchFilter.hasAttachment),
|
_buildQuickSearchFilterButton(context, QuickSearchFilter.hasAttachment),
|
||||||
const SizedBox(width: 8),
|
MailboxDashboardViewWebStyle.searchFilterSizeBoxMargin,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -484,8 +485,8 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildQuickSearchFilterButton(
|
Widget _buildQuickSearchFilterButton(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
QuickSearchFilter searchFilter
|
QuickSearchFilter searchFilter,
|
||||||
) {
|
) {
|
||||||
return Obx(() {
|
return Obx(() {
|
||||||
final searchEmailFilter = controller.searchController.searchEmailFilter.value;
|
final searchEmailFilter = controller.searchController.searchEmailFilter.value;
|
||||||
@@ -503,6 +504,11 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
|||||||
searchEmailFilter,
|
searchEmailFilter,
|
||||||
sortOrderType);
|
sortOrderType);
|
||||||
|
|
||||||
|
EdgeInsetsGeometry? buttonPadding;
|
||||||
|
if (searchFilter != QuickSearchFilter.sortBy) {
|
||||||
|
buttonPadding = MailboxDashboardViewWebStyle.getSearchFilterButtonPadding(isSelected);
|
||||||
|
}
|
||||||
|
|
||||||
return SearchFilterButton(
|
return SearchFilterButton(
|
||||||
key: Key('${searchFilter.name}_search_filter_button'),
|
key: Key('${searchFilter.name}_search_filter_button'),
|
||||||
searchFilter: searchFilter,
|
searchFilter: searchFilter,
|
||||||
@@ -516,12 +522,14 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
|
|||||||
listAddressOfTo: listAddressOfTo,
|
listAddressOfTo: listAddressOfTo,
|
||||||
userName: userName,
|
userName: userName,
|
||||||
mailbox: mailbox,
|
mailbox: mailbox,
|
||||||
|
buttonPadding: buttonPadding,
|
||||||
onSelectSearchFilterAction: _onSelectSearchFilterAction,
|
onSelectSearchFilterAction: _onSelectSearchFilterAction,
|
||||||
|
onDeleteSearchFilterAction: controller.onDeleteSearchFilterAction,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onSelectSearchFilterAction(
|
Future<void> _onSelectSearchFilterAction(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
QuickSearchFilter searchFilter,
|
QuickSearchFilter searchFilter,
|
||||||
{RelativeRect? buttonPosition}
|
{RelativeRect? buttonPosition}
|
||||||
|
|||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
|
class MailboxDashboardViewWebStyle {
|
||||||
|
static const SizedBox searchFilterSizeBoxMargin = SizedBox(width: 8);
|
||||||
|
|
||||||
|
static EdgeInsetsGeometry getSearchFilterButtonPadding(bool isSelected) {
|
||||||
|
if (isSelected) {
|
||||||
|
return const EdgeInsetsDirectional.only(start: 12, end: 4);
|
||||||
|
} else {
|
||||||
|
return const EdgeInsets.symmetric(horizontal: 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,9 +5,14 @@ class SearchFilterButtonStyle {
|
|||||||
static const double iconSize = 16;
|
static const double iconSize = 16;
|
||||||
static const double deleteIconSize = 10;
|
static const double deleteIconSize = 10;
|
||||||
static const double spaceSize = 4;
|
static const double spaceSize = 4;
|
||||||
static const double buttonSize = 35;
|
|
||||||
|
|
||||||
static const EdgeInsetsGeometry buttonPadding = EdgeInsets.symmetric(horizontal: 12, vertical: 8);
|
static EdgeInsetsGeometry getButtonPadding(bool isSelected) {
|
||||||
|
if (isSelected) {
|
||||||
|
return const EdgeInsetsDirectional.only(start: 12, end: 4, top: 4, bottom: 4);
|
||||||
|
} else {
|
||||||
|
return const EdgeInsets.symmetric(horizontal: 12, vertical: 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
static const EdgeInsetsGeometry elementPadding = EdgeInsetsDirectional.only(start: 8);
|
static const EdgeInsetsGeometry elementPadding = EdgeInsetsDirectional.only(start: 8);
|
||||||
static const BorderRadius borderRadius = BorderRadius.all(Radius.circular(10));
|
static const BorderRadius borderRadius = BorderRadius.all(Radius.circular(10));
|
||||||
|
|
||||||
|
|||||||
+8
-4
@@ -15,6 +15,7 @@ typedef OnSelectSearchFilterAction = Function(
|
|||||||
BuildContext context,
|
BuildContext context,
|
||||||
QuickSearchFilter searchFilter,
|
QuickSearchFilter searchFilter,
|
||||||
{RelativeRect? buttonPosition});
|
{RelativeRect? buttonPosition});
|
||||||
|
typedef OnDeleteSearchFilterAction = Function(QuickSearchFilter searchFilter);
|
||||||
|
|
||||||
class SearchFilterButton extends StatelessWidget {
|
class SearchFilterButton extends StatelessWidget {
|
||||||
|
|
||||||
@@ -32,7 +33,9 @@ class SearchFilterButton extends StatelessWidget {
|
|||||||
final UserName? userName;
|
final UserName? userName;
|
||||||
final PresentationMailbox? mailbox;
|
final PresentationMailbox? mailbox;
|
||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
|
final EdgeInsetsGeometry? buttonPadding;
|
||||||
final OnSelectSearchFilterAction? onSelectSearchFilterAction;
|
final OnSelectSearchFilterAction? onSelectSearchFilterAction;
|
||||||
|
final OnDeleteSearchFilterAction? onDeleteSearchFilterAction;
|
||||||
|
|
||||||
const SearchFilterButton({
|
const SearchFilterButton({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -48,7 +51,9 @@ class SearchFilterButton extends StatelessWidget {
|
|||||||
this.userName,
|
this.userName,
|
||||||
this.mailbox,
|
this.mailbox,
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
|
this.buttonPadding,
|
||||||
this.onSelectSearchFilterAction,
|
this.onSelectSearchFilterAction,
|
||||||
|
this.onDeleteSearchFilterAction,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -69,8 +74,7 @@ class SearchFilterButton extends StatelessWidget {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: SearchFilterButtonStyle.borderRadius,
|
borderRadius: SearchFilterButtonStyle.borderRadius,
|
||||||
color: backgroundColor ?? searchFilter.getBackgroundColor(isFilterSelected: isSelected)),
|
color: backgroundColor ?? searchFilter.getBackgroundColor(isFilterSelected: isSelected)),
|
||||||
padding: SearchFilterButtonStyle.buttonPadding,
|
padding: buttonPadding ?? SearchFilterButtonStyle.getButtonPadding(isSelected),
|
||||||
height: SearchFilterButtonStyle.buttonSize,
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
@@ -104,9 +108,9 @@ class SearchFilterButton extends StatelessWidget {
|
|||||||
icon: imagePaths.icDeleteSelection,
|
icon: imagePaths.icDeleteSelection,
|
||||||
iconSize: SearchFilterButtonStyle.deleteIconSize,
|
iconSize: SearchFilterButtonStyle.deleteIconSize,
|
||||||
iconColor: AppColor.colorTextBody,
|
iconColor: AppColor.colorTextBody,
|
||||||
padding: EdgeInsets.zero,
|
padding: const EdgeInsets.all(8),
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
margin: SearchFilterButtonStyle.elementPadding,
|
onTapActionCallback: () => onDeleteSearchFilterAction?.call(searchFilter),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -70,16 +70,19 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
|
|||||||
QuickSearchFilter.last7Days,
|
QuickSearchFilter.last7Days,
|
||||||
QuickSearchFilter.fromMe,
|
QuickSearchFilter.fromMe,
|
||||||
],
|
],
|
||||||
actionButtonBuilder: (context, filterAction) {
|
actionButtonBuilder: (context, filterAction, suggestionsListState) {
|
||||||
if (filterAction is QuickSearchFilter) {
|
if (filterAction is QuickSearchFilter) {
|
||||||
return buildListButtonForQuickSearchForm(context, filterAction);
|
return buildListButtonForQuickSearchForm(
|
||||||
|
context,
|
||||||
|
filterAction,
|
||||||
|
suggestionsListState);
|
||||||
} else {
|
} else {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
buttonActionCallback: (filterAction) {
|
buttonActionCallback: (filterAction) {
|
||||||
if (filterAction is QuickSearchFilter) {
|
if (filterAction is QuickSearchFilter) {
|
||||||
_dashBoardController.addFilterToSuggestionForm(filterAction);
|
_searchController.addQuickSearchFilterToSuggestionSearchView(filterAction);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
listActionPadding: const EdgeInsets.only(left: 12, right: 12, top: 12, bottom: 6),
|
listActionPadding: const EdgeInsets.only(left: 12, right: 12, top: 12, bottom: 6),
|
||||||
@@ -94,7 +97,7 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
buttonShowAllResult: (context, keyword) {
|
buttonShowAllResult: (context, keyword, _) {
|
||||||
if (keyword is String) {
|
if (keyword is String) {
|
||||||
return _buildShowAllResultButton(context, keyword);
|
return _buildShowAllResultButton(context, keyword);
|
||||||
} else {
|
} else {
|
||||||
@@ -221,7 +224,11 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildListButtonForQuickSearchForm(BuildContext context, QuickSearchFilter searchFilter) {
|
Widget buildListButtonForQuickSearchForm(
|
||||||
|
BuildContext context,
|
||||||
|
QuickSearchFilter searchFilter,
|
||||||
|
SuggestionsListState suggestionsListState
|
||||||
|
) {
|
||||||
return Obx(() {
|
return Obx(() {
|
||||||
final isSelected = searchFilter.isApplied(_searchController.listFilterOnSuggestionForm);
|
final isSelected = searchFilter.isApplied(_searchController.listFilterOnSuggestionForm);
|
||||||
|
|
||||||
@@ -230,6 +237,10 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
|
|||||||
imagePaths: _imagePaths,
|
imagePaths: _imagePaths,
|
||||||
isSelected: isSelected,
|
isSelected: isSelected,
|
||||||
backgroundColor: searchFilter.getSuggestionBackgroundColor(isFilterSelected: isSelected),
|
backgroundColor: searchFilter.getSuggestionBackgroundColor(isFilterSelected: isSelected),
|
||||||
|
onDeleteSearchFilterAction: (searchFilter) {
|
||||||
|
_searchController.deleteQuickSearchFilterFromSuggestionSearchView(searchFilter);
|
||||||
|
suggestionsListState.invalidateSuggestions();
|
||||||
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user