TF-1961 Add script handle lazy loading image in html

(cherry picked from commit b57c93f47dc7c621e24506818d44b6360a9b9239)
This commit is contained in:
dab246
2023-08-16 12:30:49 +07:00
committed by Dat Vu
parent 1af33dd20d
commit e2de23fdfd
5 changed files with 52 additions and 8 deletions
@@ -39,6 +39,15 @@ class ImageTransformer extends DomTransformer {
imageSource: src imageSource: src
); );
imageElement.attributes['src'] = imageBase64 ?? src; imageElement.attributes['src'] = imageBase64 ?? src;
} else if (src.startsWith('https://') || src.startsWith('http://')) {
final classAttribute = imageElement.attributes['class'];
if (classAttribute != null) {
imageElement.attributes['class'] = '$classAttribute lazy-loading';
} else {
imageElement.attributes['class'] = 'lazy-loading';
}
imageElement.attributes['data-src'] = src;
imageElement.attributes.remove('src');
} }
})); }));
} }
@@ -54,10 +54,10 @@ String generateHtml(String content, {
''' : ''} ''' : ''}
${styleCSS ?? ''} ${styleCSS ?? ''}
</style> </style>
${javaScripts ?? ''}
</head> </head>
<body ${direction == TextDirection.rtl ? 'dir="rtl"' : ''} style = "overflow-x: hidden"> <body ${direction == TextDirection.rtl ? 'dir="rtl"' : ''} style = "overflow-x: hidden">
<div class="tmail-content">$content</div> <div class="tmail-content">$content</div>
${javaScripts ?? ''}
</body> </body>
</html> </html>
'''; ''';
@@ -68,6 +68,39 @@ class HtmlUtils {
} }
'''; ''';
static const scriptLazyLoadImage = '''
<script type="text/javascript">
const lazyImages = document.querySelectorAll("img.lazy-loading");
const options = {
root: null, // Use the viewport as the root
rootMargin: "0px",
threshold: 0.1 // Specify the threshold for intersection
};
const handleIntersection = (entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = entry.target;
const src = img.getAttribute("data-src");
// Replace the placeholder with the actual image source
img.src = src;
// Stop observing the image
observer.unobserve(img);
}
});
};
const observer = new IntersectionObserver(handleIntersection, options);
lazyImages.forEach((image) => {
observer.observe(image);
});
</script>
''';
static String customCssStyleHtmlEditor({TextDirection direction = TextDirection.ltr}) { static String customCssStyleHtmlEditor({TextDirection direction = TextDirection.ltr}) {
if (PlatformInfo.isWeb) { if (PlatformInfo.isWeb) {
return ''' return '''
@@ -4,6 +4,7 @@ import 'dart:math' as math;
import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/html_transformer/html_template.dart'; import 'package:core/presentation/utils/html_transformer/html_template.dart';
import 'package:core/presentation/utils/html_transformer/html_utils.dart';
import 'package:core/presentation/views/html_viewer/html_viewer_controller_for_web.dart'; import 'package:core/presentation/views/html_viewer/html_viewer_controller_for_web.dart';
import 'package:core/utils/app_logger.dart'; import 'package:core/utils/app_logger.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@@ -171,7 +172,7 @@ class _HtmlContentViewerOnWebState extends State<HtmlContentViewerOnWeb> {
minHeight: minHeight, minHeight: minHeight,
minWidth: minWidth, minWidth: minWidth,
styleCSS: tooltipLinkCss, styleCSS: tooltipLinkCss,
javaScripts: webViewActionScripts + scriptsDisableZoom, javaScripts: webViewActionScripts + scriptsDisableZoom + HtmlUtils.scriptLazyLoadImage,
direction: widget.direction); direction: widget.direction);
return htmlTemplate; return htmlTemplate;
@@ -65,7 +65,11 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
void initState() { void initState() {
super.initState(); super.initState();
actualHeight = widget.heightContent; actualHeight = widget.heightContent;
_htmlData = generateHtml(widget.contentHtml, direction: widget.direction); _htmlData = generateHtml(
widget.contentHtml,
direction: widget.direction,
javaScripts: HtmlUtils.scriptLazyLoadImage,
);
} }
@override @override
@@ -76,7 +80,8 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
widget.direction != oldWidget.direction) { widget.direction != oldWidget.direction) {
_htmlData = generateHtml( _htmlData = generateHtml(
widget.contentHtml, widget.contentHtml,
direction: widget.direction direction: widget.direction,
javaScripts: HtmlUtils.scriptLazyLoadImage,
); );
} }
} }
@@ -176,8 +181,6 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
actualHeight = minHeight; actualHeight = minHeight;
} }
} }
return Future.value(null);
} }
Future<void> _setActualWidthView() async { Future<void> _setActualWidthView() async {
@@ -210,8 +213,6 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
widget.onWebViewLoaded?.call(isScrollActivated); widget.onWebViewLoaded?.call(isScrollActivated);
} }
} }
return Future.value(null);
} }
void _hideLoadingProgress() { void _hideLoadingProgress() {