TF-524 Create RecentSearchCache and TypeAHeadQuickSearch widget
This commit is contained in:
@@ -1,21 +1,24 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/base/mixin/network_connection_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/composer_view_web.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/email_view.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_view_web.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/recent_search.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mixin/filter_email_popup_menu_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mixin/user_setting_popup_menu_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/email_quick_search_item_tile_widget.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/recent_search_item_tile_widget.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/app_setting.dart';
|
||||
import 'package:tmail_ui_user/features/manage_account/presentation/model/reading_pane.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/extensions/filter_message_option_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/thread_view.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/search_app_bar_widget.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/routes/app_routes.dart';
|
||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||
@@ -157,7 +160,9 @@ class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> with Ne
|
||||
}),
|
||||
const SizedBox(width: 16),
|
||||
Obx(() => !controller.isSearchActive() ? const Spacer() : const SizedBox.shrink()),
|
||||
Obx(() => controller.isSearchActive() ? Expanded(child: _buildSearchForm(context)) : const SizedBox.shrink()),
|
||||
Obx(() => controller.isSearchActive()
|
||||
? Expanded(child: _buildSearchForm(context))
|
||||
: const SizedBox.shrink()),
|
||||
Obx(() => !controller.isSearchActive()
|
||||
? (SearchBarView(_imagePaths)
|
||||
..hintTextSearch(AppLocalizations.of(context).search_emails)
|
||||
@@ -396,24 +401,119 @@ class MailboxDashBoardView extends GetWidget<MailboxDashBoardController> with Ne
|
||||
}
|
||||
|
||||
Widget _buildSearchForm(BuildContext context) {
|
||||
return (SearchAppBarWidget(context, _imagePaths, _responsiveUtils,
|
||||
controller.searchQuery,
|
||||
controller.searchFocus,
|
||||
controller.searchInputController,
|
||||
suggestionSearch: controller.suggestionSearch)
|
||||
..addDecoration(const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
color: AppColor.colorBgSearchBar))
|
||||
..setMargin(const EdgeInsets.only(right: 10))
|
||||
..setHeightSearchBar(45)
|
||||
..setHintText(AppLocalizations.of(context).search_mail)
|
||||
..addOnCancelSearchPressed(() {
|
||||
controller.disableSearch();
|
||||
controller.dispatchAction(CancelSelectionAllEmailAction());
|
||||
})
|
||||
..addOnClearTextSearchAction(() => controller.clearSearchText())
|
||||
..addOnTextChangeSearchAction((query) => controller.addSuggestionSearch(query))
|
||||
..addOnSearchTextAction((query) => controller.searchEmail(context, query)))
|
||||
.build();
|
||||
return Row(
|
||||
children: [
|
||||
buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icBack, color: AppColor.colorTextButton, fit: BoxFit.fill),
|
||||
onTap: () {
|
||||
controller.disableSearch();
|
||||
controller.dispatchAction(CancelSelectionAllEmailAction());
|
||||
}),
|
||||
Expanded(child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
color: AppColor.colorBgSearchBar),
|
||||
height: 45,
|
||||
child: TypeAheadFormFieldQuickSearch<PresentationEmail, RecentSearch>(
|
||||
textFieldConfiguration: QuickSearchTextFieldConfiguration(
|
||||
controller: controller.searchInputController,
|
||||
autofocus: true,
|
||||
focusNode: controller.searchFocus,
|
||||
textInputAction: TextInputAction.done,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
enabledBorder: InputBorder.none,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
hintText: AppLocalizations.of(context).search_mail,
|
||||
hintStyle: const TextStyle(color: AppColor.colorHintSearchBar, fontSize: 17.0),
|
||||
labelStyle: const TextStyle(color: AppColor.colorHintSearchBar, fontSize: 17.0)
|
||||
),
|
||||
leftButton: buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icSearchBar, width: 16, height: 16, fit: BoxFit.fill),
|
||||
onTap: () => {}),
|
||||
rightButton: buildIconWeb(
|
||||
icon: SvgPicture.asset(_imagePaths.icComposerClose, width: 18, height: 18, fit: BoxFit.fill),
|
||||
onTap: () {
|
||||
controller.searchInputController.clear();
|
||||
controller.clearSearchText();
|
||||
})
|
||||
),
|
||||
suggestionsBoxDecoration: QuickSearchSuggestionsBoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: _responsiveUtils.isDesktop(context) ? 556 : double.infinity,
|
||||
maxHeight: 322),
|
||||
),
|
||||
actionButton: Padding(
|
||||
padding: const EdgeInsets.only(left: 24, top: 24, right: 24, bottom: 20),
|
||||
child: Row(
|
||||
children: [
|
||||
(ButtonBuilder(_imagePaths.icAttachmentSB)
|
||||
..decoration(BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: AppColor.colorButtonHeaderThread))
|
||||
..paddingIcon(const EdgeInsets.only(right: 5))
|
||||
..padding(const EdgeInsets.symmetric(horizontal: 12, vertical: 8))
|
||||
..radiusSplash(10)
|
||||
..size(16)
|
||||
..textStyle(const TextStyle(fontSize: 13, color: AppColor.colorTextButtonHeaderThread))
|
||||
..onPressActionClick(() => {})
|
||||
..text(AppLocalizations.of(context).hasAttachment, isVertical: false))
|
||||
.build(),
|
||||
const SizedBox(width: 8),
|
||||
(ButtonBuilder(_imagePaths.icCalendarSB)
|
||||
..decoration(BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: AppColor.colorButtonHeaderThread))
|
||||
..paddingIcon(const EdgeInsets.only(right: 5))
|
||||
..padding(const EdgeInsets.symmetric(horizontal: 12, vertical: 8))
|
||||
..radiusSplash(10)
|
||||
..size(16)
|
||||
..textStyle(const TextStyle(fontSize: 13, color: AppColor.colorTextButtonHeaderThread))
|
||||
..onPressActionClick(() => {})
|
||||
..text(AppLocalizations.of(context).last7Days, isVertical: false))
|
||||
.build(),
|
||||
const SizedBox(width: 8),
|
||||
(ButtonBuilder(_imagePaths.icUserSB)
|
||||
..decoration(BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: AppColor.colorButtonHeaderThread))
|
||||
..paddingIcon(const EdgeInsets.only(right: 5))
|
||||
..padding(const EdgeInsets.symmetric(horizontal: 12, vertical: 8))
|
||||
..radiusSplash(10)
|
||||
..size(16)
|
||||
..textStyle(const TextStyle(fontSize: 13, color: AppColor.colorTextButtonHeaderThread))
|
||||
..onPressActionClick(() => {})
|
||||
..text(AppLocalizations.of(context).fromMe, isVertical: false))
|
||||
.build(),
|
||||
],
|
||||
),
|
||||
),
|
||||
titleHeaderRecent: Padding(
|
||||
padding: const EdgeInsets.only(left: 24, right: 24, bottom: 8),
|
||||
child: Text(AppLocalizations.of(context).recent,
|
||||
style: const TextStyle(fontSize: 13.0,
|
||||
color: AppColor.colorTextButtonHeaderThread,
|
||||
fontWeight: FontWeight.w500))),
|
||||
getRecentCallback: (pattern) async {
|
||||
return [];
|
||||
},
|
||||
itemRecentBuilder: (context, recent) {
|
||||
return RecentSearchItemTileWidget(recent);
|
||||
},
|
||||
suggestionsCallback: (pattern) async {
|
||||
return [];
|
||||
},
|
||||
itemBuilder: (context, email) {
|
||||
return EmailQuickSearchItemTileWidget(email, controller.selectedMailbox.value);
|
||||
},
|
||||
onSuggestionSelected: (autoCompleteResult) async {
|
||||
}),
|
||||
)),
|
||||
const SizedBox(width: 16),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/email/presentation_email.dart';
|
||||
import 'package:model/extensions/presentation_email_extension.dart';
|
||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||
|
||||
class EmailQuickSearchItemTileWidget extends StatelessWidget {
|
||||
|
||||
final imagePath = Get.find<ImagePaths>();
|
||||
|
||||
final PresentationEmail _presentationEmail;
|
||||
final PresentationMailbox? _presentationMailbox;
|
||||
|
||||
EmailQuickSearchItemTileWidget(
|
||||
this._presentationEmail,
|
||||
this._presentationMailbox,
|
||||
{Key? key}
|
||||
) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
_presentationEmail.hasStarred ? imagePath.icStar : imagePath.icUnStar,
|
||||
width: 20, height: 20, fit: BoxFit.fill),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
Text(_getInformationSender(),
|
||||
maxLines: 1,
|
||||
overflow: BuildUtils.isWeb ? null : TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black)),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Text(_presentationEmail.getEmailTitle(),
|
||||
maxLines: 1,
|
||||
overflow: BuildUtils.isWeb ? null : TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Colors.black)),
|
||||
),
|
||||
if (_presentationEmail.hasAttachment == true)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: SvgPicture.asset(imagePath.icAttachment, width: 14, height: 14, fit: BoxFit.fill),
|
||||
),
|
||||
Text(_presentationEmail.getReceivedAt(Localizations.localeOf(context).toLanguageTag()),
|
||||
textAlign: TextAlign.right,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Colors.black))
|
||||
]),
|
||||
const SizedBox(height: 3),
|
||||
Text(_presentationEmail.getPartialContent(),
|
||||
maxLines: 1,
|
||||
overflow: BuildUtils.isWeb ? null : TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: AppColor.colorContentEmail))
|
||||
]
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _getInformationSender() {
|
||||
if (_presentationMailbox?.role == PresentationMailbox.roleSent
|
||||
|| _presentationMailbox?.role == PresentationMailbox.roleDrafts
|
||||
|| _presentationMailbox?.role == PresentationMailbox.roleOutbox) {
|
||||
return _presentationEmail.recipientsName();
|
||||
}
|
||||
return _presentationEmail.getSenderName();
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
|
||||
import 'package:core/core.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/domain/model/recent_search.dart';
|
||||
|
||||
class RecentSearchItemTileWidget extends StatelessWidget {
|
||||
|
||||
final imagePath = Get.find<ImagePaths>();
|
||||
|
||||
final RecentSearch recentSearch;
|
||||
|
||||
RecentSearchItemTileWidget(this.recentSearch, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(imagePath.icClockSB),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(recentSearch.value,
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Colors.black)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user