Skip to content

Commit

Permalink
Merge pull request #259 from humhub/255-custompage-with-iframe-leave-…
Browse files Browse the repository at this point in the history
…the-ios-app

Only navigate in an external browser when isNotForMainFrame and navigation type is LINK
  • Loading branch information
marc-farre authored Dec 5, 2024
2 parents bbf0400 + bc0803b commit 340dd7a
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 53 deletions.
80 changes: 28 additions & 52 deletions lib/pages/web_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@ class WebViewAppState extends ConsumerState<WebView> {
onProgressChanged: _onProgressChanged,
onReceivedError: _onReceivedError,
onDownloadStartRequest: _onDownloadStartRequest,
onLongPressHitTestResult:
WebViewGlobalController.onLongPressHitTestResult,
onLongPressHitTestResult: WebViewGlobalController.onLongPressHitTestResult,
),
)),
);
Expand Down Expand Up @@ -129,15 +128,12 @@ class WebViewAppState extends ConsumerState<WebView> {
}
String? payloadFromPush = InitFromUrl.usePayload();
if (payloadFromPush != null) url = payloadFromPush;
return URLRequest(
url: WebUri(url ?? _manifest.startUrl),
headers: ref.read(humHubProvider).customHeaders);
return URLRequest(url: WebUri(url ?? _manifest.startUrl), headers: ref.read(humHubProvider).customHeaders);
}

