|
|
|
import 'package:flutter/cupertino.dart';
|
|
|
|
import 'package:flutter_html/flutter_html.dart';
|
|
|
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
|
|
import 'package:get/get.dart';
|
|
|
|
import 'package:isekai_wiki/global.dart';
|
|
|
|
import 'package:isekai_wiki/models/settings.dart';
|
|
|
|
import 'package:isekai_wiki/reactive/reactive.dart';
|
|
|
|
import 'package:isekai_wiki/styles.dart';
|
|
|
|
|
|
|
|
class WikiPageParserController extends GetxController {
|
|
|
|
InAppWebViewController? webviewCotroller;
|
|
|
|
|
|
|
|
var contentHtml = "".obs;
|
|
|
|
var safeAreaPadding = const EdgeInsets.all(0).obs;
|
|
|
|
var textZoom = 100.obs;
|
|
|
|
|
|
|
|
var loading = true.obs;
|
|
|
|
|
|
|
|
@override
|
|
|
|
void onInit() {
|
|
|
|
super.onInit();
|
|
|
|
|
|
|
|
ever(contentHtml, (_) {
|
|
|
|
loading.value = true;
|
|
|
|
|
|
|
|
if (contentHtml.value.isNotEmpty) {
|
|
|
|
webviewCotroller?.loadData(
|
|
|
|
data: contentHtml.value,
|
|
|
|
baseUrl: Uri.parse(Global.siteConfig.baseUrl),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
ever(textZoom, (_) {
|
|
|
|
webviewCotroller?.setOptions(
|
|
|
|
options: InAppWebViewGroupOptions(
|
|
|
|
android: AndroidInAppWebViewOptions(textZoom: textZoom.value),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void onWebViewCreated(InAppWebViewController controller) {
|
|
|
|
webviewCotroller = controller;
|
|
|
|
|
|
|
|
webviewCotroller?.loadData(
|
|
|
|
data: contentHtml.value,
|
|
|
|
baseUrl: Uri.parse(Global.siteConfig.baseUrl),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void onPageCommitVisible(InAppWebViewController controller, Uri? uri) {
|
|
|
|
controller.injectCSSCode(source: """
|
|
|
|
body {
|
|
|
|
padding-top: ${safeAreaPadding.value.top}px;
|
|
|
|
padding-bottom: ${safeAreaPadding.value.bottom}px;
|
|
|
|
padding-left: ${safeAreaPadding.value.left}px;
|
|
|
|
padding-right: ${safeAreaPadding.value.right}px;
|
|
|
|
}
|
|
|
|
""");
|
|
|
|
controller.evaluateJavascript(source: """
|
|
|
|
var metaEl = document.createElement("meta");
|
|
|
|
metaEl.name = "viewport";
|
|
|
|
metaEl.content = "width=device-width, initial-scale=1.0, user-scalable=yes, minimum-scale=0.25, maximum-scale=5.0";
|
|
|
|
document.head.appendChild(metaEl);
|
|
|
|
""");
|
|
|
|
|
|
|
|
if (contentHtml.value.isNotEmpty) {
|
|
|
|
Future.delayed(const Duration(milliseconds: 100)).then((value) {
|
|
|
|
loading.value = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class WikiPageParser extends StatefulWidget {
|
|
|
|
final String? contentHtml;
|
|
|
|
final EdgeInsets? padding;
|
|
|
|
|
|
|
|
const WikiPageParser({super.key, this.contentHtml, this.padding});
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<StatefulWidget> createState() {
|
|
|
|
return _WikiParserState();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class _WikiParserState extends ReactiveState<WikiPageParser> {
|
|
|
|
var c = WikiPageParserController();
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
|
|
|
c = Get.put(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void receiveProps() {
|
|
|
|
c.contentHtml.value = widget.contentHtml ?? "";
|
|
|
|
c.safeAreaPadding.value = widget.padding ?? const EdgeInsets.all(0);
|
|
|
|
c.textZoom.value = (MediaQuery.of(Get.context!).textScaleFactor * 100).round();
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget _buildRender() {
|
|
|
|
return ListView(
|
|
|
|
children: <Widget>[
|
|
|
|
Container(
|
|
|
|
color: Styles.panelBackgroundColor,
|
|
|
|
child: SafeArea(
|
|
|
|
top: false,
|
|
|
|
bottom: false,
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
|
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
|
|
|
Html(
|
|
|
|
data: c.contentHtml.value,
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget _buildWebview() {
|
|
|
|
return Obx(
|
|
|
|
() => Stack(
|
|
|
|
children: [
|
|
|
|
Opacity(
|
|
|
|
opacity: c.loading.value ? 0 : 1,
|
|
|
|
child: InAppWebView(
|
|
|
|
onWebViewCreated: c.onWebViewCreated,
|
|
|
|
onPageCommitVisible: c.onPageCommitVisible,
|
|
|
|
initialOptions: InAppWebViewGroupOptions(
|
|
|
|
android: AndroidInAppWebViewOptions(
|
|
|
|
textZoom: c.textZoom.value,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
if (c.loading.value)
|
|
|
|
const Center(
|
|
|
|
child: CupertinoActivityIndicator(radius: 20),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
var sc = Get.find<AppSettingsController>();
|
|
|
|
return Obx(() => sc.betaPageRender.value ? _buildRender() : _buildWebview());
|
|
|
|
}
|
|
|
|
}
|