TF-3945 Change style for signature composer
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -272,6 +272,7 @@ extension AppColor on Color {
|
|||||||
static const m3Primary95 = Color(0xFFE3F1FF);
|
static const m3Primary95 = Color(0xFFE3F1FF);
|
||||||
static const gray49454F = Color(0xFF49454F);
|
static const gray49454F = Color(0xFF49454F);
|
||||||
static const lightGrayF9FAFB = Color(0xFFF9FAFB);
|
static const lightGrayF9FAFB = Color(0xFFF9FAFB);
|
||||||
|
static const black4D4D4D = Color(0xFF4D4D4D);
|
||||||
|
|
||||||
static const mapGradientColor = [
|
static const mapGradientColor = [
|
||||||
[Color(0xFF21D4FD), Color(0xFFB721FF)],
|
[Color(0xFF21D4FD), Color(0xFFB721FF)],
|
||||||
|
|||||||
+2
-2
@@ -10,7 +10,7 @@ extension SanitizeSignatureInEmailContentExtension on ComposerController {
|
|||||||
if (emailContent == null) return;
|
if (emailContent == null) return;
|
||||||
|
|
||||||
final emailDocument = parse(emailContent);
|
final emailDocument = parse(emailContent);
|
||||||
final existedSignatureButton = emailDocument.querySelector('button.tmail-signature-button');
|
final existedSignatureButton = emailDocument.querySelector('.tmail-signature-button');
|
||||||
if (existedSignatureButton != null) return;
|
if (existedSignatureButton != null) return;
|
||||||
|
|
||||||
final signature = emailDocument.querySelector('div.tmail-signature');
|
final signature = emailDocument.querySelector('div.tmail-signature');
|
||||||
@@ -26,7 +26,7 @@ extension SanitizeSignatureInEmailContentExtension on ComposerController {
|
|||||||
void synchronizeInitEmailDraftHash(String? emailContent) {
|
void synchronizeInitEmailDraftHash(String? emailContent) {
|
||||||
try {
|
try {
|
||||||
final emailDocument = parse(emailContent);
|
final emailDocument = parse(emailContent);
|
||||||
final signatureButton = emailDocument.querySelector('button.tmail-signature-button');
|
final signatureButton = emailDocument.querySelector('.tmail-signature-button');
|
||||||
if (signatureButton == null) return;
|
if (signatureButton == null) return;
|
||||||
|
|
||||||
restoringSignatureButton = false;
|
restoringSignatureButton = false;
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:core/presentation/utils/theme_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SignatureTooltipWidget extends StatelessWidget {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
const SignatureTooltipWidget({super.key, required this.message});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.black4D4D4D,
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black.withValues(alpha: 0.16),
|
||||||
|
blurRadius: 24,
|
||||||
|
),
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black.withValues(alpha: 0.08),
|
||||||
|
blurRadius: 2,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
message,
|
||||||
|
style: ThemeUtils.textStyleInter600().copyWith(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 12,
|
||||||
|
height: 20 / 12,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@ import 'package:core/utils/html/html_template.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/widgets/web/signature_tooltip_widget.dart';
|
||||||
|
import 'package:tmail_ui_user/main/localizations/app_localizations.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);
|
||||||
@@ -74,6 +76,11 @@ class _WebEditorState extends State<WebEditorWidget> {
|
|||||||
late HtmlEditorController _editorController;
|
late HtmlEditorController _editorController;
|
||||||
bool _dropListenerRegistered = false;
|
bool _dropListenerRegistered = false;
|
||||||
Function(Event)? _dropListener;
|
Function(Event)? _dropListener;
|
||||||
|
|
||||||
|
OverlayEntry? _signatureTooltipEntry;
|
||||||
|
final GlobalKey _signatureTooltipKey = GlobalKey();
|
||||||
|
double _signatureTooltipLeft = 0;
|
||||||
|
bool _signatureTooltipReady = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -108,6 +115,7 @@ class _WebEditorState extends State<WebEditorWidget> {
|
|||||||
window.removeEventListener("message", _dropListener!);
|
window.removeEventListener("message", _dropListener!);
|
||||||
_dropListener = null;
|
_dropListener = null;
|
||||||
}
|
}
|
||||||
|
_hideSignatureTooltip();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +187,92 @@ class _WebEditorState extends State<WebEditorWidget> {
|
|||||||
onImageUpload: widget.onPasteImageSuccessAction,
|
onImageUpload: widget.onPasteImageSuccessAction,
|
||||||
onImageUploadError: widget.onPasteImageFailureAction,
|
onImageUploadError: widget.onPasteImageFailureAction,
|
||||||
onInitialTextLoadComplete: widget.onInitialContentLoadComplete,
|
onInitialTextLoadComplete: widget.onInitialContentLoadComplete,
|
||||||
|
onSignatureHoverIn: (position, isContentVisible) {
|
||||||
|
log('_WebEditorState::build: onSignatureHoverIn position: $position');
|
||||||
|
_showSignatureTooltipAtPosition(
|
||||||
|
position,
|
||||||
|
isContentVisible
|
||||||
|
? AppLocalizations.of(context).hideSignature
|
||||||
|
: AppLocalizations.of(context).showSignature,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onSignatureHoverOut: () {
|
||||||
|
log('_WebEditorState::build: onSignatureHoverOut');
|
||||||
|
_hideSignatureTooltip();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showSignatureTooltipAtPosition(
|
||||||
|
SignaturePosition position,
|
||||||
|
String message,
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
final overlay = Overlay.maybeOf(context);
|
||||||
|
_signatureTooltipEntry?.remove();
|
||||||
|
|
||||||
|
_signatureTooltipReady = false;
|
||||||
|
_signatureTooltipLeft = position.left;
|
||||||
|
|
||||||
|
_signatureTooltipEntry = OverlayEntry(
|
||||||
|
builder: (context) {
|
||||||
|
return Positioned(
|
||||||
|
top: position.top + position.height + 8,
|
||||||
|
left: _signatureTooltipLeft,
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: Opacity(
|
||||||
|
opacity: _signatureTooltipReady ? 1 : 0,
|
||||||
|
child: SignatureTooltipWidget(
|
||||||
|
key: _signatureTooltipKey,
|
||||||
|
message: message,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
overlay?.insert(_signatureTooltipEntry!);
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
try {
|
||||||
|
final renderBox = _signatureTooltipKey.currentContext
|
||||||
|
?.findRenderObject() as RenderBox?;
|
||||||
|
if (renderBox == null) return;
|
||||||
|
|
||||||
|
final tooltipWidth = renderBox.size.width;
|
||||||
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
final centerLeft =
|
||||||
|
position.left + (position.width / 2) - (tooltipWidth / 2);
|
||||||
|
final leftAligned = position.left;
|
||||||
|
final rightAligned = position.left + position.width - tooltipWidth;
|
||||||
|
|
||||||
|
if (centerLeft < 8) {
|
||||||
|
_signatureTooltipLeft = leftAligned;
|
||||||
|
} else if (centerLeft + tooltipWidth > screenWidth - 8) {
|
||||||
|
_signatureTooltipLeft = rightAligned;
|
||||||
|
} else {
|
||||||
|
_signatureTooltipLeft = centerLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
_signatureTooltipReady = true;
|
||||||
|
_signatureTooltipEntry?.markNeedsBuild();
|
||||||
|
} catch (e) {
|
||||||
|
logError(
|
||||||
|
'_WebEditorState::_showTooltipAtPosition:addPostFrameCallback:Exception = $e',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
logError('_WebEditorState::_showTooltipAtPosition:Exception = $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _hideSignatureTooltip() {
|
||||||
|
_signatureTooltipEntry?.remove();
|
||||||
|
_signatureTooltipEntry = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4665,5 +4665,17 @@
|
|||||||
"type": "text",
|
"type": "text",
|
||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"hideSignature": "Hide signature",
|
||||||
|
"@hideSignature": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"showSignature": "Show signature",
|
||||||
|
"@showSignature": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4920,4 +4920,18 @@ class AppLocalizations {
|
|||||||
name: 'dialogWarningMessageForForwardsToOtherDomains',
|
name: 'dialogWarningMessageForForwardsToOtherDomains',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get hideSignature {
|
||||||
|
return Intl.message(
|
||||||
|
'Hide signature',
|
||||||
|
name: 'hideSignature',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String get showSignature {
|
||||||
|
return Intl.message(
|
||||||
|
'Show signature',
|
||||||
|
name: 'showSignature',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1268,10 +1268,10 @@ packages:
|
|||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: main
|
ref: main
|
||||||
resolved-ref: "7184ed773603b0bc8d4863a6d60141f46e65c37e"
|
resolved-ref: "05f78b3e2d4535ade646667db5d5602234fe7b5e"
|
||||||
url: "https://github.com/linagora/html-editor-enhanced.git"
|
url: "https://github.com/linagora/html-editor-enhanced.git"
|
||||||
source: git
|
source: git
|
||||||
version: "3.2.1"
|
version: "3.2.3"
|
||||||
html_unescape:
|
html_unescape:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
Reference in New Issue
Block a user