1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-26 10:50:29 +02:00

fix(mobile): check and request permissions when saving files to prevent hard crash

This commit is contained in:
Daniel Hurd 2024-12-25 17:01:30 +13:00
parent ef0070c3fd
commit 371ab39331
2 changed files with 56 additions and 2 deletions

View File

@ -141,7 +141,7 @@ class DownloadStateNotifier extends StateNotifier<DownloadState> {
}
void downloadAsset(Asset asset, BuildContext context) async {
await _downloadService.download(asset);
await _downloadService.download(asset, context: context);
}
void cancelDownload(String id) async {

View File

@ -13,6 +13,9 @@ import 'package:immich_mobile/repositories/file_media.repository.dart';
import 'package:immich_mobile/services/api.service.dart';
import 'package:immich_mobile/utils/download.dart';
import 'package:logging/logging.dart';
import 'package:permission_handler/permission_handler.dart' as ph;
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
final downloadServiceProvider = Provider(
(ref) => DownloadService(
@ -158,7 +161,11 @@ class DownloadService {
return await FileDownloader().cancelTaskWithId(id);
}
Future<void> download(Asset asset) async {
Future<void> download(Asset asset, {BuildContext? context}) async {
if (!await _handlePermission(context)) {
return;
}
if (asset.isImage && asset.livePhotoVideoId != null && Platform.isIOS) {
await _downloadRepository.download(
_buildDownloadTask(
@ -196,6 +203,53 @@ class DownloadService {
}
}
Future<bool> _handlePermission(BuildContext? context) async {
final permission = await ph.Permission.photos.status;
if (permission.isDenied || permission.isPermanentlyDenied) {
if (context == null) return false;
final bool? shouldRequest = await showDialog<bool>(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('permission_onboarding_request').tr(),
content: const Text('permission_onboarding_permission_denied').tr(),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text('cancel').tr(),
),
TextButton(
onPressed: () => Navigator.pop(context, true),
child: Text(
permission.isPermanentlyDenied
? 'permission_onboarding_go_to_settings'
: 'permission_onboarding_grant_permission',
).tr(),
),
],
);
},
);
if (shouldRequest == true) {
if (permission.isPermanentlyDenied) {
await ph.openAppSettings();
return false;
}
final result = await ph.Permission.photos.request();
if (!result.isGranted) {
return false;
}
} else {
return false;
}
}
return true;
}
DownloadTask _buildDownloadTask(
String id,
String filename, {