Skip to content

Commit

Permalink
Merge pull request #198 from humhub/191-upgrade-flutter_inappwebview-…
Browse files Browse the repository at this point in the history
…to-v600

191 upgrade flutter inappwebview to v6.x
  • Loading branch information
luke- authored Jul 1, 2024
2 parents b012d3b + c81b8bb commit 2f3bc03
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 86 deletions.
12 changes: 5 additions & 7 deletions lib/components/register_push_in_app_browser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,17 @@ import 'package:flutter_inappwebview/flutter_inappwebview.dart';

class RegisterPushInAppBrowser extends InAppBrowser {
final URLRequest request;
late InAppBrowserClassOptions options;
late InAppBrowserClassSettings settings;

RegisterPushInAppBrowser({required this.request}) {
options = InAppBrowserClassOptions(
crossPlatform: InAppBrowserOptions(hidden: true),
inAppWebViewGroupOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(javaScriptEnabled: true),
),
settings = InAppBrowserClassSettings(
browserSettings: InAppBrowserSettings(hidden: true),
webViewSettings: InAppWebViewSettings(javaScriptEnabled: true),
);
}

Future<void> register() async {
await openUrlRequest(urlRequest: request, options: options);
await openUrlRequest(urlRequest: request, settings: settings);
close();
}
}
49 changes: 22 additions & 27 deletions lib/flavored/web_view.f.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
super.initState();

pullToRefreshController = PullToRefreshController(
options: PullToRefreshOptions(
settings: PullToRefreshSettings(
color: HexColor(instance.manifest.themeColor),
),
onRefresh: () async {
Expand All @@ -74,15 +74,15 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
bottom: false,
child: InAppWebView(
initialUrlRequest: _initialRequest,
initialOptions: _options,
initialSettings: _settings,
pullToRefreshController: pullToRefreshController,
shouldOverrideUrlLoading: _shouldOverrideUrlLoading,
shouldInterceptFetchRequest: _shouldInterceptFetchRequest,
onWebViewCreated: _onWebViewCreated,
onCreateWindow: _onCreateWindow,
onLoadStop: _onLoadStop,
onLoadStart: _onLoadStart,
onLoadError: _onLoadError,
onReceivedError: _onLoadError,
onProgressChanged: _onProgressChanged,
),
),
Expand All @@ -98,24 +98,18 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
if (payload is String) payloadFromPush = payload;
if (payloadForInitFromPush != null) url = payloadForInitFromPush;
if (payloadFromPush != null) url = payloadFromPush;
return URLRequest(url: Uri.parse(url), headers: instance.customHeaders);
return URLRequest(url: WebUri(url), headers: instance.customHeaders);
}

InAppWebViewGroupOptions get _options => InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
useShouldOverrideUrlLoading: true,
useShouldInterceptFetchRequest: true,
javaScriptEnabled: true,
supportZoom: false,
javaScriptCanOpenWindowsAutomatically: true,
),
android: AndroidInAppWebViewOptions(
supportMultipleWindows: true,
useHybridComposition: true,
),
ios: IOSInAppWebViewOptions(
allowsInlineMediaPlayback: true,
),
InAppWebViewSettings get _settings => InAppWebViewSettings(
useShouldOverrideUrlLoading: true,
useShouldInterceptFetchRequest: true,
javaScriptEnabled: true,
supportZoom: false,
javaScriptCanOpenWindowsAutomatically: true,
supportMultipleWindows: true,
useHybridComposition: true,
allowsInlineMediaPlayback: true,
);

Future<NavigationActionPolicy?> _shouldOverrideUrlLoading(
Expand All @@ -129,8 +123,8 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
}
// 2nd Append customHeader if url is in app redirect and CANCEL the requests without custom headers
if (Platform.isAndroid ||
action.iosWKNavigationType == IOSWKNavigationType.LINK_ACTIVATED ||
action.iosWKNavigationType == IOSWKNavigationType.FORM_SUBMITTED) {
action.navigationType == NavigationType.LINK_ACTIVATED ||
action.navigationType == NavigationType.FORM_SUBMITTED) {
Map<String, String> mergedMap = {...instance.customHeaders, ...?action.request.headers};
URLRequest newRequest = action.request.copyWith(headers: mergedMap);
controller.loadUrl(urlRequest: newRequest);
Expand All @@ -147,7 +141,7 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
WebMessageListener(
jsObjectName: "flutterChannel",
onPostMessage: (inMessage, sourceOrigin, isMainFrame, replyProxy) async {
ChannelMessage message = ChannelMessage.fromJson(inMessage!);
ChannelMessage message = ChannelMessage.fromJson(inMessage!.data);
await _handleJSMessage(message, headlessWebView!);
},
),
Expand Down Expand Up @@ -191,8 +185,9 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
_setAjaxHeadersJQuery(controller);
}

