import 'dart:async'; import 'dart:convert'; import 'package:flutter/widgets.dart'; import 'package:git_touch/utils/utils.dart'; import 'package:webview_flutter/webview_flutter.dart'; class HtmlView extends StatefulWidget { HtmlView(String text, {String? cssText, List cssLinks = const []}) : html = '${cssLinks.map((link) => '').join('')}$text'; final String html; @override State createState() => _HtmlViewState(); } class _HtmlViewState extends State { late Timer timer; double? height; late WebViewController controller; var loaded = false; updateHeight() async { final value = await controller .runJavascriptReturningResult('document.documentElement.scrollHeight;'); // print(value); if (mounted) { setState(() { height = double.parse(value); }); } } @override void dispose() { timer.cancel(); super.dispose(); } @override Widget build(BuildContext context) { final uri = Uri.dataFromString( widget.html, mimeType: 'text/html', encoding: Encoding.getByName('utf-8'), ); return SizedBox( height: height ?? 1, // must be integer(android). 0 would return the wrong height on page finished. child: WebView( initialUrl: uri.toString(), javascriptMode: JavascriptMode.unrestricted, onWebViewCreated: (c) async { controller = c; timer = Timer.periodic(const Duration(milliseconds: 1000), (t) { updateHeight(); }); }, onPageFinished: (some) async { timer.cancel(); updateHeight(); }, navigationDelegate: (request) { if (loaded) { launchStringUrl(request.url); // TODO: return NavigationDecision.prevent; } else { loaded = true; return NavigationDecision.navigate; } }, ), ); } }