mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-07-09 19:54:17 +08:00
Add a PoC for rendering equations with KaTex
It kind of works. The main problem is that the webview shows itself and doesn't disappear after taking a screenshot. Also, I'm having to use an old form of the community flutter webview plugin as the official "community" plugin, doesn't support screenshots. Overall, not bad. It'll probably just be easier to fork the webview completely and fix the issues I'm encountering. on iOS; Trying to take a screenshot resulted in a crash.
This commit is contained in:
271
lib/main_webview.dart
Normal file
271
lib/main_webview.dart
Normal file
@ -0,0 +1,271 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
|
||||
|
||||
const kAndroidUserAgent =
|
||||
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Mobile Safari/537.36';
|
||||
|
||||
String selectedUrl = 'https://gitjournal.io/test_katex.html';
|
||||
|
||||
void main() {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
runApp(MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
final flutterWebViewPlugin = FlutterWebviewPlugin();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Flutter WebView Demo',
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
),
|
||||
routes: {
|
||||
'/': (_) => const MyHomePage(title: 'Flutter WebView Demo'),
|
||||
'/widget': (_) {
|
||||
return WebviewScaffold(
|
||||
url: selectedUrl,
|
||||
appBar: AppBar(
|
||||
title: const Text('Widget WebView'),
|
||||
),
|
||||
withZoom: true,
|
||||
withLocalStorage: true,
|
||||
hidden: true,
|
||||
initialChild: Container(
|
||||
color: Colors.redAccent,
|
||||
child: const Center(
|
||||
child: Text('Waiting.....'),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: BottomAppBar(
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
IconButton(
|
||||
icon: const Icon(Icons.arrow_back_ios),
|
||||
onPressed: () {
|
||||
flutterWebViewPlugin.goBack();
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.arrow_forward_ios),
|
||||
onPressed: () {
|
||||
flutterWebViewPlugin.goForward();
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.autorenew),
|
||||
onPressed: () {
|
||||
flutterWebViewPlugin.reload();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
const MyHomePage({Key key, this.title}) : super(key: key);
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
_MyHomePageState createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
// Instance of WebView plugin
|
||||
final flutterWebViewPlugin = FlutterWebviewPlugin();
|
||||
|
||||
// On destroy stream
|
||||
StreamSubscription _onDestroy;
|
||||
|
||||
// On urlChanged stream
|
||||
StreamSubscription<String> _onUrlChanged;
|
||||
|
||||
// On urlChanged stream
|
||||
StreamSubscription<WebViewStateChanged> _onStateChanged;
|
||||
|
||||
StreamSubscription<WebViewHttpError> _onHttpError;
|
||||
|
||||
StreamSubscription<double> _onProgressChanged;
|
||||
|
||||
StreamSubscription<double> _onScrollYChanged;
|
||||
|
||||
StreamSubscription<double> _onScrollXChanged;
|
||||
|
||||
final _urlCtrl = TextEditingController(text: selectedUrl);
|
||||
|
||||
final _codeCtrl = TextEditingController(text: 'window.navigator.userAgent');
|
||||
|
||||
final _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
final _history = [];
|
||||
|
||||
Uint8List imageData = Uint8List(0);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
flutterWebViewPlugin.close();
|
||||
|
||||
_urlCtrl.addListener(() {
|
||||
selectedUrl = _urlCtrl.text;
|
||||
});
|
||||
|
||||
// Add a listener to on destroy WebView, so you can make came actions.
|
||||
_onDestroy = flutterWebViewPlugin.onDestroy.listen((_) {
|
||||
if (mounted) {
|
||||
// Actions like show a info toast.
|
||||
_scaffoldKey.currentState.showSnackBar(
|
||||
const SnackBar(content: const Text('Webview Destroyed')));
|
||||
}
|
||||
});
|
||||
|
||||
// Add a listener to on url changed
|
||||
_onUrlChanged = flutterWebViewPlugin.onUrlChanged.listen((String url) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_history.add('onUrlChanged: $url');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
_onScrollYChanged =
|
||||
flutterWebViewPlugin.onScrollYChanged.listen((double y) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_history.add('Scroll in Y Direction: $y');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
_onScrollXChanged =
|
||||
flutterWebViewPlugin.onScrollXChanged.listen((double x) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_history.add('Scroll in X Direction: $x');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
_onStateChanged =
|
||||
flutterWebViewPlugin.onStateChanged.listen((WebViewStateChanged state) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_history.add('onStateChanged: ${state.type} ${state.url}');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
_onHttpError =
|
||||
flutterWebViewPlugin.onHttpError.listen((WebViewHttpError error) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_history.add('onHttpError: ${error.code} ${error.url}');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// Every listener should be canceled, the same should be done with this stream.
|
||||
_onDestroy.cancel();
|
||||
_onUrlChanged.cancel();
|
||||
_onStateChanged.cancel();
|
||||
_onHttpError.cancel();
|
||||
_onProgressChanged.cancel();
|
||||
_onScrollXChanged.cancel();
|
||||
_onScrollYChanged.cancel();
|
||||
|
||||
flutterWebViewPlugin.dispose();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: AppBar(
|
||||
title: const Text('Plugin example app'),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (imageData.isNotEmpty) Image.memory(imageData),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: TextField(controller: _urlCtrl),
|
||||
),
|
||||
RaisedButton(
|
||||
onPressed: () {
|
||||
flutterWebViewPlugin.launch(selectedUrl, hidden: true);
|
||||
},
|
||||
child: const Text('Open "hidden" Webview'),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: TextField(controller: _codeCtrl),
|
||||
),
|
||||
RaisedButton(
|
||||
onPressed: () {
|
||||
var js =
|
||||
"""katex.render("\\\\pm\\\\sqrt{a^2 + b^2}", document.body, {
|
||||
throwOnError: false
|
||||
});""";
|
||||
final future = flutterWebViewPlugin.evalJavascript(js);
|
||||
future.then((String result) async {
|
||||
print("Eval done $result");
|
||||
setState(() {
|
||||
_history.add('eval: $result');
|
||||
});
|
||||
|
||||
var _imageData = await flutterWebViewPlugin.takeScreenshot();
|
||||
print("Got $_imageData");
|
||||
setState(() {
|
||||
imageData = _imageData;
|
||||
});
|
||||
//flutterWebViewPlugin.close();
|
||||
});
|
||||
},
|
||||
child: const Text('Eval javascript katex'),
|
||||
),
|
||||
RaisedButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_history.clear();
|
||||
});
|
||||
flutterWebViewPlugin.close();
|
||||
},
|
||||
child: const Text('Close'),
|
||||
),
|
||||
RaisedButton(
|
||||
onPressed: () {
|
||||
flutterWebViewPlugin.getCookies().then((m) {
|
||||
setState(() {
|
||||
_history.add('cookies: $m');
|
||||
});
|
||||
});
|
||||
},
|
||||
child: const Text('Cookies'),
|
||||
),
|
||||
Text(_history.join('\n'))
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -282,6 +282,15 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_webview_plugin:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: HEAD
|
||||
resolved-ref: "045bd6357ce81162d05e367133a95a53ad291451"
|
||||
url: "https://github.com/breez/flutter_webview_plugin.git"
|
||||
source: git
|
||||
version: "0.3.0+2"
|
||||
font_awesome_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -49,6 +49,8 @@ dependencies:
|
||||
ssh_key:
|
||||
git: https://github.com/GitJournal/ssh_key.git
|
||||
isolate: ^2.0.3
|
||||
flutter_webview_plugin:
|
||||
git: https://github.com/breez/flutter_webview_plugin.git
|
||||
|
||||
dev_dependencies:
|
||||
flutter_launcher_icons: "^0.7.2"
|
||||
|
Reference in New Issue
Block a user