Skip to content

Commit

Permalink
Merge pull request #85 from humhub/82-js-of-external-modules-not-loaded
Browse files Browse the repository at this point in the history
82 js of external modules not loaded
  • Loading branch information
luke- committed Jul 2, 2023
2 parents d8638ca + 8dc7b4c commit 22fe8a6
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 25 deletions.
10 changes: 10 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
PODS:
- "app_settings (3.0.0+1)":
- Flutter
- connectivity_plus (0.0.1):
- Flutter
- ReachabilitySwift
- Firebase/CoreOnly (10.3.0):
- FirebaseCore (= 10.3.0)
- Firebase/Messaging (10.3.0):
Expand Down Expand Up @@ -81,6 +84,7 @@ PODS:
- permission_handler_apple (9.0.4):
- Flutter
- PromisesObjC (2.2.0)
- ReachabilitySwift (5.0.0)
- receive_sharing_intent (0.0.1):
- Flutter
- uni_links (0.0.1):
Expand All @@ -92,6 +96,7 @@ PODS:

DEPENDENCIES:
- app_settings (from `.symlinks/plugins/app_settings/ios`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- Flutter (from `Flutter`)
Expand Down Expand Up @@ -119,10 +124,13 @@ SPEC REPOS:
- nanopb
- OrderedSet
- PromisesObjC
- ReachabilitySwift

EXTERNAL SOURCES:
app_settings:
:path: ".symlinks/plugins/app_settings/ios"
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/ios"
firebase_core:
:path: ".symlinks/plugins/firebase_core/ios"
firebase_messaging:
Expand Down Expand Up @@ -154,6 +162,7 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
app_settings: d103828c9f5d515c4df9ee754dabd443f7cedcf3
connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a
Firebase: f92fc551ead69c94168d36c2b26188263860acd9
firebase_core: 6242f038aefa4582e028536e71312f7e3a41e6bb
firebase_messaging: ee61b8065c395a117864224e3031729e656232af
Expand All @@ -174,6 +183,7 @@ SPEC CHECKSUMS:
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
receive_sharing_intent: c0d87310754e74c0f9542947e7cbdf3a0335a3b1
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
Expand Down
7 changes: 7 additions & 0 deletions lib/pages/opener.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:humhub/pages/web_view.dart';
Expand Down Expand Up @@ -198,4 +199,10 @@ class OpenerState extends ConsumerState<Opener> {
),
);
}

@override
void dispose() {
controlLer.urlTextController.dispose();
super.dispose();
}
}
46 changes: 24 additions & 22 deletions lib/pages/web_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:app_settings/app_settings.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app_badger/flutter_app_badger.dart';
Expand All @@ -12,15 +13,16 @@ import 'package:humhub/models/manifest.dart';
import 'package:humhub/pages/opener.dart';
import 'package:humhub/util/extensions.dart';
import 'package:humhub/util/notifications/plugin.dart';
import 'package:humhub/util/opener_controller.dart';
import 'package:humhub/util/push/push_plugin.dart';
import 'package:humhub/util/providers.dart';
import 'package:loggy/loggy.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:humhub/util/router.dart' as m;

import '../components/in_app_browser.dart';
import '../models/hum_hub.dart';
import '../util/connectivity_plugin.dart';

