diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index 4baddaa..d20a8bf 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -1,6 +1,7 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:pixes/foundation/app.dart'; import 'package:pixes/network/network.dart'; +import 'package:pixes/pages/webview_page.dart'; import 'package:pixes/utils/app_links.dart'; import 'package:pixes/utils/translation.dart'; import 'package:url_launcher/url_launcher_string.dart'; @@ -186,7 +187,6 @@ class _LoginPageState extends State { void onContinue() async { var url = await Network().generateWebviewUrl(); - launchUrlString(url); onLink = (uri) { if (uri.scheme == "pixiv") { onFinished(uri.queryParameters["code"]!); @@ -198,6 +198,18 @@ class _LoginPageState extends State { setState(() { waitingForAuth = true; }); + if(App.isMobile && mounted) { + context.to(() => WebviewPage(url, onNavigation: (req) { + if(req.url.startsWith("pixiv://")) { + App.rootNavigatorKey.currentState!.pop(); + onLink?.call(Uri.parse(req.url)); + return false; + } + return true; + },)); + } else { + launchUrlString(url); + } } void onFinished(String code) async { diff --git a/lib/pages/webview_page.dart b/lib/pages/webview_page.dart new file mode 100644 index 0000000..c4684c4 --- /dev/null +++ b/lib/pages/webview_page.dart @@ -0,0 +1,81 @@ +import 'package:fluent_ui/fluent_ui.dart'; +import 'package:pixes/components/md.dart'; +import 'package:url_launcher/url_launcher_string.dart'; +import 'package:webview_flutter/webview_flutter.dart'; + +import '../foundation/app.dart'; + +double get _appBarHeight => App.isDesktop ? 36.0 : 48.0; + +class WebviewPage extends StatefulWidget { + const WebviewPage(this.url, {this.onNavigation, super.key}); + + final String url; + + final bool Function(NavigationRequest req)? onNavigation; + + @override + State createState() => _WebviewPageState(); +} + +class _WebviewPageState extends State { + WebViewController? controller; + + @override + void initState() { + super.initState(); + } + + NavigationDecision handleNavigation(NavigationRequest req) { + if (widget.onNavigation != null) { + return widget.onNavigation!(req) + ? NavigationDecision.navigate + : NavigationDecision.prevent; + } + return NavigationDecision.navigate; + } + + @override + Widget build(BuildContext context) { + controller ??= WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setBackgroundColor(FluentTheme.of(context).brightness == Brightness.light + ? Colors.white + : Colors.black) + ..setNavigationDelegate( + NavigationDelegate( + onProgress: (int progress) { + // Update loading bar. + }, + onPageStarted: (String url) {}, + onPageFinished: (String url) {}, + onWebResourceError: (WebResourceError error) {}, + onNavigationRequest: handleNavigation, + ), + ) + ..loadRequest(Uri.parse(widget.url)); + return Column( + children: [ + SizedBox( + height: _appBarHeight, + child: Row( + children: [ + const Text("Webview"), + const Spacer(), + IconButton( + icon: const Icon(MdIcons.open_in_new, size: 20,), + onPressed: () { + launchUrlString(widget.url); + context.pop(); + }, + ), + ], + ).paddingHorizontal(16), + ).paddingTop(MediaQuery.of(context).padding.top), + Expanded( + child: WebViewWidget(controller: controller!,), + ), + ], + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 787047a..ce46f81 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -651,6 +651,38 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.1" + webview_flutter: + dependency: "direct main" + description: + name: webview_flutter + sha256: "25e1b6e839e8cbfbd708abc6f85ed09d1727e24e08e08c6b8590d7c65c9a8932" + url: "https://pub.dev" + source: hosted + version: "4.7.0" + webview_flutter_android: + dependency: transitive + description: + name: webview_flutter_android + sha256: dad3313c9ead95517bb1cae5e1c9d20ba83729d5a59e5e83c0a2d66203f27f91 + url: "https://pub.dev" + source: hosted + version: "3.16.1" + webview_flutter_platform_interface: + dependency: transitive + description: + name: webview_flutter_platform_interface + sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d + url: "https://pub.dev" + source: hosted + version: "2.10.0" + webview_flutter_wkwebview: + dependency: transitive + description: + name: webview_flutter_wkwebview + sha256: "7affdf9d680c015b11587181171d3cad8093e449db1f7d9f0f08f4f33d24f9a0" + url: "https://pub.dev" + source: hosted + version: "3.13.1" win32: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 2ab658a..ddef299 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -55,6 +55,7 @@ dependencies: file_selector: ^1.0.1 flutter_file_dialog: 3.0.1 archive: ^3.5.1 + webview_flutter: ^4.7.0 dev_dependencies: flutter_test: sdk: flutter