diff --git a/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart b/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart
index 1ada91dec..a78e8b89c 100644
--- a/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart
+++ b/core/lib/presentation/views/html_viewer/html_content_viewer_widget.dart
@@ -5,11 +5,12 @@ import 'package:core/presentation/constants/constants_ui.dart';
import 'package:core/presentation/views/loading/cupertino_loading_widget.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/html/html_interaction.dart';
+import 'package:core/utils/html/html_template.dart';
import 'package:core/utils/html/html_utils.dart';
import 'package:core/utils/platform_info.dart';
-import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
+import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:url_launcher/url_launcher.dart' as launcher;
import 'package:url_launcher/url_launcher_string.dart';
@@ -30,10 +31,12 @@ class HtmlContentViewer extends StatefulWidget {
final double? contentPadding;
final bool useDefaultFont;
final double? maxHtmlContentHeight;
- final double minHtmlContentHeight;
+ final double htmlContentMinHeight;
final double offsetHtmlContentHeight;
final bool keepAlive;
final bool enableQuoteToggle;
+ final bool disableScrolling;
+ final double? maxViewHeight;
final OnLoadWidthHtmlViewerAction? onLoadWidthHtmlViewer;
final OnMailtoDelegateAction? onMailtoDelegateAction;
@@ -47,13 +50,15 @@ class HtmlContentViewer extends StatefulWidget {
required this.contentHtml,
this.initialWidth,
this.direction,
- this.minHtmlContentHeight = ConstantsUI.htmlContentMinHeight,
+ this.htmlContentMinHeight = ConstantsUI.htmlContentMinHeight,
this.offsetHtmlContentHeight = ConstantsUI.htmlContentOffsetHeight,
this.keepAlive = false,
this.enableQuoteToggle = false,
this.keepWidthWhileLoading = false,
this.contentPadding,
this.useDefaultFont = false,
+ this.disableScrolling = false,
+ this.maxViewHeight,
this.maxHtmlContentHeight,
this.onLoadWidthHtmlViewer,
this.onMailtoDelegateAction,
@@ -72,45 +77,39 @@ class HtmlContentViewState extends State with AutomaticKeepAl
late InAppWebViewController _webViewController;
late double _actualHeight;
late Set> _gestureRecognizers;
- late StringBuffer _customScriptsBuilder;
+ late InAppWebViewSettings _webViewSetting;
final _loadingBarNotifier = ValueNotifier(true);
String? _htmlData;
- final _webViewSetting = InAppWebViewSettings(
- transparentBackground: true,
- verticalScrollBarEnabled: false,
- supportZoom: false,
- );
-
@visibleForTesting
InAppWebViewController get webViewController => _webViewController;
@override
void initState() {
super.initState();
- if (PlatformInfo.isAndroid) {
- _gestureRecognizers = {
- Factory(() => LongPressGestureRecognizer()),
+ _webViewSetting = InAppWebViewSettings(
+ transparentBackground: true,
+ verticalScrollBarEnabled: false,
+ supportZoom: false,
+ disableHorizontalScroll: widget.disableScrolling,
+ disableVerticalScroll: widget.disableScrolling,
+ horizontalScrollBarEnabled: !widget.disableScrolling,
+ );
+
+ _gestureRecognizers = {
+ Factory(
+ () => LongPressGestureRecognizer(
+ duration: PlatformInfo.isAndroid
+ ? null
+ : _longPressGestureDurationIOS,
+ ),
+ ),
+ if (PlatformInfo.isAndroid && !widget.disableScrolling)
Factory(() => ScaleGestureRecognizer()),
- };
- } else {
- _gestureRecognizers = {
- Factory(() => LongPressGestureRecognizer(duration: _longPressGestureDurationIOS)),
- };
- }
- _customScriptsBuilder = StringBuffer();
- _customScriptsBuilder.write(HtmlInteraction.scriptsHandleLazyLoadingBackgroundImage);
- if (widget.enableQuoteToggle) {
- _customScriptsBuilder.write(HtmlUtils.quoteToggleScript);
- }
- if (widget.initialWidth != null) {
- _customScriptsBuilder.write(HtmlInteraction.generateNormalizeImageScript(widget.initialWidth!));
- }
- if (PlatformInfo.isAndroid) {
- _customScriptsBuilder.write(HtmlInteraction.scriptsHandleContentSizeChanged);
- }
+ };
+
_initialData();
}
@@ -125,16 +124,33 @@ class HtmlContentViewState extends State with AutomaticKeepAl
}
void _initialData() {
- _actualHeight = widget.minHtmlContentHeight;
- _htmlData = HtmlUtils.generateHtmlDocument(
- content: widget.enableQuoteToggle
+ _actualHeight = widget.htmlContentMinHeight;
+
+ final processedContent = widget.enableQuoteToggle
? HtmlUtils.addQuoteToggle(widget.contentHtml)
- : widget.contentHtml,
+ : widget.contentHtml;
+
+ final combinedCss = [
+ if (widget.enableQuoteToggle) HtmlUtils.quoteToggleStyle,
+ if (widget.disableScrolling) HtmlTemplate.disableScrollingStyleCSS,
+ ].join();
+
+ final combinedScripts = [
+ HtmlInteraction.scriptsHandleLazyLoadingBackgroundImage,
+ if (widget.enableQuoteToggle) HtmlUtils.quoteToggleScript,
+ if (widget.initialWidth != null)
+ HtmlInteraction.generateNormalizeImageScript(widget.initialWidth!),
+ if (PlatformInfo.isAndroid)
+ HtmlInteraction.scriptsHandleContentSizeChanged,
+ ].join();
+
+ _htmlData = HtmlUtils.generateHtmlDocument(
+ content: processedContent,
direction: widget.direction,
- javaScripts: _customScriptsBuilder.toString(),
+ javaScripts: combinedScripts,
+ styleCSS: combinedCss,
contentPadding: widget.contentPadding,
useDefaultFont: widget.useDefaultFont,
- styleCSS: widget.enableQuoteToggle ? HtmlUtils.quoteToggleStyle : null
);
}
@@ -142,23 +158,20 @@ class HtmlContentViewState extends State with AutomaticKeepAl
Widget build(BuildContext context) {
super.build(context);
final child = Stack(children: [
- if (_htmlData == null)
- const SizedBox.shrink()
- else
- SizedBox(
- height: _actualHeight,
- width: widget.initialWidth,
- child: InAppWebView(
- key: ValueKey(_htmlData),
- initialSettings: _webViewSetting,
- onWebViewCreated: _onWebViewCreated,
- onLoadStop: _onLoadStop,
- onContentSizeChanged: _onContentSizeChanged,
- shouldOverrideUrlLoading: _shouldOverrideUrlLoading,
- gestureRecognizers: _gestureRecognizers,
- onScrollChanged: (controller, x, y) => controller.scrollTo(x: 0, y: 0)
+ if (_htmlData?.trim().isNotEmpty == true)
+ if (widget.maxViewHeight != null)
+ Container(
+ height: _actualHeight,
+ width: widget.initialWidth,
+ constraints: BoxConstraints(maxHeight: widget.maxViewHeight!),
+ child: _buildWebView(),
)
- ),
+ else
+ SizedBox(
+ height: _actualHeight,
+ width: widget.initialWidth,
+ child: _buildWebView(),
+ ),
ValueListenableBuilder(
valueListenable: _loadingBarNotifier,
builder: (context, loading, child) {
@@ -171,23 +184,42 @@ class HtmlContentViewState extends State with AutomaticKeepAl
),
]);
- if (!widget.keepWidthWhileLoading) return child;
- return SizedBox(
- width: widget.initialWidth,
- child: child,
+ if (!widget.keepWidthWhileLoading) {
+ return child;
+ } else {
+ return SizedBox(width: widget.initialWidth, child: child);
+ }
+ }
+
+ Widget _buildWebView() {
+ return InAppWebView(
+ key: ValueKey(_htmlData),
+ initialSettings: _webViewSetting,
+ onWebViewCreated: _onWebViewCreated,
+ onLoadStop: _onLoadStop,
+ onContentSizeChanged: _onContentSizeChanged,
+ shouldOverrideUrlLoading: _shouldOverrideUrlLoading,
+ gestureRecognizers: _gestureRecognizers,
+ onScrollChanged: widget.disableScrolling ? null : _onScrollChanged,
);
}
+ void _onScrollChanged(InAppWebViewController controller, int x, int y) {
+ controller.scrollTo(x: 0, y: 0);
+ }
+
void _onWebViewCreated(InAppWebViewController controller) async {
log('_HtmlContentViewState::_onWebViewCreated:');
_webViewController = controller;
await controller.loadData(data: _htmlData ?? '');
- controller.addJavaScriptHandler(
- handlerName: HtmlInteraction.scrollEventJSChannelName,
- callback: _onHandleScrollEvent
- );
+ if (!widget.disableScrolling) {
+ controller.addJavaScriptHandler(
+ handlerName: HtmlInteraction.scrollEventJSChannelName,
+ callback: _onHandleScrollEvent,
+ );
+ }
if (PlatformInfo.isAndroid) {
controller.addJavaScriptHandler(
@@ -230,12 +262,8 @@ class HtmlContentViewState extends State with AutomaticKeepAl
double currentHeight = maxContentHeight + widget.offsetHtmlContentHeight;
if (PlatformInfo.isIOS && widget.maxHtmlContentHeight != null) {
- final bool isClipped = currentHeight > widget.maxHtmlContentHeight!;
- if (isClipped) {
- widget.onHtmlContentClippedAction?.call(true);
- }
- currentHeight = currentHeight.clamp(
- widget.minHtmlContentHeight,
+ currentHeight = _reStandardizeHeight(
+ currentHeight,
widget.maxHtmlContentHeight!,
);
}
@@ -259,58 +287,74 @@ class HtmlContentViewState extends State with AutomaticKeepAl
log('_HtmlContentViewState::_getActualSizeHtmlViewer(): listSize: $listSize');
- bool isScrollActivated = false;
- Set>? newGestureRecognizers;
-
final double? scrollWidth = listSize[0] is num ? (listSize[0] as num).toDouble() : null;
final double? offsetWidth = listSize[1] is num ? (listSize[1] as num).toDouble() : null;
final double? scrollHeight = listSize[2] is num ? (listSize[2] as num).toDouble() : null;
- if (scrollWidth != null && offsetWidth != null) {
- isScrollActivated = scrollWidth.round() == offsetWidth.round();
- if (!isScrollActivated && PlatformInfo.isIOS) {
- newGestureRecognizers = {
- Factory(() => LongPressGestureRecognizer(duration: _longPressGestureDurationIOS)),
- Factory(() => HorizontalDragGestureRecognizer()),
- };
- }
- }
+ bool isContentFullyVisible = scrollWidth != null &&
+ offsetWidth != null &&
+ scrollWidth.round() == offsetWidth.round();
+
+ final isIOSScrollingEnabled = !isContentFullyVisible && PlatformInfo.isIOS;
+ log('_HtmlContentViewState::_getActualSizeHtmlViewer: isIOSScrollingEnabled = $isIOSScrollingEnabled | isContentFullyVisible = $isContentFullyVisible');
if (scrollHeight != null && scrollHeight > 0) {
double currentHeight = scrollHeight + widget.offsetHtmlContentHeight;
if (PlatformInfo.isIOS && widget.maxHtmlContentHeight != null) {
- final bool isClipped = currentHeight > widget.maxHtmlContentHeight!;
- if (isClipped) {
- widget.onHtmlContentClippedAction?.call(true);
- }
- currentHeight = currentHeight.clamp(
- widget.minHtmlContentHeight,
+ currentHeight = _reStandardizeHeight(
+ currentHeight,
widget.maxHtmlContentHeight!,
);
}
+ log('_HtmlContentViewState::_getActualSizeHtmlViewer: currentHeight = $currentHeight');
- if (_actualHeight != currentHeight || newGestureRecognizers != null) {
- log('_HtmlContentViewState::_getActualSizeHtmlViewer: currentHeight = $currentHeight');
+ if (_actualHeight != currentHeight || isIOSScrollingEnabled) {
setState(() {
_actualHeight = currentHeight;
- if (newGestureRecognizers != null) {
- _gestureRecognizers = newGestureRecognizers;
+ if (isIOSScrollingEnabled && !widget.disableScrolling) {
+ _gestureRecognizers = _iOSGestureRecognizersWithScrolling;
}
});
}
- } else if (newGestureRecognizers != null) {
+ } else if (isIOSScrollingEnabled && !widget.disableScrolling) {
setState(() {
- _gestureRecognizers = newGestureRecognizers!;
+ _gestureRecognizers = _iOSGestureRecognizersWithScrolling;
});
}
- if (!isScrollActivated) {
- await _webViewController.evaluateJavascript(source: HtmlInteraction.runScriptsHandleScrollEvent);
+ if (!isContentFullyVisible && !widget.disableScrolling) {
+ await _webViewController.evaluateJavascript(
+ source: HtmlInteraction.runScriptsHandleScrollEvent,
+ );
+
+ widget.onLoadWidthHtmlViewer?.call(isContentFullyVisible);
}
- widget.onLoadWidthHtmlViewer?.call(isScrollActivated);
}
+ double _reStandardizeHeight(double currentHeight, double maxHtmlContentHeight) {
+ final bool isClipped = currentHeight > maxHtmlContentHeight;
+ if (isClipped) {
+ widget.onHtmlContentClippedAction?.call(true);
+ }
+
+ return currentHeight.clamp(
+ widget.htmlContentMinHeight,
+ maxHtmlContentHeight,
+ );
+ }
+
+ Set> get _iOSGestureRecognizersWithScrolling => {
+ Factory(
+ () => LongPressGestureRecognizer(
+ duration: _longPressGestureDurationIOS,
+ ),
+ ),
+ Factory(
+ () => HorizontalDragGestureRecognizer(),
+ ),
+ };
+
Future _shouldOverrideUrlLoading(
InAppWebViewController controller,
NavigationAction navigationAction
diff --git a/lib/features/identity_creator/presentation/widgets/identity_creator_form_bottom_view.dart b/lib/features/identity_creator/presentation/widgets/identity_creator_form_bottom_view.dart
index 8a2954c5a..6583b9f1e 100644
--- a/lib/features/identity_creator/presentation/widgets/identity_creator_form_bottom_view.dart
+++ b/lib/features/identity_creator/presentation/widgets/identity_creator_form_bottom_view.dart
@@ -1,6 +1,7 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/views/checkbox/custom_icon_labeled_checkbox.dart';
import 'package:core/presentation/views/dialog/confirm_dialog_button.dart';
+import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_controller.dart';
@@ -82,7 +83,11 @@ class IdentityCreatorFormBottomView extends StatelessWidget {
if (isMobile) {
return Padding(
- padding: const EdgeInsetsDirectional.symmetric(horizontal: 17),
+ padding: EdgeInsetsDirectional.only(
+ start: 17,
+ end: 17,
+ bottom: PlatformInfo.isMobile ? 24 : 0,
+ ),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,