TF-2930 Fix not persist hasRequestReadReceipt when reload browser

This commit is contained in:
dab246
2024-07-18 01:20:27 +07:00
committed by Dat H. Pham
parent 4ccb46137a
commit e65a6f2682
13 changed files with 87 additions and 122 deletions
@@ -5,7 +5,7 @@ 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/presentation/model/create_email_request.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/composer_cache.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/save_composer_cache_state.dart';
@@ -22,18 +22,18 @@ class SaveComposerCacheOnWebInteractor {
CreateEmailRequest createEmailRequest,
AccountId accountId,
UserName userName,
{required ScreenDisplayMode displayMode}
) async {
try {
final emailCreated = await _composerRepository.generateEmail(createEmailRequest);
final identity = createEmailRequest.identity;
await _composerCacheRepository.saveComposerCacheOnWeb(
emailCreated,
accountId: accountId,
userName: userName,
displayMode: displayMode,
identity: identity,
readReceipentEnabled: createEmailRequest.isRequestReadReceipt);
composerCache: ComposerCache(
email: emailCreated,
identity: createEmailRequest.identity,
hasRequestReadReceipt: createEmailRequest.hasRequestReadReceipt,
displayMode: createEmailRequest.displayMode
));
return Right(SaveComposerCacheSuccess());
} catch (exception) {
return Left(SaveComposerCacheFailure(exception));
@@ -219,7 +219,6 @@ class ComposerController extends BaseController with DragDropFileMixin implement
createFocusNodeInput();
scrollControllerEmailAddress.addListener(_scrollControllerEmailAddressListener);
_listenStreamEvent();
_getAlwaysReadReceiptSetting();
_beforeReconnectManager.addListener(onBeforeReconnect);
}
@@ -427,8 +426,7 @@ class ComposerController extends BaseController with DragDropFileMixin implement
await _saveComposerCacheOnWebInteractor.execute(
createEmailRequest,
mailboxDashBoardController.accountId.value!,
mailboxDashBoardController.sessionCurrent!.username,
displayMode: screenDisplayMode.value);
mailboxDashBoardController.sessionCurrent!.username);
}
Future<CreateEmailRequest?> _generateCreateEmailRequest() async {
@@ -452,7 +450,7 @@ class ComposerController extends BaseController with DragDropFileMixin implement
toRecipients: listToEmailAddress.toSet(),
ccRecipients: listCcEmailAddress.toSet(),
bccRecipients: listBccEmailAddress.toSet(),
isRequestReadReceipt: hasRequestReadReceipt.value,
hasRequestReadReceipt: hasRequestReadReceipt.value,
identity: identitySelected.value,
attachments: uploadController.attachmentsUploaded,
inlineAttachments: uploadController.mapInlineAttachments,
@@ -464,7 +462,8 @@ class ComposerController extends BaseController with DragDropFileMixin implement
unsubscribeEmailId: composerArguments.value!.previousEmailId,
messageId: composerArguments.value!.messageId,
references: composerArguments.value!.references,
emailSendingQueue: composerArguments.value!.sendingEmail
emailSendingQueue: composerArguments.value!.sendingEmail,
displayMode: screenDisplayMode.value
);
}
@@ -668,8 +667,6 @@ class ComposerController extends BaseController with DragDropFileMixin implement
accountId: accountId,
downloadUrl: downloadUrl
);
hasRequestReadReceipt.value = arguments.readRecepientEnabled ?? false;
break;
case EmailActionType.composeFromUnsubscribeMailtoLink:
if (arguments.subject != null) {
@@ -687,6 +684,13 @@ class ComposerController extends BaseController with DragDropFileMixin implement
default:
break;
}
if (composerArguments.value?.emailActionType == EmailActionType.reopenComposerBrowser) {
log('ComposerController::_initEmail: hasRequestReadReceipt = ${arguments.hasRequestReadReceipt}');
hasRequestReadReceipt.value = arguments.hasRequestReadReceipt ?? false;
} else {
_getAlwaysReadReceiptSetting();
}
}
}
@@ -985,7 +989,7 @@ class ComposerController extends BaseController with DragDropFileMixin implement
toRecipients: listToEmailAddress.toSet(),
ccRecipients: listCcEmailAddress.toSet(),
bccRecipients: listBccEmailAddress.toSet(),
isRequestReadReceipt: hasRequestReadReceipt.value,
hasRequestReadReceipt: hasRequestReadReceipt.value,
identity: identitySelected.value,
attachments: uploadController.attachmentsUploaded,
inlineAttachments: uploadController.mapInlineAttachments,
@@ -998,7 +1002,8 @@ class ComposerController extends BaseController with DragDropFileMixin implement
unsubscribeEmailId: composerArguments.value!.previousEmailId,
messageId: composerArguments.value!.messageId,
references: composerArguments.value!.references,
emailSendingQueue: composerArguments.value!.sendingEmail
emailSendingQueue: composerArguments.value!.sendingEmail,
displayMode: screenDisplayMode.value
),
createNewAndSendEmailInteractor: _createNewAndSendEmailInteractor,
onCancelSendingEmailAction: _handleCancelSendingMessage,
@@ -2104,6 +2109,7 @@ class ComposerController extends BaseController with DragDropFileMixin implement
}
void _getAlwaysReadReceiptSetting() {
log('ComposerController::_getAlwaysReadReceiptSetting:');
final accountId = mailboxDashBoardController.accountId.value;
if (accountId != null) {
consumeState(_getAlwaysReadReceiptSettingInteractor.execute(accountId));
@@ -2220,7 +2226,7 @@ class ComposerController extends BaseController with DragDropFileMixin implement
toRecipients: listToEmailAddress.toSet(),
ccRecipients: listCcEmailAddress.toSet(),
bccRecipients: listBccEmailAddress.toSet(),
isRequestReadReceipt: hasRequestReadReceipt.value,
hasRequestReadReceipt: hasRequestReadReceipt.value,
identity: identitySelected.value,
attachments: uploadController.attachmentsUploaded,
inlineAttachments: uploadController.mapInlineAttachments,
@@ -2231,7 +2237,8 @@ class ComposerController extends BaseController with DragDropFileMixin implement
unsubscribeEmailId: composerArguments.value!.previousEmailId,
messageId: composerArguments.value!.messageId,
references: composerArguments.value!.references,
emailSendingQueue: composerArguments.value!.sendingEmail
emailSendingQueue: composerArguments.value!.sendingEmail,
displayMode: screenDisplayMode.value
),
createNewAndSaveEmailToDraftsInteractor: _createNewAndSaveEmailToDraftsInteractor,
onCancelSavingEmailToDraftsAction: _handleCancelSavingMessageToDrafts,
@@ -142,7 +142,7 @@ extension CreateEmailRequestExtension on CreateEmailRequest {
attachments: newEmailAttachments.isNotEmpty
? newEmailAttachments
: null,
headerMdn: isRequestReadReceipt
headerMdn: hasRequestReadReceipt
? { IndividualHeaderIdentifier.headerMdn: createMdnEmailAddress() }
: null,
);
@@ -8,6 +8,7 @@ import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/email/attachment.dart';
import 'package:model/email/email_action_type.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart';
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
class CreateEmailRequest with EquatableMixin {
@@ -17,7 +18,7 @@ class CreateEmailRequest with EquatableMixin {
final EmailActionType emailActionType;
final String subject;
final String emailContent;
final bool isRequestReadReceipt;
final bool hasRequestReadReceipt;
final Set<EmailAddress> fromSender;
final Set<EmailAddress> toRecipients;
final Set<EmailAddress> ccRecipients;
@@ -34,6 +35,7 @@ class CreateEmailRequest with EquatableMixin {
final MessageIdsHeaderValue? messageId;
final MessageIdsHeaderValue? references;
final SendingEmail? emailSendingQueue;
final ScreenDisplayMode displayMode;
CreateEmailRequest({
required this.session,
@@ -45,7 +47,7 @@ class CreateEmailRequest with EquatableMixin {
required this.toRecipients,
required this.ccRecipients,
required this.bccRecipients,
this.isRequestReadReceipt = true,
this.hasRequestReadReceipt = true,
this.identity,
this.attachments,
this.inlineAttachments,
@@ -57,7 +59,8 @@ class CreateEmailRequest with EquatableMixin {
this.unsubscribeEmailId,
this.messageId,
this.references,
this.emailSendingQueue
this.emailSendingQueue,
this.displayMode = ScreenDisplayMode.normal
});
@override
@@ -72,7 +75,7 @@ class CreateEmailRequest with EquatableMixin {
ccRecipients,
bccRecipients,
identity,
isRequestReadReceipt,
hasRequestReadReceipt,
attachments,
inlineAttachments,
outboxMailboxId,
@@ -83,6 +86,7 @@ class CreateEmailRequest with EquatableMixin {
unsubscribeEmailId,
references,
references,
emailSendingQueue
emailSendingQueue,
displayMode,
];
}
@@ -7,6 +7,7 @@ import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart';
import 'package:html_editor_enhanced/html_editor.dart';
import 'package:model/email/email_action_type.dart';
import 'package:tmail_ui_user/features/composer/domain/state/restore_email_inline_images_state.dart';
import 'package:tmail_ui_user/features/composer/presentation/view/editor_view_mixin.dart';
import 'package:tmail_ui_user/features/composer/presentation/widgets/web/web_editor_widget.dart';
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
@@ -102,7 +103,7 @@ class WebEditorView extends StatelessWidget with EditorViewMixin {
onDragEnter: onDragEnter,
),
(success) {
if (success is GetEmailContentLoading) {
if (success is GetEmailContentLoading || success is RestoringEmailInlineImages) {
return const CupertinoLoadingWidget(padding: EdgeInsets.all(16.0));
} else {
var newContent = success is GetEmailContentSuccess
@@ -4,7 +4,6 @@ import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/base/widget/circle_loading_widget.dart';
import 'package:tmail_ui_user/features/composer/domain/state/download_image_as_base64_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/restore_email_inline_images_state.dart';
import 'package:tmail_ui_user/features/upload/domain/state/attachment_upload_state.dart';
class InsertImageLoadingBarWidget extends StatelessWidget {
@@ -38,9 +37,7 @@ class InsertImageLoadingBarWidget extends StatelessWidget {
return viewState.fold(
(failure) => const SizedBox.shrink(),
(success) {
if (success is DownloadingImageAsBase64 ||
success is RestoringEmailInlineImages
) {
if (success is DownloadingImageAsBase64) {
return CircleLoadingWidget(padding: padding);
} else {
return const SizedBox.shrink();
@@ -28,7 +28,7 @@ class ComposerArguments extends RouterArguments {
final List<Identity>? identities;
final Identity? selectedIdentity;
final List<Attachment>? inlineImages;
final bool? readRecepientEnabled;
final bool? hasRequestReadReceipt;
final ScreenDisplayMode displayMode;
ComposerArguments({
@@ -48,7 +48,7 @@ class ComposerArguments extends RouterArguments {
this.identities,
this.selectedIdentity,
this.inlineImages,
this.readRecepientEnabled,
this.hasRequestReadReceipt,
this.displayMode = ScreenDisplayMode.normal
});
@@ -98,7 +98,7 @@ class ComposerArguments extends RouterArguments {
attachments: composerCache.email?.allAttachments.getListAttachmentsDisplayedOutside(composerCache.email?.htmlBodyAttachments ?? []),
selectedIdentity: composerCache.identity,
inlineImages: composerCache.email?.allAttachments.listAttachmentsDisplayedInContent,
readRecepientEnabled: composerCache.readReceipentEnabled,
hasRequestReadReceipt: composerCache.hasRequestReadReceipt,
displayMode: composerCache.displayMode,
);
@@ -187,7 +187,12 @@ class ComposerArguments extends RouterArguments {
body,
messageId,
references,
previousEmailId,
identities,
selectedIdentity,
inlineImages,
hasRequestReadReceipt,
displayMode,
];
ComposerArguments copyWith({
@@ -207,7 +212,7 @@ class ComposerArguments extends RouterArguments {
List<Identity>? identities,
Identity? selectedIdentity,
List<Attachment>? inlineImages,
bool? readRecepientEnabled,
bool? hasRequestReadReceipt,
ScreenDisplayMode? displayMode,
}) {
return ComposerArguments(
@@ -227,7 +232,7 @@ class ComposerArguments extends RouterArguments {
identities: identities ?? this.identities,
selectedIdentity: selectedIdentity ?? this.selectedIdentity,
inlineImages: inlineImages ?? this.inlineImages,
readRecepientEnabled: readRecepientEnabled ?? this.readRecepientEnabled,
hasRequestReadReceipt: hasRequestReadReceipt ?? this.hasRequestReadReceipt,
displayMode: displayMode ?? this.displayMode,
);
}
@@ -1,22 +1,14 @@
import 'package:core/presentation/utils/html_transformer/transform_configuration.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/composer_cache.dart';
abstract class SessionStorageComposerDatasource {
Future<void> saveComposerCacheOnWeb(
Email email,
{
required AccountId accountId,
required UserName userName,
required ScreenDisplayMode displayMode,
Identity? identity,
bool? readReceipentEnabled,
}
);
Future<void> saveComposerCacheOnWeb({
required AccountId accountId,
required UserName userName,
required ComposerCache composerCache,
});
Future<ComposerCache> getComposerCacheOnWeb(
AccountId accountId,
@@ -1,13 +1,12 @@
import 'dart:convert';
import 'package:collection/collection.dart';
import 'package:core/core.dart';
import 'package:core/domain/exceptions/web_session_exception.dart';
import 'package:core/presentation/utils/html_transformer/html_transform.dart';
import 'package:core/presentation/utils/html_transformer/transform_configuration.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.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/model/composer_cache.dart';
import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart';
@@ -50,30 +49,18 @@ class SessionStorageComposerDatasourceImpl
}
@override
Future<void> saveComposerCacheOnWeb(
Email email,
{
required AccountId accountId,
required UserName userName,
required ScreenDisplayMode displayMode,
Identity? identity,
bool? readReceipentEnabled
}
) async {
Future<void> saveComposerCacheOnWeb({
required AccountId accountId,
required UserName userName,
required ComposerCache composerCache,
}) async {
return Future.sync(() {
final composerCacheKey = TupleKey(
EmailActionType.reopenComposerBrowser.name,
accountId.asString,
userName.value).toString();
Map<String, String> entries = {
composerCacheKey: jsonEncode(
ComposerCache(
displayMode: displayMode,
email: email,
identity: identity,
readReceipentEnabled: readReceipentEnabled,
).toJson()
)
composerCacheKey: jsonEncode(composerCache.toJson())
};
html.window.sessionStorage.addAll(entries);
}).catchError(_exceptionThrower.throwException);
@@ -1,44 +1,35 @@
import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart';
part 'composer_cache.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class ComposerCache with EquatableMixin {
final Email? email;
final Identity? identity;
final bool? readReceipentEnabled;
final bool? hasRequestReadReceipt;
final ScreenDisplayMode displayMode;
ComposerCache({
required this.displayMode,
this.email,
this.identity,
this.readReceipentEnabled,
this.hasRequestReadReceipt,
this.displayMode = ScreenDisplayMode.normal
});
factory ComposerCache.fromJson(Map<String, dynamic> json) => _$ComposerCacheFromJson(json);
Map<String, dynamic> toJson() => _$ComposerCacheToJson(this);
@override
List<Object?> get props => [
email,
identity,
readReceipentEnabled
hasRequestReadReceipt,
displayMode
];
Map<String, dynamic> toJson() {
return <String, dynamic>{
'email': email?.toJson(),
'identity': identity?.toJson(),
'readReceipentEnabled': readReceipentEnabled,
'displayMode': displayMode.toJson()
};
}
factory ComposerCache.fromJson(Map<String, dynamic> map) {
return ComposerCache(
displayMode: ScreenDisplayMode.fromJson(map['displayMode'] ?? ''),
email: map['email'] != null ? Email.fromJson(map['email']) : null,
identity: map['identity'] != null ? Identity.fromJson(map['identity']) : null,
readReceipentEnabled: map['readReceipentEnabled'] as bool?
);
}
}
@@ -1,9 +1,6 @@
import 'package:core/presentation/utils/html_transformer/transform_configuration.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.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/model/composer_cache.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/repository/composer_cache_repository.dart';
@@ -28,23 +25,15 @@ class ComposerCacheRepositoryImpl extends ComposerCacheRepository {
}
@override
Future<void> saveComposerCacheOnWeb(
Email email,
{
required AccountId accountId,
required UserName userName,
required ScreenDisplayMode displayMode,
Identity? identity,
bool? readReceipentEnabled
}
) {
Future<void> saveComposerCacheOnWeb({
required AccountId accountId,
required UserName userName,
required ComposerCache composerCache,
}) {
return composerCacheDataSource.saveComposerCacheOnWeb(
email,
accountId: accountId,
userName: userName,
displayMode: displayMode,
identity: identity,
readReceipentEnabled: readReceipentEnabled);
composerCache: composerCache);
}
@override
@@ -1,22 +1,14 @@
import 'package:core/presentation/utils/html_transformer/transform_configuration.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/user_name.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/data/model/composer_cache.dart';
abstract class ComposerCacheRepository {
Future<void> saveComposerCacheOnWeb(
Email email,
{
required AccountId accountId,
required UserName userName,
required ScreenDisplayMode displayMode,
Identity? identity,
bool? readReceipentEnabled
}
);
Future<void> saveComposerCacheOnWeb({
required AccountId accountId,
required UserName userName,
required ComposerCache composerCache,
});
Future<ComposerCache> getComposerCacheOnWeb(
AccountId accountId,
@@ -33,7 +33,7 @@ extension ListAttachmentExtension on List<Attachment> {
required String downloadUrl
}) {
final mapUrlDownloadCID = {
for (var attachment in listAttachmentsDisplayedInContent)
for (var attachment in this)
attachment.cid! : attachment.getDownloadUrl(downloadUrl, accountId)
};
return mapUrlDownloadCID;