Skip to content

TF-3358 Save draft locally periodically #3598

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
12 changes: 6 additions & 6 deletions lib/features/base/widget/email_avatar_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,26 @@ import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/image/avatar_builder.dart';
import 'package:flutter/material.dart';
import 'package:model/email/presentation_email.dart';
import 'package:model/extensions/presentation_email_extension.dart';

class EmailAvatarBuilder extends StatelessWidget {

final PresentationEmail emailSelected;
final String avatarText;
final List<Color>? avatarColors;

const EmailAvatarBuilder({
Key? key,
required this.emailSelected
required this.avatarText,
this.avatarColors,
}) : super(key: key);

@override
Widget build(BuildContext context) {
return (AvatarBuilder()
..text(emailSelected.getAvatarText())
..text(avatarText)
..size(50)
..addTextStyle(ThemeUtils.textStyleHeadingH4(color: Colors.white))
..backgroundColor(AppColor.colorAvatar)
..avatarColor(emailSelected.avatarColors))
..avatarColor(avatarColors))
.build();
}
}
9 changes: 9 additions & 0 deletions lib/features/caching/clients/local_email_draft_client.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import 'package:tmail_ui_user/features/caching/config/hive_cache_client.dart';
import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/local_email_draft.dart';

class LocalEmailDraftClient extends HiveCacheClient<LocalEmailDraft> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please dont forget to upgrade hiveDBVersion

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a new box to the hive database does not require a version upgrade. A version upgrade is only required when changing the data structure of an existing box.


@override
String get tableName => CachingConstants.localDraftEmailCacheBoxName;
}
5 changes: 5 additions & 0 deletions lib/features/caching/config/hive_cache_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_cache.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_rights_cache.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/state_cache.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/state_type.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/local_email_draft.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/recent_search_cache.dart';
import 'package:tmail_ui_user/features/offline_mode/model/attachment_hive_cache.dart';
import 'package:tmail_ui_user/features/offline_mode/model/detailed_email_hive_cache.dart';
Expand Down Expand Up @@ -192,6 +193,10 @@ class HiveCacheConfig {
OidcConfigurationCacheAdapter(),
CachingConstants.OIDC_CONFIGURATION_CACHE_ID,
);
registerCacheAdapter<LocalEmailDraft>(
LocalEmailDraftAdapter(),
CachingConstants.LOCAL_EMAIL_DRAFT_CACHE_ID
);
}