void _onLoadError(InAppWebViewController controller, Uri? url, int code, String message) async {
if (code == -1009) ShowDialog.of(context).noInternetPopup();
void _onLoadError(InAppWebViewController controller, WebResourceRequest request,
WebResourceError error) async {
if (error.description == 'net::ERR_INTERNET_DISCONNECTED') ShowDialog.of(context).noInternetPopup();
pullToRefreshController.endRefreshing();
setState(() {});
}
Expand Down Expand Up @@ -221,7 +216,7 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
String? token = ref.read(pushTokenProvider).value;
if (token != null) {
var postData = Uint8List.fromList(utf8.encode("token=$token"));
await headlessWebView.webViewController.postUrl(url: Uri.parse(message.url!), postData: postData);
await headlessWebView.webViewController?.postUrl(url: WebUri(message.url!), postData: postData);
}
var status = await Permission.notification.status;
// status.isDenied: The user has previously denied the notification permission
Expand All @@ -237,9 +232,9 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
String? token = ref.read(pushTokenProvider).value;
if (token != null) {
var postData = Uint8List.fromList(utf8.encode("token=$token"));
URLRequest request = URLRequest(url: Uri.parse(message.url!), method: "POST", body: postData);
URLRequest request = URLRequest(url: WebUri(message.url!), method: "POST", body: postData);
// Works but for admin to see the changes it need to reload a page because a request is called on separate instance.
await headlessWebView.webViewController.loadUrl(urlRequest: request);
await headlessWebView.webViewController?.loadUrl(urlRequest: request);
}
break;
default:
Expand Down
43 changes: 20 additions & 23 deletions lib/pages/web_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,13 @@ class WebViewAppState extends ConsumerState<WebView> {
late AuthInAppBrowser authBrowser;
late Manifest manifest;
late URLRequest _initialRequest;
final _options = InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
useShouldOverrideUrlLoading: true,
useShouldInterceptFetchRequest: true,
javaScriptEnabled: true,
supportZoom: false,
javaScriptCanOpenWindowsAutomatically: true,
),
android: AndroidInAppWebViewOptions(
supportMultipleWindows: true,
),
final _settings = InAppWebViewSettings(
useShouldOverrideUrlLoading: true,
useShouldInterceptFetchRequest: true,
javaScriptEnabled: true,
supportZoom: false,
javaScriptCanOpenWindowsAutomatically: true,
supportMultipleWindows: true,
);

late PullToRefreshController _pullToRefreshController;
Expand All @@ -63,7 +59,7 @@ class WebViewAppState extends ConsumerState<WebView> {
SchedulerBinding.instance.addPostFrameCallback((_) {
_initialRequest = _initRequest;
_pullToRefreshController = PullToRefreshController(
options: PullToRefreshOptions(
settings: PullToRefreshSettings(
color: HexColor(manifest.themeColor),
),
onRefresh: () async {
Expand Down Expand Up @@ -96,7 +92,7 @@ class WebViewAppState extends ConsumerState<WebView> {
bottom: false,
child: InAppWebView(
initialUrlRequest: _initialRequest,
initialOptions: _options,
initialSettings: _settings,
pullToRefreshController: _pullToRefreshController,
shouldOverrideUrlLoading: _shouldOverrideUrlLoading,
onWebViewCreated: _onWebViewCreated,
Expand All @@ -121,8 +117,9 @@ class WebViewAppState extends ConsumerState<WebView> {
_setAjaxHeadersJQuery(controller);
},
onProgressChanged: _onProgressChanged,
onLoadError: (InAppWebViewController controller, Uri? url, int code, String message) {
if (code == -1009) NoConnectionDialog.show(context);
onReceivedError: (InAppWebViewController controller, WebResourceRequest request,
WebResourceError error) {
if (error.description == 'net::ERR_INTERNET_DISCONNECTED') NoConnectionDialog.show(context);
},
),
),
Expand All @@ -141,8 +138,8 @@ class WebViewAppState extends ConsumerState<WebView> {
}
// 2nd Append customHeader if url is in app redirect and CANCEL the requests without custom headers
if (Platform.isAndroid ||
action.iosWKNavigationType == IOSWKNavigationType.LINK_ACTIVATED ||
action.iosWKNavigationType == IOSWKNavigationType.FORM_SUBMITTED) {
action.navigationType == NavigationType.LINK_ACTIVATED ||
action.navigationType == NavigationType.FORM_SUBMITTED) {
Map<String, String> mergedMap = {...?_initialRequest.headers, ...?action.request.headers};
URLRequest newRequest = action.request.copyWith(headers: mergedMap);
controller.loadUrl(urlRequest: newRequest);
Expand All @@ -164,7 +161,7 @@ class WebViewAppState extends ConsumerState<WebView> {
jsObjectName: "flutterChannel",
onPostMessage: (inMessage, sourceOrigin, isMainFrame, replyProxy) async {
logInfo(inMessage);
ChannelMessage message = ChannelMessage.fromJson(inMessage!);
ChannelMessage message = ChannelMessage.fromJson(inMessage!.data);
await _handleJSMessage(message, headlessWebView!);
logDebug('flutterChannel triggered: ${message.type}');
},
Expand Down Expand Up @@ -201,7 +198,7 @@ class WebViewAppState extends ConsumerState<WebView> {
}
String? payloadFromPush = InitFromPush.usePayload();
if (payloadFromPush != null) url = payloadFromPush;
return URLRequest(url: Uri.parse(url ?? manifest.startUrl), headers: ref.read(humHubProvider).customHeaders);
return URLRequest(url: WebUri(url ?? manifest.startUrl), headers: ref.read(humHubProvider).customHeaders);
}

_onLoadStop(InAppWebViewController controller, Uri? url) {
Expand Down Expand Up @@ -270,8 +267,8 @@ class WebViewAppState extends ConsumerState<WebView> {
String? token = ref.read(pushTokenProvider).value;
if (token != null) {
var postData = Uint8List.fromList(utf8.encode("token=$token"));
URLRequest request = URLRequest(url: Uri.parse(message.url!), method: "POST", body: postData);
await headlessWebView.webViewController.loadUrl(urlRequest: request);
URLRequest request = URLRequest(url: WebUri(message.url!), method: "POST", body: postData);
await headlessWebView.webViewController?.loadUrl(urlRequest: request);
}
var status = await Permission.notification.status;
// status.isDenied: The user has previously denied the notification permission
Expand All @@ -285,9 +282,9 @@ class WebViewAppState extends ConsumerState<WebView> {
String? token = ref.read(pushTokenProvider).value;
if (token != null) {
var postData = Uint8List.fromList(utf8.encode("token=$token"));
URLRequest request = URLRequest(url: Uri.parse(message.url!), method: "POST", body: postData);
URLRequest request = URLRequest(url: WebUri(message.url!), method: "POST", body: postData);
// Works but for admin to see the changes it need to reload a page because a request is called on separate instance.
await headlessWebView.webViewController.loadUrl(urlRequest: request);
await headlessWebView.webViewController?.loadUrl(urlRequest: request);
}
break;
case ChannelAction.none:
Expand Down
20 changes: 9 additions & 11 deletions lib/util/auth_in_app_browser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,22 @@ import 'package:loggy/loggy.dart';

class AuthInAppBrowser extends InAppBrowser {
final Manifest manifest;
late InAppBrowserClassOptions options;
late InAppBrowserClassSettings settings;
final Function concludeAuth;
static const String userAgent =
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';

AuthInAppBrowser({required this.manifest, required this.concludeAuth}) {
options = InAppBrowserClassOptions(
crossPlatform: InAppBrowserOptions(
settings = InAppBrowserClassSettings(
browserSettings: InAppBrowserSettings(
hideUrlBar: false,
toolbarTopBackgroundColor: HexColor(manifest.themeColor),
),
inAppWebViewGroupOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
javaScriptEnabled: true,
useShouldOverrideUrlLoading: true,
userAgent: userAgent,
applicationNameForUserAgent: 'HumHub-Mobile'),
),
webViewSettings: InAppWebViewSettings(
javaScriptEnabled: true,
useShouldOverrideUrlLoading: true,
userAgent: userAgent,
applicationNameForUserAgent: 'HumHub-Mobile'),
);
}

Expand All @@ -39,6 +37,6 @@ class AuthInAppBrowser extends InAppBrowser {
}

launchUrl(URLRequest urlRequest) {
openUrlRequest(urlRequest: urlRequest, options: options);
openUrlRequest(urlRequest: urlRequest, settings: settings);
}
}
26 changes: 13 additions & 13 deletions lib/util/extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,34 +41,34 @@ extension FutureAsyncValueX<T> on Future<AsyncValue<T>> {

extension URLRequestExtension on URLRequest {
URLRequest copyWith({
Uri? url,
WebUri? url,
String? method,
Uint8List? body,
Map<String, String>? headers,
bool? iosAllowsCellularAccess,
bool? iosAllowsConstrainedNetworkAccess,
bool? iosAllowsExpensiveNetworkAccess,
IOSURLRequestCachePolicy? iosCachePolicy,
URLRequestCachePolicy? iosCachePolicy,
bool? iosHttpShouldHandleCookies,
bool? iosHttpShouldUsePipelining,
IOSURLRequestNetworkServiceType? iosNetworkServiceType,
URLRequestNetworkServiceType? iosNetworkServiceType,
double? iosTimeoutInterval,
Uri? iosMainDocumentURL,
WebUri? iosMainDocumentURL,
}) {
return URLRequest(
url: url ?? this.url,
method: method ?? this.method,
headers: headers ?? this.headers,
body: body ?? this.body,
iosAllowsCellularAccess: iosAllowsCellularAccess ?? this.iosAllowsCellularAccess,
iosAllowsConstrainedNetworkAccess: iosAllowsConstrainedNetworkAccess ?? this.iosAllowsConstrainedNetworkAccess,
iosAllowsExpensiveNetworkAccess: iosAllowsExpensiveNetworkAccess ?? this.iosAllowsExpensiveNetworkAccess,
iosCachePolicy: iosCachePolicy ?? this.iosCachePolicy,
iosHttpShouldHandleCookies: iosHttpShouldHandleCookies ?? this.iosHttpShouldHandleCookies,
iosHttpShouldUsePipelining: iosHttpShouldUsePipelining ?? this.iosHttpShouldUsePipelining,
iosNetworkServiceType: iosNetworkServiceType ?? this.iosNetworkServiceType,
iosTimeoutInterval: iosTimeoutInterval ?? this.iosTimeoutInterval,
iosMainDocumentURL: iosMainDocumentURL ?? this.iosMainDocumentURL,
allowsCellularAccess: iosAllowsCellularAccess ?? allowsCellularAccess,
allowsConstrainedNetworkAccess: iosAllowsConstrainedNetworkAccess ?? allowsConstrainedNetworkAccess,
allowsExpensiveNetworkAccess: iosAllowsExpensiveNetworkAccess ?? allowsExpensiveNetworkAccess,
cachePolicy: iosCachePolicy,
httpShouldHandleCookies: iosHttpShouldHandleCookies ?? httpShouldHandleCookies,
httpShouldUsePipelining: iosHttpShouldUsePipelining ?? httpShouldUsePipelining,
networkServiceType: iosNetworkServiceType,
timeoutInterval: iosTimeoutInterval,
mainDocumentURL: iosMainDocumentURL,
);
}
}
Expand Down
2 changes: 2 additions & 0 deletions macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import connectivity_plus
import firebase_core
import firebase_messaging
import flutter_app_badger
import flutter_inappwebview_macos
import flutter_local_notifications
import flutter_native_timezone
import flutter_secure_storage_macos
Expand All @@ -21,6 +22,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
FlutterAppBadgerPlugin.register(with: registry.registrar(forPlugin: "FlutterAppBadgerPlugin"))
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
FlutterNativeTimezonePlugin.register(with: registry.registrar(forPlugin: "FlutterNativeTimezonePlugin"))
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
Expand Down
Loading

0 comments on commit 2f3bc03

Please sign in to comment.