TF-248 Update AppBar of ThreadView

This commit is contained in:
dab246
2022-02-08 18:00:56 +07:00
committed by Dat H. Pham
parent 74131407f2
commit 4a49ce8150
9 changed files with 67 additions and 94 deletions
+3
View File
@@ -0,0 +1,3 @@
<svg width="20" height="16" viewBox="0 0 20 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.21911 5.87534C4.56412 5.44408 5.19341 5.37416 5.62467 5.71917L9.99998 9.21941L14.3753 5.71917C14.8065 5.37416 15.4358 5.44408 15.7808 5.87534C16.1259 6.3066 16.0559 6.9359 15.6247 7.28091L10.6247 11.2809C10.2595 11.5731 9.7405 11.5731 9.37528 11.2809L4.37528 7.28091C3.94402 6.9359 3.8741 6.3066 4.21911 5.87534Z" fill="#007AFF"/>
</svg>

After

Width:  |  Height:  |  Size: 486 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 12L4 12M6 12C6 12.5304 6.21071 13.0391 6.58579 13.4142C6.96086 13.7893 7.46957 14 8 14C8.53043 14 9.03914 13.7893 9.41421 13.4142C9.78929 13.0391 10 12.5304 10 12M6 12C6 11.4696 6.21071 10.9609 6.58579 10.5858C6.96086 10.2107 7.46957 10 8 10C8.53043 10 9.03914 10.2107 9.41421 10.5858C9.78929 10.9609 10 11.4696 10 12M10 12L20 12M18 18C18 17.4696 17.7893 16.9609 17.4142 16.5858C17.0391 16.2107 16.5304 16 16 16C15.4696 16 14.9609 16.2107 14.5858 16.5858C14.2107 16.9609 14 17.4696 14 18M18 18C18 18.5304 17.7893 19.0391 17.4142 19.4142C17.0391 19.7893 16.5304 20 16 20C15.4696 20 14.9609 19.7893 14.5858 19.4142C14.2107 19.0391 14 18.5304 14 18M18 18L20 18M14 18L4 18M18 6C18 5.46957 17.7893 4.96086 17.4142 4.58579C17.0391 4.21071 16.5304 4 16 4C15.4696 4 14.9609 4.21071 14.5858 4.58579C14.2107 4.96086 14 5.46957 14 6M18 6C18 6.53043 17.7893 7.03914 17.4142 7.41421C17.0391 7.78929 16.5304 8 16 8C15.4696 8 14.9609 7.78929 14.5858 7.41421C14.2107 7.03914 14 6.53043 14 6M18 6L20 6M14 6L4 6" stroke="#99A2AD" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,6 +1,6 @@
extension CapitalizeExtension on String {
String get inCaps => this.length > 0 ?'${this[0].toUpperCase()}${this.substring(1)}':'';
String get inCaps => this.length > 0 ?'${this[0].toUpperCase()}${this.toLowerCase().substring(1)}':'';
String get allInCaps => this.toUpperCase();
String get capitalizeFirstEach => this.replaceAll(RegExp(' +'), ' ').split(" ").map((str) => str.inCaps).join(" ");
}
@@ -64,6 +64,7 @@ extension AppColor on Color {
static const lineItemListColor = Color(0xFF99A2AD);
static const colorNameEmail = Color(0xFF000000);
static const colorContentEmail = Color(0xFF6D7885);
static const colorTextButton = Color(0xFF007AFF);
static const mapGradientColor = [
[Color(0xFF21D4FD), Color(0xFFB721FF)],
@@ -47,6 +47,8 @@ class ImagePaths {
String get icUnStar => _getImagePath('ic_unstar.svg');
String get icAttachment => _getImagePath('ic_attachment.svg');
String get icChevron => _getImagePath('ic_chevron.svg');
String get icChevronDown => _getImagePath('ic_chevron_down.svg');
String get icFilter => _getImagePath('ic_filter.svg');
String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
@@ -1,9 +1,7 @@
import 'package:core/core.dart';
import 'package:core/presentation/extensions/color_extension.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/model.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';
@@ -44,7 +42,7 @@ class ThreadView extends GetWidget<ThreadController> {
Container(
alignment: Alignment.center,
padding: EdgeInsets.zero,
color: responsiveUtils.isMobile(context) ? AppColor.bgMailboxListMail : AppColor.primaryLightColor,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
@@ -107,11 +105,8 @@ class ThreadView extends GetWidget<ThreadController> {
context,
imagePaths,
responsiveUtils,
controller.mailboxDashBoardController.selectedMailbox.value,
controller.mailboxDashBoardController.userProfile.value)
..onOpenUserInformationAction(() => {})
..onOpenSearchMailActionClick(() => controller.enableSearch(context))
..onOpenListMailboxActionClick(() => controller.openMailboxLeftMenu()))
controller.mailboxDashBoardController.selectedMailbox.value)
..addOpenListMailboxActionClick(() => controller.openMailboxLeftMenu()))
.build();
}
@@ -271,7 +266,7 @@ class ThreadView extends GetWidget<ThreadController> {
height: double.infinity,
alignment: Alignment.center,
padding: EdgeInsets.zero,
color: responsiveUtils.isMobile(context) ? AppColor.bgMailboxListMail : Colors.white,
color: Colors.white,
child: Obx(() {
if (controller.isSearchActive()) {
if (controller.mailboxDashBoardController.suggestionSearch.isNotEmpty) {
@@ -332,9 +327,7 @@ class ThreadView extends GetWidget<ThreadController> {
itemBuilder: (context, index) => Obx(() => (EmailTileBuilder(
context,
imagePaths,
controller.getSelectMode(listPresentationEmail[index], controller.mailboxDashBoardController.selectedEmail.value),
listPresentationEmail[index],
responsiveUtils,
controller.mailboxDashBoardController.selectedMailbox.value?.role,
controller.currentSelectMode.value,
controller.mailboxDashBoardController.searchState.value.searchStatus,
@@ -1,46 +1,35 @@
import 'dart:ui';
import 'package:core/core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
typedef OnOpenSearchMailActionClick = void Function();
typedef OnFilterEmailAction = void Function();
typedef OnOpenListMailboxActionClick = void Function();
typedef OnOpenUserInformationActionClick = void Function();
class AppBarThreadWidgetBuilder {
OnOpenSearchMailActionClick? _onOpenSearchMailActionClick;
OnFilterEmailAction? _onFilterEmailAction;
OnOpenListMailboxActionClick? _onOpenListMailboxActionClick;
OnOpenUserInformationActionClick? _onOpenUserInformationActionClick;
final BuildContext _context;
final ImagePaths _imagePaths;
final ResponsiveUtils _responsiveUtils;
final PresentationMailbox? _presentationMailbox;
final UserProfile? _userProfile;
AppBarThreadWidgetBuilder(
this._context,
this._imagePaths,
this._responsiveUtils,
this._presentationMailbox,
this._userProfile,
);
void onOpenUserInformationAction(
OnOpenUserInformationActionClick onOpenUserInformationActionClick) {
_onOpenUserInformationActionClick = onOpenUserInformationActionClick;
void addOnFilterEmailAction(OnFilterEmailAction onFilterEmailAction) {
_onFilterEmailAction = onFilterEmailAction;
}
void onOpenSearchMailActionClick(OnOpenSearchMailActionClick onOpenSearchMailActionClick) {
_onOpenSearchMailActionClick = onOpenSearchMailActionClick;
}
void onOpenListMailboxActionClick(OnOpenListMailboxActionClick onOpenListMailboxActionClick) {
void addOpenListMailboxActionClick(OnOpenListMailboxActionClick onOpenListMailboxActionClick) {
_onOpenListMailboxActionClick = onOpenListMailboxActionClick;
}
@@ -50,37 +39,38 @@ class AppBarThreadWidgetBuilder {
alignment: Alignment.topCenter,
color: Colors.white,
margin: EdgeInsets.zero,
padding: EdgeInsets.only(left: 16, top: 16, bottom: 8, right: 16),
padding: EdgeInsets.only(left: 8, top: 16, bottom: 8, right: 8),
child: MediaQuery(
data: MediaQueryData(padding: EdgeInsets.zero),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (_responsiveUtils.isMobile(_context)) _buildIconUser(),
_buildEditButton(),
Expanded(child: _buildContentCenterAppBar()),
_buildIconSearch(),
_buildFilterButton(),
]
)
)
);
}
Widget _buildIconUser() {
return GestureDetector(
onTap: () => {
if (_onOpenUserInformationActionClick != null) {
_onOpenUserInformationActionClick!()
}},
child: Padding(
padding: EdgeInsets.zero,
child: (AvatarBuilder()
..text(_userProfile != null ? _userProfile!.getAvatarText() : '')
..size(36))
.build()));
Widget _buildEditButton() {
return Material(
borderRadius: BorderRadius.circular(12),
color: Colors.transparent,
child: Padding(
padding: EdgeInsets.only(right: 16),
child: TextButton(
onPressed: () {},
child: Text(
AppLocalizations.of(_context).edit,
style: TextStyle(fontSize: 17, color: AppColor.colorTextButton),
),
)
)
);
}
Widget _buildIconSearch() {
Widget _buildFilterButton() {
return Material(
borderRadius: BorderRadius.circular(12),
color: Colors.transparent,
@@ -88,12 +78,8 @@ class AppBarThreadWidgetBuilder {
padding: EdgeInsets.only(left: 16),
child: IconButton(
color: AppColor.baseTextColor,
icon: SvgPicture.asset(_imagePaths.icSearch, color: AppColor.baseTextColor, fit: BoxFit.fill),
onPressed: () => {
if (_onOpenSearchMailActionClick != null) {
_onOpenSearchMailActionClick!()
}
}
icon: SvgPicture.asset(_imagePaths.icFilter, color: AppColor.baseTextColor, fit: BoxFit.fill),
onPressed: () => _onFilterEmailAction?.call()
)
)
);
@@ -101,56 +87,46 @@ class AppBarThreadWidgetBuilder {
Widget _buildContentCenterAppBar() {
return Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: () => {
if (_onOpenListMailboxActionClick != null) {
_onOpenListMailboxActionClick!()
}},
onTap: () => _onOpenListMailboxActionClick?.call(),
child: Padding(
padding: EdgeInsets.only(left: 16, right: 8),
padding: EdgeInsets.zero,
child: Container(
padding: EdgeInsets.zero,
margin: EdgeInsets.zero,
constraints: BoxConstraints(maxWidth: _getMaxWidthAppBarTitle()),
child: Text(
'${ _presentationMailbox?.name?.name ?? ''}',
'${_presentationMailbox?.name?.name.capitalizeFirstEach ?? ''}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 22, color: AppColor.titleAppBarMailboxListMail, fontWeight: FontWeight.w500))
style: TextStyle(fontSize: 21, color: AppColor.colorNameEmail, fontWeight: FontWeight.w700))
))),
if(_presentationMailbox?.getCountUnReadEmails().isNotEmpty == true)
Container(
margin: EdgeInsets.zero,
padding: EdgeInsets.only(left: 8, right: 8, top: 2.5, bottom: 2.5),
decoration:BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: AppColor.backgroundCounterMailboxColor),
child: Text(
'${_presentationMailbox?.getCountUnReadEmails() ?? ''} ${AppLocalizations.of(_context).unread_email_notification}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 10, color: AppColor.counterMailboxColor, fontWeight: FontWeight.w500),
)),
Transform(
transform: Matrix4.translationValues(-10.0, 0.0, 0.0),
child: Material(
borderRadius: BorderRadius.circular(12),
color: Colors.transparent,
child: IconButton(
padding: EdgeInsets.zero,
color: AppColor.baseTextColor,
icon: SvgPicture.asset(_imagePaths.icChevronDown, width: 20, height: 16, fit: BoxFit.fill),
onPressed: () => _onOpenListMailboxActionClick?.call())))
]
);
}
double _getMaxWidthAppBarTitle() {
var width = MediaQuery.of(_context).size.width;
var widthSiblingsWidget = _presentationMailbox?.getCountUnReadEmails().isNotEmpty == true
? 150
: 100;
var widthSiblingsWidget = 220;
if (_responsiveUtils.isTablet(_context)) {
width = width * 0.7;
widthSiblingsWidget = _presentationMailbox?.getCountUnReadEmails().isNotEmpty == true
? 70
: 0;
widthSiblingsWidget = 300;
} else if (_responsiveUtils.isDesktop(_context)) {
width = width * 0.2;
widthSiblingsWidget = _presentationMailbox?.getCountUnReadEmails().isNotEmpty == true
? 50
: 0;
widthSiblingsWidget = 300;
}
final maxWidth = width - widthSiblingsWidget;
return maxWidth;
@@ -1,9 +1,7 @@
import 'dart:math';
import 'dart:ui';
import 'package:core/core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart';
@@ -16,11 +14,9 @@ typedef OnMarkAsStarEmailActionClick = void Function(PresentationEmail selectedE
class EmailTileBuilder {
final SelectMode _selectMode;
final ImagePaths _imagePaths;
final PresentationEmail _presentationEmail;
final BuildContext _context;
final ResponsiveUtils _responsiveUtils;
final SelectMode _selectModeAll;
final Role? _mailboxRole;
final SearchStatus _searchStatus;
@@ -33,9 +29,7 @@ class EmailTileBuilder {
EmailTileBuilder(
this._context,
this._imagePaths,
this._selectMode,
this._presentationEmail,
this._responsiveUtils,
this._mailboxRole,
this._selectModeAll,
this._searchStatus,
@@ -66,7 +60,7 @@ class EmailTileBuilder {
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(0),
color: _getBackgroundColorItem()),
color: Colors.white),
child: MediaQuery(
data: MediaQueryData(padding: EdgeInsets.zero),
child: Column(children: [
@@ -206,7 +200,7 @@ class EmailTileBuilder {
if (_selectModeAll == SelectMode.ACTIVE) {
return AnimatedSwitcher(
duration: Duration(milliseconds: 600),
transitionBuilder: __transitionBuilder,
transitionBuilder: _transitionBuilder,
child: _presentationEmail.selectMode == SelectMode.ACTIVE
? (IconBuilder(_imagePaths.icSelected)
..addOnTapActionClick(() {
@@ -237,7 +231,7 @@ class EmailTileBuilder {
}
}
Widget __transitionBuilder(Widget widget, Animation<double> animation) {
Widget _transitionBuilder(Widget widget, Animation<double> animation) {
final rotateAnim = Tween(begin: pi, end: 0.0).animate(animation);
return AnimatedBuilder(
animation: rotateAnim,
@@ -254,10 +248,6 @@ class EmailTileBuilder {
);
}
Color _getBackgroundColorItem() {
return _responsiveUtils.isMobile(_context) ? AppColor.bgMailboxListMail : Colors.white;
}
String _getInformationSender() {
if (_mailboxRole == PresentationMailbox.roleSent
|| _mailboxRole == PresentationMailbox.roleDrafts
@@ -459,5 +459,10 @@ class AppLocalizations {
name: 'results',
);
}
String get edit {
return Intl.message('Edit',
name: 'edit');
}
}