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 
This commit is contained in:
Vishesh Handa
2020-05-19 19:30:32 +02:00
parent fb48fc648d
commit 9167398309
3 changed files with 55 additions and 10 deletions

@ -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<KatexWidget> {
static final _globalMutex = Mutex();
static var flutterWebViewPlugin = FlutterWebviewPlugin();
String imagePath;
JavascriptChannel jsChannel;
StreamSubscription<WebViewStateChanged> _onStateChanged;
final flutterWebViewPlugin = FlutterWebviewPlugin();
final selectedUrl = 'https://gitjournal.io/test_katex.html';
@override
@ -32,16 +37,45 @@ class _KatexWidgetState extends State<KatexWidget> {
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());
if (mounted) {
setState(() {
print("State has been set");
print("State has been set $tmpFile");
imagePath = tmpFile;
});
}
flutterWebViewPlugin.close();
_onStateChanged.cancel();
_onStateChanged = null;
print("Releasing Katex mutex lock ${widget.input}");
_globalMutex.release();
},
);
_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;
@ -50,7 +84,6 @@ class _KatexWidgetState extends State<KatexWidget> {
}
});
flutterWebViewPlugin.close();
flutterWebViewPlugin.launch(
selectedUrl,
hidden: true,
@ -61,13 +94,17 @@ class _KatexWidgetState extends State<KatexWidget> {
@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));
}
}

@ -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:

@ -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"