TF-3761 Update search bar for search mailbox in left menu

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-06-02 03:29:07 +07:00
committed by Dat H. Pham
parent 34cc7abe9b
commit b625894c39
5 changed files with 71 additions and 120 deletions
@@ -162,7 +162,7 @@ extension AppColor on Color {
static const colorSpamReportBannerLabelColor = Color(0xFF626D7A);
static const colorSpamReportBannerButtonBackground = Color(0xFFEBEDF0);
static const colorSubtitle = Color(0xFF6D7885);
static const colorBackgroundSearchMailboxInput = Color(0xFFEBEDF0);
static const searchInputBackground = Color(0xFFE0E9F1);
static const colorMailboxHovered = Color(0xFFEBEDF0);
static const colorMailboxPath = Color(0xFF818C99);
static const colorIconUnSubscribedMailbox = Color(0xFFAEB7C2);
@@ -660,7 +660,7 @@ class _TypeAheadFieldQuickSearchState<T, P, R>
)
: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(12)),
color: AppColor.colorBgDesktop,
color: AppColor.searchInputBackground,
),
height: widget.maxHeight,
child: Row(
@@ -3,6 +3,7 @@ import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:core/presentation/views/quick_search/quick_search_input_form.dart';
import 'package:core/presentation/views/quick_search/quick_search_suggestion_box_decoration.dart';
import 'package:core/presentation/views/quick_search/quick_search_suggestion_list.dart';
@@ -221,12 +222,15 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
labelStyle: const TextStyle(color: Colors.black, fontSize: 16.0)
),
leftButton: Padding(
padding: const EdgeInsetsDirectional.only(start: 8),
child: buildIconWeb(
minSize: 40,
iconPadding: EdgeInsets.zero,
icon: SvgPicture.asset(_imagePaths.icSearchBar, fit: BoxFit.fill),
onTap: () => _invokeSearchEmailAction(_searchController.searchInputController.text.trim())
padding: const EdgeInsetsDirectional.symmetric(horizontal: 12),
child: TMailButtonWidget.fromIcon(
icon: _imagePaths.icSearchBar,
iconColor: AppColor.steelGray400,
iconSize: 28,
backgroundColor: Colors.transparent,
padding: const EdgeInsets.all(4),
tooltipMessage: AppLocalizations.of(context).search,
onTapActionCallback: () => _invokeSearchEmailAction(_searchController.searchInputController.text.trim())
)
),
clearTextButton: buildIconWeb(
@@ -234,6 +238,7 @@ class SearchInputFormWidget extends StatelessWidget with AppLoaderMixin {
_imagePaths.icClearTextSearch,
width: 16,
height: 16,
colorFilter: AppColor.steelGray400.asFilter(),
fit: BoxFit.fill
),
onTap: _searchController.clearTextSearch
@@ -1,6 +1,7 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:core/presentation/views/text/text_field_builder.dart';
import 'package:core/utils/direction_utils.dart';
import 'package:core/utils/platform_info.dart';
@@ -17,7 +18,6 @@ import 'package:tmail_ui_user/features/mailbox/presentation/model/context_item_m
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/utils/mailbox_utils.dart';
import 'package:tmail_ui_user/features/search/mailbox/presentation/search_mailbox_controller.dart';
import 'package:tmail_ui_user/features/search/mailbox/presentation/utils/search_mailbox_utils.dart';
import 'package:tmail_ui_user/features/search/mailbox/presentation/widgets/mailbox_searched_item_builder.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -45,20 +45,23 @@ class SearchMailboxView extends GetWidget<SearchMailboxController>
}
Widget _buildSearchBody(BuildContext context) {
return Container(
return ColoredBox(
color: backgroundColor ?? Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Column(children: [
Container(
color: Colors.transparent,
padding: SearchMailboxUtils.getPaddingAppBar(context, controller.responsiveUtils),
child: _buildSearchInputForm(context)
Padding(
padding: const EdgeInsetsDirectional.only(
start: 16,
end: 16,
top: 12,
),
child: _buildSearchInputForm(context),
),
if (!controller.responsiveUtils.isWebDesktop(context))
const Divider(color: AppColor.colorDividerComposer, height: 1),
_buildLoadingView(),
Expanded(
child: _buildMailboxListView(context)
child: Padding(
padding: const EdgeInsets.only(top: 12),
child: _buildMailboxListView(context),
)
)
]),
);
@@ -70,7 +73,7 @@ class SearchMailboxView extends GetWidget<SearchMailboxController>
(success) {
if (success is LoadingSearchMailbox) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
padding: const EdgeInsets.only(top: 12),
child: loadingWidget);
} else {
return const SizedBox.shrink();
@@ -81,57 +84,50 @@ class SearchMailboxView extends GetWidget<SearchMailboxController>
Widget _buildSearchInputForm(BuildContext context) {
return Row(children: [
buildIconWeb(
minSize: SearchMailboxUtils.getIconSize(context, controller.responsiveUtils),
iconPadding: EdgeInsets.zero,
splashRadius: SearchMailboxUtils.getIconSplashRadius(context, controller.responsiveUtils),
icon: SvgPicture.asset(
controller.imagePaths.icBack,
colorFilter: AppColor.colorTextButton.asFilter(),
fit: BoxFit.fill
),
tooltip: AppLocalizations.of(context).back,
onTap: () => controller.closeSearchView(context)
TMailButtonWidget.fromIcon(
icon: controller.imagePaths.icBack,
iconColor: AppColor.steelGray400,
backgroundColor: Colors.transparent,
width: 36,
height: 36,
margin: const EdgeInsetsDirectional.only(end: 8),
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 14),
tooltipMessage: AppLocalizations.of(context).back,
onTapActionCallback: () => controller.closeSearchView(context),
),
Expanded(child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(controller.responsiveUtils.isWebDesktop(context) ? 12 : 0)),
color: controller.responsiveUtils.isWebDesktop(context)
? AppColor.colorBackgroundSearchMailboxInput
: Colors.transparent
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(12)),
color: AppColor.searchInputBackground
),
alignment: Alignment.center,
child: Row(children: [
Padding(
padding: SearchMailboxUtils.getPaddingInputSearchIcon(context, controller.responsiveUtils),
child: buildIconWeb(
minSize: 40,
iconPadding: EdgeInsets.zero,
icon: SvgPicture.asset(
controller.imagePaths.icSearchBar,
colorFilter: AppColor.colorTextButton.asFilter(),
fit: BoxFit.fill
),
tooltip: AppLocalizations.of(context).search,
onTap: () => controller.handleSearchButtonPressed(context)
padding: const EdgeInsets.symmetric(horizontal: 12),
child: TMailButtonWidget.fromIcon(
icon: controller.imagePaths.icSearchBar,
iconColor: AppColor.steelGray400,
iconSize: 28,
backgroundColor: Colors.transparent,
padding: const EdgeInsets.all(4),
tooltipMessage: AppLocalizations.of(context).search,
onTapActionCallback: () =>
controller.handleSearchButtonPressed(context)
),
),
Expanded(child: _buildTextFieldSearchInput(context)),
Obx(() {
if (controller.currentSearchQuery.isNotEmpty) {
return Padding(
padding: const EdgeInsets.only(right: 2),
child: buildIconWeb(
minSize: 40,
iconPadding: EdgeInsets.zero,
icon: SvgPicture.asset(
controller.imagePaths.icClearSearchInput,
width: 24,
height: 24,
fit: BoxFit.fill
),
tooltip: AppLocalizations.of(context).clearAll,
onTap: controller.clearAllTextInputSearchForm),
padding: const EdgeInsetsDirectional.only(end: 12),
child: TMailButtonWidget.fromIcon(
icon: controller.imagePaths.icClearSearchInput,
iconColor: AppColor.steelGray400,
iconSize: 28,
padding: const EdgeInsets.all(4),
tooltipMessage: AppLocalizations.of(context).clearAll,
onTapActionCallback: controller.clearAllTextInputSearchForm,
),
);
} else {
return const SizedBox.shrink();
@@ -150,19 +146,21 @@ class SearchMailboxView extends GetWidget<SearchMailboxController>
maxLines: 1,
controller: controller.textInputSearchController,
textDirection: DirectionUtils.getDirectionByLanguage(context),
textStyle: const TextStyle(
textStyle: ThemeUtils.textStyleBodyBody2(
color: Colors.black,
fontSize: 15,
fontWeight: FontWeight.normal),
),
keyboardType: TextInputType.text,
onTextSubmitted: (text) => controller.onTextSearchSubmitted(context, text),
decoration: InputDecoration(
contentPadding: EdgeInsets.zero,
contentPadding: const EdgeInsetsDirectional.only(
end: 12,
bottom: 14,
top: 14,
),
hintText: AppLocalizations.of(context).searchForFolders,
hintStyle: const TextStyle(
color: AppColor.loginTextFieldHintColor,
fontSize: 15,
fontWeight: FontWeight.normal),
hintStyle: ThemeUtils.textStyleBodyBody2(
color: AppColor.steelGray400,
),
border: InputBorder.none
),
);
@@ -171,9 +169,9 @@ class SearchMailboxView extends GetWidget<SearchMailboxController>
Widget _buildMailboxListView(BuildContext context) {
return Obx(() {
return ListView.builder(
padding: SearchMailboxUtils.getPaddingListViewMailboxSearched(context, controller.responsiveUtils),
key: const Key('list_mailbox_searched'),
itemCount: controller.listMailboxSearched.length,
padding: const EdgeInsets.symmetric(horizontal: 16),
shrinkWrap: true,
primary: false,
itemBuilder: (context, index) {
@@ -2,58 +2,6 @@ import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:flutter/material.dart';
class SearchMailboxUtils {
static EdgeInsets getPaddingAppBar(BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isWebDesktop(context)) {
return const EdgeInsets.symmetric(vertical: 8, horizontal: 16);
} else {
if (responsiveUtils.isScreenWithShortestSide(context)) {
return const EdgeInsets.symmetric(horizontal: 12, vertical: 8);
} else {
return const EdgeInsets.symmetric(horizontal: 28, vertical: 8);
}
}
}
static EdgeInsets getPaddingInputSearchIcon(BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isWebDesktop(context)) {
return const EdgeInsets.only(left: 5, right: 2);
} else {
if (responsiveUtils.isScreenWithShortestSide(context)) {
return const EdgeInsets.only(left: 6, right: 14);
} else {
return const EdgeInsets.only(left: 8, right: 16);
}
}
}
static double getIconSize(BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isWebDesktop(context)) {
return 30;
} else {
return 40;
}
}
static double getIconSplashRadius(BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isWebDesktop(context)) {
return 10;
} else {
return 15;
}
}
static EdgeInsets getPaddingListViewMailboxSearched(BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isWebDesktop(context)) {
return const EdgeInsets.only(left: 16, right: 16, bottom: 16);
} else {
if (responsiveUtils.isScreenWithShortestSide(context)) {
return const EdgeInsets.all(16);
} else {
return const EdgeInsets.symmetric(horizontal: 32, vertical: 16);
}
}
}
static EdgeInsets getPaddingItemListView(BuildContext context, ResponsiveUtils responsiveUtils) {
if (responsiveUtils.isWebDesktop(context)) {
return const EdgeInsets.all(8);