diff --git a/lib/apps/flavored/util/router.f.dart b/lib/apps/flavored/util/router.f.dart new file mode 100644 index 0000000..1419fe7 --- /dev/null +++ b/lib/apps/flavored/util/router.f.dart @@ -0,0 +1,15 @@ +import 'package:flutter/cupertino.dart'; +import 'package:humhub/apps/flavored/web_view.f.dart'; + +final GlobalKey navigatorKeyF = GlobalKey(); + +NavigatorState? get navigator => navigatorKeyF.currentState; + +class RouterF { + static String? initRoute = WebViewF.path; + static dynamic initParams; + + static var routes = { + WebViewF.path: (context) => const WebViewF(), + }; +} diff --git a/lib/apps/flavored/web_view.f.dart b/lib/apps/flavored/web_view.f.dart index 6f0af5b..7e2c1d9 100644 --- a/lib/apps/flavored/web_view.f.dart +++ b/lib/apps/flavored/web_view.f.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_app_badger/flutter_app_badger.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -13,15 +14,16 @@ import 'package:humhub/util/extensions.dart'; import 'package:humhub/util/loading_provider.dart'; import 'package:humhub/util/notifications/channel.dart'; import 'package:humhub/util/notifications/plugin.dart'; -import 'package:humhub/util/providers.dart'; import 'package:humhub/util/push/provider.dart'; import 'package:humhub/util/show_dialog.dart'; import 'package:humhub/util/web_view_global_controller.dart'; import 'package:loggy/loggy.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class WebViewF extends ConsumerStatefulWidget { + static const String path = '/web_view_f'; const WebViewF({super.key}); @override @@ -48,7 +50,7 @@ class FlavoredWebViewState extends ConsumerState { Widget build(BuildContext context) { // ignore: deprecated_member_use return WillPopScope( - onWillPop: () => WebViewGlobalController.value!.exitApp(context, ref), + onWillPop: () => exitApp(context, ref), child: Scaffold( backgroundColor: HexColor(instance.manifest.themeColor), body: SafeArea( @@ -58,8 +60,8 @@ class FlavoredWebViewState extends ConsumerState { initialOptions: _options, pullToRefreshController: _pullToRefreshController, shouldOverrideUrlLoading: _shouldOverrideUrlLoading, - onWebViewCreated: _onWebViewCreated, shouldInterceptFetchRequest: _shouldInterceptFetchRequest, + onWebViewCreated: _onWebViewCreated, onCreateWindow: _onCreateWindow, onLoadStop: _onLoadStop, onLoadStart: _onLoadStart, @@ -79,17 +81,17 @@ class FlavoredWebViewState extends ConsumerState { } InAppWebViewGroupOptions get _options => InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - useShouldOverrideUrlLoading: true, - useShouldInterceptFetchRequest: true, - javaScriptEnabled: true, - supportZoom: false, - javaScriptCanOpenWindowsAutomatically: true, - ), - android: AndroidInAppWebViewOptions( - supportMultipleWindows: true, - ), - ); + crossPlatform: InAppWebViewOptions( + useShouldOverrideUrlLoading: true, + useShouldInterceptFetchRequest: true, + javaScriptEnabled: true, + supportZoom: false, + javaScriptCanOpenWindowsAutomatically: true, + ), + android: AndroidInAppWebViewOptions( + supportMultipleWindows: true, + ), + ); PullToRefreshController get _pullToRefreshController => PullToRefreshController( options: PullToRefreshOptions( @@ -99,8 +101,8 @@ class FlavoredWebViewState extends ConsumerState { Uri? url = await WebViewGlobalController.value!.getUrl(); if (url != null) { WebViewGlobalController.value!.loadUrl( - urlRequest: URLRequest( - url: await WebViewGlobalController.value!.getUrl(), headers: ref.read(humHubProvider).customHeaders), + urlRequest: + URLRequest(url: await WebViewGlobalController.value!.getUrl(), headers: instance.customHeaders), ); } else { WebViewGlobalController.value!.reload(); @@ -170,7 +172,7 @@ class FlavoredWebViewState extends ConsumerState { .evaluateJavascript(source: "document.querySelector('#login-rememberme').checked=true"); WebViewGlobalController.value!.evaluateJavascript( source: - "document.querySelector('#account-login-form > div.form-group.field-login-rememberme').style.display='none';"); + "document.querySelector('#account-login-form > div.form-group.field-login-rememberme').style.display='none';"); } _setAjaxHeadersJQuery(controller); await _pullToRefreshController.endRefreshing(); @@ -178,7 +180,7 @@ class FlavoredWebViewState extends ConsumerState { } Future _onLoadStart(InAppWebViewController controller, Uri? url) async { - await _setAjaxHeadersJQuery(controller); + _setAjaxHeadersJQuery(controller); LoadingProvider.of(ref).dismissAll(); } @@ -200,7 +202,8 @@ class FlavoredWebViewState extends ConsumerState { Future _setAjaxHeadersJQuery(InAppWebViewController controller) async { String jsCode = "\$.ajaxSetup({headers: ${jsonEncode(instance.customHeaders).toString()}});"; - await controller.evaluateJavascript(source: jsCode); + dynamic jsResponse = await controller.evaluateJavascript(source: jsCode); + logInfo(jsResponse != null ? jsResponse.toString() : "Script returned null value"); } Future _handleJSMessage(ChannelMessage message, HeadlessInAppWebView headlessWebView) async { @@ -235,6 +238,36 @@ class FlavoredWebViewState extends ConsumerState { } } + Future exitApp(context, ref) async { + bool canGoBack = await WebViewGlobalController.value!.canGoBack(); + if (canGoBack) { + WebViewGlobalController.value!.goBack(); + return Future.value(false); + } else { + final exitConfirmed = await showDialog( + context: context, + builder: (context) => AlertDialog( + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))), + title: Text(AppLocalizations.of(context)!.web_view_exit_popup_title), + content: Text(AppLocalizations.of(context)!.web_view_exit_popup_content), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: Text(AppLocalizations.of(context)!.no), + ), + TextButton( + onPressed: () { + SystemNavigator.pop(); + }, + child: Text(AppLocalizations.of(context)!.yes), + ), + ], + ), + ); + return exitConfirmed ?? false; + } + } + @override void dispose() { super.dispose(); diff --git a/lib/apps/flavored_app.dart b/lib/apps/flavored_app.dart index 1c67a7e..3b4ebd7 100644 --- a/lib/apps/flavored_app.dart +++ b/lib/apps/flavored_app.dart @@ -1,12 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:humhub/apps/flavored/web_view.f.dart'; +import 'package:humhub/apps/flavored/util/router.f.dart'; import 'package:humhub/util/intent/intent_plugin.dart'; import 'package:humhub/util/loading_provider.dart'; import 'package:humhub/util/notifications/plugin.dart'; import 'package:humhub/util/override_locale.dart'; import 'package:humhub/util/push/push_plugin.dart'; import 'package:humhub/util/storage_service.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class FlavoredApp extends ConsumerStatefulWidget { const FlavoredApp({super.key}); @@ -26,8 +27,13 @@ class FlavoredAppState extends ConsumerState { builder: (overrideLocale) => Builder( builder: (context) => MaterialApp( debugShowCheckedModeBanner: false, - builder: (context, child) => const LoadingProvider( - child: WebViewF(), + initialRoute: RouterF.initRoute, + routes: RouterF.routes, + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + navigatorKey: navigatorKeyF, + builder: (context, child) => LoadingProvider( + child: child!, ), theme: ThemeData( fontFamily: 'OpenSans', diff --git a/lib/pages/web_view.dart b/lib/pages/web_view.dart index 12e904d..fd13666 100644 --- a/lib/pages/web_view.dart +++ b/lib/pages/web_view.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:app_settings/app_settings.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_app_badger/flutter_app_badger.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -73,7 +74,7 @@ class WebViewAppState extends ConsumerState { ); // ignore: deprecated_member_use return WillPopScope( - onWillPop: () => WebViewGlobalController.value!.exitApp(context, ref), + onWillPop: () => exitApp(context, ref), child: Scaffold( backgroundColor: HexColor(manifest.themeColor), body: SafeArea( @@ -101,6 +102,7 @@ class WebViewAppState extends ConsumerState { }, onLoadStop: _onLoadStop, onLoadStart: (controller, uri) async { + logDebug("onLoadStart"); _setAjaxHeadersJQuery(controller); }, onProgressChanged: _onProgressChanged, @@ -149,6 +151,7 @@ class WebViewAppState extends ConsumerState { logInfo(inMessage); ChannelMessage message = ChannelMessage.fromJson(inMessage!); await _handleJSMessage(message, headlessWebView!); + logDebug('flutterChannel triggered: ${message.type}'); }, ), ); @@ -156,6 +159,7 @@ class WebViewAppState extends ConsumerState { } Future _shouldInterceptFetchRequest(InAppWebViewController controller, FetchRequest request) async { + logDebug("_shouldInterceptFetchRequest"); request.headers!.addAll(_initialRequest.headers!); return request; } @@ -299,6 +303,39 @@ class WebViewAppState extends ConsumerState { } } + Future exitApp(context, ref) async { + bool canGoBack = await WebViewGlobalController.value!.canGoBack(); + if (canGoBack) { + WebViewGlobalController.value!.goBack(); + return Future.value(false); + } else { + final exitConfirmed = await showDialog( + context: context, + builder: (context) => AlertDialog( + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))), + title: Text(AppLocalizations.of(context)!.web_view_exit_popup_title), + content: Text(AppLocalizations.of(context)!.web_view_exit_popup_content), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: Text(AppLocalizations.of(context)!.no), + ), + TextButton( + onPressed: () { + var isHide = ref.read(humHubProvider).isHideDialog; + isHide + ? SystemNavigator.pop() + : Navigator.of(context).pushNamedAndRemoveUntil(Opener.path, (Route route) => false); + }, + child: Text(AppLocalizations.of(context)!.yes), + ), + ], + ), + ); + return exitConfirmed ?? false; + } + } + @override void dispose() { super.dispose(); diff --git a/lib/util/extensions.dart b/lib/util/extensions.dart index 17d23a5..524afc8 100644 --- a/lib/util/extensions.dart +++ b/lib/util/extensions.dart @@ -1,51 +1,8 @@ -import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:humhub/pages/opener.dart'; import 'package:humhub/util/const.dart'; -import 'package:humhub/util/providers.dart'; import 'package:loggy/loggy.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -extension MyWebViewController on InAppWebViewController { - Future exitApp(context, ref) async { - bool canGoBack = await this.canGoBack(); - if (canGoBack) { - goBack(); - return Future.value(false); - } else { - final exitConfirmed = await showDialog( - context: context, - builder: (context) => AlertDialog( - shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))), - title: Text(AppLocalizations.of(context)!.web_view_exit_popup_title), - content: Text(AppLocalizations.of(context)!.web_view_exit_popup_content), - actions: [ - TextButton( - onPressed: () => Navigator.of(context).pop(false), - child: Text(AppLocalizations.of(context)!.no), - ), - TextButton( - onPressed: () { - closeOrOpenDialog(context, ref); - }, - child: Text(AppLocalizations.of(context)!.yes), - ), - ], - ), - ); - return exitConfirmed ?? false; - } - } - - closeOrOpenDialog(BuildContext context, WidgetRef ref) { - var isHide = ref.read(humHubProvider).isHideDialog; - isHide - ? SystemNavigator.pop() - : Navigator.of(context).pushNamedAndRemoveUntil(Opener.path, (Route route) => false); - } -} class HexColor extends Color { static int _getColorFromHex(String hexColor) {