void registerCacheAdapter<T>(TypeAdapter<T> typeAdapter, int typeId) {
Expand Down
2 changes: 2 additions & 0 deletions lib/features/caching/utils/caching_constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class CachingConstants {
static const int SENDING_EMAIL_HIVE_CACHE_ID = 18;
static const int SESSION_HIVE_CACHE_ID = 19;
static const int OIDC_CONFIGURATION_CACHE_ID = 20;
static const int LOCAL_EMAIL_DRAFT_CACHE_ID = 21;

static const String fcmCacheBoxName = 'fcm_cache_box';
static const String newEmailCacheBoxName = 'new_email_cache_box';
Expand All @@ -28,6 +29,7 @@ class CachingConstants {
static const String sessionCacheBoxName = 'session_cache_box';
static const String firebaseRegistrationCacheBoxName = 'firebase_registration_cache_box';
static const String oidcConfigurationCacheBoxName = 'oidc_configuration_cache_box';
static const String localDraftEmailCacheBoxName = 'local_email_draft_cache_box';

static const String oidcConfigurationCacheKeyName = 'oidc_configuration_cache_key';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';

class SaveLocalEmailDraftSuccess extends UIState {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, we should keep the id of which local email was saved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use it for anything right now, so keeping it at this point is unnecessary.


class SaveLocalEmailDraftFailure extends FeatureFailure {

SaveLocalEmailDraftFailure(dynamic exception) : super(exception: exception);
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class CreateNewAndSaveEmailToDraftsInteractor {
try {
yield dartz.Right<Failure, Success>(GenerateEmailLoading());

final emailCreated = await _createEmailObject(createEmailRequest);
final emailCreated = createEmailRequest.emailCreated
?? await _createEmailObject(createEmailRequest);

if (emailCreated != null) {
if (createEmailRequest.draftsEmailId == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/utils/html_transformer/transform_configuration.dart';
import 'package:dartz/dartz.dart';
import 'package:tmail_ui_user/features/composer/domain/state/restore_email_inline_images_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/local_email_draft_repository.dart';

class RestoreEmailInlineImagesInteractor {
RestoreEmailInlineImagesInteractor(this._composerCacheRepository);
RestoreEmailInlineImagesInteractor(this._localEmailDraftRepository);

final ComposerCacheRepository _composerCacheRepository;
final LocalEmailDraftRepository _localEmailDraftRepository;

Stream<Either<Failure, Success>> execute({
required String htmlContent,
Expand All @@ -18,7 +18,7 @@ class RestoreEmailInlineImagesInteractor {
try {
yield Right(RestoringEmailInlineImages());

final emailContent = await _composerCacheRepository.restoreEmailInlineImages(
final emailContent = await _localEmailDraftRepository.restoreEmailInlineImages(
htmlContent,
transformConfiguration,
mapUrlDownloadCID);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:tmail_ui_user/features/composer/domain/repository/composer_repository.dart';
import 'package:tmail_ui_user/features/composer/domain/state/save_local_email_draft_state.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/create_email_request_extension.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/create_email_request.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/local_email_draft_repository.dart';

class SaveLocalEmailDraftInteractor {
final LocalEmailDraftRepository _localEmailDraftRepository;
final ComposerRepository _composerRepository;

SaveLocalEmailDraftInteractor(
this._localEmailDraftRepository,
this._composerRepository,
);

Future<Either<Failure, Success>> execute(
CreateEmailRequest createEmailRequest,
AccountId accountId,
UserName userName,
) async {
try {
final emailCreated = await _composerRepository.generateEmail(
createEmailRequest,
withIdentityHeader: true,
isDraft: true,
);
await _localEmailDraftRepository.saveLocalEmailDraft(
createEmailRequest.generateLocalEmailDraftFromEmail(
email: emailCreated,
accountId: accountId,
userName: userName,
),
);
return Right(SaveLocalEmailDraftSuccess());
} catch (exception) {
return Left(SaveLocalEmailDraftFailure(exception));
}
}
}
50 changes: 26 additions & 24 deletions lib/features/composer/presentation/composer_bindings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import 'package:tmail_ui_user/features/composer/domain/usecases/create_new_and_s
import 'package:tmail_ui_user/features/composer/domain/usecases/create_new_and_send_email_interactor.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/download_image_as_base64_interactor.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/restore_email_inline_images_interactor.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/save_composer_cache_on_web_interactor.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/save_local_email_draft_interactor.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/upload_attachment_interactor.dart';
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
import 'package:tmail_ui_user/features/composer/presentation/controller/rich_text_mobile_tablet_controller.dart';
Expand Down Expand Up @@ -48,11 +48,13 @@ import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_api.dart';
import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_isolate_worker.dart';
import 'package:tmail_ui_user/features/mailbox/data/repository/mailbox_repository_impl.dart';
import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/session_storage_composer_datasource.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/session_storage_composer_datasoure_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/repository/composer_cache_repository_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_composer_cache_by_id_on_web_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource/local_email_draft_datasource.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/datasource_impl/local_email_draft_datasource_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/local_email_draft_manager.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/local_email_draft_worker_queue.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/repository/local_email_draft_repository_impl.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/local_email_draft_repository.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_local_email_draft_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_all_identities_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/preferences/bindings/preferences_interactors_bindings.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/profiles/identities/identity_interactors_bindings.dart';
Expand Down Expand Up @@ -143,8 +145,10 @@ class ComposerBindings extends BaseBindings {
Get.find<SessionStorageManager>(),
Get.find<CacheExceptionThrower>(),
), tag: composerId);
Get.lazyPut(() => SessionStorageComposerDatasourceImpl(
Get.lazyPut(() => LocalEmailDraftDataSourceImpl(
Get.find<HtmlTransform>(),
Get.find<LocalEmailDraftManager>(),
Get.find<LocalEmailDraftWorkerQueue>(),
Get.find<CacheExceptionThrower>(),
), tag: composerId);
}
Expand Down Expand Up @@ -183,8 +187,8 @@ class ComposerBindings extends BaseBindings {
() => Get.find<PrintFileDataSourceImpl>(tag: composerId),
tag: composerId,
);
Get.lazyPut<SessionStorageComposerDatasource>(
() => Get.find<SessionStorageComposerDatasourceImpl>(tag: composerId),
Get.lazyPut<LocalEmailDraftDatasource>(
() => Get.find<LocalEmailDraftDataSourceImpl>(tag: composerId),
tag: composerId,
);
}
Expand All @@ -199,7 +203,7 @@ class ComposerBindings extends BaseBindings {
Get.find<Uuid>(),
), tag: composerId);
Get.lazyPut(
() => ComposerCacheRepositoryImpl(Get.find<SessionStorageComposerDatasource>(tag: composerId)),
() => LocalEmailDraftRepositoryImpl(Get.find<LocalEmailDraftDatasource>(tag: composerId)),
tag: composerId,
);
Get.lazyPut(
Expand Down Expand Up @@ -232,8 +236,8 @@ class ComposerBindings extends BaseBindings {
() => Get.find<ComposerRepositoryImpl>(tag: composerId),
tag: composerId,
);
Get.lazyPut<ComposerCacheRepository>(
() => Get.find<ComposerCacheRepositoryImpl>(tag: composerId),
Get.lazyPut<LocalEmailDraftRepository>(
() => Get.find<LocalEmailDraftRepositoryImpl>(tag: composerId),
tag: composerId,
);
Get.lazyPut<ContactRepository>(
Expand Down Expand Up @@ -269,11 +273,11 @@ class ComposerBindings extends BaseBindings {
tag: composerId,
);
Get.lazyPut(
() => RemoveComposerCacheByIdOnWebInteractor(Get.find<ComposerCacheRepository>(tag: composerId)),
() => RemoveLocalEmailDraftInteractor(Get.find<LocalEmailDraftRepository>(tag: composerId)),
tag: composerId,
);
Get.lazyPut(() => SaveComposerCacheOnWebInteractor(
Get.find<ComposerCacheRepository>(tag: composerId),
Get.lazyPut(() => SaveLocalEmailDraftInteractor(
Get.find<LocalEmailDraftRepository>(tag: composerId),
Get.find<ComposerRepository>(tag: composerId),
), tag: composerId);
Get.lazyPut(
Expand All @@ -293,7 +297,7 @@ class ComposerBindings extends BaseBindings {
Get.find<ComposerRepository>(tag: composerId),
), tag: composerId);
Get.lazyPut(
() => RestoreEmailInlineImagesInteractor(Get.find<ComposerCacheRepository>(tag: composerId)),
() => RestoreEmailInlineImagesInteractor(Get.find<LocalEmailDraftRepository>(tag: composerId)),
tag: composerId,
);
Get.lazyPut(
Expand Down Expand Up @@ -322,8 +326,6 @@ class ComposerBindings extends BaseBindings {
Get.find<GetEmailContentInteractor>(tag: composerId),
Get.find<GetAllIdentitiesInteractor>(tag: composerId),
Get.find<UploadController>(tag: composerId),
Get.find<RemoveComposerCacheByIdOnWebInteractor>(tag: composerId),
Get.find<SaveComposerCacheOnWebInteractor>(tag: composerId),
Get.find<DownloadImageAsBase64Interactor>(tag: composerId),
Get.find<TransformHtmlEmailContentInteractor>(tag: composerId),
Get.find<GetServerSettingInteractor>(tag: composerId),
Expand Down Expand Up @@ -357,7 +359,7 @@ class ComposerBindings extends BaseBindings {
Get.delete<EmailHiveCacheDataSourceImpl>(tag: composerId);
Get.delete<EmailLocalStorageDataSourceImpl>(tag: composerId);
Get.delete<EmailSessionStorageDatasourceImpl>(tag: composerId);
Get.delete<SessionStorageComposerDatasourceImpl>(tag: composerId);
Get.delete<LocalEmailDraftDataSourceImpl>(tag: composerId);

Get.delete<AttachmentUploadDataSource>(tag: composerId);
Get.delete<ComposerDataSource>(tag: composerId);
Expand All @@ -367,16 +369,16 @@ class ComposerBindings extends BaseBindings {
Get.delete<HtmlDataSource>(tag: composerId);
Get.delete<StateDataSource>(tag: composerId);
Get.delete<PrintFileDataSource>(tag: composerId);
Get.delete<SessionStorageComposerDatasource>(tag: composerId);
Get.delete<LocalEmailDraftDatasource>(tag: composerId);

Get.delete<ComposerRepositoryImpl>(tag: composerId);
Get.delete<ComposerCacheRepositoryImpl>(tag: composerId);
Get.delete<LocalEmailDraftRepositoryImpl>(tag: composerId);
Get.delete<ContactRepositoryImpl>(tag: composerId);
Get.delete<MailboxRepositoryImpl>(tag: composerId);
Get.delete<EmailRepositoryImpl>(tag: composerId);

Get.delete<ComposerRepository>(tag: composerId);
Get.delete<ComposerCacheRepository>(tag: composerId);
Get.delete<LocalEmailDraftRepository>(tag: composerId);
Get.delete<ContactRepository>(tag: composerId);
Get.delete<MailboxRepository>(tag: composerId);
Get.delete<EmailRepository>(tag: composerId);
Expand All @@ -385,8 +387,8 @@ class ComposerBindings extends BaseBindings {
Get.delete<LocalImagePickerInteractor>(tag: composerId);
Get.delete<UploadAttachmentInteractor>(tag: composerId);
Get.delete<GetEmailContentInteractor>(tag: composerId);
Get.delete<RemoveComposerCacheByIdOnWebInteractor>(tag: composerId);
Get.delete<SaveComposerCacheOnWebInteractor>(tag: composerId);
Get.delete<RemoveLocalEmailDraftInteractor>(tag: composerId);
Get.delete<SaveLocalEmailDraftInteractor>(tag: composerId);
Get.delete<DownloadImageAsBase64Interactor>(tag: composerId);
Get.delete<TransformHtmlEmailContentInteractor>(tag: composerId);
Get.delete<CreateNewAndSendEmailInteractor>(tag: composerId);
Expand Down
Loading
Loading