Skip to content

Commit

Permalink
Add exit app logic to specific web_views
Browse files Browse the repository at this point in the history
  • Loading branch information
PrimozRatej committed May 21, 2024
1 parent 707419e commit 5d65891
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 66 deletions.
15 changes: 15 additions & 0 deletions lib/apps/flavored/util/router.f.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'package:flutter/cupertino.dart';
import 'package:humhub/apps/flavored/web_view.f.dart';

final GlobalKey<NavigatorState> navigatorKeyF = GlobalKey<NavigatorState>();

NavigatorState? get navigator => navigatorKeyF.currentState;

class RouterF {
static String? initRoute = WebViewF.path;
static dynamic initParams;

static var routes = {
WebViewF.path: (context) => const WebViewF(),
};
}
71 changes: 52 additions & 19 deletions lib/apps/flavored/web_view.f.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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
Expand All @@ -48,7 +50,7 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
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(
Expand All @@ -58,8 +60,8 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
initialOptions: _options,
pullToRefreshController: _pullToRefreshController,
shouldOverrideUrlLoading: _shouldOverrideUrlLoading,
onWebViewCreated: _onWebViewCreated,
shouldInterceptFetchRequest: _shouldInterceptFetchRequest,
onWebViewCreated: _onWebViewCreated,
onCreateWindow: _onCreateWindow,
onLoadStop: _onLoadStop,
onLoadStart: _onLoadStart,
Expand All @@ -79,17 +81,17 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
}

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(
Expand All @@ -99,8 +101,8 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
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();
Expand Down Expand Up @@ -170,15 +172,15 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
.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();
LoadingProvider.of(ref).dismissAll();
}

Future<void> _onLoadStart(InAppWebViewController controller, Uri? url) async {
await _setAjaxHeadersJQuery(controller);
_setAjaxHeadersJQuery(controller);
LoadingProvider.of(ref).dismissAll();
}

Expand All @@ -200,7 +202,8 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {

Future<void> _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<void> _handleJSMessage(ChannelMessage message, HeadlessInAppWebView headlessWebView) async {
Expand Down Expand Up @@ -235,6 +238,36 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
}
}

Future<bool> exitApp(context, ref) async {
bool canGoBack = await WebViewGlobalController.value!.canGoBack();
if (canGoBack) {
WebViewGlobalController.value!.goBack();
return Future.value(false);
} else {
final exitConfirmed = await showDialog<bool>(
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: <Widget>[
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();
Expand Down
12 changes: 9 additions & 3 deletions lib/apps/flavored_app.dart
Original file line number Diff line number Diff line change
@@ -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});
Expand All @@ -26,8 +27,13 @@ class FlavoredAppState extends ConsumerState<FlavoredApp> {
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',
Expand Down
39 changes: 38 additions & 1 deletion lib/pages/web_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -73,7 +74,7 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
);
// ignore: deprecated_member_use
return WillPopScope(
onWillPop: () => WebViewGlobalController.value!.exitApp(context, ref),
onWillPop: () => exitApp(context, ref),
child: Scaffold(
backgroundColor: HexColor(manifest.themeColor),
body: SafeArea(
Expand Down Expand Up @@ -101,6 +102,7 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
},
onLoadStop: _onLoadStop,
onLoadStart: (controller, uri) async {
logDebug("onLoadStart");
_setAjaxHeadersJQuery(controller);
},
onProgressChanged: _onProgressChanged,
Expand Down Expand Up @@ -149,13 +151,15 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
logInfo(inMessage);
ChannelMessage message = ChannelMessage.fromJson(inMessage!);
await _handleJSMessage(message, headlessWebView!);
logDebug('flutterChannel triggered: ${message.type}');
},
),
);
WebViewGlobalController.setValue(controller);
}

Future<FetchRequest?> _shouldInterceptFetchRequest(InAppWebViewController controller, FetchRequest request) async {
logDebug("_shouldInterceptFetchRequest");
request.headers!.addAll(_initialRequest.headers!);
return request;
}
Expand Down Expand Up @@ -299,6 +303,39 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
}
}

Future<bool> exitApp(context, ref) async {
bool canGoBack = await WebViewGlobalController.value!.canGoBack();
if (canGoBack) {
WebViewGlobalController.value!.goBack();
return Future.value(false);
} else {
final exitConfirmed = await showDialog<bool>(
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: <Widget>[
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<dynamic> route) => false);
},
child: Text(AppLocalizations.of(context)!.yes),
),
],
),
);
return exitConfirmed ?? false;
}
}

@override
void dispose() {
super.dispose();
Expand Down
43 changes: 0 additions & 43 deletions lib/util/extensions.dart
Original file line number Diff line number Diff line change
@@ -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<bool> exitApp(context, ref) async {
bool canGoBack = await this.canGoBack();
if (canGoBack) {
goBack();
return Future.value(false);
} else {
final exitConfirmed = await showDialog<bool>(
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: <Widget>[
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<dynamic> route) => false);
}
}

class HexColor extends Color {
static int _getColorFromHex(String hexColor) {
Expand Down

0 comments on commit 5d65891

Please sign in to comment.