Future<NavigationActionPolicy?> _shouldOverrideUrlLoading(
InAppWebViewController controller, NavigationAction action) async {
WebViewGlobalController.ajaxSetHeaders(
headers: ref.read(humHubProvider).customHeaders);
WebViewGlobalController.ajaxSetHeaders(headers: ref.read(humHubProvider).customHeaders);
WebViewGlobalController.listenToImageOpen();
WebViewGlobalController.appendViewportFitCover();

Expand All @@ -153,19 +149,17 @@ class WebViewAppState extends ConsumerState<WebView> {
return NavigationActionPolicy.CANCEL;
}
// For all other external links
if (!url.startsWith(_manifest.baseUrl) && !action.isForMainFrame) {
await launchUrl(action.request.url!.uriValue,
mode: LaunchMode.externalApplication);
if (!url.startsWith(_manifest.baseUrl) &&
!action.isForMainFrame &&
action.navigationType == NavigationType.LINK_ACTIVATED) {
await launchUrl(action.request.url!.uriValue, mode: LaunchMode.externalApplication);
return NavigationActionPolicy.CANCEL;
}
// 2nd Append customHeader if url is in app redirect and CANCEL the requests without custom headers
if (Platform.isAndroid ||
action.navigationType == NavigationType.LINK_ACTIVATED ||
action.navigationType == NavigationType.FORM_SUBMITTED) {
Map<String, String> mergedMap = {
...?_initialRequest.headers,
...?action.request.headers
};
Map<String, String> mergedMap = {...?_initialRequest.headers, ...?action.request.headers};
URLRequest newRequest = action.request.copyWith(headers: mergedMap);
controller.loadUrl(urlRequest: newRequest);
return NavigationActionPolicy.CANCEL;
Expand All @@ -180,8 +174,7 @@ class WebViewAppState extends ConsumerState<WebView> {
await controller.addWebMessageListener(
WebMessageListener(
jsObjectName: "flutterChannel",
onPostMessage:
(inMessage, sourceOrigin, isMainFrame, replyProxy) async {
onPostMessage: (inMessage, sourceOrigin, isMainFrame, replyProxy) async {
logInfo(inMessage);
ChannelMessage message = ChannelMessage.fromJson(inMessage!.data);
await _handleJSMessage(message, _headlessWebView!);
Expand All @@ -192,15 +185,13 @@ class WebViewAppState extends ConsumerState<WebView> {
WebViewGlobalController.setValue(controller);
}

Future<FetchRequest?> _shouldInterceptFetchRequest(
InAppWebViewController controller, FetchRequest request) async {
Future<FetchRequest?> _shouldInterceptFetchRequest(InAppWebViewController controller, FetchRequest request) async {
logDebug("_shouldInterceptFetchRequest");
request.headers!.addAll(_initialRequest.headers!);
return request;
}

Future<bool?> _onCreateWindow(InAppWebViewController controller,
CreateWindowAction createWindowAction) async {
Future<bool?> _onCreateWindow(InAppWebViewController controller, CreateWindowAction createWindowAction) async {
WebUri? urlToOpen = createWindowAction.request.url;

if (urlToOpen == null) return Future.value(false);
Expand All @@ -224,22 +215,20 @@ class WebViewAppState extends ConsumerState<WebView> {
_onLoadStop(InAppWebViewController controller, Uri? url) {
// Disable remember me checkbox on login and set def. value to true: check if the page is actually login page, if it is inject JS that hides element
if (url!.path.contains('/user/auth/login')) {
WebViewGlobalController.value!.evaluateJavascript(
source: "document.querySelector('#login-rememberme').checked=true");
WebViewGlobalController.value!
.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';");
}
WebViewGlobalController.ajaxSetHeaders(
headers: ref.read(humHubProvider).customHeaders);
WebViewGlobalController.ajaxSetHeaders(headers: ref.read(humHubProvider).customHeaders);
WebViewGlobalController.listenToImageOpen();
WebViewGlobalController.appendViewportFitCover();
LoadingProvider.of(ref).dismissAll();
}

void _onLoadStart(InAppWebViewController controller, Uri? url) async {
WebViewGlobalController.ajaxSetHeaders(
headers: ref.read(humHubProvider).customHeaders);
WebViewGlobalController.ajaxSetHeaders(headers: ref.read(humHubProvider).customHeaders);
WebViewGlobalController.listenToImageOpen();
WebViewGlobalController.appendViewportFitCover();
}
Expand All @@ -250,8 +239,7 @@ class WebViewAppState extends ConsumerState<WebView> {
}
}

void _onReceivedError(InAppWebViewController controller,
WebResourceRequest request, WebResourceError error) {
void _onReceivedError(InAppWebViewController controller, WebResourceRequest request, WebResourceError error) {
if (error.description == 'net::ERR_INTERNET_DISCONNECTED') {
NoConnectionDialog.show(context);
}
Expand All @@ -262,23 +250,20 @@ class WebViewAppState extends ConsumerState<WebView> {
WebViewGlobalController.value!.loadUrl(urlRequest: request);
}

Future<void> _handleJSMessage(
ChannelMessage message, HeadlessInAppWebView headlessWebView) async {
Future<void> _handleJSMessage(ChannelMessage message, HeadlessInAppWebView headlessWebView) async {
switch (message.action) {
case ChannelAction.showOpener:
ref.read(humHubProvider).setIsHideOpener(false);
ref.read(humHubProvider).clearSafeStorage();
FlutterAppBadger.updateBadgeCount(0);
Navigator.of(context).pushNamedAndRemoveUntil(
Opener.path, (Route<dynamic> route) => false);
Navigator.of(context).pushNamedAndRemoveUntil(Opener.path, (Route<dynamic> route) => false);
break;
case ChannelAction.hideOpener:
ref.read(humHubProvider).setIsHideOpener(true);
ref.read(humHubProvider).setHash(HumHub.generateHash(32));
break;
case ChannelAction.registerFcmDevice:
String? token = ref.read(pushTokenProvider).value ??
await FirebaseMessaging.instance.getToken();
String? token = ref.read(pushTokenProvider).value ?? await FirebaseMessaging.instance.getToken();
if (token != null) {
WebViewGlobalController.ajaxPost(
url: message.url!,
Expand All @@ -293,8 +278,7 @@ class WebViewAppState extends ConsumerState<WebView> {
}
break;
case ChannelAction.unregisterFcmDevice:
String? token = ref.read(pushTokenProvider).value ??
await FirebaseMessaging.instance.getToken();
String? token = ref.read(pushTokenProvider).value ?? await FirebaseMessaging.instance.getToken();
if (token != null) {
WebViewGlobalController.ajaxPost(
url: message.url!,
Expand All @@ -317,11 +301,9 @@ class WebViewAppState extends ConsumerState<WebView> {
final exitConfirmed = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0))),
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),
content: Text(AppLocalizations.of(context)!.web_view_exit_popup_content),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.of(context).pop(false),
Expand All @@ -332,8 +314,7 @@ class WebViewAppState extends ConsumerState<WebView> {
var isHide = ref.read(humHubProvider).isHideDialog;
isHide
? SystemNavigator.pop()
: Navigator.of(context).pushNamedAndRemoveUntil(
Opener.path, (Route<dynamic> route) => false);
: Navigator.of(context).pushNamedAndRemoveUntil(Opener.path, (Route<dynamic> route) => false);
},
child: Text(AppLocalizations.of(context)!.yes),
),
Expand All @@ -344,8 +325,7 @@ class WebViewAppState extends ConsumerState<WebView> {
}
}

void _onDownloadStartRequest(InAppWebViewController controller,
DownloadStartRequest downloadStartRequest) async {
void _onDownloadStartRequest(InAppWebViewController controller, DownloadStartRequest downloadStartRequest) async {
PersistentBottomSheetController? persistentController;
//bool isBottomSheetVisible = false;

Expand All @@ -365,8 +345,7 @@ class WebViewAppState extends ConsumerState<WebView> {
isDone = true;
scaffoldMessengerStateKey.currentState?.showSnackBar(
SnackBar(
content: Text(
'${AppLocalizations.of(context)!.file_download}: $filename'),
content: Text('${AppLocalizations.of(context)!.file_download}: $filename'),
action: SnackBarAction(
label: AppLocalizations.of(context)!.open,
onPressed: () {
Expand All @@ -383,22 +362,19 @@ class WebViewAppState extends ConsumerState<WebView> {
downloadTimer = Timer(const Duration(seconds: 1), () {
// Show the persistent bottom sheet if not already shown
if (!isDone) {
persistentController =
_scaffoldKey.currentState!.showBottomSheet((context) {
persistentController = _scaffoldKey.currentState!.showBottomSheet((context) {
return Container(
width: MediaQuery.of(context).size.width,
height: 100,
color: const Color(0xff313033),
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"${AppLocalizations.of(context)!.downloading}...",
style: const TextStyle(
fontWeight: FontWeight.bold, color: Colors.white),
style: const TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
),
Stack(
alignment: Alignment.center,
Expand Down
4 changes: 3 additions & 1 deletion lib/util/auth_in_app_browser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class AuthInAppBrowser extends InAppBrowser {
settings = InAppBrowserClassSettings(
browserSettings: InAppBrowserSettings(
hideUrlBar: true,
hideTitleBar: true,
closeOnCannotGoBack: true,
shouldCloseOnBackButtonPressed: true,
toolbarTopBackgroundColor: Colors.white,
toolbarTopTintColor: HexColor(manifest.themeColor),
Expand All @@ -40,6 +42,6 @@ class AuthInAppBrowser extends InAppBrowser {
}

launchUrl(URLRequest urlRequest) {
openUrlRequest(urlRequest: urlRequest, /*options: options,*/ settings: settings);
openUrlRequest(urlRequest: urlRequest, settings: settings);
}
}

0 comments on commit 340dd7a

Please sign in to comment.