diff --git a/assets/fonts/SFProText/SF-Pro-Text-Bold.otf b/assets/fonts/SFProText/SF-Pro-Text-Bold.otf new file mode 100644 index 000000000..57ef54d76 Binary files /dev/null and b/assets/fonts/SFProText/SF-Pro-Text-Bold.otf differ diff --git a/assets/fonts/SFProText/SF-Pro-Text-Medium.ttf b/assets/fonts/SFProText/SF-Pro-Text-Medium.ttf new file mode 100644 index 000000000..b2a88a0ef Binary files /dev/null and b/assets/fonts/SFProText/SF-Pro-Text-Medium.ttf differ diff --git a/assets/fonts/SFProText/SF-Pro-Text-Regular.ttf b/assets/fonts/SFProText/SF-Pro-Text-Regular.ttf new file mode 100644 index 000000000..ef923910a Binary files /dev/null and b/assets/fonts/SFProText/SF-Pro-Text-Regular.ttf differ diff --git a/assets/fonts/SFProText/SF-Pro-Text-Semibold.otf b/assets/fonts/SFProText/SF-Pro-Text-Semibold.otf new file mode 100644 index 000000000..52fb9d11e Binary files /dev/null and b/assets/fonts/SFProText/SF-Pro-Text-Semibold.otf differ diff --git a/assets/images/ic_unread.svg b/assets/images/ic_unread.svg new file mode 100644 index 000000000..bd8053fad --- /dev/null +++ b/assets/images/ic_unread.svg @@ -0,0 +1,3 @@ + + + diff --git a/core/lib/presentation/constants/constants_ui.dart b/core/lib/presentation/constants/constants_ui.dart index c33906f1f..38650e270 100644 --- a/core/lib/presentation/constants/constants_ui.dart +++ b/core/lib/presentation/constants/constants_ui.dart @@ -1,3 +1,4 @@ class ConstantsUI { static const fontApp = 'CircularStd'; + static const fontSFProText = 'SFProText'; } \ No newline at end of file diff --git a/core/lib/presentation/extensions/color_extension.dart b/core/lib/presentation/extensions/color_extension.dart index 1f00a5271..ed5810f62 100644 --- a/core/lib/presentation/extensions/color_extension.dart +++ b/core/lib/presentation/extensions/color_extension.dart @@ -61,6 +61,9 @@ extension AppColor on Color { static const backgroundCountAttachment = Color(0x681C1C1C); static const bgStatusResultSearch = Color(0xFFF5F5F7); static const bgWordSearch = Color(0xFFD7D6FC); + static const lineItemListColor = Color(0xFF99A2AD); + static const colorNameEmail = Color(0xFF000000); + static const colorContentEmail = Color(0xFF6D7885); static const mapGradientColor = [ [Color(0xFF21D4FD), Color(0xFFB721FF)], diff --git a/core/lib/presentation/resources/image_paths.dart b/core/lib/presentation/resources/image_paths.dart index 52960210a..ca91ff1c7 100644 --- a/core/lib/presentation/resources/image_paths.dart +++ b/core/lib/presentation/resources/image_paths.dart @@ -42,6 +42,7 @@ class ImagePaths { String get icMore => _getImagePath('ic_more.svg'); String get icPhotoLibrary => _getImagePath('ic_photo_library.svg'); String get icEmptyImageDefault => _getImagePath('empty_image_default.svg'); + String get icUnread => _getImagePath('ic_unread.svg'); String _getImagePath(String imageName) { return AssetsPaths.images + imageName; diff --git a/core/lib/presentation/utils/theme_utils.dart b/core/lib/presentation/utils/theme_utils.dart index e3dd399cc..d9220971c 100644 --- a/core/lib/presentation/utils/theme_utils.dart +++ b/core/lib/presentation/utils/theme_utils.dart @@ -5,7 +5,7 @@ import 'package:flutter/material.dart'; ThemeData appTheme() { return ThemeData( scaffoldBackgroundColor: Colors.white, - fontFamily: ConstantsUI.fontApp, + fontFamily: ConstantsUI.fontSFProText, appBarTheme: appBarTheme(), textTheme: textTheme(), visualDensity: VisualDensity.adaptivePlatformDensity, diff --git a/lib/features/thread/presentation/widgets/email_tile_builder.dart b/lib/features/thread/presentation/widgets/email_tile_builder.dart index de0b3860b..28044b7d3 100644 --- a/lib/features/thread/presentation/widgets/email_tile_builder.dart +++ b/lib/features/thread/presentation/widgets/email_tile_builder.dart @@ -4,6 +4,7 @@ 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'; import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart'; @@ -60,157 +61,149 @@ class EmailTileBuilder { highlightColor: Colors.transparent), child: Container( key: Key('thread_tile'), - margin: EdgeInsets.only(bottom: 10), - padding: EdgeInsets.only(top: 10, bottom: 10, left: 25, right: 6), + margin: EdgeInsets.zero, + padding: EdgeInsets.only(bottom: 10, left: 20, right: 6), alignment: Alignment.center, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(_selectModeAll == SelectMode.ACTIVE ? 0 : 16), + borderRadius: BorderRadius.circular(0), color: _getBackgroundColorItem()), child: MediaQuery( data: MediaQueryData(padding: EdgeInsets.zero), - child: ListTile( - contentPadding: EdgeInsets.zero, - onTap: () => { - if (_onOpenEmailActionClick != null) { - _onOpenEmailActionClick!(_presentationEmail) - } - }, - onLongPress: () => { - if (_onSelectEmailActionClick != null) { - _onSelectEmailActionClick!(_presentationEmail) - } - }, - leading: Transform( - transform: Matrix4.translationValues(-10.0, -2.0, 0.0), - child: _buildAvatarIcon()), - title: Transform( - transform: Matrix4.translationValues(-10.0, 0.0, 0.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: _searchStatus == SearchStatus.ACTIVE && _searchQuery != null && _searchQuery!.value.isNotEmpty - ? RichTextBuilder( - _getInformationSender(), - '${_searchQuery!.value}', - TextStyle( - fontSize: 14, - color: AppColor.mailboxTextColor, - fontWeight: _presentationEmail.isUnReadEmail() ? FontWeight.bold : FontWeight.w500), - TextStyle( - fontSize: 14, - color: AppColor.mailboxTextColor, - backgroundColor: AppColor.bgWordSearch, - fontWeight: _presentationEmail.isUnReadEmail() ? FontWeight.bold : FontWeight.w500)).build() - : Text( - _getInformationSender(), - maxLines: 1, - overflow:TextOverflow.ellipsis, - style: TextStyle( - fontSize: 14, - color: AppColor.mailboxTextColor, - fontWeight: _presentationEmail.isUnReadEmail() ? FontWeight.bold : FontWeight.w500)) - ), - Padding( - padding: EdgeInsets.only(right: 4), - child: Text( - '${_presentationEmail.getReceivedAt(Localizations.localeOf(_context).toLanguageTag())}', - maxLines: 1, - overflow:TextOverflow.ellipsis, - style: TextStyle( - fontSize: 12, - color: _presentationEmail.isUnReadEmail() ? AppColor.sentTimeTextColorUnRead : AppColor.baseTextColor))) - ], - ) - ), - subtitle: Transform( - transform: Matrix4.translationValues(-10.0, 8.0, 0.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(bottom: 3), - child: Row( - children: [ - Expanded( - child: _searchStatus == SearchStatus.ACTIVE && _searchQuery != null && _searchQuery!.value.isNotEmpty - ? RichTextBuilder( - '${_presentationEmail.getEmailTitle()}', - '${_searchQuery!.value}', - TextStyle( - fontSize: 12, - color: _presentationEmail.isUnReadEmail() ? AppColor.subjectEmailTextColorUnRead : AppColor.baseTextColor, - fontWeight: _presentationEmail.isUnReadEmail() ? FontWeight.bold : FontWeight.w500), - TextStyle( - fontSize: 12, - backgroundColor: AppColor.bgWordSearch, - color: _presentationEmail.isUnReadEmail() ? AppColor.subjectEmailTextColorUnRead : AppColor.baseTextColor, - fontWeight: _presentationEmail.isUnReadEmail() ? FontWeight.bold : FontWeight.w500)).build() - : Text( - '${_presentationEmail.getEmailTitle()}', - maxLines: 1, - overflow:TextOverflow.ellipsis, - style: TextStyle( - fontSize: 12, - color: _presentationEmail.isUnReadEmail() ? AppColor.subjectEmailTextColorUnRead : AppColor.baseTextColor, - fontWeight: _presentationEmail.isUnReadEmail() ? FontWeight.bold : FontWeight.w500)) - ), - if (_searchStatus == SearchStatus.ACTIVE && _presentationEmail.mailboxName.isNotEmpty) - Container( - margin: EdgeInsets.only(left: 8), - padding: EdgeInsets.only(left: 8, right: 8, top: 3, bottom: 3), - constraints: BoxConstraints(maxWidth: 100), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: AppColor.backgroundCounterMailboxColor), - child: Text( - '${_presentationEmail.mailboxName}', - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle(fontSize: 10, color: AppColor.mailboxTextColor, fontWeight: FontWeight.bold), - ) - ) - ], - )), - Row( - crossAxisAlignment: CrossAxisAlignment.center, + child: Column(children: [ + ListTile( + contentPadding: EdgeInsets.zero, + onTap: () => { + if (_onOpenEmailActionClick != null) { + _onOpenEmailActionClick!(_presentationEmail) + } + }, + onLongPress: () => { + if (_onSelectEmailActionClick != null) { + _onSelectEmailActionClick!(_presentationEmail) + } + }, + leading: Transform( + transform: Matrix4.translationValues(-5.0, 0.0, 0.0), + child: _buildAvatarIcon()), + title: Transform( + transform: Matrix4.translationValues(-8.0, 0.0, 0.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ + if (_presentationEmail.isUnReadEmail()) + Padding( + padding: EdgeInsets.only(top: 6, right: 5), + child: SvgPicture.asset(_imagePaths.icUnread, width: 9, height: 9, fit: BoxFit.fill)), Expanded( - child: _searchStatus == SearchStatus.ACTIVE && _searchQuery != null && _searchQuery!.value.isNotEmpty - ? RichTextBuilder( - '${_presentationEmail.getPartialContent()}', - '${_searchQuery!.value}', - TextStyle(fontSize: 12, color: AppColor.baseTextColor), - TextStyle(fontSize: 12, color: AppColor.baseTextColor, backgroundColor: AppColor.bgWordSearch)).build() - : Text( - '${_presentationEmail.getPartialContent()}', + child: _searchStatus == SearchStatus.ACTIVE && _searchQuery != null && _searchQuery!.value.isNotEmpty + ? RichTextBuilder( + _getInformationSender(), + '${_searchQuery!.value}', + TextStyle(fontSize: 15, color: AppColor.colorNameEmail, fontWeight: FontWeight.w600), + TextStyle(fontSize: 15, color: AppColor.colorNameEmail, backgroundColor: AppColor.bgWordSearch, fontWeight: FontWeight.w600)).build() + : Text( + _getInformationSender(), + maxLines: 1, + overflow:TextOverflow.ellipsis, + style: TextStyle(fontSize: 15, color: AppColor.colorNameEmail, fontWeight: FontWeight.w600)) + ), + Padding( + padding: EdgeInsets.only(right: 4), + child: Text( + '${_presentationEmail.getReceivedAt(Localizations.localeOf(_context).toLanguageTag())}', maxLines: 1, overflow:TextOverflow.ellipsis, - style: TextStyle(fontSize: 12, color: AppColor.baseTextColor)) - ), - if (_presentationEmail.hasAttachment == true) - (ButtonBuilder(_imagePaths.icShare) + style: TextStyle(fontSize: 13, color: AppColor.colorContentEmail))) + ], + ) + ), + subtitle: Transform( + transform: Matrix4.translationValues(-8.0, 8.0, 0.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.zero, + child: Row( + children: [ + Expanded( + child: _searchStatus == SearchStatus.ACTIVE && _searchQuery != null && _searchQuery!.value.isNotEmpty + ? RichTextBuilder( + '${_presentationEmail.getEmailTitle()}', + '${_searchQuery!.value}', + TextStyle( + fontSize: 13, + color: _presentationEmail.isUnReadEmail() ? AppColor.subjectEmailTextColorUnRead : AppColor.colorNameEmail), + TextStyle( + fontSize: 13, + backgroundColor: AppColor.bgWordSearch, + color: _presentationEmail.isUnReadEmail() ? AppColor.subjectEmailTextColorUnRead : AppColor.colorNameEmail)).build() + : Text( + '${_presentationEmail.getEmailTitle()}', + maxLines: 1, + overflow:TextOverflow.ellipsis, + style: TextStyle(fontSize: 13, color: AppColor.colorNameEmail)) + ), + if (_searchStatus == SearchStatus.ACTIVE && _presentationEmail.mailboxName.isNotEmpty) + Container( + margin: EdgeInsets.only(left: 8), + padding: EdgeInsets.only(left: 8, right: 8, top: 3, bottom: 3), + constraints: BoxConstraints(maxWidth: 100), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: AppColor.backgroundCounterMailboxColor), + child: Text( + '${_presentationEmail.mailboxName}', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: 10, color: AppColor.mailboxTextColor, fontWeight: FontWeight.bold), + ) + ) + ], + )), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: _searchStatus == SearchStatus.ACTIVE && _searchQuery != null && _searchQuery!.value.isNotEmpty + ? RichTextBuilder( + '${_presentationEmail.getPartialContent()}', + '${_searchQuery!.value}', + TextStyle(fontSize: 13, color: AppColor.colorContentEmail), + TextStyle(fontSize: 13, color: AppColor.colorContentEmail, backgroundColor: AppColor.bgWordSearch)).build() + : Text( + '${_presentationEmail.getPartialContent()}', + maxLines: 1, + overflow:TextOverflow.ellipsis, + style: TextStyle(fontSize: 13, color: AppColor.colorContentEmail)) + ), + if (_presentationEmail.hasAttachment == true) + (ButtonBuilder(_imagePaths.icShare) + ..padding(5) + ..size(20)) + .build(), + (ButtonBuilder(_presentationEmail.isFlaggedEmail() ? _imagePaths.icFlagged : _imagePaths.icFlag) ..padding(5) - ..size(20)) - .build(), - (ButtonBuilder(_presentationEmail.isFlaggedEmail() ? _imagePaths.icFlagged : _imagePaths.icFlag) - ..padding(5) - ..size(20) - ..onPressActionClick(() { + ..size(20) + ..onPressActionClick(() { if (_onMarkAsStarEmailActionClick != null) { _onMarkAsStarEmailActionClick!(_presentationEmail); } })) - .build(), + .build(), + ], + ) ], ) - ], - ) + ), ), - ), + Padding( + padding: EdgeInsets.only(top: 8, right: 12), + child: Divider(color: AppColor.lineItemListColor, height: 1, thickness: 0.2)), + ]), ) ) ); @@ -269,21 +262,7 @@ class EmailTileBuilder { } Color _getBackgroundColorItem() { - if (_selectModeAll == SelectMode.ACTIVE) { - if (_presentationEmail.selectMode == SelectMode.ACTIVE) { - return AppColor.mailboxSelectedBackgroundColor; - } else { - return _responsiveUtils.isMobile(_context) ? AppColor.bgMailboxListMail : Colors.white; - } - } else { - if (_responsiveUtils.isMobile(_context)) { - return AppColor.bgMailboxListMail; - } else if (_responsiveUtils.isDesktop(_context)) { - return _selectMode == SelectMode.ACTIVE ? AppColor.mailboxSelectedBackgroundColor : Colors.white; - } else { - return Colors.white; - } - } + return _responsiveUtils.isMobile(_context) ? AppColor.bgMailboxListMail : Colors.white; } String _getInformationSender() { diff --git a/model/lib/extensions/presentation_email_extension.dart b/model/lib/extensions/presentation_email_extension.dart index dd9f7d150..4d143ff4d 100644 --- a/model/lib/extensions/presentation_email_extension.dart +++ b/model/lib/extensions/presentation_email_extension.dart @@ -38,7 +38,8 @@ extension PresentationEmailExtension on PresentationEmail { replyTo: replyTo, mailboxIds: mailboxIds, mailboxNames: mailboxNames, - selectMode: selectMode == SelectMode.INACTIVE ? SelectMode.ACTIVE : SelectMode.INACTIVE + selectMode: selectMode == SelectMode.INACTIVE ? SelectMode.ACTIVE : SelectMode.INACTIVE, + avatarColors: avatarColors, ); } @@ -59,7 +60,8 @@ extension PresentationEmailExtension on PresentationEmail { replyTo: replyTo, mailboxIds: mailboxIds, mailboxNames: mailboxNames, - selectMode: selectMode + selectMode: selectMode, + avatarColors: avatarColors, ); } diff --git a/pubspec.yaml b/pubspec.yaml index 5645978be..d72518c29 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -181,4 +181,13 @@ flutter: weight: 700 - asset: assets/fonts/CircularStd/CircularStd-Medium.otf weight: 500 - - asset: assets/fonts/CircularStd/CircularStd-Book.otf \ No newline at end of file + - asset: assets/fonts/CircularStd/CircularStd-Book.otf + - family: SFProText + fonts: + - asset: assets/fonts/SFProText/SF-Pro-Text-Bold.otf + weight: 700 + - asset: assets/fonts/SFProText/SF-Pro-Text-Semibold.otf + weight: 600 + - asset: assets/fonts/SFProText/SF-Pro-Text-Medium.ttf + weight: 500 + - asset: assets/fonts/SFProText/SF-Pro-Text-Regular.ttf \ No newline at end of file