Fix cannot copy & paste base64 image as inline image in composer web
This commit is contained in:
@@ -15,6 +15,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:html_editor_enhanced/html_editor.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/identities/identity.dart';
|
import 'package:jmap_dart_client/jmap/identities/identity.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||||
@@ -86,6 +87,7 @@ import 'package:tmail_ui_user/features/server_settings/domain/usecases/get_alway
|
|||||||
import 'package:tmail_ui_user/features/upload/domain/exceptions/pick_file_exception.dart';
|
import 'package:tmail_ui_user/features/upload/domain/exceptions/pick_file_exception.dart';
|
||||||
import 'package:tmail_ui_user/features/upload/domain/extensions/list_file_info_extension.dart';
|
import 'package:tmail_ui_user/features/upload/domain/extensions/list_file_info_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/upload/domain/extensions/file_info_extension.dart';
|
import 'package:tmail_ui_user/features/upload/domain/extensions/file_info_extension.dart';
|
||||||
|
import 'package:tmail_ui_user/features/upload/domain/extensions/list_file_upload_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/upload/domain/model/upload_task_id.dart';
|
import 'package:tmail_ui_user/features/upload/domain/model/upload_task_id.dart';
|
||||||
import 'package:tmail_ui_user/features/upload/domain/state/attachment_upload_state.dart';
|
import 'package:tmail_ui_user/features/upload/domain/state/attachment_upload_state.dart';
|
||||||
import 'package:tmail_ui_user/features/upload/domain/state/local_file_picker_state.dart';
|
import 'package:tmail_ui_user/features/upload/domain/state/local_file_picker_state.dart';
|
||||||
@@ -2136,11 +2138,7 @@ class ComposerController extends BaseController with DragDropFileMixin implement
|
|||||||
required DropDoneDetails details,
|
required DropDoneDetails details,
|
||||||
required double maxWidth
|
required double maxWidth
|
||||||
}) async {
|
}) async {
|
||||||
if (responsiveUtils.isMobile(context)) {
|
_setUpMaxWidthInlineImage(context: context, maxWidth: maxWidth);
|
||||||
maxWithEditor = maxWidth - 40;
|
|
||||||
} else {
|
|
||||||
maxWithEditor = maxWidth - 70;
|
|
||||||
}
|
|
||||||
|
|
||||||
final listFileInfo = await onDragDone(context: context, details: details);
|
final listFileInfo = await onDragDone(context: context, details: details);
|
||||||
|
|
||||||
@@ -2152,13 +2150,9 @@ class ComposerController extends BaseController with DragDropFileMixin implement
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final listAttachments = listFileInfo
|
|
||||||
.where((fileInfo) => fileInfo.isInline != true)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
uploadController.validateTotalSizeAttachmentsBeforeUpload(
|
uploadController.validateTotalSizeAttachmentsBeforeUpload(
|
||||||
totalSizePreparedFiles: listFileInfo.totalSize,
|
totalSizePreparedFiles: listFileInfo.totalSize,
|
||||||
totalSizePreparedFilesWithDispositionAttachment: listAttachments.totalSize,
|
totalSizePreparedFilesWithDispositionAttachment: listFileInfo.listAttachmentFiles.totalSize,
|
||||||
onValidationSuccess: () => _uploadAttachmentsAction(pickedFiles: listFileInfo)
|
onValidationSuccess: () => _uploadAttachmentsAction(pickedFiles: listFileInfo)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -2341,4 +2335,43 @@ class ComposerController extends BaseController with DragDropFileMixin implement
|
|||||||
await _saveComposerCacheOnWebAction();
|
await _saveComposerCacheOnWebAction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _setUpMaxWidthInlineImage({
|
||||||
|
required BuildContext context,
|
||||||
|
required double maxWidth
|
||||||
|
}) {
|
||||||
|
if (responsiveUtils.isMobile(context)) {
|
||||||
|
maxWithEditor = maxWidth - 40;
|
||||||
|
} else {
|
||||||
|
maxWithEditor = maxWidth - 70;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleOnPasteImageSuccessAction({
|
||||||
|
required BuildContext context,
|
||||||
|
required double maxWidth,
|
||||||
|
required List<FileUpload> listFileUpload
|
||||||
|
}) {
|
||||||
|
log('ComposerController::handleOnPasteImageSuccessAction: listFileUpload = ${listFileUpload.length}');
|
||||||
|
_setUpMaxWidthInlineImage(context: context, maxWidth: maxWidth);
|
||||||
|
|
||||||
|
final listFileInfo = listFileUpload.toListFileInfo();
|
||||||
|
|
||||||
|
uploadController.validateTotalSizeAttachmentsBeforeUpload(
|
||||||
|
totalSizePreparedFiles: listFileInfo.totalSize,
|
||||||
|
onValidationSuccess: () => _uploadAttachmentsAction(pickedFiles: listFileInfo)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleOnPasteImageFailureAction({
|
||||||
|
required BuildContext context,
|
||||||
|
List<FileUpload>? listFileUpload,
|
||||||
|
String? base64,
|
||||||
|
required UploadError uploadError
|
||||||
|
}) {
|
||||||
|
logError('ComposerController::handleOnPasteImageFailureAction: $uploadError');
|
||||||
|
appToast.showToastErrorMessage(
|
||||||
|
context,
|
||||||
|
AppLocalizations.of(context).thisImageCannotBePastedIntoTheEditor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -190,6 +190,18 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
width: constraints.maxWidth,
|
width: constraints.maxWidth,
|
||||||
height: constraints.maxHeight,
|
height: constraints.maxHeight,
|
||||||
onDragEnter: controller.handleOnDragEnterHtmlEditorWeb,
|
onDragEnter: controller.handleOnDragEnterHtmlEditorWeb,
|
||||||
|
onPasteImageSuccessAction: (listFileUpload) => controller.handleOnPasteImageSuccessAction(
|
||||||
|
context: context,
|
||||||
|
maxWidth: constraintsEditor.maxWidth,
|
||||||
|
listFileUpload: listFileUpload
|
||||||
|
),
|
||||||
|
onPasteImageFailureAction: (listFileUpload, base64, uploadError) =>
|
||||||
|
controller.handleOnPasteImageFailureAction(
|
||||||
|
context: context,
|
||||||
|
listFileUpload: listFileUpload,
|
||||||
|
base64: base64,
|
||||||
|
uploadError: uploadError
|
||||||
|
),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -430,6 +442,18 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
width: constraints.maxWidth,
|
width: constraints.maxWidth,
|
||||||
height: constraints.maxHeight,
|
height: constraints.maxHeight,
|
||||||
onDragEnter: controller.handleOnDragEnterHtmlEditorWeb,
|
onDragEnter: controller.handleOnDragEnterHtmlEditorWeb,
|
||||||
|
onPasteImageSuccessAction: (listFileUpload) => controller.handleOnPasteImageSuccessAction(
|
||||||
|
context: context,
|
||||||
|
maxWidth: constraintsEditor.maxWidth,
|
||||||
|
listFileUpload: listFileUpload
|
||||||
|
),
|
||||||
|
onPasteImageFailureAction: (listFileUpload, base64, uploadError) =>
|
||||||
|
controller.handleOnPasteImageFailureAction(
|
||||||
|
context: context,
|
||||||
|
listFileUpload: listFileUpload,
|
||||||
|
base64: base64,
|
||||||
|
uploadError: uploadError
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
@@ -688,6 +712,18 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
width: constraints.maxWidth,
|
width: constraints.maxWidth,
|
||||||
height: constraints.maxHeight,
|
height: constraints.maxHeight,
|
||||||
onDragEnter: controller.handleOnDragEnterHtmlEditorWeb,
|
onDragEnter: controller.handleOnDragEnterHtmlEditorWeb,
|
||||||
|
onPasteImageSuccessAction: (listFileUpload) => controller.handleOnPasteImageSuccessAction(
|
||||||
|
context: context,
|
||||||
|
maxWidth: constraintsBody.maxWidth,
|
||||||
|
listFileUpload: listFileUpload
|
||||||
|
),
|
||||||
|
onPasteImageFailureAction: (listFileUpload, base64, uploadError) =>
|
||||||
|
controller.handleOnPasteImageFailureAction(
|
||||||
|
context: context,
|
||||||
|
listFileUpload: listFileUpload,
|
||||||
|
base64: base64,
|
||||||
|
uploadError: uploadError
|
||||||
|
),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
import 'dart:convert' as convert;
|
import 'dart:convert' as convert;
|
||||||
import 'dart:typed_data' as type_data;
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:html_editor_enhanced/utils/file_upload_model.dart';
|
import 'package:html_editor_enhanced/utils/file_upload_model.dart';
|
||||||
import 'package:model/upload/file_info.dart';
|
import 'package:model/upload/file_info.dart';
|
||||||
|
|
||||||
@@ -23,22 +20,17 @@ extension FileUploadExtension on FileUpload {
|
|||||||
return base64;
|
return base64;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<FileInfo?> toFileInfo() async {
|
FileInfo? toFileInfo() {
|
||||||
if (base64Data != null) {
|
if (base64Data != null) {
|
||||||
final bytes = await compute(convertBase64ToBytes, base64Data!);
|
|
||||||
return FileInfo.fromBytes(
|
return FileInfo.fromBytes(
|
||||||
bytes: bytes,
|
bytes: convert.base64Decode(base64Data!),
|
||||||
name: name,
|
name: name,
|
||||||
size: size,
|
size: size,
|
||||||
type: type,
|
type: type,
|
||||||
|
isInline: true
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8List convertBase64ToBytes(String base64) {
|
|
||||||
type_data.Uint8List decodeBytes = convert.base64Decode(base64);
|
|
||||||
return decodeBytes;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -15,8 +15,6 @@ import 'package:tmail_ui_user/features/email/domain/state/transform_html_email_c
|
|||||||
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/main/utils/app_utils.dart';
|
import 'package:tmail_ui_user/main/utils/app_utils.dart';
|
||||||
|
|
||||||
typedef OnDragEnterListener = Function(List<dynamic>? types);
|
|
||||||
|
|
||||||
class WebEditorView extends StatelessWidget with EditorViewMixin {
|
class WebEditorView extends StatelessWidget with EditorViewMixin {
|
||||||
|
|
||||||
final HtmlEditorController editorController;
|
final HtmlEditorController editorController;
|
||||||
@@ -33,6 +31,8 @@ class WebEditorView extends StatelessWidget with EditorViewMixin {
|
|||||||
final double? width;
|
final double? width;
|
||||||
final double? height;
|
final double? height;
|
||||||
final OnDragEnterListener? onDragEnter;
|
final OnDragEnterListener? onDragEnter;
|
||||||
|
final OnPasteImageSuccessAction? onPasteImageSuccessAction;
|
||||||
|
final OnPasteImageFailureAction? onPasteImageFailureAction;
|
||||||
|
|
||||||
const WebEditorView({
|
const WebEditorView({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -50,6 +50,8 @@ class WebEditorView extends StatelessWidget with EditorViewMixin {
|
|||||||
this.width,
|
this.width,
|
||||||
this.height,
|
this.height,
|
||||||
this.onDragEnter,
|
this.onDragEnter,
|
||||||
|
this.onPasteImageSuccessAction,
|
||||||
|
this.onPasteImageFailureAction,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -76,6 +78,8 @@ class WebEditorView extends StatelessWidget with EditorViewMixin {
|
|||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
onDragEnter: onDragEnter,
|
onDragEnter: onDragEnter,
|
||||||
|
onPasteImageSuccessAction: onPasteImageSuccessAction,
|
||||||
|
onPasteImageFailureAction: onPasteImageFailureAction,
|
||||||
);
|
);
|
||||||
case EmailActionType.editDraft:
|
case EmailActionType.editDraft:
|
||||||
case EmailActionType.editSendingEmail:
|
case EmailActionType.editSendingEmail:
|
||||||
@@ -101,6 +105,8 @@ class WebEditorView extends StatelessWidget with EditorViewMixin {
|
|||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
onDragEnter: onDragEnter,
|
onDragEnter: onDragEnter,
|
||||||
|
onPasteImageSuccessAction: onPasteImageSuccessAction,
|
||||||
|
onPasteImageFailureAction: onPasteImageFailureAction,
|
||||||
),
|
),
|
||||||
(success) {
|
(success) {
|
||||||
if (success is GetEmailContentLoading || success is RestoringEmailInlineImages) {
|
if (success is GetEmailContentLoading || success is RestoringEmailInlineImages) {
|
||||||
@@ -126,6 +132,8 @@ class WebEditorView extends StatelessWidget with EditorViewMixin {
|
|||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
onDragEnter: onDragEnter,
|
onDragEnter: onDragEnter,
|
||||||
|
onPasteImageSuccessAction: onPasteImageSuccessAction,
|
||||||
|
onPasteImageFailureAction: onPasteImageFailureAction,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,6 +166,8 @@ class WebEditorView extends StatelessWidget with EditorViewMixin {
|
|||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
onDragEnter: onDragEnter,
|
onDragEnter: onDragEnter,
|
||||||
|
onPasteImageSuccessAction: onPasteImageSuccessAction,
|
||||||
|
onPasteImageFailureAction: onPasteImageFailureAction,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
(success) {
|
(success) {
|
||||||
@@ -186,6 +196,8 @@ class WebEditorView extends StatelessWidget with EditorViewMixin {
|
|||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
onDragEnter: onDragEnter,
|
onDragEnter: onDragEnter,
|
||||||
|
onPasteImageSuccessAction: onPasteImageSuccessAction,
|
||||||
|
onPasteImageFailureAction: onPasteImageFailureAction,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,6 +217,8 @@ class WebEditorView extends StatelessWidget with EditorViewMixin {
|
|||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
onDragEnter: onDragEnter,
|
onDragEnter: onDragEnter,
|
||||||
|
onPasteImageSuccessAction: onPasteImageSuccessAction,
|
||||||
|
onPasteImageFailureAction: onPasteImageFailureAction,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import 'package:core/utils/app_logger.dart';
|
|||||||
import 'package:core/utils/html/html_utils.dart';
|
import 'package:core/utils/html/html_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:html_editor_enhanced/html_editor.dart';
|
import 'package:html_editor_enhanced/html_editor.dart';
|
||||||
import 'package:tmail_ui_user/features/composer/presentation/view/web/web_editor_view.dart';
|
|
||||||
import 'package:universal_html/html.dart' hide VoidCallback;
|
import 'package:universal_html/html.dart' hide VoidCallback;
|
||||||
|
|
||||||
typedef OnChangeContentEditorAction = Function(String? text);
|
typedef OnChangeContentEditorAction = Function(String? text);
|
||||||
@@ -13,6 +12,12 @@ typedef OnInitialContentEditorAction = Function(String text);
|
|||||||
typedef OnMouseDownEditorAction = Function(BuildContext context);
|
typedef OnMouseDownEditorAction = Function(BuildContext context);
|
||||||
typedef OnEditorSettingsChange = Function(EditorSettings settings);
|
typedef OnEditorSettingsChange = Function(EditorSettings settings);
|
||||||
typedef OnEditorTextSizeChanged = Function(int? size);
|
typedef OnEditorTextSizeChanged = Function(int? size);
|
||||||
|
typedef OnDragEnterListener = Function(List<dynamic>? types);
|
||||||
|
typedef OnPasteImageSuccessAction = Function(List<FileUpload> listFileUpload);
|
||||||
|
typedef OnPasteImageFailureAction = Function(
|
||||||
|
List<FileUpload>? listFileUpload,
|
||||||
|
String? base64,
|
||||||
|
UploadError uploadError);
|
||||||
|
|
||||||
class WebEditorWidget extends StatefulWidget {
|
class WebEditorWidget extends StatefulWidget {
|
||||||
|
|
||||||
@@ -29,6 +34,8 @@ class WebEditorWidget extends StatefulWidget {
|
|||||||
final double? width;
|
final double? width;
|
||||||
final double? height;
|
final double? height;
|
||||||
final OnDragEnterListener? onDragEnter;
|
final OnDragEnterListener? onDragEnter;
|
||||||
|
final OnPasteImageSuccessAction? onPasteImageSuccessAction;
|
||||||
|
final OnPasteImageFailureAction? onPasteImageFailureAction;
|
||||||
|
|
||||||
const WebEditorWidget({
|
const WebEditorWidget({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -45,6 +52,8 @@ class WebEditorWidget extends StatefulWidget {
|
|||||||
this.width,
|
this.width,
|
||||||
this.height,
|
this.height,
|
||||||
this.onDragEnter,
|
this.onDragEnter,
|
||||||
|
this.onPasteImageSuccessAction,
|
||||||
|
this.onPasteImageFailureAction,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -179,6 +188,8 @@ class _WebEditorState extends State<WebEditorWidget> {
|
|||||||
),
|
),
|
||||||
onDragEnter: widget.onDragEnter,
|
onDragEnter: widget.onDragEnter,
|
||||||
onDragLeave: (_) {},
|
onDragLeave: (_) {},
|
||||||
|
onImageUpload: widget.onPasteImageSuccessAction,
|
||||||
|
onImageUploadError: widget.onPasteImageFailureAction,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import 'package:model/upload/file_info.dart';
|
import 'package:model/upload/file_info.dart';
|
||||||
|
|
||||||
extension ListFileInfoExtension on List<FileInfo> {
|
extension ListFileInfoExtension on List<FileInfo> {
|
||||||
@@ -7,4 +6,6 @@ extension ListFileInfoExtension on List<FileInfo> {
|
|||||||
num get totalSize => listSize.isEmpty ? 0 : listSize.reduce((sum, size) => sum + size);
|
num get totalSize => listSize.isEmpty ? 0 : listSize.reduce((sum, size) => sum + size);
|
||||||
|
|
||||||
List<FileInfo> get listInlineFiles => where((fileInfo) => fileInfo.isInline == true).toList();
|
List<FileInfo> get listInlineFiles => where((fileInfo) => fileInfo.isInline == true).toList();
|
||||||
|
|
||||||
|
List<FileInfo> get listAttachmentFiles => where((fileInfo) => fileInfo.isInline != true).toList();
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:html_editor_enhanced/html_editor.dart';
|
||||||
|
import 'package:model/upload/file_info.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/extensions/file_upload_extension.dart';
|
||||||
|
|
||||||
|
extension ListFileUploadExtension on List<FileUpload> {
|
||||||
|
List<FileInfo> toListFileInfo() => map((fileUpload) => fileUpload.toFileInfo()).whereNotNull().toList();
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"@@last_modified": "2024-08-20T10:36:35.487743",
|
"@@last_modified": "2024-08-19T19:20:23.876948",
|
||||||
"initializing_data": "Initializing data...",
|
"initializing_data": "Initializing data...",
|
||||||
"@initializing_data": {
|
"@initializing_data": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -3987,5 +3987,11 @@
|
|||||||
"type": "text",
|
"type": "text",
|
||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"thisImageCannotBePastedIntoTheEditor": "This image cannot be pasted into the editor.",
|
||||||
|
"@thisImageCannotBePastedIntoTheEditor": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4159,13 +4159,13 @@ class AppLocalizations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String get emptySpamFolderFailed {
|
String get emptySpamFolderFailed {
|
||||||
return Intl.message(''
|
return Intl.message(
|
||||||
'Empty spam folder failed',
|
'Empty spam folder failed',
|
||||||
name: 'emptySpamFolderFailed');
|
name: 'emptySpamFolderFailed');
|
||||||
}
|
}
|
||||||
|
|
||||||
String get markAsSpamFailed {
|
String get markAsSpamFailed {
|
||||||
return Intl.message(''
|
return Intl.message(
|
||||||
'Mark as spam failed',
|
'Mark as spam failed',
|
||||||
name: 'markAsSpamFailed');
|
name: 'markAsSpamFailed');
|
||||||
}
|
}
|
||||||
@@ -4176,4 +4176,10 @@ class AppLocalizations {
|
|||||||
name: 'canNotUploadFileToSignature'
|
name: 'canNotUploadFileToSignature'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get thisImageCannotBePastedIntoTheEditor {
|
||||||
|
return Intl.message(
|
||||||
|
'This image cannot be pasted into the editor.',
|
||||||
|
name: 'thisImageCannotBePastedIntoTheEditor');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -28,12 +28,14 @@ class FileInfo with EquatableMixin {
|
|||||||
String? name,
|
String? name,
|
||||||
int? size,
|
int? size,
|
||||||
String? type,
|
String? type,
|
||||||
|
bool? isInline,
|
||||||
}) {
|
}) {
|
||||||
return FileInfo(
|
return FileInfo(
|
||||||
fileName: name ?? '',
|
fileName: name ?? '',
|
||||||
fileSize: size ?? 0,
|
fileSize: size ?? 0,
|
||||||
bytes: bytes,
|
bytes: bytes,
|
||||||
type: type
|
type: type,
|
||||||
|
isInline: isInline,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user