TF-46 Create object, builder for model and core module

This commit is contained in:
dab246
2021-08-26 17:03:04 +07:00
committed by Dat H. Pham
parent b70fc6edb8
commit 17bad5ec51
21 changed files with 203 additions and 12 deletions
+4
View File
@@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18 6L6 18" stroke="#7E869B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6 6L18 18" stroke="#7E869B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 311 B

+4
View File
@@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.7" d="M10 13C10.4295 13.5741 10.9774 14.0491 11.6066 14.3929C12.2357 14.7367 12.9315 14.9411 13.6467 14.9923C14.3618 15.0435 15.0796 14.9403 15.7513 14.6897C16.4231 14.4392 17.0331 14.047 17.54 13.54L20.54 10.54C21.4508 9.59695 21.9548 8.33394 21.9434 7.02296C21.932 5.71198 21.4061 4.45791 20.4791 3.53087C19.5521 2.60383 18.298 2.07799 16.987 2.0666C15.676 2.0552 14.413 2.55918 13.47 3.46997L11.75 5.17997" stroke="#7E869B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14 11C13.5705 10.4259 13.0226 9.9508 12.3934 9.60704C11.7642 9.26328 11.0684 9.05886 10.3533 9.00765C9.63816 8.95643 8.92037 9.05961 8.24861 9.3102C7.57685 9.56079 6.96684 9.95291 6.45996 10.46L3.45996 13.46C2.54917 14.403 2.04519 15.666 2.05659 16.977C2.06798 18.288 2.59382 19.542 3.52086 20.4691C4.4479 21.3961 5.70197 21.922 7.01295 21.9334C8.32393 21.9447 9.58694 21.4408 10.53 20.53L12.24 18.82" stroke="#7E869B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

+5
View File
@@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 13C12.5523 13 13 12.5523 13 12C13 11.4477 12.5523 11 12 11C11.4477 11 11 11.4477 11 12C11 12.5523 11.4477 13 12 13Z" stroke="#7E869B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19 13C19.5523 13 20 12.5523 20 12C20 11.4477 19.5523 11 19 11C18.4477 11 18 11.4477 18 12C18 12.5523 18.4477 13 19 13Z" stroke="#7E869B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M5 13C5.55228 13 6 12.5523 6 12C6 11.4477 5.55228 11 5 11C4.44772 11 4 11.4477 4 12C4 12.5523 4.44772 13 5 13Z" stroke="#7E869B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 733 B

+11
View File
@@ -0,0 +1,11 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M22.2843 12.1421H6.72793" stroke="#ACAFFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M22.2843 12.1421L3.19246 21.3345L6.728 12.1421L3.19246 2.94975L22.2843 12.1421Z" stroke="#ACAFFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 520 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 6L8 10L12 6" stroke="#A2A8B5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 211 B

