1
0
mirror of https://github.com/GitJournal/GitJournal.git synced 2025-07-13 06:30:51 +08:00

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 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart'; import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:mutex/mutex.dart';
class KatexWidget extends StatefulWidget { class KatexWidget extends StatefulWidget {
final String input; final String input;
@ -15,10 +17,13 @@ class KatexWidget extends StatefulWidget {
} }
class _KatexWidgetState extends State<KatexWidget> { class _KatexWidgetState extends State<KatexWidget> {
static final _globalMutex = Mutex();
static var flutterWebViewPlugin = FlutterWebviewPlugin();
String imagePath; String imagePath;
JavascriptChannel jsChannel; JavascriptChannel jsChannel;
StreamSubscription<WebViewStateChanged> _onStateChanged;
final flutterWebViewPlugin = FlutterWebviewPlugin();
final selectedUrl = 'https://gitjournal.io/test_katex.html'; final selectedUrl = 'https://gitjournal.io/test_katex.html';
@override @override
@ -32,17 +37,46 @@ class _KatexWidgetState extends State<KatexWidget> {
print(message.message); print(message.message);
var uri = UriData.parse(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()); File(tmpFile).writeAsBytesSync(uri.contentAsBytes());
setState(() { if (mounted) {
print("State has been set"); setState(() {
imagePath = tmpFile; 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 (!mounted) return;
if (state.type == WebViewState.finishLoad) { if (state.type == WebViewState.finishLoad) {
@ -50,7 +84,6 @@ class _KatexWidgetState extends State<KatexWidget> {
} }
}); });
flutterWebViewPlugin.close();
flutterWebViewPlugin.launch( flutterWebViewPlugin.launch(
selectedUrl, selectedUrl,
hidden: true, hidden: true,
@ -61,13 +94,17 @@ class _KatexWidgetState extends State<KatexWidget> {
@override @override
void dispose() { void dispose() {
flutterWebViewPlugin.dispose(); // flutterWebViewPlugin.dispose();
if (_onStateChanged != null) {
_onStateChanged.cancel();
}
super.dispose(); super.dispose();
} }
void _renderKatex() { void _renderKatex() {
var katex = widget.input; var katex = widget.input;
print("Trying to render $katex");
var js = """katex.render("$katex", document.body, { var js = """katex.render("$katex", document.body, {
throwOnError: false throwOnError: false
}); });
@ -86,7 +123,7 @@ html2canvas(document.body, {backgroundColor: 'rgba(0, 0, 0, 0)', removeContainer
return Container(); return Container();
} }
print("Building Network Image"); print("Building Network Image $imagePath");
return Image.file(File(imagePath)); return Image.file(File(imagePath));
} }
} }

@ -509,6 +509,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "1.0.2"
mutex:
dependency: "direct main"
description:
name: mutex
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
node_interop: node_interop:
dependency: transitive dependency: transitive
description: description:

@ -41,6 +41,7 @@ dependencies:
flutter_emoji: ">= 2.0.0" flutter_emoji: ">= 2.0.0"
git_url_parse2: ^0.0.1 git_url_parse2: ^0.0.1
synchronized: ^2.2.0 synchronized: ^2.2.0
mutex: ^1.0.3
steel_crypt: ^1.7.1+1 steel_crypt: ^1.7.1+1
font_awesome_flutter: ^8.7.0 font_awesome_flutter: ^8.7.0
sentry: ">=3.0.0 <4.0.0" sentry: ">=3.0.0 <4.0.0"