Skip to content

Commit

Permalink
Use one navigatorKey and save files to ApplicationDocumentsDirectory …
Browse files Browse the repository at this point in the history
…on ios
  • Loading branch information
PrimozRatej committed Sep 22, 2024
1 parent 9c05938 commit 05654be
Show file tree
Hide file tree
Showing 17 changed files with 123 additions and 41 deletions.
4 changes: 3 additions & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

<!-- For older versions (For Android 12 (API 31) and Below) -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

<application
android:label="HumHub"
android:name="${applicationName}"
Expand Down
14 changes: 8 additions & 6 deletions lib/app_flavored.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:humhub/flavored/models/humhub.f.dart';
import 'package:humhub/flavored/util/intent_plugin.f.dart';
import 'package:humhub/flavored/util/router.f.dart';
import 'package:humhub/util/const.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/permission_handler.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';
Expand All @@ -24,10 +26,10 @@ class FlavoredAppState extends ConsumerState<FlavoredApp> {
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) async {
final status = await Permission.notification.status;
if (!status.isGranted) {
await Permission.notification.request();
}
await PermissionHandler.requestPermissions([
Permission.notification,
Permission.manageExternalStorage,
]);
});
}

Expand All @@ -41,13 +43,13 @@ class FlavoredAppState extends ConsumerState<FlavoredApp> {
child: OverrideLocale(
builder: (overrideLocale) => Builder(
builder: (context) => MaterialApp(
scaffoldMessengerKey: scaffoldMessengerStateKeyF,
scaffoldMessengerKey: scaffoldMessengerStateKey,
debugShowCheckedModeBanner: false,
initialRoute: RouterF.initRoute,
routes: RouterF.routes,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
navigatorKey: navigatorKeyF,
navigatorKey: navigatorKey,
builder: (context, child) => child!,
theme: ThemeData(
fontFamily: 'OpenSans',
Expand Down
14 changes: 6 additions & 8 deletions lib/app_opener.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:humhub/util/const.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/permission_handler.dart';
import 'package:humhub/util/push/push_plugin.dart';
import 'package:humhub/util/router.dart';
import 'package:humhub/util/storage_service.dart';
Expand All @@ -23,14 +25,10 @@ class OpenerAppState extends ConsumerState<OpenerApp> {
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) async {
final notifications = await Permission.notification.status;
if (!notifications.isGranted) {
await Permission.notification.request();
}
final storage = await Permission.manageExternalStorage.status;
if (!storage.isGranted) {
await Permission.manageExternalStorage.request();
}
await PermissionHandler.requestPermissions([
Permission.notification,
Permission.manageExternalStorage,
]);
});
}

Expand Down
12 changes: 6 additions & 6 deletions lib/flavored/util/intent_plugin.f.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:humhub/flavored/util/router.f.dart';
import 'package:humhub/flavored/web_view.f.dart';
import 'package:humhub/util/const.dart';
import 'package:humhub/util/loading_provider.dart';
import 'package:loggy/loggy.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
Expand Down Expand Up @@ -68,7 +68,7 @@ class IntentPluginFState extends ConsumerState<IntentPluginF> {
if (!mounted) return;
_latestUri = uri;
String? redirectUrl = uri?.toString();
if (redirectUrl != null && navigatorKeyF.currentState != null) {
if (redirectUrl != null && navigatorKey.currentState != null) {
tryNavigateWithOpener(redirectUrl);
}
_err = null;
Expand Down Expand Up @@ -103,11 +103,11 @@ class IntentPluginFState extends ConsumerState<IntentPluginF> {
}
_latestUri = uri;
String? redirectUrl = uri.queryParameters['url'];
if (redirectUrl != null && navigatorKeyF.currentState != null) {
if (redirectUrl != null && navigatorKey.currentState != null) {
tryNavigateWithOpener(redirectUrl);
} else {
if (redirectUrl != null) {
navigatorKeyF.currentState!.pushNamed(WebViewF.path, arguments: redirectUrl);
navigatorKey.currentState!.pushNamed(WebViewF.path, arguments: redirectUrl);
return;
}
}
Expand All @@ -125,13 +125,13 @@ class IntentPluginFState extends ConsumerState<IntentPluginF> {
Future<bool> tryNavigateWithOpener(String redirectUrl) async {
LoadingProvider.of(ref).showLoading();
bool isNewRouteSameAsCurrent = false;
navigatorKeyF.currentState!.popUntil((route) {
navigatorKey.currentState!.popUntil((route) {
if (route.settings.name == WebViewF.path) {
isNewRouteSameAsCurrent = true;
}
return true;
});
navigatorKeyF.currentState!.pushNamed(WebViewF.path, arguments: redirectUrl);
navigatorKey.currentState!.pushNamed(WebViewF.path, arguments: redirectUrl);
return isNewRouteSameAsCurrent;
}
}
10 changes: 5 additions & 5 deletions lib/flavored/util/notifications/channel.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:humhub/flavored/util/router.f.dart';
import 'package:humhub/flavored/web_view.f.dart';
import 'package:humhub/util/const.dart';
import 'package:humhub/util/notifications/channel.dart';
import 'package:humhub/util/notifications/init_from_push.dart';

Expand All @@ -14,19 +14,19 @@ class NotificationChannelF extends NotificationChannel {
///
@override
Future<void> onTap(String? payload) async {
if (payload != null && navigatorKeyF.currentState != null) {
if (payload != null && navigatorKey.currentState != null) {
bool isNewRouteSameAsCurrent = false;
navigatorKeyF.currentState!.popUntil((route) {
navigatorKey.currentState!.popUntil((route) {
if (route.settings.name == WebViewF.path) {
isNewRouteSameAsCurrent = true;
}
return true;
});
if (isNewRouteSameAsCurrent) {
navigatorKeyF.currentState!.pushNamed(WebViewF.path, arguments: payload);
navigatorKey.currentState!.pushNamed(WebViewF.path, arguments: payload);
return;
}
navigatorKeyF.currentState!.pushNamed(WebViewF.path, arguments: payload);
navigatorKey.currentState!.pushNamed(WebViewF.path, arguments: payload);
} else {
if (payload != null) {
InitFromPush.setPayload(payload);
Expand Down
6 changes: 2 additions & 4 deletions lib/flavored/util/router.f.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:humhub/flavored/web_view.f.dart';
import 'package:humhub/util/const.dart';

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

NavigatorState? get navigator => navigatorKeyF.currentState;
NavigatorState? get navigator => navigatorKey.currentState;

class RouterF {
static String? initRoute = WebViewF.path;
Expand Down
6 changes: 3 additions & 3 deletions lib/flavored/web_view.f.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:humhub/app_flavored.dart';
import 'package:humhub/flavored/models/humhub.f.dart';
import 'package:humhub/flavored/util/router.f.dart';
import 'package:humhub/util/auth_in_app_browser.dart';
import 'package:humhub/models/channel_message.dart';
import 'package:humhub/util/const.dart';
import 'package:humhub/util/extensions.dart';
import 'package:humhub/util/loading_provider.dart';
import 'package:humhub/util/notifications/init_from_push.dart';
Expand Down Expand Up @@ -279,7 +279,7 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
downloadStartRequest: downloadStartRequest,
controller: controller,
onSuccess: (File file, String filename) {
scaffoldMessengerStateKeyF.currentState?.showSnackBar(
scaffoldMessengerStateKey.currentState?.showSnackBar(
SnackBar(
content: Text('${AppLocalizations.of(context)!.file_download}: $filename'),
action: SnackBarAction(
Expand All @@ -293,7 +293,7 @@ class FlavoredWebViewState extends ConsumerState<WebViewF> {
);
},
onError: (er) {
scaffoldMessengerStateKeyF.currentState?.showSnackBar(
scaffoldMessengerStateKey.currentState?.showSnackBar(
SnackBar(
content: Text(AppLocalizations.of(context)!.generic_error),
),
Expand Down
3 changes: 3 additions & 0 deletions lib/l10n/app_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
"file_download": "Datei heruntergeladen",
"generic_error": "Uups! Etwas ist schiefgelaufen.",

"enable_permissions": "Berechtigungen aktivieren.",

"settings": "Einstellungen",
"connect": "Verbinden",
"open": "Öffnen",
"cancel": "Abbrechen",
Expand Down
3 changes: 3 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"file_download": "File downloaded",
"generic_error": "Oops! Something went wrong.",

"enable_permissions": "Enable permissions.",

"settings": "Settings",
"connect": "Connect",
"open": "Open",
"cancel" : "Cancel",
Expand Down
3 changes: 3 additions & 0 deletions lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
"file_download": "Fichier téléchargé",
"generic_error": "Oups ! Quelque chose s'est mal passé.",

"enable_permissions": "Activer les autorisations.",

"settings": "Paramètres",
"connect": "Connecter",
"open": "Ouvrir",
"cancel": "Annuler",
Expand Down
1 change: 1 addition & 0 deletions lib/pages/web_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'package:humhub/models/hum_hub.dart';
import 'package:humhub/models/manifest.dart';
import 'package:humhub/pages/opener.dart';
import 'package:humhub/util/connectivity_plugin.dart';
import 'package:humhub/util/const.dart';
import 'package:humhub/util/extensions.dart';
import 'package:humhub/util/file_handler.dart';
import 'package:humhub/util/loading_provider.dart';
Expand Down
3 changes: 3 additions & 0 deletions lib/util/const.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import 'package:flutter/material.dart';

final GlobalKey<ScaffoldMessengerState> scaffoldMessengerStateKey = GlobalKey<ScaffoldMessengerState>();
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

class StorageKeys {
static String humhubInstance = "humHubInstance";
static String lastInstanceUrl = "humHubLastUrl";
Expand Down
15 changes: 12 additions & 3 deletions lib/util/file_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import 'dart:convert';
import 'dart:io';

import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:humhub/util/permission_handler.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

class FileHandler {
final InAppWebViewController controller;
Expand Down Expand Up @@ -41,7 +43,14 @@ class FileHandler {
this.onError,
});

download() async {
download() {
PermissionHandler.runWithPermissionCheck(
permissions: [Permission.storage],
action: () => _download(),
);
}

_download() async {
try {
await controller.evaluateJavascript(source: _jsCode);
await controller.evaluateJavascript(source: "downloadFile('${downloadStartRequest.url.toString()}');");
Expand Down Expand Up @@ -109,15 +118,15 @@ class FileHandler {
Directory? directory;

if (Platform.isIOS) {
directory = await getDownloadsDirectory();
directory = await getApplicationDocumentsDirectory();
} else {
String check = "/storage/emulated/0/Download";

bool dirDownloadExists = await Directory(check).exists();
if (dirDownloadExists) {
directory = Directory(check);
} else {
directory = await getExternalStorageDirectory();
directory = await getApplicationDocumentsDirectory();
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/util/intent/intent_plugin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:humhub/pages/web_view.dart';
import 'package:humhub/util/const.dart';
import 'package:humhub/util/loading_provider.dart';
import 'package:humhub/util/router.dart';
import 'package:humhub/util/openers/universal_opener_controller.dart';
import 'package:loggy/loggy.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/util/notifications/channel.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:humhub/flavored/util/notifications/channel.dart';
import 'package:humhub/pages/web_view.dart';
import 'package:humhub/util/const.dart';
import 'package:humhub/util/notifications/init_from_push.dart';
import 'package:humhub/util/openers/universal_opener_controller.dart';
import 'package:humhub/util/router.dart';
import 'package:package_info_plus/package_info_plus.dart';

class NotificationChannel {
Expand Down
62 changes: 62 additions & 0 deletions lib/util/permission_handler.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:humhub/util/const.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

class PermissionHandler {
// Static method that takes a list of permissions and handles requests
static Future<void> requestPermissions(List<Permission> permissions) async {
for (Permission permission in permissions) {
// Check the current status of the permission
PermissionStatus status = await permission.status;

// Only request the permission if it has never been asked or is not granted
if (status.isDenied || status.isRestricted || status.isPermanentlyDenied) {
continue; // Don't request again if it's denied or restricted
}

// Request the permission if not granted
if (!status.isGranted) {
await permission.request();
}
}
}

// Static method to check permissions before executing a function
static Future<void> runWithPermissionCheck({
required List<Permission> permissions,
required Function action,
}) async {
bool allPermissionsGranted = true;

for (Permission permission in permissions) {
PermissionStatus status = await permission.status;
if (!status.isGranted) {
allPermissionsGranted = false;
break;
}
}

if (allPermissionsGranted || Platform.isIOS) {
// All permissions are granted, run the provided action
action();
} else {
// Show a SnackBar indicating that permissions are missing
if(navigatorKey.currentState != null && navigatorKey.currentState!.mounted){
scaffoldMessengerStateKey.currentState?.showSnackBar(
SnackBar(
content: Text(AppLocalizations.of(navigatorKey.currentState!.context)!.enable_permissions),
action: SnackBarAction(
label: AppLocalizations.of(navigatorKey.currentState!.context)!.settings,
onPressed: () {
openAppSettings();
},
),
),
);
}
}
}
}
Loading

0 comments on commit 05654be

Please sign in to comment.