+1
View File
@@ -25,6 +25,7 @@ export 'presentation/views/list/tree_view.dart';
export 'presentation/views/button/button_builder.dart';
export 'presentation/views/image/avatar_builder.dart';
export 'presentation/views/list/sliver_grid_delegate_fixed_height.dart';
export 'presentation/views/text/text_form_field_builder.dart';
// Resources
export 'presentation/resources/assets_paths.dart';
@@ -16,3 +16,21 @@ extension DateTimeExtension on DateTime {
return now.year == this.year;
}
}
extension DateTimeNullableExtension on DateTime? {
String toPattern() {
if (this != null) {
if (this!.isToday()) {
return 'h:mm a';
} else if (this!.isYesterday()) {
return 'EEE';
} else if (this!.isThisYear()) {
return 'MMMd';
} else {
return 'yMMMd';
}
}
return 'yMMMd';
}
}
@@ -46,4 +46,10 @@ extension AppColor on Color {
static const avatarTextColor = Color(0xFF3840F7);
static const sentTimeTextColorUnRead = Color(0xFF182952);
static const subjectEmailTextColorUnRead = Color(0xFF3840F7);
static const dividerColor = Color(0xFFEAEAEA);
static const bgComposer = Color(0xFFFBFBFF);
static const emailAddressChipColor = Color(0xFFF5F5F7);
static const enableSendEmailButtonColor = Color(0xFF3840F7);
static const disableSendEmailButtonColor = Color(0xFFACAFFF);
static const borderLeftEmailContentColor = Color(0xFFEFEFEF);
}
@@ -12,4 +12,18 @@ extension HtmlExtension on String {
String removeMaxHeightZeroPixel() => replaceAll(RegExp('max-height:0px;'), '');
String changeStyleBackground() => replaceAll(RegExp('background:'), 'background-color:');
String addBorderLefForBlockQuote() => replaceAll(RegExp('<blockquote'), '<blockquote style=\"margin-left:8px;margin-right:8px;padding-left:12px;padding-right:12px;border-left:6px solid #EFEFEF;\"');
String addBlockTag(String tag, {String? attribute}) => attribute != null ? '<$tag $attribute>$this</$tag>' : '<$tag>$this</$tag>';
String addNewLineTag({int count = 1}) {
if (count == 1) return '$this<br>';
var htmlString = this;
for (var i = 0; i < count; i++) {
htmlString = '$htmlString<br>';
}
return htmlString;
}
}
@@ -31,6 +31,11 @@ class ImagePaths {
String get icOffline => _getImagePath('ic_offline.svg');
String get icFlagged => _getImagePath('ic_flagged.svg');
String get icMoreReceiver => _getImagePath('ic_more_receiver.svg');
String get icComposerClose => _getImagePath('ic_composer_close.svg');
String get icComposerSend => _getImagePath('ic_composer_send.svg');
String get icComposerMenu => _getImagePath('ic_composer_menu.svg');
String get icComposerFileShare => _getImagePath('ic_composer_file_share.svg');
String get icExpandAddress => _getImagePath('ic_expand_address.svg');
String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
@@ -20,7 +20,8 @@ class HtmlMessagePurifier {
.removeMaxHeightZeroPixel()
.removeMaxWidthZeroPixel()
.removeHeightZeroPixel()
.removeWidthZeroPixel();
.removeWidthZeroPixel()
.addBorderLefForBlockQuote();
}
String sanitizeHtml(
@@ -16,6 +16,7 @@ class ButtonBuilder {
double? _padding;
bool? _isVertical;
Key? _key;
Color? _color;
ButtonBuilder key(Key key) {
_key = key;
@@ -27,6 +28,11 @@ class ButtonBuilder {
return this;
}
ButtonBuilder color(Color color) {
_color = color;
return this;
}
ButtonBuilder padding(double padding) {
_padding = padding;
return this;
@@ -40,7 +46,7 @@ class ButtonBuilder {
ButtonBuilder(this._icon);
ButtonBuilder onBackActionClick(OnPressActionClick onPressActionClick) {
ButtonBuilder onPressActionClick(OnPressActionClick onPressActionClick) {
_onPressActionClick = onPressActionClick;
return this;
}
@@ -88,7 +94,7 @@ class ButtonBuilder {
Widget _buildIcon() => Padding(
padding: EdgeInsets.all(_padding ?? 10),
child: SvgPicture.asset(_icon ?? '', width: _size ?? 24, height: _size ?? 24, fit: BoxFit.fill));
child: SvgPicture.asset(_icon ?? '', width: _size ?? 24, height: _size ?? 24, fit: BoxFit.fill, color: _color));
Widget _buildText() {
return Text(
@@ -8,6 +8,8 @@ class TextFieldBuilder {
TextInputAction? _textInputAction;
InputDecoration? _inputDecoration;
bool? _obscureText;
int? _maxLines = 1;
TextEditingController? _textController;
TextFieldBuilder key(Key key) {
_key = key;
@@ -39,13 +41,25 @@ class TextFieldBuilder {
return this;
}
TextFieldBuilder setText(String value) {
_textController = TextEditingController.fromValue(TextEditingValue(text: value));
return this;
}
TextFieldBuilder maxLines(int? value) {
_maxLines = value;
return this;
}
TextField build() {
return TextField(
key: _key ?? Key('TextFieldBuilder'),
onChanged: _onTextChange,
cursorColor: AppColor.primaryColor,
controller: _textController,
textInputAction: _textInputAction,
decoration: _inputDecoration,
maxLines: _maxLines,
style: _textStyle ?? TextStyle(color: AppColor.textFieldTextColor),
obscureText: _obscureText ?? false,
);
@@ -0,0 +1,53 @@
import 'package:flutter/material.dart';
typedef OnTapActionClick = void Function();
class TextFormFieldBuilder {
Key? _key;
ValueChanged<String>? _onTextChange;
InputDecoration? _inputDecoration;
TextInputAction? _textInputAction;
TextStyle? _textStyle;
OnTapActionClick? _onTapActionClick;
void key(Key key) {
_key = key;
}
void onChange(ValueChanged<String> onChange) {
_onTextChange = onChange;
}
void textStyle(TextStyle style) {
_textStyle = style;
}
void textDecoration(InputDecoration inputDecoration) {
_inputDecoration = inputDecoration;
}
void textInputAction(TextInputAction inputAction) {
_textInputAction = inputAction;
}
void addOnTapActionClick(OnTapActionClick onTapActionClick) {
_onTapActionClick = onTapActionClick;
}
TextFormField build() {
return TextFormField(
key: _key ?? Key('text_form_field_builder'),
keyboardType: TextInputType.multiline,
maxLines: null,
onChanged: _onTextChange,
style: _textStyle,
decoration: _inputDecoration,
textInputAction: _textInputAction,
onTap: () {
if (_onTapActionClick != null) {
_onTapActionClick!();
}
},
);
}
}
+7
View File
@@ -0,0 +1,7 @@
enum EmailActionType {
reply,
forward,
replyAll,
compose,
}
@@ -0,0 +1,6 @@
enum PrefixEmailAddress {
to,
cc,
bcc
}
+1 -1
View File
@@ -53,7 +53,7 @@ class PresentationEmail with EquatableMixin {
String getAvatarText() {
if (getSenderName().isNotEmpty) {
return getSenderName().substring(0, 1).toUpperCase();
return getSenderName()[0].toUpperCase();
}
return '';
}
@@ -3,11 +3,27 @@ import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
extension EmailAddressExtension on EmailAddress {
String asString() {
if (name != null && name!.isNotEmpty) {
if (getName().isNotEmpty) {
return name!;
} else if (email != null && email!.isNotEmpty) {
} else if (getEmail().isNotEmpty) {
return email!;
}
return '';
}
String asFullString() {
if (getName().isNotEmpty) {
if (getEmail().isNotEmpty) {
return '${name!} <${email!}>';
}
return name!;
} else if (getEmail().isNotEmpty) {
return email!;
}
return '';
}
String getEmail() => email != null ? email! : '';
String getName() => name != null ? name! : '';
}
@@ -4,20 +4,21 @@ import 'package:model/extensions/email_address_extension.dart';
extension ListEmailAddressExtension on Set<EmailAddress>? {
List<String> getListEmailAddress({ExpandMode expandMode = ExpandMode.EXPAND, int limitAddress = 1}) {
List<String> getListEmailAddress({ExpandMode expandMode = ExpandMode.EXPAND, int limitAddress = 1, bool isFullEmailAddress = false}) {
if (this != null) {
if (expandMode == ExpandMode.EXPAND) {
return this!.map((emailAddress) => emailAddress.asString()).toList();
return this!.map((emailAddress) => isFullEmailAddress ? emailAddress.asFullString() : emailAddress.asString()).toList();
} else {
final address = this!.map((emailAddress) => emailAddress.asString()).toList();
final address = this!.map((emailAddress) => isFullEmailAddress ? emailAddress.asFullString() : emailAddress.asString()).toList();
return address.length > limitAddress ? address.sublist(0, limitAddress) : address;
}
}
return [];
}
String listEmailAddressToString({ExpandMode expandMode = ExpandMode.EXPAND, int limitAddress = 1}) {
return getListEmailAddress(expandMode: expandMode, limitAddress: limitAddress).join(', ');
String listEmailAddressToString({ExpandMode expandMode = ExpandMode.EXPAND, int limitAddress = 1, bool isFullEmailAddress = false}) {
final listEmail = getListEmailAddress(expandMode: expandMode, limitAddress: limitAddress, isFullEmailAddress: isFullEmailAddress);
return listEmail.isNotEmpty ? listEmail.join(', ') : '';
}
int numberEmailAddress() => this != null ? this!.length : 0;
@@ -0,0 +1,13 @@
import 'package:intl/intl.dart';
import 'package:jmap_dart_client/jmap/core/utc_date.dart';
extension UTCDateExtension on UTCDate? {
String formatDate({String pattern = 'yMMMd', String locale = 'en_US'}) {
if (this != null) {
return DateFormat(pattern, locale).format(this!.value);
} else {
return '';
}
}
}
+4 -1
View File
@@ -19,9 +19,12 @@ export 'mailbox/expand_mode.dart';
// Email
export 'email/presentation_email.dart';
export 'email/email_content.dart';
export 'email/prefix_email_address.dart';
export 'email/email_action_type.dart';
export 'email/presentation_email_address.dart';
// Extensions
export 'extensions/email_address_extension.dart';
export 'extensions/list_email_address_extension.dart';
export 'extensions/session_extension.dart';
export 'extensions/session_extension.dart';
export 'extensions/utcdate_extension.dart';