TF-1933 Fix text overflow with ellipsis is weird and ugly by design

(cherry picked from commit a4dd353672eca725abd66bee94347dc339b1102f)
This commit is contained in:
dab246
2023-06-27 21:48:18 +07:00
committed by Dat Vu
parent bc8a03cbce
commit 04a8274b49
13 changed files with 115 additions and 134 deletions
+1
View File
@@ -49,6 +49,7 @@ export 'presentation/views/text/text_field_builder.dart';
export 'presentation/views/text/text_form_field_builder.dart';
export 'presentation/views/text/input_decoration_builder.dart';
export 'presentation/views/text/rich_text_builder.dart';
export 'presentation/views/text/text_overflow_builder.dart';
export 'presentation/views/responsive/responsive_widget.dart';
export 'presentation/views/list/tree_view.dart';
export 'presentation/views/button/button_builder.dart';
@@ -40,8 +40,9 @@ extension StringExtension on String {
}
}
String get withUnicodeCharacter {
String get overflow {
return characters
.replaceAll(Characters(''), Characters('\u{200B}'))
.replaceAll(Characters('-'), Characters('\u{2011}'))
.toString();
}
@@ -0,0 +1,38 @@
import 'package:core/presentation/extensions/string_extension.dart';
import 'package:core/presentation/utils/style_utils.dart';
import 'package:flutter/material.dart';
class TextOverflowBuilder extends StatelessWidget {
final String data;
final TextStyle? style;
final TextAlign? textAlign;
final bool? softWrap;
final int? maxLines;
final TextDirection? textDirection;
final TextOverflow? overflow;
const TextOverflowBuilder(this.data, {
super.key,
this.style,
this.textAlign,
this.softWrap = CommonTextStyle.defaultSoftWrap,
this.maxLines = 1,
this.textDirection,
this.overflow = CommonTextStyle.defaultTextOverFlow,
});
@override
Widget build(BuildContext context) {
return Text(
data.overflow,
style: style,
textAlign: textAlign,
softWrap: softWrap,
maxLines: maxLines,
textDirection: textDirection,
overflow: overflow,
);
}
}
@@ -1,6 +1,5 @@
import 'package:core/presentation/extensions/capitalize_extension.dart';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/extensions/string_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
@@ -8,6 +7,7 @@ import 'package:core/presentation/utils/style_utils.dart';
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/views/list/sliver_grid_delegate_fixed_height.dart';
import 'package:core/presentation/views/text/text_field_builder.dart';
import 'package:core/presentation/views/text/text_overflow_builder.dart';
import 'package:core/utils/direction_utils.dart';
import 'package:core/utils/platform_info.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
@@ -85,13 +85,10 @@ abstract class BaseComposerView extends GetWidget<ComposerController>
)
),
),
Expanded(child: Text(
Expanded(child: TextOverflowBuilder(
controller.identitySelected.value != null
? (controller.identitySelected.value?.email ?? '').withUnicodeCharacter
: (controller.userProfile?.email ?? '').withUnicodeCharacter,
maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
? (controller.identitySelected.value?.email ?? '')
: (controller.userProfile?.email ?? ''),
style: const TextStyle(
fontSize: 17,
fontWeight: FontWeight.normal,
@@ -1,9 +1,9 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/extensions/string_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/style_utils.dart';
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/views/text/text_overflow_builder.dart';
import 'package:core/utils/direction_utils.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
@@ -293,15 +293,12 @@ class MailBoxFolderTileBuilder {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Text(
(_mailboxNode.item.name?.name ?? '').withUnicodeCharacter,
maxLines: 1,
softWrap: CommonTextStyle.defaultSoftWrap,
overflow: CommonTextStyle.defaultTextOverFlow,
child: TextOverflowBuilder(
(_mailboxNode.item.name?.name ?? ''),
style: TextStyle(
fontSize: _mailboxNode.item.isTeamMailboxes ? 16 : 15,
color: _mailboxNode.item.isTeamMailboxes ? Colors.black : AppColor.colorNameEmail,
fontWeight: _mailboxNode.item.isTeamMailboxes ? FontWeight.bold : FontWeight.normal),
fontSize: _mailboxNode.item.isTeamMailboxes ? 16 : 15,
color: _mailboxNode.item.isTeamMailboxes ? Colors.black : AppColor.colorNameEmail,
fontWeight: _mailboxNode.item.isTeamMailboxes ? FontWeight.bold : FontWeight.normal),
),
),
if (showTrailingItem)
@@ -309,15 +306,12 @@ class MailBoxFolderTileBuilder {
],
),
if(_mailboxNode.item.isTeamMailboxes)
Text(
(_mailboxNode.item.emailTeamMailBoxes ?? '').withUnicodeCharacter,
maxLines: 1,
softWrap: CommonTextStyle.defaultSoftWrap,
overflow: CommonTextStyle.defaultTextOverFlow,
TextOverflowBuilder(
(_mailboxNode.item.emailTeamMailBoxes ?? ''),
style: const TextStyle(
fontSize: 13,
color: AppColor.colorEmailAddressFull,
fontWeight: FontWeight.w400),
fontSize: 13,
color: AppColor.colorEmailAddressFull,
fontWeight: FontWeight.w400),
)
],
);
@@ -1,14 +1,13 @@
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/utils/style_utils.dart';
import 'package:core/presentation/views/text/text_overflow_builder.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
class SendingQueueMailboxWidget extends StatelessWidget {
@@ -59,11 +58,8 @@ class SendingQueueMailboxWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Text(
child: TextOverflowBuilder(
AppLocalizations.of(context).sendingQueue,
maxLines: 1,
softWrap: CommonTextStyle.defaultSoftWrap,
overflow: CommonTextStyle.defaultTextOverFlow,
style: const TextStyle(
fontSize: 15,
color: AppColor.colorNameEmail,
@@ -71,14 +67,9 @@ class SendingQueueMailboxWidget extends StatelessWidget {
),
),
Padding(
padding: EdgeInsets.only(
right: AppUtils.isDirectionRTL(context) ? 0 : 12,
left: AppUtils.isDirectionRTL(context) ? 12 : 0,
),
child: Text(
padding: const EdgeInsetsDirectional.only(start: 12),
child: TextOverflowBuilder(
_getCountSendingEmails(),
maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow,
style: const TextStyle(
fontSize: 13,
color: Colors.black,
@@ -1,9 +1,8 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/extensions/string_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/style_utils.dart';
import 'package:core/presentation/views/image/avatar_builder.dart';
import 'package:core/presentation/views/text/text_overflow_builder.dart';
import 'package:core/utils/direction_utils.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
@@ -52,11 +51,8 @@ class UserInformationWidgetBuilder extends StatelessWidget {
Expanded(child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_userProfile != null ? '${_userProfile?.email}'.withUnicodeCharacter : '',
maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
TextOverflowBuilder(
_userProfile != null ? '${_userProfile?.email}' : '',
style: const TextStyle(
fontSize: 17,
color: AppColor.colorNameEmail,
@@ -65,12 +61,15 @@ class UserInformationWidgetBuilder extends StatelessWidget {
),
const SizedBox(height: 10),
if (subtitle != null)
MaterialTextButton(
label: AppLocalizations.of(context).manage_account,
onTap: onSubtitleClick,
borderRadius: 20,
padding: const EdgeInsetsDirectional.symmetric(horizontal: 8, vertical: 8),
customStyle: const TextStyle(fontSize: 14, color: AppColor.colorTextButton),
Transform(
transform: Matrix4.translationValues(-8.0, 0.0, 0.0),
child: MaterialTextButton(
label: AppLocalizations.of(context).manage_account,
onTap: onSubtitleClick,
borderRadius: 20,
padding: const EdgeInsetsDirectional.symmetric(horizontal: 8, vertical: 8),
customStyle: const TextStyle(fontSize: 14, color: AppColor.colorTextButton),
),
)
])),
if (PlatformInfo.isMobile)
@@ -1,8 +1,7 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/extensions/string_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/style_utils.dart';
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/views/text/text_overflow_builder.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
@@ -65,10 +64,8 @@ class IdentityListTileBuilder extends StatelessWidget {
children: [
Padding(
padding: const EdgeInsets.only(bottom: 6),
child: Text(
(identity.name ?? '').withUnicodeCharacter,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
child: TextOverflowBuilder(
(identity.name ?? ''),
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
@@ -122,15 +119,13 @@ class IdentityListTileBuilder extends StatelessWidget {
alignment: Alignment.centerLeft,
child: SvgPicture.asset(imagePath, width: 15, height: 15))),
const SizedBox(width: 4),
Expanded(child: Text(
(text ?? '').withUnicodeCharacter,
Expanded(child: TextOverflowBuilder(
(text ?? ''),
style: const TextStyle(
color: AppColor.colorEmailAddressFull,
fontWeight: FontWeight.normal,
fontSize: 13,
),
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap
))
]),
);
@@ -151,15 +146,13 @@ class IdentityListTileBuilder extends StatelessWidget {
decoration: TextDecoration.underline,
color: AppColor.colorTextButton))),
const SizedBox(width: 4),
Expanded(child: Text(
(text ?? '').withUnicodeCharacter,
Expanded(child: TextOverflowBuilder(
(text ?? ''),
style: const TextStyle(
color: AppColor.colorEmailAddressFull,
fontWeight: FontWeight.normal,
fontSize: 13,
),
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap
))
]),
);
@@ -1,9 +1,8 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/extensions/string_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/style_utils.dart';
import 'package:core/presentation/views/responsive/responsive_widget.dart';
import 'package:core/presentation/views/text/text_overflow_builder.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@@ -204,11 +203,8 @@ class _MailboxSearchedItemBuilderState extends State<MailboxSearchedItemBuilder>
}
Widget _buildTitleItem() {
return Text(
(widget._presentationMailbox.name?.name ?? '').withUnicodeCharacter,
maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
return TextOverflowBuilder(
(widget._presentationMailbox.name?.name ?? ''),
style: const TextStyle(
fontSize: 15,
color: Colors.black
@@ -218,11 +214,8 @@ class _MailboxSearchedItemBuilderState extends State<MailboxSearchedItemBuilder>
Widget _buildSubtitleItem() {
if (widget._presentationMailbox.mailboxPath?.isNotEmpty == true) {
return Text(
(widget._presentationMailbox.mailboxPath ?? '').withUnicodeCharacter,
maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap,
return TextOverflowBuilder(
(widget._presentationMailbox.mailboxPath ?? ''),
style: const TextStyle(
fontSize: 11,
color: AppColor.colorMailboxPath,
@@ -230,11 +223,8 @@ class _MailboxSearchedItemBuilderState extends State<MailboxSearchedItemBuilder>
),
);
} else if (widget._presentationMailbox.isTeamMailboxes) {
return Text(
(widget._presentationMailbox.emailTeamMailBoxes ?? '').withUnicodeCharacter,
maxLines: 1,
softWrap: CommonTextStyle.defaultSoftWrap,
overflow: CommonTextStyle.defaultTextOverFlow,
return TextOverflowBuilder(
(widget._presentationMailbox.emailTeamMailBoxes ?? ''),
style: const TextStyle(
fontSize: 11,
color: AppColor.colorEmailAddressFull,
@@ -3,7 +3,6 @@ import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/style_utils.dart';
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/direction_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@@ -33,7 +32,6 @@ class AppBarSendingQueueWidget extends StatelessWidget {
final imagePaths = Get.find<ImagePaths>();
return LayoutBuilder(builder: (context, constraints) {
log('AppBarSendingQueueWidget::build(): MAX_WIDTH: ${constraints.maxWidth}');
return Container(
height: 52,
color: Colors.white,
@@ -1,7 +1,6 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/utils/app_logger.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_queue_utils.dart';
@@ -17,7 +16,6 @@ class BannerMessageSendingQueueWidget extends StatelessWidget {
final imagePath = getBinding<ImagePaths>();
return LayoutBuilder(builder: (context, constraints) {
log('BannerMessageSendingQueueWidget::build(): MAX_WIDTH: ${constraints.maxWidth}');
return Container(
margin: SendingQueueUtils.getMarginBannerMessageByResponsiveSize(constraints.maxWidth),
padding: const EdgeInsets.all(16),
@@ -1,9 +1,8 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/extensions/string_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/style_utils.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/presentation/views/text/text_overflow_builder.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
@@ -41,7 +40,6 @@ class SendingEmailTileWidget extends StatelessWidget {
final imagePaths = Get.find<ImagePaths>();
return LayoutBuilder(builder: (context, constraints) {
log('SendingEmailTileWidget::build(): MAX_WIDTH: ${constraints.maxWidth}');
return Material(
color: Colors.transparent,
child: InkWell(
@@ -90,11 +88,8 @@ class SendingEmailTileWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(children: [
Expanded(child: Text(
AppLocalizations.of(context).titleRecipientSendingEmail(sendingEmail.presentationEmail.recipientsName()).withUnicodeCharacter,
softWrap: CommonTextStyle.defaultSoftWrap,
overflow: CommonTextStyle.defaultTextOverFlow,
maxLines: 1,
Expanded(child: TextOverflowBuilder(
AppLocalizations.of(context).titleRecipientSendingEmail(sendingEmail.presentationEmail.recipientsName()),
style: TextStyle(
fontSize: 15,
color: sendingEmail.sendingState.getTitleSendingEmailItemColor(),
@@ -142,11 +137,8 @@ class SendingEmailTileWidget extends StatelessWidget {
)
]),
const SizedBox(height: 8),
Text(
sendingEmail.presentationEmail.getEmailTitle().withUnicodeCharacter,
softWrap: CommonTextStyle.defaultSoftWrap,
overflow: CommonTextStyle.defaultTextOverFlow,
maxLines: 1,
TextOverflowBuilder(
sendingEmail.presentationEmail.getEmailTitle(),
style: TextStyle(
fontSize: 13,
color: sendingEmail.sendingState.getSubTitleSendingEmailItemColor(),
@@ -5,6 +5,7 @@ import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/style_utils.dart';
import 'package:core/presentation/views/text/rich_text_builder.dart';
import 'package:core/presentation/views/text/text_overflow_builder.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@@ -39,11 +40,8 @@ mixin BaseEmailItemTile {
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: AppColor.backgroundCounterMailboxColor),
child: Text(
email.mailboxName.withUnicodeCharacter,
maxLines: 1,
softWrap: CommonTextStyle.defaultSoftWrap,
overflow: CommonTextStyle.defaultTextOverFlow,
child: TextOverflowBuilder(
email.mailboxName,
style: const TextStyle(
fontSize: 10,
color: AppColor.mailboxTextColor,
@@ -85,7 +83,7 @@ mixin BaseEmailItemTile {
) {
if (isSearchEnabled(isSearchEmailRunning, query)) {
return RichTextBuilder(
informationSender(email, mailbox).withUnicodeCharacter,
informationSender(email, mailbox).overflow,
query?.value ?? '',
TextStyle(
fontSize: 15,
@@ -98,16 +96,13 @@ mixin BaseEmailItemTile {
fontWeight: buildFontForReadEmail(email))
).build();
} else {
return Text(
informationSender(email, mailbox).withUnicodeCharacter,
softWrap: CommonTextStyle.defaultSoftWrap,
return TextOverflowBuilder(
informationSender(email, mailbox),
style: TextStyle(
fontSize: 15,
overflow: CommonTextStyle.defaultTextOverFlow,
maxLines: 1,
style: TextStyle(
fontSize: 15,
overflow: CommonTextStyle.defaultTextOverFlow,
color: buildTextColorForReadEmail(email),
fontWeight: buildFontForReadEmail(email))
color: buildTextColorForReadEmail(email),
fontWeight: buildFontForReadEmail(email))
);
}
}
@@ -119,7 +114,7 @@ mixin BaseEmailItemTile {
) {
if (isSearchEnabled(isSearchEmailRunning, query)) {
return RichTextBuilder(
email.getEmailTitle().withUnicodeCharacter,
email.getEmailTitle().overflow,
query?.value ?? '',
TextStyle(
fontSize: 13,
@@ -132,15 +127,12 @@ mixin BaseEmailItemTile {
fontWeight: buildFontForReadEmail(email))
).build();
} else {
return Text(
email.getEmailTitle().withUnicodeCharacter,
softWrap: CommonTextStyle.defaultSoftWrap,
overflow: CommonTextStyle.defaultTextOverFlow,
maxLines: 1,
style: TextStyle(
fontSize: 13,
color: buildTextColorForReadEmail(email),
fontWeight: buildFontForReadEmail(email))
return TextOverflowBuilder(
email.getEmailTitle(),
style: TextStyle(
fontSize: 13,
color: buildTextColorForReadEmail(email),
fontWeight: buildFontForReadEmail(email))
);
}
}
@@ -152,7 +144,7 @@ mixin BaseEmailItemTile {
) {
if (isSearchEnabled(isSearchEmailRunning, query)) {
return RichTextBuilder(
email.getPartialContent().withUnicodeCharacter,
email.getPartialContent().overflow,
query?.value ?? '',
const TextStyle(
fontSize: 13,
@@ -164,15 +156,12 @@ mixin BaseEmailItemTile {
backgroundColor: AppColor.bgWordSearch)
).build();
} else {
return Text(
email.getPartialContent().withUnicodeCharacter,
maxLines: 1,
softWrap: CommonTextStyle.defaultSoftWrap,
overflow: CommonTextStyle.defaultTextOverFlow,
style: const TextStyle(
fontSize: 13,
color: AppColor.colorContentEmail,
fontWeight: FontWeight.normal)
return TextOverflowBuilder(
email.getPartialContent(),
style: const TextStyle(
fontSize: 13,
color: AppColor.colorContentEmail,
fontWeight: FontWeight.normal)
);
}
}