class WebViewApp extends ConsumerStatefulWidget {
const WebViewApp({super.key});
Expand All @@ -38,7 +40,6 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
final _options = InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
useShouldOverrideUrlLoading: true,
useShouldInterceptAjaxRequest: true,
useShouldInterceptFetchRequest: true,
javaScriptEnabled: true,
),
Expand Down Expand Up @@ -80,9 +81,12 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
pullToRefreshController: _pullToRefreshController,
shouldOverrideUrlLoading: _shouldOverrideUrlLoading,
onWebViewCreated: _onWebViewCreated,
shouldInterceptAjaxRequest: _shouldInterceptAjaxRequest,
shouldInterceptFetchRequest: _shouldInterceptFetchRequest,
onLoadStop: _onLoadStop,
onLoadStart: (controller, uri) async {
bool isConnected = await ConnectivityPlugin.hasConnectivity;
_setAjaxHeadersJQuery(controller);
},
onProgressChanged: _onProgressChanged,
onConsoleMessage: (controller, msg) {
// Handle the web resource error here
Expand All @@ -93,6 +97,7 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
log('Http Error: $description');
},
onLoadError: (InAppWebViewController controller, Uri? url, int code, String message) {
if(code== -1009) NoConnectionDialog.show(context);
log('Load Error: $message');
},
),
Expand All @@ -106,6 +111,7 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
Future<NavigationActionPolicy?> _shouldOverrideUrlLoading(
InAppWebViewController controller, NavigationAction action) async {
// 1st check if url is not def. app url and open it in a browser or inApp.
_setAjaxHeadersJQuery(controller);
final url = action.request.url!.origin;
if (!url.startsWith(manifest.baseUrl)) {
authBrowser.launchUrl(action.request);
Expand Down Expand Up @@ -166,27 +172,12 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
webViewController = controller;
}

Future<AjaxRequest?> _shouldInterceptAjaxRequest(InAppWebViewController controller, AjaxRequest request) async {
_initialRequest.headers!.forEach((key, value) {
request.headers!.setRequestHeader(key, value);
});
return request;
}

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

URLRequest get _initRequest {
//Append random hash to customHeaders in this state the header should always exist.
bool isHideDialog = ref.read(humHubProvider).isHideDialog;
Map<String, String> customHeaders = {};
customHeaders.addAll({
'x-humhub-app-token': ref.read(humHubProvider).randomHash!,
'x-humhub-app': ref.read(humHubProvider).appVersion!,
'x-humhub-app-ostate': isHideDialog ? '1' : '0'
});
final args = ModalRoute.of(context)!.settings.arguments;
String? url;
if (args is Manifest) {
Expand All @@ -199,7 +190,7 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
if (args == null) {
manifest = m.MyRouter.initParams;
}
return URLRequest(url: Uri.parse(url ?? manifest.baseUrl), headers: customHeaders);
return URLRequest(url: Uri.parse(url ?? manifest.baseUrl), headers: ref.read(humHubProvider).customHeaders);
}

_onLoadStop(InAppWebViewController controller, Uri? url) {
Expand All @@ -210,6 +201,7 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
source:
"document.querySelector('#account-login-form > div.form-group.field-login-rememberme').style.display='none';");
}
_setAjaxHeadersJQuery(controller);
_pullToRefreshController?.endRefreshing();
}

Expand All @@ -228,10 +220,14 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
: PullToRefreshController(
options: _pullToRefreshOptions,
onRefresh: () async {
if (defaultTargetPlatform == TargetPlatform.android) {
Uri? url = await webViewController.getUrl();
if (url != null) {
webViewController.loadUrl(
urlRequest: URLRequest(
url: await webViewController.getUrl(), headers: ref.read(humHubProvider).customHeaders),
);
} else {
webViewController.reload();
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
webViewController.loadUrl(urlRequest: URLRequest(url: await webViewController.getUrl()));
}
},
);
Expand Down Expand Up @@ -261,4 +257,10 @@ class WebViewAppState extends ConsumerState<WebViewApp> {
),
);
}

Future<void> _setAjaxHeadersJQuery(InAppWebViewController controller) async {
String jsCode = "\$.ajaxSetup({headers: ${jsonEncode(ref.read(humHubProvider).customHeaders).toString()}});";
dynamic jsResponse = await controller.evaluateJavascript(source: jsCode);
log(jsResponse != null ? jsResponse.toString() : "Script returned null value");
}
}
71 changes: 71 additions & 0 deletions lib/util/connectivity_plugin.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class ConnectivityPlugin extends ConsumerStatefulWidget {
final Widget child;

const ConnectivityPlugin({
Key? key,
required this.child,
}) : super(key: key);

@override
ConnectivityPluginState createState() => ConnectivityPluginState();

static Future<bool> get hasConnectivity async {
ConnectivityResult connectivityResult = await Connectivity().checkConnectivity();
return connectivityResult != ConnectivityResult.none;
}
}

