From f746c4b51e50ee21bbd29fd500de130f4b17870e Mon Sep 17 00:00:00 2001 From: Bruce Liu Date: Mon, 18 Jan 2021 15:16:28 +0800 Subject: [PATCH] use jaguar to serve resources --- assets/article/article.js | 93 +++++++++---------- ios/Podfile.lock | 12 +-- lib/main.dart | 2 + lib/pages/article_page.dart | 64 +++++-------- lib/pages/settings/services/feedbin_page.dart | 2 + lib/pages/settings/services/fever_page.dart | 2 + lib/utils/global.dart | 6 ++ pubspec.lock | 70 ++++++++++++-- pubspec.yaml | 4 +- 9 files changed, 154 insertions(+), 101 deletions(-) diff --git a/assets/article/article.js b/assets/article/article.js index 9241569..b71bc03 100644 --- a/assets/article/article.js +++ b/assets/article/article.js @@ -1,53 +1,52 @@ -function r(params) { - function get(name) { - if (name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(params)) - return decodeURIComponent(name[1]) - return null +function get(name) { + if (name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(location.search)) + return decodeURIComponent(name[1]) + return null +} +async function getArticle(url) { + let article = get("a") + if (get("m") === "1") { + return (await Mercury.parse(url, {html: article})).content || "" + } else { + return article } - async function getArticle(url) { - let article = get("a") - if (get("m") === "1") { - return (await Mercury.parse(url, {html: article})).content || "" - } else { - return article - } +} +document.documentElement.style.fontSize = get("s") + "px" +let theme = get("t") +if (theme !== null) document.documentElement.classList.add(theme === "1" ? "light" : "dark") +let url = get("u") +getArticle(url).then(article => { + let domParser = new DOMParser() + let dom = domParser.parseFromString(get("h"), "text/html") + dom.getElementsByTagName("article")[0].innerHTML = article + let baseUrl = url.split("/").slice(0, 3).join("/") + for (let s of dom.getElementsByTagName("script")) { + s.parentNode.removeChild(s) } - document.documentElement.style.fontSize = get("s") + "px" - let theme = get("t") - if (theme !== null) document.documentElement.classList.add(theme === "1" ? "light" : "dark") - let url = get("u") - getArticle(url).then(article => { - let domParser = new DOMParser() - let dom = domParser.parseFromString(get("h"), "text/html") - dom.getElementsByTagName("article")[0].innerHTML = article - let baseUrl = url.split("/").slice(0, 3).join("/") - for (let s of dom.getElementsByTagName("script")) { - s.parentNode.removeChild(s) - } - for (let e of dom.querySelectorAll("*[src]")) { - if (e.src && !e.src.startsWith("http")) { - if (e.src.startsWith("/")) { - e.src = baseUrl + e.src - } else if (e.src.startsWith(":")) { - e.src = "http" + e.src - } else { - e.src = baseUrl + "/" + e.src - } + for (let e of dom.querySelectorAll("*[src]")) { + if (e.src && !e.src.startsWith("http")) { + if (e.src.startsWith("/")) { + e.src = baseUrl + e.src + } else if (e.src.startsWith(":")) { + e.src = "http" + e.src + } else { + e.src = baseUrl + "/" + e.src } } - for (let e of dom.querySelectorAll("*[href]")) { - if (e.href && !e.href.startsWith("http")) { - if (e.href.startsWith("/")) { - e.href = baseUrl + e.href - } else if (e.href.startsWith(":")) { - e.href = "http" + e.href - } else { - e.href = baseUrl + "/" + e.href - } + } + for (let e of dom.querySelectorAll("*[href]")) { + if (e.href && !e.href.startsWith("http")) { + if (e.href.startsWith("/")) { + e.href = baseUrl + e.href + } else if (e.href.startsWith(":")) { + e.href = "http" + e.href + } else { + e.href = baseUrl + "/" + e.href } } - let main = document.getElementById("main") - main.innerHTML = dom.body.innerHTML - main.classList.add("show") - }) -} + } + let main = document.getElementById("main") + main.innerHTML = dom.body.innerHTML + main.classList.add("show") +}) + diff --git a/ios/Podfile.lock b/ios/Podfile.lock index f263f8b..ff34946 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,7 +1,5 @@ PODS: - Flutter (1.0.0) - - flutter_inappwebview (0.0.1): - - Flutter - FMDB (2.7.5): - FMDB/standard (= 2.7.5) - FMDB/standard (2.7.5) @@ -18,16 +16,18 @@ PODS: - FMDB (>= 2.7.5) - url_launcher (0.0.1): - Flutter + - webview_flutter (0.0.1): + - Flutter DEPENDENCIES: - Flutter (from `Flutter`) - - flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`) - package_info (from `.symlinks/plugins/package_info/ios`) - path_provider (from `.symlinks/plugins/path_provider/ios`) - share (from `.symlinks/plugins/share/ios`) - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`) - url_launcher (from `.symlinks/plugins/url_launcher/ios`) + - webview_flutter (from `.symlinks/plugins/webview_flutter/ios`) SPEC REPOS: trunk: @@ -36,8 +36,6 @@ SPEC REPOS: EXTERNAL SOURCES: Flutter: :path: Flutter - flutter_inappwebview: - :path: ".symlinks/plugins/flutter_inappwebview/ios" package_info: :path: ".symlinks/plugins/package_info/ios" path_provider: @@ -50,10 +48,11 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/sqflite/ios" url_launcher: :path: ".symlinks/plugins/url_launcher/ios" + webview_flutter: + :path: ".symlinks/plugins/webview_flutter/ios" SPEC CHECKSUMS: Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c - flutter_inappwebview: 69dfbac46157b336ffbec19ca6dfd4638c7bf189 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c @@ -61,6 +60,7 @@ SPEC CHECKSUMS: shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef + webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96 PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c diff --git a/lib/main.dart b/lib/main.dart index fa8bc08..2498720 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -22,6 +22,7 @@ import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; import 'package:path/path.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:webview_flutter/webview_flutter.dart'; import 'generated/l10n.dart'; import 'models/global_model.dart'; @@ -33,6 +34,7 @@ void main() async { SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( statusBarColor: Colors.transparent, )); + WebView.platform = SurfaceAndroidWebView(); } runApp(MyApp()); SystemChannels.lifecycle.setMessageHandler((msg) { diff --git a/lib/pages/article_page.dart b/lib/pages/article_page.dart index f37a667..991841c 100644 --- a/lib/pages/article_page.dart +++ b/lib/pages/article_page.dart @@ -11,7 +11,6 @@ import 'package:fluent_reader_lite/utils/global.dart'; import 'package:fluent_reader_lite/utils/store.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:intl/intl.dart'; import 'package:http/http.dart' as http; import 'package:provider/provider.dart'; @@ -19,6 +18,7 @@ import 'package:tuple/tuple.dart'; import 'package:share/share.dart'; import 'package:fluent_reader_lite/components/cupertino_toolbar.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'package:webview_flutter/webview_flutter.dart'; class ArticlePage extends StatefulWidget { static final GlobalKey state = GlobalKey(); @@ -30,22 +30,13 @@ class ArticlePage extends StatefulWidget { } class ArticlePageState extends State { - InAppWebViewController _controller; + WebViewController _controller; int requestId = 0; bool loaded = false; bool navigated = false; SourceOpenTarget _target; String iid; bool isSourceFeed; - String localParams; - - static final _webViewOptions = InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - useShouldOverrideUrlLoading: true, - debuggingEnabled: true, - transparentBackground: true, - ), - ); void loadNewItem(String id, {bool isSource}) { if (!Global.itemsModel.getItem(id).hasRead) { @@ -60,21 +51,17 @@ class ArticlePageState extends State { }); } - Future _onNewWindow(_, CreateWindowRequest request) async { - await launch(request.url); - return false; - } - - Future _onNavigate(_, ShouldOverrideUrlLoadingRequest request) async { + Future _onNavigate(NavigationRequest request) async { if (navigated && request.isForMainFrame) { await launch(request.url); - return ShouldOverrideUrlLoadingAction.CANCEL; + return NavigationDecision.prevent; + } else { + return NavigationDecision.navigate; } - return ShouldOverrideUrlLoadingAction.ALLOW; } void _loadHtml(RSSItem item, RSSSource source, {loadFull: false}) async { - var localUrl = "assets/article/article.html"; + var localUrl = "http://127.0.0.1:9000/article/article.html"; var currId = requestId; String a; if (loadFull) { @@ -94,23 +81,22 @@ class ArticlePageState extends State { h += '
'; h = Uri.encodeComponent(h); var s = Store.getArticleFontSize(); - localParams = "?a=$a&h=$h&s=$s&u=${item.link}&m=${loadFull ? 1 : 0}"; + localUrl += "?a=$a&h=$h&s=$s&u=${item.link}&m=${loadFull ? 1 : 0}"; if (Platform.isAndroid || Global.globalModel.getBrightness() != null) { var brightness = Global.currentBrightness(context); - localParams += "&t=${brightness.index}"; + localUrl += "&t=${brightness.index}"; } - if (currId == requestId) _controller.loadFile(assetFilePath: localUrl); - + if (currId == requestId) _controller.loadUrl(localUrl); } - void _onPageReady(_, String url) async { - if (url != "about:blank") { - if (localParams != null) { - _controller.evaluateJavascript(source: 'r("$localParams")'); - setState(() { loaded = true; }); - } - navigated = true; + void _onPageReady(_) async { + if (Platform.isAndroid || Global.globalModel.getBrightness() != null) { + await Future.delayed(Duration(milliseconds: 300)); } + setState(() { loaded = true; }); + } + void _onWebpageReady(_) { + if (loaded) navigated = true; } void _setOpenTarget(RSSSource source, {SourceOpenTarget target}) { @@ -134,9 +120,7 @@ class ArticlePageState extends State { break; case SourceOpenTarget.Webpage: case SourceOpenTarget.External: - localParams = null; - _controller.loadUrl(url: item.link); - setState(() { loaded = true; }); + _controller.loadUrl(item.link); break; } } @@ -168,16 +152,16 @@ class ArticlePageState extends State { Center( child: CupertinoActivityIndicator() ), - InAppWebView( + WebView( key: Key("a-$iid-${_target.index}"), - onWebViewCreated: (InAppWebViewController webViewController) { + javascriptMode: JavascriptMode.unrestricted, + onWebViewCreated: (WebViewController webViewController) { _controller = webViewController; _loadOpenTarget(item, source); }, - onLoadStop: _onPageReady, - onCreateWindow: _onNewWindow, - shouldOverrideUrlLoading: _onNavigate, - initialOptions: _webViewOptions, + onPageStarted: _onPageReady, + onPageFinished: _onWebpageReady, + navigationDelegate: _onNavigate, ), ], ), bottom: false,); diff --git a/lib/pages/settings/services/feedbin_page.dart b/lib/pages/settings/services/feedbin_page.dart index 69bcff3..68ce568 100644 --- a/lib/pages/settings/services/feedbin_page.dart +++ b/lib/pages/settings/services/feedbin_page.dart @@ -84,6 +84,7 @@ class _FeedbinPageState extends State { await Global.syncModel.syncWithService(); Global.syncModel.checkHasService(); _validating = false; + DialogHelper().hide(context); if (mounted) Navigator.of(context).pop(); } else { setState(() { _validating = false; }); @@ -122,6 +123,7 @@ class _FeedbinPageState extends State { DialogWidget.progress(style: DialogStyle.cupertino), ); await Global.syncModel.removeService(); + DialogHelper().hide(context); final navigator = Navigator.of(context); while (navigator.canPop()) navigator.pop(); } diff --git a/lib/pages/settings/services/fever_page.dart b/lib/pages/settings/services/fever_page.dart index 612ff7d..4b351ea 100644 --- a/lib/pages/settings/services/fever_page.dart +++ b/lib/pages/settings/services/fever_page.dart @@ -87,6 +87,7 @@ class _FeverPageState extends State { await Global.syncModel.syncWithService(); Global.syncModel.checkHasService(); _validating = false; + DialogHelper().hide(context); if (mounted) Navigator.of(context).pop(); } else { setState(() { _validating = false; }); @@ -125,6 +126,7 @@ class _FeverPageState extends State { DialogWidget.progress(style: DialogStyle.cupertino), ); await Global.syncModel.removeService(); + DialogHelper().hide(context); final navigator = Navigator.of(context); while (navigator.canPop()) navigator.pop(); } diff --git a/lib/utils/global.dart b/lib/utils/global.dart index f7c1c08..33d63d0 100644 --- a/lib/utils/global.dart +++ b/lib/utils/global.dart @@ -10,6 +10,8 @@ import 'package:fluent_reader_lite/models/sync_model.dart'; import 'package:fluent_reader_lite/utils/db.dart'; import 'package:fluent_reader_lite/utils/store.dart'; import 'package:flutter/cupertino.dart'; +import 'package:jaguar/serve/server.dart'; +import 'package:jaguar_flutter_asset/jaguar_flutter_asset.dart'; import 'package:sqflite/sqflite.dart'; abstract class Global { @@ -22,6 +24,7 @@ abstract class Global { static SyncModel syncModel; static ServiceHandler service; static Database db; + static Jaguar server; static final GlobalKey tabletPanel = GlobalKey(); static void init() { @@ -64,6 +67,9 @@ abstract class Global { .millisecondsSinceEpoch, ], ); + server = Jaguar(address: "127.0.0.1",port: 9000); + server.addRoute(serveFlutterAssets()); + await server.serve(); await sourcesModel.init(); await feedsModel.all.init(); if (globalModel.syncOnStart) await syncModel.syncWithService(); diff --git a/pubspec.lock b/pubspec.lock index 559ee8f..32c4e01 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -22,6 +22,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.5.0-nullsafety.3" + auth_header: + dependency: transitive + description: + name: auth_header + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.4" boolean_selector: dependency: transitive description: @@ -132,13 +139,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.0" - flutter_inappwebview: - dependency: "direct main" - description: - name: flutter_inappwebview - url: "https://pub.flutter-io.cn" - source: hosted - version: "4.0.0+4" flutter_localizations: dependency: "direct main" description: flutter @@ -175,6 +175,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "3.1.4" + http_server: + dependency: transitive + description: + name: http_server + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.9.8+3" image: dependency: transitive description: @@ -189,6 +196,34 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.17.0-nullsafety.2" + jaguar: + dependency: "direct main" + description: + name: jaguar + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.46" + jaguar_common: + dependency: transitive + description: + name: jaguar_common + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.4" + jaguar_flutter_asset: + dependency: "direct main" + description: + name: jaguar_flutter_asset + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.0" + jaguar_serializer: + dependency: transitive + description: + name: jaguar_serializer + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.12" js: dependency: transitive description: @@ -196,6 +231,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.6.3-nullsafety.3" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.11.4" matcher: dependency: transitive description: @@ -294,6 +336,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.0.4+3" + path_tree: + dependency: transitive + description: + name: path_tree + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.4" pedantic: dependency: transitive description: @@ -544,6 +593,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.0-nullsafety.5" + webview_flutter: + dependency: "direct main" + description: + name: webview_flutter + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.0-nullsafety.3" win32: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 58086e2..eec385c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,7 +31,9 @@ dependencies: intl: ^0.17.0-nullsafety.2 http: ^0.12.2 html: ^0.14.0+4 - flutter_inappwebview: ^4.0.0+4 + webview_flutter: ^2.0.0-nullsafety.3 + jaguar: ^2.4.46 + jaguar_flutter_asset: ^2.2.0 url_launcher: ^5.7.10 sqflite: ^1.3.2+1 path: ^1.7.0 -- 2.38.5