From 9167398309e916b7be01d652fef3684fd28951de Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Tue, 19 May 2020 19:30:32 +0200 Subject: [PATCH] KatexWidget: Allow multiple widgets to exist Since there can be only one instance of the WebView, we need to lock in between render calls to the webview. Related to #125 --- lib/widgets/katex_widget.dart | 57 +++++++++++++++++++++++++++++------ pubspec.lock | 7 +++++ pubspec.yaml | 1 + 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/lib/widgets/katex_widget.dart b/lib/widgets/katex_widget.dart index 0ee8d478..3c4cf0c9 100644 --- a/lib/widgets/katex_widget.dart +++ b/lib/widgets/katex_widget.dart @@ -1,9 +1,11 @@ +import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_webview_plugin/flutter_webview_plugin.dart'; import 'package:path/path.dart' as p; +import 'package:mutex/mutex.dart'; class KatexWidget extends StatefulWidget { final String input; @@ -15,10 +17,13 @@ class KatexWidget extends StatefulWidget { } class _KatexWidgetState extends State { + static final _globalMutex = Mutex(); + static var flutterWebViewPlugin = FlutterWebviewPlugin(); + String imagePath; JavascriptChannel jsChannel; + StreamSubscription _onStateChanged; - final flutterWebViewPlugin = FlutterWebviewPlugin(); final selectedUrl = 'https://gitjournal.io/test_katex.html'; @override @@ -32,17 +37,46 @@ class _KatexWidgetState extends State { print(message.message); var uri = UriData.parse(message.message); - var tmpFile = p.join(Directory.systemTemp.path, "katex.png"); + + String tmpFile; + var num = 0; + while (true) { + tmpFile = p.join(Directory.systemTemp.path, "katex_$num.png"); + if (!File(tmpFile).existsSync()) { + break; + } + num += 1; + } File(tmpFile).writeAsBytesSync(uri.contentAsBytes()); - setState(() { - print("State has been set"); - imagePath = tmpFile; - }); + if (mounted) { + setState(() { + print("State has been set $tmpFile"); + imagePath = tmpFile; + }); + } + + flutterWebViewPlugin.close(); + _onStateChanged.cancel(); + _onStateChanged = null; + + print("Releasing Katex mutex lock ${widget.input}"); + _globalMutex.release(); }, ); - flutterWebViewPlugin.onStateChanged.listen((WebViewStateChanged state) { + _initAsync(); + } + + void _initAsync() async { + print("Trying to acquire Katex mutex lock ${widget.input}"); + await _globalMutex.acquire(); + print("Acquired to Katex mutex lock ${widget.input}"); + + flutterWebViewPlugin.close(); + + _onStateChanged = + flutterWebViewPlugin.onStateChanged.listen((WebViewStateChanged state) { if (!mounted) return; if (state.type == WebViewState.finishLoad) { @@ -50,7 +84,6 @@ class _KatexWidgetState extends State { } }); - flutterWebViewPlugin.close(); flutterWebViewPlugin.launch( selectedUrl, hidden: true, @@ -61,13 +94,17 @@ class _KatexWidgetState extends State { @override void dispose() { - flutterWebViewPlugin.dispose(); + // flutterWebViewPlugin.dispose(); + if (_onStateChanged != null) { + _onStateChanged.cancel(); + } super.dispose(); } void _renderKatex() { var katex = widget.input; + print("Trying to render $katex"); var js = """katex.render("$katex", document.body, { throwOnError: false }); @@ -86,7 +123,7 @@ html2canvas(document.body, {backgroundColor: 'rgba(0, 0, 0, 0)', removeContainer return Container(); } - print("Building Network Image"); + print("Building Network Image $imagePath"); return Image.file(File(imagePath)); } } diff --git a/pubspec.lock b/pubspec.lock index 48233d5d..db78ee03 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -509,6 +509,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" + mutex: + dependency: "direct main" + description: + name: mutex + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" node_interop: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1ccce37d..4bf8b681 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,6 +41,7 @@ dependencies: flutter_emoji: ">= 2.0.0" git_url_parse2: ^0.0.1 synchronized: ^2.2.0 + mutex: ^1.0.3 steel_crypt: ^1.7.1+1 font_awesome_flutter: ^8.7.0 sentry: ">=3.0.0 <4.0.0"