class ConnectivityPluginState extends ConsumerState<ConnectivityPlugin> {
@override
Widget build(BuildContext context) {
return StreamBuilder<ConnectivityResult?>(
stream: Connectivity().onConnectivityChanged,
builder: (context, snap) {
if (snap.hasData) {
// Process the data from the stream
ConnectivityResult result = snap.data!;
if (result == ConnectivityResult.none) {
WidgetsBinding.instance.addPostFrameCallback((_) {
// Use a small delay to show the dialog after the build phase
NoConnectionDialog.show(context);
});
}
}
return widget.child;
},
);
}
}

class NoConnectionDialog extends StatelessWidget {
const NoConnectionDialog({super.key});

@override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text('No Connection'),
content: const Text('Please check your internet connection and try again.'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop(); // Close the dialog
},
),
],
);
}

static show(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return const NoConnectionDialog();
},
);
}
}
17 changes: 15 additions & 2 deletions lib/util/opener_controller.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart';
Expand All @@ -6,6 +7,7 @@ import 'package:humhub/models/manifest.dart';
import 'package:humhub/util/providers.dart';
import 'package:http/http.dart' as http;
import 'api_provider.dart';
import 'connectivity_plugin.dart';
import 'form_helper.dart';
import 'dart:developer';

Expand All @@ -17,6 +19,7 @@ class OpenerController {
late String? postcodeErrorMessage;
final String formUrlKey = "redirect_url";
final String error404 = "404";
final String noConnection = "no_connection";
final WidgetRef ref;

OpenerController({required this.ref, required this.helper});
Expand Down Expand Up @@ -47,6 +50,16 @@ class OpenerController {
// Validate the URL format and if !value.isEmpty
if (!helper.validate()) return;
helper.save();

var hasConnection = await ConnectivityPlugin.hasConnectivity;
if (!hasConnection) {
String value = urlTextController.text;
urlTextController.text = noConnection;
helper.validate();
urlTextController.text = value;
asyncData = null;
return;
}
// Get the manifest.json for given url.
await findManifest(helper.model[formUrlKey]!);
// If manifest.json does not exist the url is incorrect.
Expand All @@ -72,7 +85,7 @@ class OpenerController {
}
}

bool get allOk => !(asyncData!.hasError || !doesViewExist);
bool get allOk => !(asyncData == null || asyncData!.hasError || !doesViewExist);

Uri assumeUrl(String url) {
if (url.startsWith("https://") || url.startsWith("http://")) return Uri.parse(url);
Expand All @@ -81,7 +94,7 @@ class OpenerController {

String? validateUrl(String? value) {
if (value == error404) return 'Your HumHub installation does not exist';

if (value == noConnection) return 'Please check your internet connection.';
if (value == null || value.isEmpty) {
return 'Specify you HumHub location';
}
Expand Down
6 changes: 6 additions & 0 deletions lib/util/providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ class HumHubNotifier extends ChangeNotifier {
String? get appVersion => _humHubInstance.appVersion;
String? get pushToken => _humHubInstance.pushToken;

Map<String, String> get customHeaders =>{
'x-humhub-app-token': randomHash!,
'x-humhub-app': appVersion!,
'x-humhub-app-ostate': isHideDialog ? '1' : '0'
};

void setIsHideOpener(bool isHide) {
_humHubInstance.isHideOpener = isHide;
_updateSafeStorage();
Expand Down
2 changes: 2 additions & 0 deletions macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import FlutterMacOS
import Foundation

import connectivity_plus
import firebase_core
import firebase_messaging
import flutter_app_badger
Expand All @@ -15,6 +16,7 @@ import package_info_plus
import url_launcher_macos

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
FlutterAppBadgerPlugin.register(with: registry.registrar(forPlugin: "FlutterAppBadgerPlugin"))
Expand Down
Loading

0 comments on commit 22fe8a6

Please sign in to comment.