diff --git a/ios/Podfile.lock b/ios/Podfile.lock index df400e1e..ba442dd1 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -13,8 +13,9 @@ PODS: - FMDB/standard (2.7.5) - package_info (0.0.1): - Flutter - - path_provider_ios (0.0.1): + - path_provider_foundation (0.0.1): - Flutter + - FlutterMacOS - "permission_handler (5.1.0+2)": - Flutter - Reachability (3.2) @@ -22,7 +23,7 @@ PODS: - Flutter - shared_preferences_ios (0.0.1): - Flutter - - sqflite (0.0.2): + - sqflite (0.0.3): - Flutter - FMDB (>= 2.7.5) - Toast (4.0.0) @@ -37,7 +38,7 @@ DEPENDENCIES: - Flutter (from `Flutter`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - package_info (from `.symlinks/plugins/package_info/ios`) - - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - permission_handler (from `.symlinks/plugins/permission_handler/ios`) - share (from `.symlinks/plugins/share/ios`) - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`) @@ -62,8 +63,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/fluttertoast/ios" package_info: :path: ".symlinks/plugins/package_info/ios" - path_provider_ios: - :path: ".symlinks/plugins/path_provider_ios/ios" + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/darwin" permission_handler: :path: ".symlinks/plugins/permission_handler/ios" share: @@ -84,15 +85,15 @@ SPEC CHECKSUMS: fluttertoast: 16fbe6039d06a763f3533670197d01fc73459037 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 - path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 + path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 share: 0b2c3e82132f5888bccca3351c504d0003b3b410 shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad - sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 + sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de - webview_flutter_wkwebview: b7e70ef1ddded7e69c796c7390ee74180182971f + webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index d515fbef..feb3548f 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -485,7 +485,7 @@ "${BUILT_PRODUCTS_DIR}/device_info_plus/device_info_plus.framework", "${BUILT_PRODUCTS_DIR}/fluttertoast/fluttertoast.framework", "${BUILT_PRODUCTS_DIR}/package_info/package_info.framework", - "${BUILT_PRODUCTS_DIR}/path_provider_ios/path_provider_ios.framework", + "${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework", "${BUILT_PRODUCTS_DIR}/share/share.framework", "${BUILT_PRODUCTS_DIR}/shared_preferences_ios/shared_preferences_ios.framework", "${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework", @@ -501,7 +501,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fluttertoast.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_ios.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/share.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_ios.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework", diff --git a/lib/page/code_detail_page_web.dart b/lib/page/code_detail_page_web.dart index 0ef2d6b8..f61ac1b1 100644 --- a/lib/page/code_detail_page_web.dart +++ b/lib/page/code_detail_page_web.dart @@ -1,5 +1,4 @@ import 'dart:convert'; -import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; @@ -47,29 +46,29 @@ class CodeDetailPageWeb extends StatefulWidget { class _CodeDetailPageState extends State { bool isLand = false; + late final WebViewController controller; + @override void initState() { + controller = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted); + super.initState(); - if (Platform.isAndroid) { - WebView.platform = SurfaceAndroidWebView(); - } } - Future _getData() async { + Future _getData() async { if (widget.data != null) { - return widget.data; + return Uri.dataFromString(widget.data!); } var res = await ReposDao.getReposFileDirDao( widget.userName, widget.reposName, path: widget.path, branch: widget.branch, text: true, isHtml: true); if (res != null && res.result) { String data2 = HtmlUtils.resolveHtmlFile(res, "java"); - String url = new Uri.dataFromString(data2, - mimeType: 'text/html', encoding: Encoding.getByName("utf-8")) - .toString(); - return url; + return new Uri.dataFromString(data2, + mimeType: 'text/html', encoding: Encoding.getByName("utf-8")); } - return ""; + return null; } @override @@ -86,11 +85,12 @@ class _CodeDetailPageState extends State { appBar: new AppBar( title: GSYTitleBar(widget.title), ), - body: FutureBuilder( - initialData: widget.data, + body: FutureBuilder( + initialData: + widget.data != null ? Uri.dataFromString(widget.data!) : null, future: _getData(), builder: (context, result) { - if (result.data == null || result.data!.isEmpty) { + if (result.data == null) { return new Center( child: new Container( width: 200.0, @@ -111,9 +111,9 @@ class _CodeDetailPageState extends State { ), ); } - return WebView( - initialUrl: result.data, - javascriptMode: JavascriptMode.unrestricted, + controller.loadRequest(result.data!); + return WebViewWidget( + controller: controller, ); }, ), diff --git a/lib/page/gsy_webview.dart b/lib/page/gsy_webview.dart index c0f6295f..2a7a72b4 100644 --- a/lib/page/gsy_webview.dart +++ b/lib/page/gsy_webview.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:flutter/material.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:gsy_github_app_flutter/common/localization/default_localizations.dart'; @@ -45,12 +43,33 @@ class _GSYWebViewState extends State { bool isLoading = true; + late final WebViewController controller; + @override void initState() { + controller = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setNavigationDelegate( + NavigationDelegate( + onProgress: (int progress) { + // Update loading bar. + }, + onPageStarted: (String url) {}, + onPageFinished: (String url) { + setState(() { + isLoading = false; + }); + }, + onWebResourceError: (WebResourceError error) {}, + ), + ) + ..addJavaScriptChannel("name", onMessageReceived: (message) { + print(message.message); + FocusScope.of(context).requestFocus(focusNode); + }) + ..loadRequest(Uri.parse(widget.url)); + super.initState(); - if (Platform.isAndroid) { - WebView.platform = SurfaceAndroidWebView(); - } } @override @@ -64,23 +83,9 @@ class _GSYWebViewState extends State { TextField( focusNode: focusNode, ), - WebView( - initialUrl: widget.url, - javascriptMode: JavascriptMode.unrestricted, - onPageFinished: (_) { - setState(() { - isLoading = false; - }); - }, - javascriptChannels: Set.from([ - JavascriptChannel( - name: 'Print', - onMessageReceived: (JavascriptMessage message) { - ///print("FFFFFF"); - print(message.message); - FocusScope.of(context).requestFocus(focusNode); - }) - ])), + WebViewWidget( + controller: controller, + ), if (isLoading) new Center( child: new Container( diff --git a/lib/page/login/login_webview.dart b/lib/page/login/login_webview.dart index a1f8df0d..75a09125 100644 --- a/lib/page/login/login_webview.dart +++ b/lib/page/login/login_webview.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:flutter/material.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:gsy_github_app_flutter/common/localization/default_localizations.dart'; @@ -7,6 +5,11 @@ import 'package:gsy_github_app_flutter/common/style/gsy_style.dart'; import 'package:gsy_github_app_flutter/widget/gsy_common_option_widget.dart'; import 'package:webview_flutter/webview_flutter.dart'; +// Import for Android features. +import 'package:webview_flutter_android/webview_flutter_android.dart'; + +// Import for iOS features. +import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart'; class LoginWebView extends StatefulWidget { final String url; @@ -19,13 +22,58 @@ class LoginWebView extends StatefulWidget { } class _LoginWebViewState extends State { + late final WebViewController controller; + + late final PlatformWebViewControllerCreationParams params; @override void initState() { - super.initState(); - if(Platform.isAndroid) { - WebView.platform = SurfaceAndroidWebView(); + if (WebViewPlatform.instance is WebKitWebViewPlatform) { + params = WebKitWebViewControllerCreationParams( + allowsInlineMediaPlayback: true, + mediaTypesRequiringUserAction: const {}, + ); + } else { + params = const PlatformWebViewControllerCreationParams(); + } + + controller = WebViewController.fromPlatformCreationParams(params); + if (controller.platform is AndroidWebViewController) { + //AndroidWebViewController.enableDebugging(true); + (controller.platform as AndroidWebViewController) + .setMediaPlaybackRequiresUserGesture(true); } + controller + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setBackgroundColor(const Color(0x00000000)) + ..setNavigationDelegate( + NavigationDelegate( + onProgress: (int progress) { + // Update loading bar. + }, + onPageStarted: (String url) {}, + onPageFinished: (String url) { + setState(() { + isLoading = false; + }); + }, + onWebResourceError: (WebResourceError error) {}, + onNavigationRequest: (NavigationRequest request) { + if (request.url.startsWith("gsygithubapp://authed")) { + var code = Uri.parse(request.url).queryParameters["code"]; + print("code ${code}"); + Navigator.of(context).pop(code); + return NavigationDecision.prevent; + } + return NavigationDecision.navigate; + }, + ), + ) + ..loadRequest(Uri.parse( + widget.url, + )); + + super.initState(); } _renderTitle() { @@ -35,12 +83,12 @@ class _LoginWebViewState extends State { return new Row(children: [ new Expanded( child: new Container( - child: new Text( - widget.title, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - )), + child: new Text( + widget.title, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + )), GSYCommonOptionWidget(url: widget.url), ]); } @@ -60,24 +108,9 @@ class _LoginWebViewState extends State { TextField( focusNode: focusNode, ), - WebView( - initialUrl: widget.url, - javascriptMode: JavascriptMode.unrestricted, - initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy.always_allow, - navigationDelegate: (NavigationRequest navigation) { - if (navigation.url.startsWith("gsygithubapp://authed")) { - var code = Uri.parse(navigation.url).queryParameters["code"]; - print("code ${code}"); - Navigator.of(context).pop(code); - return NavigationDecision.prevent; - } - return NavigationDecision.navigate; - }, - onPageFinished: (_) { - setState(() { - isLoading = false; - }); - }), + WebViewWidget( + controller: controller, + ), if (isLoading) new Center( child: new Container( @@ -102,4 +135,4 @@ class _LoginWebViewState extends State { ), ); } -} \ No newline at end of file +} diff --git a/lib/page/repos/repository_detail_issue_list_page.dart b/lib/page/repos/repository_detail_issue_list_page.dart index 30c6e9d2..0da888cc 100644 --- a/lib/page/repos/repository_detail_issue_list_page.dart +++ b/lib/page/repos/repository_detail_issue_list_page.dart @@ -57,7 +57,7 @@ class RepositoryDetailIssuePageState extends State @override showRefreshLoading() { new Future.delayed(const Duration(seconds: 0), () { - refreshIKey.currentState!.show().then((e) {}); + refreshIKey.currentState?.show().then((e) {}); return true; }); } diff --git a/lib/redux/login_redux.dart b/lib/redux/login_redux.dart index 48e36f1b..6f045e01 100644 --- a/lib/redux/login_redux.dart +++ b/lib/redux/login_redux.dart @@ -63,7 +63,7 @@ class LoginMiddleware implements MiddlewareClass { void call(Store store, dynamic action, NextDispatcher next) { if (action is LogoutAction) { UserDao.clearAll(store); - CookieManager().clearCookies(); + WebViewCookieManager().clearCookies(); SqlManager.close(); NavigatorUtils.goLogin(action.context); } diff --git a/pubspec.lock b/pubspec.lock index d6152839..81dc34e7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -661,58 +661,50 @@ packages: dependency: "direct main" description: name: path_provider - sha256: "3f6e0d697dc557ed6589107c8c13eda5ad488285917788379bbf392e3e30ea37" + sha256: "909b84830485dbcd0308edf6f7368bc8fd76afa26a270420f34cabea2a6467a0" url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.10" + version: "2.1.0" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: dfaa152e93c3a6fec632482928c770b2156dfb873582e99fbd6ac3b3de651d4c + sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1" url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.14" - path_provider_ios: + version: "2.2.0" + path_provider_foundation: dependency: transitive description: - name: path_provider_ios - sha256: "060ca9249d85bda6ee4ea2ecb3f4698a32f73183e0dee4f469bee8e146eadc1f" + name: path_provider_foundation + sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.9" + version: "2.3.1" path_provider_linux: dependency: transitive description: name: path_provider_linux - sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.1.7" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - sha256: "2a97e7fbb7ae9dcd0dfc1220a78e9ec3e71da691912e617e8715ff2a13086ae8" + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.6" + version: "2.2.1" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - sha256: "3dc0d51b07f85fec3746d9f4e8d31c73bb173cafa2e763f03f8df2e8d1878882" + sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.3" + version: "2.1.1" path_provider_windows: dependency: transitive description: name: path_provider_windows - sha256: "1cc550ec9881c47cb836f37e4db8f94405bd4e33b63efdd20cb9c7c68be6034b" + sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.2" + version: "2.2.1" permission_handler: dependency: "direct main" description: @@ -962,18 +954,18 @@ packages: dependency: "direct main" description: name: sqflite - sha256: "5e2704b28b59e66d0d3c63ccc27704263926f81d5b62d330652955b7d80a38fb" + sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a" url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.1" + version: "2.3.0" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: b504fc5b4576a05586a0bb99d9bcc0d37a78d9d5ed68b96c361d5d3a8e538275 + sha256: "1b92f368f44b0dee2425bb861cfa17b6f6cf3961f762ff6f941d20b33355660a" url: "https://pub.flutter-io.cn" source: hosted - version: "2.2.1+1" + version: "2.5.0" stack_trace: dependency: transitive description: @@ -1162,34 +1154,34 @@ packages: dependency: "direct main" description: name: webview_flutter - sha256: "9563cb6e54c06980586b80946e6d8b35287d18efc7b55c5bc2ca448688ec65b5" + sha256: "04a0782fb058b7c71f2048935583488f4d32e9147ca403abc4e58f1de9964629" url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.0" + version: "4.2.3" webview_flutter_android: dependency: transitive description: name: webview_flutter_android - sha256: "3f7a54076b66f5bb14e5559404349cda479b036b7b8b3f85e8cd90290fc214b8" + sha256: "9427774649fd3c8b7ff53523051395d13aed2ca355822b822e6493d79f5fc05a" url: "https://pub.flutter-io.cn" source: hosted - version: "2.8.7" + version: "3.10.0" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface - sha256: "6144d750f56ae63fdaad10ff09e0f762142beabde4fefdc2d32564f75572d905" + sha256: "6d9213c65f1060116757a7c473247c60f3f7f332cac33dc417c9e362a9a13e4f" url: "https://pub.flutter-io.cn" source: hosted - version: "1.8.1" + version: "2.6.0" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: c72110d03ad5aa61dfc1408ae50b946bf01e0e0b992bbf08f119af8dfc033334 + sha256: ed749f94ac9e814d04a258a9255cf69cfa4cc6006ff59542aea7fb4590144972 url: "https://pub.flutter-io.cn" source: hosted - version: "2.7.4" + version: "3.7.3" win32: dependency: transitive description: @@ -1224,4 +1216,4 @@ packages: version: "3.1.0" sdks: dart: ">=3.1.0-185.0.dev <4.0.0" - flutter: ">=3.0.0" + flutter: ">=3.7.0" diff --git a/pubspec.yaml b/pubspec.yaml index 1c9d5616..f66283e8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,14 +30,14 @@ dependencies: fluttertoast: ^8.0.8 share: ^2.0.4 flutter_spinkit: ^5.1.0 - sqflite: 2.0.1 + sqflite: 2.3.0 pub_semver: 2.1.4 flutter_svg: 1.0.0 flutter_slidable: ^0.6.0-nullsafety.0 dio: 5.3.1 #fconsole: 2.2.1 - path_provider: 2.0.10 - webview_flutter: 3.0.0 + path_provider: 2.1.0 + webview_flutter: 4.2.3 #bezier: ^1.1.5 flare_flutter: git: