TF-48 Implement compose and send email with simple text
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||||
|
|
||||||
|
class EmailRequest with EquatableMixin {
|
||||||
|
|
||||||
|
final Email email;
|
||||||
|
final Id submissionCreateId;
|
||||||
|
final MailboxId? mailboxIdSaved;
|
||||||
|
|
||||||
|
EmailRequest(this.email, this.submissionCreateId, {this.mailboxIdSaved});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [email, submissionCreateId, mailboxIdSaved];
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:core/core.dart';
|
||||||
|
|
||||||
|
class SendEmailSuccess extends UIState {
|
||||||
|
|
||||||
|
SendEmailSuccess();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [];
|
||||||
|
}
|
||||||
|
|
||||||
|
class SendEmailFailure extends FeatureFailure {
|
||||||
|
final exception;
|
||||||
|
|
||||||
|
SendEmailFailure(this.exception);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [exception];
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import 'package:core/core.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
|
||||||
|
|
||||||
|
class SendEmailInteractor {
|
||||||
|
final EmailRepository emailRepository;
|
||||||
|
|
||||||
|
SendEmailInteractor(this.emailRepository);
|
||||||
|
|
||||||
|
Stream<Either<Failure, Success>> execute(AccountId accountId, EmailRequest emailRequest) async* {
|
||||||
|
try {
|
||||||
|
yield Right<Failure, Success>(UIState.loading);
|
||||||
|
final result = await emailRepository.sendEmail(accountId, emailRequest);
|
||||||
|
if (result) {
|
||||||
|
yield Right<Failure, Success>(SendEmailSuccess());
|
||||||
|
} else {
|
||||||
|
yield Left(SendEmailFailure(result));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
yield Left(SendEmailFailure(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,56 @@
|
|||||||
|
import 'package:core/core.dart';
|
||||||
|
import 'package:core/presentation/utils/app_toast.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:html_editor_enhanced/html_editor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/data/datasource/autocomplete_datasource.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/data/datasource/composer_datasource.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/data/datasource_impl/autocomplete_datasource_impl.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/data/datasource_impl/composer_datasource_impl.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/data/datasource_impl/local_autocomplete_datasource_impl.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/data/datasource_impl/local_composer_datasource_impl.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/data/local/email_address_database_manager.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/data/repository/auto_complete_repository_impl.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/data/repository/composer_repository_impl.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/repository/auto_complete_repository.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/repository/composer_repository.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/usecases/save_email_addresses_interactor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/usecases/search_email_address_interactor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class ComposerBindings extends Bindings {
|
class ComposerBindings extends Bindings {
|
||||||
@override
|
@override
|
||||||
void dependencies() {
|
void dependencies() {
|
||||||
Get.lazyPut(() => ComposerController());
|
Get.lazyPut(() => EmailAddressDatabaseManager(Get.find<DatabaseClient>()));
|
||||||
|
Get.lazyPut(() => ComposerDataSourceImpl());
|
||||||
|
Get.lazyPut(() => LocalComposerDataSourceImpl(Get.find<EmailAddressDatabaseManager>()));
|
||||||
|
Get.lazyPut<ComposerDataSource>(() => Get.find<ComposerDataSourceImpl>());
|
||||||
|
Get.lazyPut(() => ComposerRepositoryImpl({
|
||||||
|
DataSourceType.network: Get.find<ComposerDataSource>(),
|
||||||
|
DataSourceType.local: Get.find<LocalComposerDataSourceImpl>(),
|
||||||
|
}));
|
||||||
|
Get.lazyPut<ComposerRepository>(() => Get.find<ComposerRepositoryImpl>());
|
||||||
|
Get.lazyPut(() => SendEmailInteractor(Get.find<EmailRepository>()));
|
||||||
|
Get.lazyPut(() => SaveEmailAddressesInteractor(Get.find<ComposerRepository>()));
|
||||||
|
Get.lazyPut(() => AutoCompleteDataSourceImpl());
|
||||||
|
Get.lazyPut<AutoCompleteDataSource>(() => Get.find<AutoCompleteDataSourceImpl>());
|
||||||
|
Get.lazyPut(() => LocalAutoCompleteDataSourceImpl(Get.find<EmailAddressDatabaseManager>()));
|
||||||
|
Get.lazyPut(() => AutoCompleteRepositoryImpl({
|
||||||
|
DataSourceType.network: Get.find<AutoCompleteDataSource>(),
|
||||||
|
DataSourceType.local: Get.find<LocalAutoCompleteDataSourceImpl>(),
|
||||||
|
}));
|
||||||
|
Get.lazyPut<AutoCompleteRepository>(() => Get.find<AutoCompleteRepositoryImpl>());
|
||||||
|
Get.lazyPut(() => SearchEmailAddressInteractor(Get.find<AutoCompleteRepository>()));
|
||||||
|
Get.lazyPut(() => Uuid());
|
||||||
|
Get.lazyPut(() => HtmlEditorController());
|
||||||
|
Get.lazyPut(() => ComposerController(
|
||||||
|
Get.find<SendEmailInteractor>(),
|
||||||
|
Get.find<SaveEmailAddressesInteractor>(),
|
||||||
|
Get.find<SearchEmailAddressInteractor>(),
|
||||||
|
Get.find<AppToast>(),
|
||||||
|
Get.find<Uuid>(),
|
||||||
|
Get.find<HtmlEditorController>()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,44 +1,91 @@
|
|||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:core/core.dart';
|
import 'package:core/core.dart';
|
||||||
|
import 'package:core/presentation/utils/app_toast.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:html_editor_enhanced/html_editor.dart';
|
import 'package:html_editor_enhanced/html_editor.dart';
|
||||||
|
import 'package:http_parser/http_parser.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email_body_part.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email_body_value.dart';
|
||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
|
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/model/auto_complete_pattern.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/state/search_email_address_state.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/usecases/save_email_addresses_interactor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/usecases/search_email_address_interactor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/usecases/send_email_interactor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email/presentation/constants/email_constants.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/model/attachment_file.dart';
|
import 'package:tmail_ui_user/features/email/presentation/model/attachment_file.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/extensions/email_content_extension.dart';
|
import 'package:tmail_ui_user/features/email/presentation/extensions/email_content_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/model/message_content.dart';
|
import 'package:tmail_ui_user/features/email/presentation/model/message_content.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class ComposerController extends GetxController {
|
class ComposerController extends BaseController {
|
||||||
|
|
||||||
final expandMode = ExpandMode.COLLAPSE.obs;
|
final expandMode = ExpandMode.COLLAPSE.obs;
|
||||||
final composerArguments = Rxn<ComposerArguments>();
|
final composerArguments = Rxn<ComposerArguments>();
|
||||||
final isEnableEmailSendButton = false.obs;
|
final isEnableEmailSendButton = false.obs;
|
||||||
final listReplyToEmailAddress = <EmailAddress>[].obs;
|
final listReplyToEmailAddress = <EmailAddress>[].obs;
|
||||||
final htmlEditorController = HtmlEditorController();
|
|
||||||
|
|
||||||
final listEmailAddressSuggestion = [
|
final SendEmailInteractor _sendEmailInteractor;
|
||||||
EmailAddress('Mike Jones', 'user1@linagora.com'),
|
final SaveEmailAddressesInteractor _saveEmailAddressInteractor;
|
||||||
EmailAddress('Mike Smith', 'user2@linagora.com'),
|
final SearchEmailAddressInteractor _searchEmailAddressInteractor;
|
||||||
EmailAddress('Jane Smith', 'user3@linagora.com'),
|
final AppToast _appToast;
|
||||||
EmailAddress('User4', 'user4@linagora.com'),
|
final Uuid _uuid;
|
||||||
EmailAddress('User5', 'user5@linagora.com')
|
final HtmlEditorController htmlEditorController;
|
||||||
];
|
|
||||||
List<EmailAddress> listToEmailAddress = [];
|
List<EmailAddress> listToEmailAddress = [];
|
||||||
List<EmailAddress> listCcEmailAddress = [];
|
List<EmailAddress> listCcEmailAddress = [];
|
||||||
List<EmailAddress> listBccEmailAddress = [];
|
List<EmailAddress> listBccEmailAddress = [];
|
||||||
|
String? _subjectEmail;
|
||||||
|
|
||||||
ComposerController();
|
void setSubjectEmail(String subject) => _subjectEmail = subject;
|
||||||
|
|
||||||
|
ComposerController(
|
||||||
|
this._sendEmailInteractor,
|
||||||
|
this._saveEmailAddressInteractor,
|
||||||
|
this._searchEmailAddressInteractor,
|
||||||
|
this._appToast,
|
||||||
|
this._uuid,
|
||||||
|
this.htmlEditorController,
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onReady() {
|
void onReady() async {
|
||||||
super.onReady();
|
super.onReady();
|
||||||
_getSelectedEmail();
|
_getSelectedEmail();
|
||||||
|
await searchEmailAddressSuggestion('');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onDone() {
|
||||||
|
viewState.value.fold(
|
||||||
|
(failure) {
|
||||||
|
_appToast.showErrorToast(AppLocalizations.of(Get.context!).error_message_sent);
|
||||||
|
Get.back();
|
||||||
|
},
|
||||||
|
(success) {
|
||||||
|
_saveEmailAddress();
|
||||||
|
_appToast.showSuccessToast(AppLocalizations.of(Get.context!).message_sent);
|
||||||
|
Get.back();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onError(error) {
|
||||||
|
_appToast.showErrorToast(AppLocalizations.of(Get.context!).error_message_sent);
|
||||||
|
Get.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getSelectedEmail() {
|
void _getSelectedEmail() {
|
||||||
@@ -166,6 +213,67 @@ class ComposerController extends GetxController {
|
|||||||
return emailQuotedHtml;
|
return emailQuotedHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Email> generateEmail() async {
|
||||||
|
final generateEmailId = EmailId(Id(_uuid.v1()));
|
||||||
|
final outboxMailboxId = composerArguments.value!.mapMailboxId[PresentationMailbox.roleOutbox];
|
||||||
|
final listFromEmailAddress = {
|
||||||
|
EmailAddress(
|
||||||
|
composerArguments.value!.userProfile.getNameDisplay(),
|
||||||
|
composerArguments.value!.userProfile.getEmailAddress())
|
||||||
|
};
|
||||||
|
final generatePartId = PartId(_uuid.v1());
|
||||||
|
final generateBlobId = Id(_uuid.v1());
|
||||||
|
|
||||||
|
final emailBodyText = await htmlEditorController.getText();
|
||||||
|
|
||||||
|
return Email(
|
||||||
|
generateEmailId,
|
||||||
|
mailboxIds: {outboxMailboxId!: true},
|
||||||
|
from: listFromEmailAddress,
|
||||||
|
to: listToEmailAddress.toSet(),
|
||||||
|
cc: listCcEmailAddress.toSet(),
|
||||||
|
bcc: listBccEmailAddress.toSet(),
|
||||||
|
subject: _subjectEmail,
|
||||||
|
htmlBody: {
|
||||||
|
EmailBodyPart(
|
||||||
|
partId: generatePartId,
|
||||||
|
blobId: generateBlobId,
|
||||||
|
type: MediaType.parse(EmailConstants.HTML_TEXT)
|
||||||
|
)},
|
||||||
|
bodyValues: {
|
||||||
|
generatePartId: EmailBodyValue(emailBodyText, false, false)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendEmailAction(BuildContext context) async {
|
||||||
|
if (isEnableEmailSendButton.value) {
|
||||||
|
_appToast.showToast(AppLocalizations.of(context).your_email_being_sent);
|
||||||
|
|
||||||
|
final email = await generateEmail();
|
||||||
|
final accountId = composerArguments.value!.session.accounts.keys.first;
|
||||||
|
final sentMailboxId = composerArguments.value!.mapMailboxId[PresentationMailbox.roleSent];
|
||||||
|
final submissionCreateId = Id(_uuid.v1());
|
||||||
|
|
||||||
|
consumeState(_sendEmailInteractor.execute(accountId, EmailRequest(email, submissionCreateId, mailboxIdSaved: sentMailboxId)));
|
||||||
|
} else {
|
||||||
|
_appToast.showErrorToast(AppLocalizations.of(context).your_email_should_have_at_least_one_recipient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _saveEmailAddress() {
|
||||||
|
final listEmailAddressCanSave = Set<EmailAddress>();
|
||||||
|
listEmailAddressCanSave.addAll(listToEmailAddress + listCcEmailAddress + listBccEmailAddress);
|
||||||
|
_saveEmailAddressInteractor.execute(listEmailAddressCanSave.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<EmailAddress>> searchEmailAddressSuggestion(String word) async {
|
||||||
|
return await _searchEmailAddressInteractor.execute(AutoCompletePattern(word: word))
|
||||||
|
.then((value) => value.fold(
|
||||||
|
(failure) => [],
|
||||||
|
(success) => success is SearchEmailAddressSuccess ? success.listEmailAddress : []));
|
||||||
|
}
|
||||||
|
|
||||||
void backToEmailViewAction() {
|
void backToEmailViewAction() {
|
||||||
Get.back();
|
Get.back();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
return Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.only(left: 20, right: 24, top: 12, bottom: 12),
|
padding: EdgeInsets.only(left: 20, right: 24, top: 12, bottom: 12),
|
||||||
child: Obx(() => (TopBarComposerWidgetBuilder(imagePaths, controller.isEnableEmailSendButton.value)
|
child: Obx(() => (TopBarComposerWidgetBuilder(imagePaths, controller.isEnableEmailSendButton.value)
|
||||||
|
..addSendEmailActionClick(() => controller.sendEmailAction(context))
|
||||||
..addBackActionClick(() => controller.backToEmailViewAction()))
|
..addBackActionClick(() => controller.backToEmailViewAction()))
|
||||||
.build()),
|
.build()),
|
||||||
);
|
);
|
||||||
@@ -66,20 +67,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 24),
|
padding: EdgeInsets.symmetric(horizontal: 24),
|
||||||
child: Obx(() {
|
child: _buildEmailAddress(context)),
|
||||||
return (EmailAddressComposerWidgetBuilder(
|
|
||||||
context,
|
|
||||||
imagePaths,
|
|
||||||
controller.expandMode.value,
|
|
||||||
controller.listEmailAddressSuggestion,
|
|
||||||
controller.listReplyToEmailAddress.isNotEmpty ? controller.listReplyToEmailAddress : controller.listToEmailAddress,
|
|
||||||
controller.listCcEmailAddress,
|
|
||||||
controller.listBccEmailAddress,
|
|
||||||
controller.composerArguments.value?.userProfile)
|
|
||||||
..addExpandAddressActionClick(() => controller.expandEmailAddressAction())
|
|
||||||
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress)))
|
|
||||||
.build();
|
|
||||||
})),
|
|
||||||
_buildSubjectEmail(context),
|
_buildSubjectEmail(context),
|
||||||
Container(
|
Container(
|
||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
@@ -92,6 +80,22 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildEmailAddress(BuildContext context) {
|
||||||
|
return Obx(() => (EmailAddressComposerWidgetBuilder(
|
||||||
|
context,
|
||||||
|
imagePaths,
|
||||||
|
controller.expandMode.value,
|
||||||
|
controller.listReplyToEmailAddress.isNotEmpty ? controller.listReplyToEmailAddress : controller.listToEmailAddress,
|
||||||
|
controller.listCcEmailAddress,
|
||||||
|
controller.listBccEmailAddress,
|
||||||
|
controller.composerArguments.value?.userProfile)
|
||||||
|
..addExpandAddressActionClick(() => controller.expandEmailAddressAction())
|
||||||
|
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress))
|
||||||
|
..addOnSuggestionEmailAddress((word) => controller.searchEmailAddressSuggestion(word)))
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildSubjectEmail(BuildContext context) {
|
Widget _buildSubjectEmail(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.only(left: 24, right: 24, bottom: 10, top: 8),
|
padding: EdgeInsets.only(left: 24, right: 24, bottom: 10, top: 8),
|
||||||
@@ -99,6 +103,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
.key(Key('subject_email_input'))
|
.key(Key('subject_email_input'))
|
||||||
.textInputAction(TextInputAction.newline)
|
.textInputAction(TextInputAction.newline)
|
||||||
.maxLines(null)
|
.maxLines(null)
|
||||||
|
.onChange((value) => controller.setSubjectEmail(value))
|
||||||
.textStyle(TextStyle(color: AppColor.nameUserColor, fontSize: 14, fontWeight: FontWeight.w500))
|
.textStyle(TextStyle(color: AppColor.nameUserColor, fontSize: 14, fontWeight: FontWeight.w500))
|
||||||
.textDecoration(InputDecoration(
|
.textDecoration(InputDecoration(
|
||||||
hintText: AppLocalizations.of(context).subject_email,
|
hintText: AppLocalizations.of(context).subject_email,
|
||||||
@@ -118,7 +123,9 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
color: AppColor.bgComposer,
|
color: AppColor.bgComposer,
|
||||||
padding: EdgeInsets.only(bottom: 30),
|
padding: controller.getEmailActionType() != EmailActionType.compose
|
||||||
|
? EdgeInsets.only(bottom: 30, left: 16, right: 16)
|
||||||
|
: EdgeInsets.only(bottom: 30),
|
||||||
alignment: Alignment.topCenter,
|
alignment: Alignment.topCenter,
|
||||||
child: _buildEmailBodyEditorQuoted(context)
|
child: _buildEmailBodyEditorQuoted(context)
|
||||||
)
|
)
|
||||||
|
|||||||
+22
-12
@@ -1,16 +1,19 @@
|
|||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:core/core.dart';
|
import 'package:core/core.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_chips_input/flutter_chips_input.dart';
|
import 'package:flutter_chips_input/flutter_chips_input.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/prefix_email_address_extension.dart';
|
import 'package:tmail_ui_user/features/composer/presentation/extensions/prefix_email_address_extension.dart';
|
||||||
|
|
||||||
typedef OnOpenExpandAddressActionClick = void Function();
|
typedef OnOpenExpandAddressActionClick = void Function();
|
||||||
|
typedef OnSuggestionEmailAddress = Future<List<EmailAddress>> Function(String word);
|
||||||
typedef OnUpdateListEmailAddressAction = void Function(
|
typedef OnUpdateListEmailAddressAction = void Function(
|
||||||
PrefixEmailAddress prefixEmailAddress,
|
PrefixEmailAddress prefixEmailAddress,
|
||||||
List<EmailAddress> listEmailAddress
|
List<EmailAddress> listEmailAddress
|
||||||
@@ -21,7 +24,6 @@ class EmailAddressComposerWidgetBuilder {
|
|||||||
final ImagePaths _imagePaths;
|
final ImagePaths _imagePaths;
|
||||||
final BuildContext _context;
|
final BuildContext _context;
|
||||||
final ExpandMode _expandMode;
|
final ExpandMode _expandMode;
|
||||||
final List<EmailAddress> _listEmailAddressSuggestion;
|
|
||||||
final List<EmailAddress> _listToEmailAddress;
|
final List<EmailAddress> _listToEmailAddress;
|
||||||
final List<EmailAddress> _listCcEmailAddress;
|
final List<EmailAddress> _listCcEmailAddress;
|
||||||
final List<EmailAddress> _listBccEmailAddress;
|
final List<EmailAddress> _listBccEmailAddress;
|
||||||
@@ -31,12 +33,12 @@ class EmailAddressComposerWidgetBuilder {
|
|||||||
|
|
||||||
OnOpenExpandAddressActionClick? _onOpenExpandAddressActionClick;
|
OnOpenExpandAddressActionClick? _onOpenExpandAddressActionClick;
|
||||||
OnUpdateListEmailAddressAction? _onUpdateListEmailAddressAction;
|
OnUpdateListEmailAddressAction? _onUpdateListEmailAddressAction;
|
||||||
|
OnSuggestionEmailAddress? _onSuggestionEmailAddress;
|
||||||
|
|
||||||
EmailAddressComposerWidgetBuilder(
|
EmailAddressComposerWidgetBuilder(
|
||||||
this._context,
|
this._context,
|
||||||
this._imagePaths,
|
this._imagePaths,
|
||||||
this._expandMode,
|
this._expandMode,
|
||||||
this._listEmailAddressSuggestion,
|
|
||||||
this._listToEmailAddress,
|
this._listToEmailAddress,
|
||||||
this._listCcEmailAddress,
|
this._listCcEmailAddress,
|
||||||
this._listBccEmailAddress,
|
this._listBccEmailAddress,
|
||||||
@@ -51,6 +53,10 @@ class EmailAddressComposerWidgetBuilder {
|
|||||||
_onUpdateListEmailAddressAction = onUpdateListEmailAddressAction;
|
_onUpdateListEmailAddressAction = onUpdateListEmailAddressAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addOnSuggestionEmailAddress(OnSuggestionEmailAddress onSuggestionEmailAddress) {
|
||||||
|
_onSuggestionEmailAddress = onSuggestionEmailAddress;
|
||||||
|
}
|
||||||
|
|
||||||
Widget build() {
|
Widget build() {
|
||||||
keyToEmailAddress.currentState?.selectSuggestion(_listToEmailAddress);
|
keyToEmailAddress.currentState?.selectSuggestion(_listToEmailAddress);
|
||||||
|
|
||||||
@@ -115,29 +121,33 @@ class EmailAddressComposerWidgetBuilder {
|
|||||||
: Key('${prefixEmailAddress.toString()}_email_address_input'),
|
: Key('${prefixEmailAddress.toString()}_email_address_input'),
|
||||||
initialValue: _getListEmailAddressCurrent(prefixEmailAddress),
|
initialValue: _getListEmailAddressCurrent(prefixEmailAddress),
|
||||||
textStyle: TextStyle(color: AppColor.nameUserColor, fontSize: 14, fontWeight: FontWeight.w500),
|
textStyle: TextStyle(color: AppColor.nameUserColor, fontSize: 14, fontWeight: FontWeight.w500),
|
||||||
|
cursorColor: AppColor.primaryColor,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
hintText: AppLocalizations.of(_context).hint_text_email_address,
|
hintText: AppLocalizations.of(_context).hint_text_email_address,
|
||||||
hintMaxLines: 1,
|
hintMaxLines: 1,
|
||||||
hintStyle: TextStyle(color: AppColor.baseTextColor, fontSize: 14, fontWeight: FontWeight.w500)),
|
hintStyle: TextStyle(color: AppColor.baseTextColor, fontSize: 14, fontWeight: FontWeight.w500)),
|
||||||
initialSuggestions: _listEmailAddressSuggestion,
|
|
||||||
findSuggestions: (query) {
|
findSuggestions: (query) {
|
||||||
if (query.isNotEmpty) {
|
if (query.isNotEmpty && _onSuggestionEmailAddress != null) {
|
||||||
final lowercaseQuery = query.toLowerCase();
|
return _onSuggestionEmailAddress!(query);
|
||||||
return _listEmailAddressSuggestion
|
|
||||||
.where((emailAddress) => emailAddress.getName().toLowerCase().contains(query.toLowerCase())
|
|
||||||
|| emailAddress.getEmail().toLowerCase().contains(query.toLowerCase()))
|
|
||||||
.toList(growable: false)
|
|
||||||
..sort((email1, email2) => email1.asString().toLowerCase().indexOf(lowercaseQuery).compareTo(email2.asString().toLowerCase().indexOf(lowercaseQuery)));
|
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
},
|
},
|
||||||
onChanged: (data) {
|
onChanged: (data) {
|
||||||
print('data: $data');
|
|
||||||
if (_onUpdateListEmailAddressAction != null) {
|
if (_onUpdateListEmailAddressAction != null) {
|
||||||
_onUpdateListEmailAddressAction!(prefixEmailAddress, data);
|
_onUpdateListEmailAddressAction!(prefixEmailAddress, data);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onChipInputActionDone: (state, value) {
|
||||||
|
if (GetUtils.isEmail(value)) {
|
||||||
|
state.selectSuggestion(EmailAddress(value, value));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChipInputChangeFocusAction: (state, value) {
|
||||||
|
if (GetUtils.isEmail(value)) {
|
||||||
|
state.selectSuggestion(EmailAddress(value, value));
|
||||||
|
}
|
||||||
|
},
|
||||||
chipBuilder: (context, state, emailAddress) {
|
chipBuilder: (context, state, emailAddress) {
|
||||||
return InputChip(
|
return InputChip(
|
||||||
key: ObjectKey(emailAddress),
|
key: ObjectKey(emailAddress),
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ class TopBarComposerWidgetBuilder {
|
|||||||
OnSendEmailActionClick? _onSendEmailActionClick;
|
OnSendEmailActionClick? _onSendEmailActionClick;
|
||||||
|
|
||||||
final ImagePaths _imagePaths;
|
final ImagePaths _imagePaths;
|
||||||
bool isEnableEmailSendButton;
|
final bool _isEnableEmailSendButton;
|
||||||
|
|
||||||
TopBarComposerWidgetBuilder(this._imagePaths, this.isEnableEmailSendButton);
|
TopBarComposerWidgetBuilder(this._imagePaths, this._isEnableEmailSendButton);
|
||||||
|
|
||||||
void addBackActionClick(OnBackActionClick onBackActionClick) {
|
void addBackActionClick(OnBackActionClick onBackActionClick) {
|
||||||
_onBackActionClick = onBackActionClick;
|
_onBackActionClick = onBackActionClick;
|
||||||
@@ -68,12 +68,11 @@ class TopBarComposerWidgetBuilder {
|
|||||||
SizedBox(width: 10),
|
SizedBox(width: 10),
|
||||||
ButtonBuilder(_imagePaths.icComposerSend)
|
ButtonBuilder(_imagePaths.icComposerSend)
|
||||||
.key(Key('button_send_email'))
|
.key(Key('button_send_email'))
|
||||||
.color(isEnableEmailSendButton ? AppColor.enableSendEmailButtonColor : AppColor.disableSendEmailButtonColor)
|
.color(_isEnableEmailSendButton ? AppColor.enableSendEmailButtonColor : AppColor.disableSendEmailButtonColor)
|
||||||
.onPressActionClick(() {
|
.onPressActionClick(() {
|
||||||
if (_onSendEmailActionClick != null && isEnableEmailSendButton) {
|
if (_onSendEmailActionClick != null && _isEnableEmailSendButton) {
|
||||||
_onSendEmailActionClick!();
|
_onSendEmailActionClick!();
|
||||||
}
|
}})
|
||||||
})
|
|
||||||
.build(),
|
.build(),
|
||||||
SizedBox(width: 10),
|
SizedBox(width: 10),
|
||||||
ButtonBuilder(_imagePaths.icComposerMenu).key(Key('button_menu_composer')).build(),
|
ButtonBuilder(_imagePaths.icComposerMenu).key(Key('button_menu_composer')).build(),
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
|
||||||
|
|
||||||
abstract class EmailDataSource {
|
abstract class EmailDataSource {
|
||||||
Future<Email> getEmailContent(AccountId accountId, EmailId emailId);
|
Future<Email> getEmailContent(AccountId accountId, EmailId emailId);
|
||||||
|
|
||||||
|
Future<bool> sendEmail(AccountId accountId, EmailRequest emailRequest);
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
|
||||||
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
|
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
|
||||||
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
||||||
|
|
||||||
@@ -17,4 +18,13 @@ class EmailDataSourceImpl extends EmailDataSource {
|
|||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> sendEmail(AccountId accountId, EmailRequest emailRequest) {
|
||||||
|
return Future.sync(() async {
|
||||||
|
return await emailAPI.sendEmail(accountId, emailRequest);
|
||||||
|
}).catchError((error) {
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,11 +2,23 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:jmap_dart_client/http/http_client.dart';
|
import 'package:jmap_dart_client/http/http_client.dart';
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/patch_object.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
import 'package:jmap_dart_client/jmap/core/properties/properties.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/reference_id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/reference_prefix.dart';
|
||||||
import 'package:jmap_dart_client/jmap/jmap_request.dart';
|
import 'package:jmap_dart_client/jmap/jmap_request.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/get/get_email_method.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/get/get_email_method.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/get/get_email_response.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/get/get_email_response.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/set/set_email_method.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/set/set_email_response.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/submission/address.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/submission/email_submission.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/submission/email_submission_id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/submission/envelope.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/submission/set/set_email_submission_method.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
|
||||||
|
import 'package:model/model.dart';
|
||||||
|
|
||||||
class EmailAPI {
|
class EmailAPI {
|
||||||
|
|
||||||
@@ -40,4 +52,55 @@ class EmailAPI {
|
|||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> sendEmail(AccountId accountId, EmailRequest emailRequest) async {
|
||||||
|
final mailboxIdSaved = emailRequest.mailboxIdSaved ?? emailRequest.email.mailboxIds?.keys.first;
|
||||||
|
|
||||||
|
final setEmailMethod = SetEmailMethod(accountId)
|
||||||
|
..addCreate(emailRequest.email.id.id, emailRequest.email);
|
||||||
|
|
||||||
|
final setEmailSubmissionMethod = SetEmailSubmissionMethod(accountId)
|
||||||
|
..addCreate(
|
||||||
|
emailRequest.submissionCreateId,
|
||||||
|
EmailSubmission(
|
||||||
|
emailId: EmailId(ReferenceId(ReferencePrefix.defaultPrefix, emailRequest.email.id.id)),
|
||||||
|
envelope: Envelope(
|
||||||
|
Address(emailRequest.email.from?.first.email ?? ''),
|
||||||
|
emailRequest.email.getRecipientEmailAddressList().map((emailAddress) => Address(emailAddress)).toSet()
|
||||||
|
)
|
||||||
|
))
|
||||||
|
..addOnSuccessUpdateEmail({
|
||||||
|
EmailSubmissionId(ReferenceId(ReferencePrefix.defaultPrefix, emailRequest.submissionCreateId)): PatchObject({
|
||||||
|
PatchObject.mailboxIdsProperty: {
|
||||||
|
mailboxIdSaved?.id.value: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
final requestBuilder = JmapRequestBuilder(httpClient, ProcessingInvocation());
|
||||||
|
|
||||||
|
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
|
||||||
|
final setEmailSubmissionInvocation = requestBuilder.invocation(setEmailSubmissionMethod);
|
||||||
|
|
||||||
|
final response = await (requestBuilder
|
||||||
|
..usings(setEmailSubmissionMethod.requiredCapabilities))
|
||||||
|
.build()
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
final setEmailResponse = response.parse<SetEmailResponse>(
|
||||||
|
setEmailInvocation.methodCallId,
|
||||||
|
SetEmailResponse.deserialize);
|
||||||
|
|
||||||
|
final setEmailSubmissionResponse = response.parse<SetEmailResponse>(
|
||||||
|
setEmailSubmissionInvocation.methodCallId,
|
||||||
|
SetEmailResponse.deserialize,
|
||||||
|
methodName: setEmailInvocation.methodName);
|
||||||
|
|
||||||
|
return Future.sync(() async {
|
||||||
|
final emailCreated = setEmailResponse!.created![emailRequest.email.id.id];
|
||||||
|
return setEmailSubmissionResponse!.updated![emailCreated!.id.id] == null;
|
||||||
|
}).catchError((error) {
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
|
||||||
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
|
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
|
||||||
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
|
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
|
||||||
|
|
||||||
@@ -14,4 +15,9 @@ class EmailRepositoryImpl extends EmailRepository {
|
|||||||
Future<Email> getEmailContent(AccountId accountId, EmailId emailId) {
|
Future<Email> getEmailContent(AccountId accountId, EmailId emailId) {
|
||||||
return emailDataSource.getEmailContent(accountId, emailId);
|
return emailDataSource.getEmailContent(accountId, emailId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> sendEmail(AccountId accountId, EmailRequest emailRequest) {
|
||||||
|
return emailDataSource.sendEmail(accountId, emailRequest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
|
||||||
import 'package:model/email/email_content.dart';
|
|
||||||
|
|
||||||
extension EmailExtension on Email {
|
|
||||||
|
|
||||||
EmailContent toEmailContent() {
|
|
||||||
return EmailContent(
|
|
||||||
id,
|
|
||||||
htmlBody: htmlBody,
|
|
||||||
attachments: attachments,
|
|
||||||
bodyValues: bodyValues
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import 'package:model/model.dart';
|
|
||||||
import 'package:core/core.dart';
|
|
||||||
|
|
||||||
extension PresentationEmailExtension on PresentationEmail {
|
|
||||||
|
|
||||||
String getTimeSentEmail(String newLocale) {
|
|
||||||
final dateTime = sentAt?.value;
|
|
||||||
return sentAt.formatDate(pattern: dateTime.toPattern(), locale: newLocale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
|
||||||
|
|
||||||
abstract class EmailRepository {
|
abstract class EmailRepository {
|
||||||
Future<Email> getEmailContent(AccountId accountId, EmailId emailId);
|
Future<Email> getEmailContent(AccountId accountId, EmailId emailId);
|
||||||
|
|
||||||
|
Future<bool> sendEmail(AccountId accountId, EmailRequest emailRequest);
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import 'package:core/core.dart';
|
import 'package:core/core.dart';
|
||||||
|
import 'package:model/model.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
|
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
|
||||||
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
|
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
|
||||||
import 'package:tmail_ui_user/features/email/domain/extensions/email_extension.dart';
|
|
||||||
|
|
||||||
class GetEmailContentInteractor {
|
class GetEmailContentInteractor {
|
||||||
final EmailRepository emailRepository;
|
final EmailRepository emailRepository;
|
||||||
|
|||||||
@@ -67,14 +67,17 @@ class EmailController extends BaseController {
|
|||||||
emailAddressExpandMode.value = expandMode;
|
emailAddressExpandMode.value = expandMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool canComposeEmail() => mailboxDashBoardController.sessionCurrent != null
|
||||||
|
&& mailboxDashBoardController.userProfile.value != null
|
||||||
|
&& mailboxDashBoardController.mapMailboxId.containsKey(PresentationMailbox.roleOutbox)
|
||||||
|
&& mailboxDashBoardController.selectedEmail.value != null;
|
||||||
|
|
||||||
void goToThreadView(BuildContext context) {
|
void goToThreadView(BuildContext context) {
|
||||||
Get.back();
|
Get.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pressEmailAction(EmailActionType emailActionType) {
|
void pressEmailAction(EmailActionType emailActionType) {
|
||||||
if (mailboxDashBoardController.selectedEmail.value != null
|
if (canComposeEmail()) {
|
||||||
&& mailboxDashBoardController.sessionCurrent != null
|
|
||||||
&& mailboxDashBoardController.userProfile.value != null) {
|
|
||||||
Get.toNamed(
|
Get.toNamed(
|
||||||
AppRoutes.COMPOSER,
|
AppRoutes.COMPOSER,
|
||||||
arguments: ComposerArguments(
|
arguments: ComposerArguments(
|
||||||
@@ -82,7 +85,8 @@ class EmailController extends BaseController {
|
|||||||
presentationEmail: mailboxDashBoardController.selectedEmail.value!,
|
presentationEmail: mailboxDashBoardController.selectedEmail.value!,
|
||||||
emailContent: emailContent,
|
emailContent: emailContent,
|
||||||
session: mailboxDashBoardController.sessionCurrent!,
|
session: mailboxDashBoardController.sessionCurrent!,
|
||||||
userProfile: mailboxDashBoardController.userProfile.value!));
|
userProfile: mailboxDashBoardController.userProfile.value!,
|
||||||
|
mapMailboxId: mailboxDashBoardController.mapMailboxId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:jmap_dart_client/jmap/mail/email/email_body_part.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email_body_part.dart';
|
||||||
import 'package:model/email/email_content.dart';
|
import 'package:model/email/email_content.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/constants/email_contants.dart';
|
import 'package:tmail_ui_user/features/email/presentation/constants/email_constants.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/model/attachment_file.dart';
|
import 'package:tmail_ui_user/features/email/presentation/model/attachment_file.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/model/message_content.dart';
|
import 'package:tmail_ui_user/features/email/presentation/model/message_content.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/model/text_format.dart';
|
import 'package:tmail_ui_user/features/email/presentation/model/text_format.dart';
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
import 'package:model/model.dart';
|
|
||||||
|
|
||||||
extension PresentationEmailExtension on PresentationEmail {
|
|
||||||
|
|
||||||
int numberOfAllEmailAddress() => to.numberEmailAddress() + cc.numberEmailAddress() + bcc.numberEmailAddress();
|
|
||||||
|
|
||||||
String getSentTime(String locale) => sentAt.formatDate(pattern: 'dd/MM/yyyy h:mm a', locale: locale);
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
|
|
||||||
class ComposerArguments with EquatableMixin {
|
class ComposerArguments with EquatableMixin {
|
||||||
@@ -9,15 +10,24 @@ class ComposerArguments with EquatableMixin {
|
|||||||
final EmailContent? emailContent;
|
final EmailContent? emailContent;
|
||||||
final Session session;
|
final Session session;
|
||||||
final UserProfile userProfile;
|
final UserProfile userProfile;
|
||||||
|
final Map<Role, MailboxId> mapMailboxId;
|
||||||
|
|
||||||
ComposerArguments({
|
ComposerArguments({
|
||||||
this.emailActionType = EmailActionType.compose,
|
this.emailActionType = EmailActionType.compose,
|
||||||
this.presentationEmail,
|
this.presentationEmail,
|
||||||
this.emailContent,
|
this.emailContent,
|
||||||
required this.session,
|
required this.session,
|
||||||
required this.userProfile
|
required this.userProfile,
|
||||||
|
required this.mapMailboxId,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [emailActionType, presentationEmail, emailContent, session, userProfile];
|
List<Object?> get props => [
|
||||||
|
emailActionType,
|
||||||
|
presentationEmail,
|
||||||
|
emailContent,
|
||||||
|
session,
|
||||||
|
userProfile,
|
||||||
|
mapMailboxId,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
+1
-2
@@ -5,7 +5,6 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:model/email/presentation_email.dart';
|
import 'package:model/email/presentation_email.dart';
|
||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/extensions/presentation_email_extension.dart';
|
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
typedef OnOpenExpandAddressReceiverActionClick = void Function();
|
typedef OnOpenExpandAddressReceiverActionClick = void Function();
|
||||||
@@ -69,7 +68,7 @@ class SenderAndReceiverInformationTileBuilder {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 6),
|
padding: EdgeInsets.only(top: 6),
|
||||||
child: Text(
|
child: Text(
|
||||||
'${_presentationEmail!.getSentTime(Localizations.localeOf(_context).toLanguageTag())}',
|
'${_presentationEmail!.getEmailDateTime(Localizations.localeOf(_context).toLanguageTag(), pattern: 'dd/MM/yyyy h:mm a')}',
|
||||||
style: TextStyle(fontSize: 12, color: AppColor.baseTextColor),
|
style: TextStyle(fontSize: 12, color: AppColor.baseTextColor),
|
||||||
))
|
))
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/datasource/atuthentitcation_datasource.dart';
|
import 'package:tmail_ui_user/features/login/data/datasource/authentication_datasource.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/model/request/account_request.dart';
|
|
||||||
import 'package:tmail_ui_user/features/login/data/model/response/user_profile_response.dart';
|
|
||||||
import 'package:tmail_ui_user/features/login/data/network/login_api.dart';
|
import 'package:tmail_ui_user/features/login/data/network/login_api.dart';
|
||||||
|
|
||||||
class AuthenticationDataSourceImpl extends AuthenticationDataSource {
|
class AuthenticationDataSourceImpl extends AuthenticationDataSource {
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:core/core.dart';
|
import 'package:core/core.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/model/request/account_request.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/model/response/user_profile_response.dart';
|
|
||||||
|
|
||||||
class LoginAPI {
|
class LoginAPI {
|
||||||
final DioClient _dioClient;
|
final DioClient _dioClient;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/datasource/atuthentitcation_datasource.dart';
|
import 'package:tmail_ui_user/features/login/data/datasource/authentication_datasource.dart';
|
||||||
import 'package:tmail_ui_user/features/login/domain/repository/authentication_repository.dart';
|
import 'package:tmail_ui_user/features/login/domain/repository/authentication_repository.dart';
|
||||||
|
|
||||||
class AuthenticationRepositoryImpl extends AuthenticationRepository {
|
class AuthenticationRepositoryImpl extends AuthenticationRepository {
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/model/response/user_profile_response.dart';
|
|
||||||
import 'package:tmail_ui_user/features/login/data/utils/login_constant.dart';
|
import 'package:tmail_ui_user/features/login/data/utils/login_constant.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/extensions/user_profile_extension.dart';
|
|
||||||
import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart';
|
import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart';
|
||||||
|
|
||||||
class CredentialRepositoryImpl extends CredentialRepository {
|
class CredentialRepositoryImpl extends CredentialRepository {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//
|
|
||||||
|
|
||||||
extension UriExtension on Uri {
|
extension UriExtension on Uri {
|
||||||
bool isBaseUrlValid() => origin.isNotEmpty;
|
bool isBaseUrlValid() => origin.isNotEmpty;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:core/core.dart';
|
import 'package:core/core.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/datasource/atuthentitcation_datasource.dart';
|
import 'package:tmail_ui_user/features/login/data/datasource/authentication_datasource.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/datasource_impl/authentication_datasource_impl.dart';
|
import 'package:tmail_ui_user/features/login/data/datasource_impl/authentication_datasource_impl.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/network/login_api.dart';
|
import 'package:tmail_ui_user/features/login/data/network/login_api.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/repository/authentication_repository_impl.dart';
|
import 'package:tmail_ui_user/features/login/data/repository/authentication_repository_impl.dart';
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
class MailboxConstants {
|
class MailboxConstants {
|
||||||
static const MAILBOX_LEVEL_SEPARATOR = "/";
|
static const MAILBOX_LEVEL_SEPARATOR = "/";
|
||||||
static const ROLE_DEFAULT = "inbox";
|
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,6 @@ import 'package:flutter/cupertino.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
|
||||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||||
import 'package:model/mailbox/select_mode.dart';
|
import 'package:model/mailbox/select_mode.dart';
|
||||||
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
||||||
@@ -78,7 +77,7 @@ class MailboxController extends BaseController {
|
|||||||
void onDone() {
|
void onDone() {
|
||||||
viewState.value.map((success) {
|
viewState.value.map((success) {
|
||||||
if (success is GetAllMailboxSuccess) {
|
if (success is GetAllMailboxSuccess) {
|
||||||
_setUpMailboxDefault(success.defaultMailboxList);
|
_setUpMapMailboxIdDefault(success.defaultMailboxList);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -90,12 +89,13 @@ class MailboxController extends BaseController {
|
|||||||
folderMailboxTree.value = await _treeBuilder.generateMailboxTree(folderMailboxList);
|
folderMailboxTree.value = await _treeBuilder.generateMailboxTree(folderMailboxList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setUpMailboxDefault(List<PresentationMailbox> defaultMailboxList) {
|
void _setUpMapMailboxIdDefault(List<PresentationMailbox> defaultMailboxList) {
|
||||||
try {
|
defaultMailboxList.forEach((presentationMailbox) {
|
||||||
final mailboxDefault = defaultMailboxList
|
if (presentationMailbox.role == PresentationMailbox.roleInbox) {
|
||||||
.firstWhere((presentationMailbox) => presentationMailbox.role == Role(MailboxConstants.ROLE_DEFAULT));
|
mailboxDashBoardController.setSelectedMailbox(presentationMailbox);
|
||||||
mailboxDashBoardController.setSelectedMailbox(mailboxDefault);
|
}
|
||||||
} catch (e) {}
|
mailboxDashBoardController.addMailboxIdToMap(presentationMailbox.role!, presentationMailbox.id);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectMode getSelectMode(PresentationMailbox presentationMailbox, PresentationMailbox? selectedMailbox) {
|
SelectMode getSelectMode(PresentationMailbox presentationMailbox, PresentationMailbox? selectedMailbox) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/email/presentation/email_controller.dart';
|
import 'package:tmail_ui_user/features/email/presentation/email_controller.dart';
|
||||||
@@ -20,6 +21,7 @@ class MailboxDashBoardController extends BaseController {
|
|||||||
final userProfile = Rxn<UserProfile>();
|
final userProfile = Rxn<UserProfile>();
|
||||||
|
|
||||||
Session? sessionCurrent;
|
Session? sessionCurrent;
|
||||||
|
Map<Role, MailboxId> mapMailboxId = Map();
|
||||||
|
|
||||||
MailboxDashBoardController(this._getUserProfileInteractor);
|
MailboxDashBoardController(this._getUserProfileInteractor);
|
||||||
|
|
||||||
@@ -57,6 +59,10 @@ class MailboxDashBoardController extends BaseController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addMailboxIdToMap(Role role, MailboxId mailboxId) {
|
||||||
|
mapMailboxId[role] = mailboxId;
|
||||||
|
}
|
||||||
|
|
||||||
void setSelectedMailbox(PresentationMailbox? newPresentationMailbox) {
|
void setSelectedMailbox(PresentationMailbox? newPresentationMailbox) {
|
||||||
selectedMailbox.value = newPresentationMailbox;
|
selectedMailbox.value = newPresentationMailbox;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:core/core.dart';
|
import 'package:core/core.dart';
|
||||||
|
import 'package:model/model.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
|
import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
|
||||||
@@ -7,7 +8,6 @@ import 'package:jmap_dart_client/jmap/core/sort/comparator.dart';
|
|||||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart';
|
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/state/get_all_email_state.dart';
|
import 'package:tmail_ui_user/features/thread/domain/state/get_all_email_state.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/domain/extensions/email_extension.dart';
|
|
||||||
|
|
||||||
class GetEmailsInMailboxInteractor {
|
class GetEmailsInMailboxInteractor {
|
||||||
final ThreadRepository threadRepository;
|
final ThreadRepository threadRepository;
|
||||||
|
|||||||
@@ -170,6 +170,10 @@ class ThreadController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool canComposeEmail() => mailboxDashBoardController.sessionCurrent != null
|
||||||
|
&& mailboxDashBoardController.userProfile.value != null
|
||||||
|
&& mailboxDashBoardController.mapMailboxId.containsKey([PresentationMailbox.roleOutbox]);
|
||||||
|
|
||||||
void openMailboxLeftMenu() {
|
void openMailboxLeftMenu() {
|
||||||
mailboxDashBoardController.openDrawer();
|
mailboxDashBoardController.openDrawer();
|
||||||
}
|
}
|
||||||
@@ -179,12 +183,13 @@ class ThreadController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void composeEmailAction() {
|
void composeEmailAction() {
|
||||||
if (mailboxDashBoardController.sessionCurrent != null && mailboxDashBoardController.userProfile.value != null) {
|
if (canComposeEmail()) {
|
||||||
Get.toNamed(
|
Get.toNamed(
|
||||||
AppRoutes.COMPOSER,
|
AppRoutes.COMPOSER,
|
||||||
arguments: ComposerArguments(
|
arguments: ComposerArguments(
|
||||||
session: mailboxDashBoardController.sessionCurrent!,
|
session: mailboxDashBoardController.sessionCurrent!,
|
||||||
userProfile: mailboxDashBoardController.userProfile.value!));
|
userProfile: mailboxDashBoardController.userProfile.value!,
|
||||||
|
mapMailboxId: mailboxDashBoardController.mapMailboxId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ class ThreadView extends GetWidget<ThreadController> {
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
elevation: 0.0,
|
elevation: 4.0,
|
||||||
child: new Icon(Icons.add),
|
child: new Icon(Icons.add),
|
||||||
backgroundColor: AppColor.appColor,
|
backgroundColor: AppColor.appColor,
|
||||||
onPressed: () => controller.composeEmailAction()
|
onPressed: () => controller.composeEmailAction()
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import 'package:core/core.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:tmail_ui_user/features/email/domain/extensions/presentation_email_extension.dart';
|
|
||||||
|
|
||||||
typedef OnOpenMailActionClick = void Function();
|
typedef OnOpenMailActionClick = void Function();
|
||||||
|
|
||||||
@@ -82,7 +81,7 @@ class EmailTileBuilder {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(right: 4),
|
padding: EdgeInsets.only(right: 4),
|
||||||
child: Text(
|
child: Text(
|
||||||
'${_presentationEmail.getTimeSentEmail(Localizations.localeOf(_context).toLanguageTag())}',
|
'${_presentationEmail.getEmailDateTime(Localizations.localeOf(_context).toLanguageTag())}',
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow:TextOverflow.ellipsis,
|
overflow:TextOverflow.ellipsis,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:core/core.dart';
|
import 'package:core/core.dart';
|
||||||
|
import 'package:core/presentation/utils/app_toast.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
@@ -10,7 +11,8 @@ class CoreBindings extends Bindings {
|
|||||||
_bindingAppImagePaths();
|
_bindingAppImagePaths();
|
||||||
_bindingResponsiveManager();
|
_bindingResponsiveManager();
|
||||||
_bindingKeyboardManager();
|
_bindingKeyboardManager();
|
||||||
_bindingValiadtor();
|
_bindingValidator();
|
||||||
|
_bindingToast();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _bindingAppImagePaths() {
|
void _bindingAppImagePaths() {
|
||||||
@@ -29,7 +31,11 @@ class CoreBindings extends Bindings {
|
|||||||
Get.put(KeyboardUtils());
|
Get.put(KeyboardUtils());
|
||||||
}
|
}
|
||||||
|
|
||||||
void _bindingValiadtor() {
|
void _bindingValidator() {
|
||||||
Get.put(HtmlMessagePurifier());
|
Get.put(HtmlMessagePurifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _bindingToast() {
|
||||||
|
Get.put(AppToast());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
import 'package:core/core.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class LocalBindings extends Bindings {
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
_bindingDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _bindingDatabase() {
|
||||||
|
Get.put(DatabaseClient());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:tmail_ui_user/main/bindings/core/core_bindings.dart';
|
import 'package:tmail_ui_user/main/bindings/core/core_bindings.dart';
|
||||||
|
import 'package:tmail_ui_user/main/bindings/local/local_bindings.dart';
|
||||||
import 'package:tmail_ui_user/main/bindings/network/network_bindings.dart';
|
import 'package:tmail_ui_user/main/bindings/network/network_bindings.dart';
|
||||||
|
|
||||||
class MainBindings extends Bindings {
|
class MainBindings extends Bindings {
|
||||||
@@ -7,5 +8,6 @@ class MainBindings extends Bindings {
|
|||||||
Future dependencies() async {
|
Future dependencies() async {
|
||||||
await CoreBindings().dependencies();
|
await CoreBindings().dependencies();
|
||||||
NetworkBindings().dependencies();
|
NetworkBindings().dependencies();
|
||||||
|
LocalBindings().dependencies();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,5 +199,33 @@ class AppLocalizations {
|
|||||||
name: 'prefix_forward_email',
|
name: 'prefix_forward_email',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get your_email_being_sent {
|
||||||
|
return Intl.message(
|
||||||
|
'Your email being sent...',
|
||||||
|
name: 'your_email_being_sent',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String get your_email_should_have_at_least_one_recipient {
|
||||||
|
return Intl.message(
|
||||||
|
'Your email should have at least one recipient',
|
||||||
|
name: 'your_email_should_have_at_least_one_recipient',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String get message_sent {
|
||||||
|
return Intl.message(
|
||||||
|
'Message sent',
|
||||||
|
name: 'message_sent',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String get error_message_sent {
|
||||||
|
return Intl.message(
|
||||||
|
'Error message sent',
|
||||||
|
name: 'error_message_sent',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user