TF-3945 Change style for signature composer

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-08-19 13:49:35 +07:00
committed by Dat H. Pham
parent 8335aaba07
commit 7f195a5422
7 changed files with 164 additions and 4 deletions
@@ -272,6 +272,7 @@ extension AppColor on Color {
static const m3Primary95 = Color(0xFFE3F1FF);
static const gray49454F = Color(0xFF49454F);
static const lightGrayF9FAFB = Color(0xFFF9FAFB);
static const black4D4D4D = Color(0xFF4D4D4D);
static const mapGradientColor = [
[Color(0xFF21D4FD), Color(0xFFB721FF)],
@@ -10,7 +10,7 @@ extension SanitizeSignatureInEmailContentExtension on ComposerController {
if (emailContent == null) return;
final emailDocument = parse(emailContent);
final existedSignatureButton = emailDocument.querySelector('button.tmail-signature-button');
final existedSignatureButton = emailDocument.querySelector('.tmail-signature-button');
if (existedSignatureButton != null) return;
final signature = emailDocument.querySelector('div.tmail-signature');
@@ -26,7 +26,7 @@ extension SanitizeSignatureInEmailContentExtension on ComposerController {
void synchronizeInitEmailDraftHash(String? emailContent) {
try {
final emailDocument = parse(emailContent);
final signatureButton = emailDocument.querySelector('button.tmail-signature-button');
final signatureButton = emailDocument.querySelector('.tmail-signature-button');
if (signatureButton == null) return;
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:flutter/material.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;
typedef OnChangeContentEditorAction = Function(String? text);
@@ -74,6 +76,11 @@ class _WebEditorState extends State<WebEditorWidget> {
late HtmlEditorController _editorController;
bool _dropListenerRegistered = false;
Function(Event)? _dropListener;
OverlayEntry? _signatureTooltipEntry;
final GlobalKey _signatureTooltipKey = GlobalKey();
double _signatureTooltipLeft = 0;
bool _signatureTooltipReady = false;
@override
void initState() {
@@ -108,6 +115,7 @@ class _WebEditorState extends State<WebEditorWidget> {
window.removeEventListener("message", _dropListener!);
_dropListener = null;
}
_hideSignatureTooltip();
super.dispose();
}
@@ -179,7 +187,92 @@ class _WebEditorState extends State<WebEditorWidget> {
onImageUpload: widget.onPasteImageSuccessAction,
onImageUploadError: widget.onPasteImageFailureAction,
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;
}
}
+12
View File
@@ -4665,5 +4665,17 @@
"type": "text",
"placeholders_order": [],
"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',
);
}
String get hideSignature {
return Intl.message(
'Hide signature',
name: 'hideSignature',
);
}
String get showSignature {
return Intl.message(
'Show signature',
name: 'showSignature',
);
}
}
+2 -2
View File
@@ -1268,10 +1268,10 @@ packages:
description:
path: "."
ref: main
resolved-ref: "7184ed773603b0bc8d4863a6d60141f46e65c37e"
resolved-ref: "05f78b3e2d4535ade646667db5d5602234fe7b5e"
url: "https://github.com/linagora/html-editor-enhanced.git"
source: git
version: "3.2.1"
version: "3.2.3"
html_unescape:
dependency: transitive
description: