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

View File

@ -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,17 +37,46 @@ 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());
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<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));
}
}

View File

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

View File

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