[mob] Refactor permission related logic (#5239)

## Description

## Tests
This commit is contained in:
Neeraj
2025-03-06 16:14:10 +05:30
committed by GitHub
12 changed files with 146 additions and 129 deletions

View File

@@ -437,81 +437,81 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/wakelock_plus/ios"
SPEC CHECKSUMS:
background_fetch: 94b36ee293e82972852dba8ede1fbcd3bd3d9d57
battery_info: 83f3aae7be2fccefab1d2bf06b8aa96f11c8bcdd
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
cupertino_http: 94ac07f5ff090b8effa6c5e2c47871d48ab7c86c
dart_ui_isolate: 46f6714abe6891313267153ef6f9748d8ecfcab1
device_info_plus: 335f3ce08d2e174b9fdc3db3db0f4e3b1f66bd89
background_fetch: 39f11371c0dce04b001c4bfd5e782bcccb0a85e2
battery_info: b6c551049266af31556b93c9d9b9452cfec0219f
connectivity_plus: 2a701ffec2c0ae28a48cf7540e279787e77c447d
cupertino_http: 947a233f40cfea55167a49f2facc18434ea117ba
dart_ui_isolate: d5bcda83ca4b04f129d70eb90110b7a567aece14
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
ffmpeg-kit-ios-full-gpl: 80adc341962e55ef709e36baa8ed9a70cf4ea62b
ffmpeg_kit_flutter_full_gpl: ce18b888487c05c46ed252cd2e7956812f2e3bd1
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
ffmpeg_kit_flutter_full_gpl: 8d15c14c0c3aba616fac04fe44b3d27d02e3c330
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
Firebase: d80354ed7f6df5f9aca55e9eb47cc4b634735eaf
firebase_core: 6cbed78b4f298ed103a9fd034e6dbc846320480f
firebase_messaging: 5e0adf2eb18b0ee59aa0c109314c091a0497ecac
firebase_core: 6e223dfa350b2edceb729cea505eaaef59330682
firebase_messaging: 07fde77ae28c08616a1d4d870450efc2b38cf40d
FirebaseCore: 99fe0c4b44a39f37d99e6404e02009d2db5d718d
FirebaseCoreInternal: df24ce5af28864660ecbd13596fc8dd3a8c34629
FirebaseInstallations: 6c963bd2a86aca0481eef4f48f5a4df783ae5917
FirebaseMessaging: 487b634ccdf6f7b7ff180fdcb2a9935490f764e8
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_email_sender: aa1e9772696691d02cd91fea829856c11efb8e58
flutter_image_compress_common: 1697a328fd72bfb335507c6bca1a65fa5ad87df1
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
flutter_local_notifications: ad39620c743ea4c15127860f4b5641649a988100
flutter_native_splash: 6cad9122ea0fad137d23137dd14b937f3e90b145
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
flutter_sodium: 7e4621538491834eba53bd524547854bcbbd6987
fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
flutter_email_sender: e03bdda7637bcd3539bfe718fddd980e9508efaa
flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e
flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
flutter_native_splash: f71420956eb811e6d310720fee915f1d42852e7a
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
flutter_sodium: a00383520fc689c688b66fd3092984174712493e
fluttertoast: 21eecd6935e7064cc1fcb733a4c5a428f3f24f0f
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
home_widget: f169fc41fd807b4d46ab6615dc44d62adbf9f64f
image_editor_common: 3de87e7c4804f4ae24c8f8a998362b98c105cac1
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
in_app_purchase_storekit: d1a48cb0f8b29dbf5f85f782f5dd79b21b90a5e6
integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e
home_widget: 0434835a4c9a75704264feff6be17ea40e0f0d57
image_editor_common: d6f6644ae4a6de80481e89fe6d0a8c49e30b4b43
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
in_app_purchase_storekit: a1ce04056e23eecc666b086040239da7619cd783
integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
local_auth_ios: f7a1841beef3151d140a967c2e46f30637cdf451
local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3
local_auth_ios: 5046a18c018dd973247a0564496c8898dbb5adf9
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
maps_launcher: edf829809ba9e894d70e569bab11c16352dedb45
media_extension: 671e2567880d96c95c65c9a82ccceed8f2e309fd
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
motion_sensors: 741e702c17467b9569a92165dda8d4d88c6167f1
motionphoto: 23e2aeb5c6380112f69468d71f970fa7438e5ed1
move_to_background: 7e3467dd2a1d1013e98c9c1cb93fd53cd7ef9d84
maps_launcher: 2e5b6a2d664ec6c27f82ffa81b74228d770ab203
media_extension: 6618f07abd762cdbfaadf1b0c56a287e820f0c84
media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1
media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e
motion_sensors: 03f55b7c637a7e365a0b5f9697a449f9059d5d91
motionphoto: 8b65ce50c7d7ff3c767534fc3768b2eed9ac24e4
move_to_background: cd3091014529ec7829e342ad2d75c0a11f4378a5
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
native_video_player: e363dd14f6a498ad8a8f7e6486a0db046ad19f13
objective_c: 89e720c30d716b036faf9c9684022048eee1eee2
onnxruntime: f9b296392c96c42882be020a59dbeac6310d81b2
native_video_player: 5d36066807b680e181473e6890dde643ac85380d
objective_c: 77e887b5ba1827970907e10e832eec1683f3431d
onnxruntime: e7c2ae44385191eaad5ae64c935a72debaddc997
onnxruntime-c: a909204639a1f035f575127ac406f781ac797c9c
onnxruntime-objc: b6fab0f1787aa6f7190c2013f03037df4718bd8b
open_mail_app: 7314a609e88eed22d53671279e189af7a0ab0f11
open_mail_app: 70273c53f768beefdafbe310c3d9086e4da3cb02
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
photo_manager: d2fbcc0f2d82458700ee6256a15018210a81d413
privacy_screen: 3159a541f5d3a31bea916cfd4e58f9dc722b3fd4
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
photo_manager: ff695c7a1dd5bc379974953a2b5c0a293f7c4c8a
privacy_screen: 1a131c052ceb3c3659934b003b0d397c2381a24e
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
receive_sharing_intent: 79c848f5b045674ad60b9fea3bafea59962ad2c1
SDWebImage: f84b0feeb08d2d11e6a9b843cb06d75ebf5b8868
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
Sentry: 0f9bc9adfc0b960e7f3bb5ec67e9a3d8193f3bdb
sentry_flutter: f4a0466dc8855998ffd59378ec33507c7dc32d7b
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
sentry_flutter: 64a43fb39ab4c7f67d8a4cad52b49e22439e58b7
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
sqlite3: fc1400008a9b3525f5914ed715a5d1af0b8f4983
sqlite3_flutter_libs: 3c323550ef3b928bc0aa9513c841e45a7d242832
system_info_plus: 555ce7047fbbf29154726db942ae785c29211740
ua_client_hints: 92fe0d139619b73ec9fcb46cc7e079a26178f586
uni_links: f191d616c4db8750f74c72c988e79a83dd297fac
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b
video_thumbnail: 584ccfa55d8fd2f3d5507218b0a18d84c839c620
volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12
wakelock_plus: 04623e3f525556020ebd4034310f20fe7fda8b49
sqlite3_flutter_libs: 069c435986dd4b63461aecd68f4b30be4a9e9daa
system_info_plus: 5393c8da281d899950d751713575fbf91c7709aa
ua_client_hints: aeabd123262c087f0ce151ef96fa3ab77bfc8b38
uni_links: 103d3319e3383ed8bce559b96b1e219fbf02ba96
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
video_thumbnail: 94ba6705afbaa120b77287080424930f23ea0c40
volume_controller: 2e3de73d6e7e81a0067310d17fb70f2f86d71ac7
wakelock_plus: 373cfe59b235a6dd5837d0fb88791d2f13a90d56
PODFILE CHECKSUM: 20e086e6008977d43a3d40260f3f9bffcac748dd

View File

@@ -11,6 +11,7 @@ import "package:photos/services/machine_learning/face_ml/face_recognition_servic
import "package:photos/services/machine_learning/machine_learning_controller.dart";
import "package:photos/services/magic_cache_service.dart";
import "package:photos/services/memories_cache_service.dart";
import "package:photos/services/permission/service.dart";
import "package:photos/services/smart_memories_service.dart";
import "package:photos/services/storage_bonus_service.dart";
import "package:photos/services/sync/trash_sync_service.dart";
@@ -143,3 +144,9 @@ FaceRecognitionService get faceRecognitionService {
_faceRecognitionService ??= FaceRecognitionService();
return _faceRecognitionService!;
}
PermissionService? _permissionService;
PermissionService get permissionService {
_permissionService ??= PermissionService(ServiceLocator.instance.prefs);
return _permissionService!;
}

View File

@@ -0,0 +1,38 @@
import "package:photo_manager/photo_manager.dart";
import "package:shared_preferences/shared_preferences.dart";
class PermissionService {
static const kHasGrantedPermissionsKey = "has_granted_permissions";
static const kPermissionStateKey = "permission_state";
final SharedPreferences _prefs;
PermissionService(this._prefs);
Future<PermissionState> requestPhotoMangerPermissions() {
return PhotoManager.requestPermissionExtend(
requestOption: const PermissionRequestOption(
androidPermission: AndroidPermission(
type: RequestType.common,
mediaLocation: true,
),
),
);
}
bool hasGrantedPermissions() {
return _prefs.getBool(kHasGrantedPermissionsKey) ?? false;
}
bool hasGrantedLimitedPermissions() {
return _prefs.getString(kPermissionStateKey) ==
PermissionState.limited.toString();
}
bool hasGrantedFullPermission() {
return (_prefs.getString(kPermissionStateKey) ?? '') ==
PermissionState.authorized.toString();
}
Future<void> onUpdatePermission(PermissionState state) async {
await _prefs.setBool(kHasGrantedPermissionsKey, true);
await _prefs.setString(kPermissionStateKey, state.toString());
}
}

View File

@@ -13,14 +13,15 @@ import 'package:photos/db/file_updation_db.dart';
import 'package:photos/db/files_db.dart';
import 'package:photos/events/backup_folders_updated_event.dart';
import 'package:photos/events/local_photos_updated_event.dart';
import "package:photos/events/permission_granted_event.dart";
import 'package:photos/events/sync_status_update_event.dart';
import 'package:photos/extensions/stop_watch.dart';
import 'package:photos/models/file/file.dart';
import "package:photos/models/ignored_file.dart";
import "package:photos/service_locator.dart";
import 'package:photos/services/app_lifecycle_service.dart';
import "package:photos/services/ignored_files_service.dart";
import 'package:photos/services/local/local_sync_util.dart';
import "package:photos/utils/photo_manager_util.dart";
import "package:photos/utils/standalone/debouncer.dart";
import 'package:shared_preferences/shared_preferences.dart';
import 'package:synchronized/synchronized.dart';
@@ -36,8 +37,6 @@ class LocalSyncService {
static const kDbUpdationTimeKey = "db_updation_time";
static const kHasCompletedFirstImportKey = "has_completed_firstImport";
static const kHasGrantedPermissionsKey = "has_granted_permissions";
static const kPermissionStateKey = "permission_state";
LocalSyncService._privateConstructor();
@@ -49,18 +48,23 @@ class LocalSyncService {
if (!AppLifecycleService.instance.isForeground) {
await PhotoManager.setIgnorePermissionCheck(true);
}
if (hasGrantedPermissions()) {
if (permissionService.hasGrantedPermissions()) {
_registerChangeCallback();
} else {
Bus.instance.on<PermissionGrantedEvent>().listen((event) async {
_registerChangeCallback();
});
}
}
Future<void> sync() async {
if (!_prefs.containsKey(kHasGrantedPermissionsKey)) {
if (!permissionService.hasGrantedPermissions()) {
_logger.info("Skipping local sync since permission has not been granted");
return;
}
if (Platform.isAndroid && AppLifecycleService.instance.isForeground) {
final permissionState = await requestPhotoMangerPermissions();
final permissionState =
await permissionService.requestPhotoMangerPermissions();
if (permissionState != PermissionState.authorized) {
_logger.severe(
"sync requested with invalid permission",
@@ -237,36 +241,6 @@ class LocalSyncService {
return _lock;
}
bool hasGrantedPermissions() {
return _prefs.getBool(kHasGrantedPermissionsKey) ?? false;
}
bool hasGrantedLimitedPermissions() {
return _prefs.getString(kPermissionStateKey) ==
PermissionState.limited.toString();
}
bool hasGrantedFullPermission() {
return (_prefs.getString(kPermissionStateKey) ?? '') ==
PermissionState.authorized.toString();
}
Future<void> onUpdatePermission(PermissionState state) async {
await _prefs.setBool(kHasGrantedPermissionsKey, true);
await _prefs.setString(kPermissionStateKey, state.toString());
}
Future<void> onPermissionGranted(PermissionState state) async {
await _prefs.setBool(kHasGrantedPermissionsKey, true);
await _prefs.setString(kPermissionStateKey, state.toString());
if (state == PermissionState.limited) {
// when limited permission is granted, by default mark all folders for
// backup
await Configuration.instance.setSelectAllFoldersForBackup(true);
}
_registerChangeCallback();
}
bool hasCompletedFirstImport() {
return _prefs.getBool(kHasCompletedFirstImportKey) ?? false;
}
@@ -365,7 +339,7 @@ class LocalSyncService {
if (_existingSync != null) {
await _existingSync!.future;
}
if (hasGrantedLimitedPermissions()) {
if (permissionService.hasGrantedLimitedPermissions()) {
unawaited(syncAll());
} else {
unawaited(sync().then((value) => _refreshDeviceFolderCountAndCover()));

View File

@@ -9,7 +9,6 @@ import 'package:photos/core/configuration.dart';
import 'package:photos/core/constants.dart';
import 'package:photos/core/errors.dart';
import 'package:photos/core/event_bus.dart';
import 'package:photos/events/permission_granted_event.dart';
import 'package:photos/events/subscription_purchased_event.dart';
import 'package:photos/events/sync_status_update_event.dart';
import 'package:photos/events/trigger_logout_event.dart';
@@ -169,10 +168,7 @@ class SyncService {
return _lastSyncStatusEvent;
}
Future<void> onPermissionGranted(PermissionState state) async {
_logger.info("Permission granted " + state.toString());
await _localSyncService.onPermissionGranted(state);
Bus.instance.fire(PermissionGrantedEvent());
Future<void> onPermissionGranted() async {
_doSync().ignore();
}

View File

@@ -5,13 +5,11 @@ import 'package:flutter/material.dart';
import "package:logging/logging.dart";
import "package:photo_manager/photo_manager.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/services/sync/local_sync_service.dart";
import "package:photos/service_locator.dart";
import 'package:photos/ui/components/buttons/icon_button_widget.dart';
import "package:photos/ui/settings/backup/backup_folder_selection_page.dart";
import "package:photos/utils/dialog_util.dart";
import "package:photos/utils/navigation_util.dart";
import "package:photos/utils/photo_manager_util.dart";
class HomeHeaderWidget extends StatefulWidget {
final Widget centerWidget;
const HomeHeaderWidget({required this.centerWidget, super.key});
@@ -48,20 +46,20 @@ class _HomeHeaderWidgetState extends State<HomeHeaderWidget> {
onTap: () async {
try {
final PermissionState state =
await requestPhotoMangerPermissions();
await LocalSyncService.instance.onUpdatePermission(state);
await permissionService.requestPhotoMangerPermissions();
await permissionService.onUpdatePermission(state);
} on Exception catch (e) {
Logger("HomeHeaderWidget").severe(
"Failed to request permission: ${e.toString()}",
e,
);
}
if (!LocalSyncService.instance.hasGrantedFullPermission()) {
if (!permissionService.hasGrantedFullPermission()) {
if (Platform.isAndroid) {
await PhotoManager.openSetting();
} else {
final bool hasGrantedLimit =
LocalSyncService.instance.hasGrantedLimitedPermissions();
permissionService.hasGrantedLimitedPermissions();
// ignore: unawaited_futures
showChoiceActionSheet(
context,

View File

@@ -4,12 +4,15 @@ import 'dart:io';
import 'package:flutter/material.dart';
import "package:logging/logging.dart";
import 'package:photo_manager/photo_manager.dart';
import "package:photos/core/configuration.dart";
import "package:photos/core/event_bus.dart";
import "package:photos/events/permission_granted_event.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/l10n/l10n.dart";
import "package:photos/service_locator.dart";
import 'package:photos/services/sync/sync_service.dart';
import "package:photos/theme/ente_theme.dart";
import "package:photos/utils/dialog_util.dart";
import "package:photos/utils/photo_manager_util.dart";
import "package:styled_text/styled_text.dart";
class GrantPermissionsWidget extends StatefulWidget {
@@ -106,11 +109,12 @@ class _GrantPermissionsWidgetState extends State<GrantPermissionsWidget> {
child: Text(S.of(context).grantPermission),
onPressed: () async {
try {
final state = await requestPhotoMangerPermissions();
final state =
await permissionService.requestPhotoMangerPermissions();
_logger.info("Permission state: $state");
if (state == PermissionState.authorized ||
state == PermissionState.limited) {
await SyncService.instance.onPermissionGranted(state);
await onPermissionGranted(state);
} else if (state == PermissionState.denied) {
await showChoiceDialog(
context,
@@ -139,4 +143,16 @@ class _GrantPermissionsWidgetState extends State<GrantPermissionsWidget> {
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
Future<void> onPermissionGranted(PermissionState state) async {
_logger.info("Permission granted " + state.toString());
await permissionService.onUpdatePermission(state);
if (state == PermissionState.limited) {
// when limited permission is granted, by default mark all folders for
// backup
await Configuration.instance.setSelectAllFoldersForBackup(true);
}
SyncService.instance.onPermissionGranted().ignore();
Bus.instance.fire(PermissionGrantedEvent());
}
}

View File

@@ -7,7 +7,7 @@ import 'package:photos/ente_theme_data.dart';
import 'package:photos/events/local_import_progress.dart';
import 'package:photos/events/sync_status_update_event.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/services/sync/local_sync_service.dart';
import "package:photos/service_locator.dart";
import 'package:photos/ui/common/bottom_shadow.dart';
import "package:photos/ui/components/buttons/button_widget.dart";
import "package:photos/ui/components/dialog_widget.dart";
@@ -44,7 +44,7 @@ class _LoadingPhotosWidgetState extends State<LoadingPhotosWidget> {
_firstImportEvent =
Bus.instance.on<SyncStatusUpdate>().listen((event) async {
if (mounted && event.status == SyncStatus.completedFirstGalleryImport) {
if (LocalSyncService.instance.hasGrantedLimitedPermissions()) {
if (permissionService.hasGrantedLimitedPermissions()) {
// Do nothing, let HomeWidget refresh
} else {
// ignore: unawaited_futures

View File

@@ -3,7 +3,7 @@ import "dart:async";
import 'package:flutter/material.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:photos/generated/l10n.dart';
import 'package:photos/services/sync/local_sync_service.dart';
import "package:photos/service_locator.dart";
import 'package:photos/ui/common/gradient_button.dart';
import 'package:photos/ui/settings/backup/backup_folder_selection_page.dart';
import 'package:photos/utils/navigation_util.dart';
@@ -42,8 +42,7 @@ class StartBackupHookWidget extends StatelessWidget {
padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
child: GradientButton(
onTap: () async {
if (LocalSyncService.instance
.hasGrantedLimitedPermissions()) {
if (permissionService.hasGrantedLimitedPermissions()) {
unawaited(PhotoManager.presentLimited());
} else {
// ignore: unawaited_futures

View File

@@ -176,7 +176,7 @@ class _HomeWidgetState extends State<HomeWidget> {
// Loading page will redirect to BackupFolderSelectionPage.
// To avoid showing folder hook in middle during routing,
// delay state refresh for home page
if (!LocalSyncService.instance.hasGrantedLimitedPermissions()) {
if (!permissionService.hasGrantedLimitedPermissions()) {
delayInRefresh = const Duration(milliseconds: 250);
}
Future.delayed(
@@ -643,7 +643,7 @@ class _HomeWidgetState extends State<HomeWidget> {
_closeDrawerIfOpen(context);
return const LandingPageWidget();
}
if (!LocalSyncService.instance.hasGrantedPermissions()) {
if (!permissionService.hasGrantedPermissions()) {
entityService.syncEntities().then((_) {
PersonService.instance.resetEmailToPartialPersonDataCache();
});
@@ -671,7 +671,7 @@ class _HomeWidgetState extends State<HomeWidget> {
_showShowBackupHook =
!Configuration.instance.hasSelectedAnyBackupFolder() &&
!LocalSyncService.instance.hasGrantedLimitedPermissions() &&
!permissionService.hasGrantedLimitedPermissions() &&
CollectionsService.instance.getActiveCollections().isEmpty;
return Stack(

View File

@@ -11,6 +11,7 @@ import "package:photos/generated/l10n.dart";
import "package:photos/l10n/l10n.dart";
import 'package:photos/models/collection/collection.dart';
import "package:photos/models/selected_files.dart";
import "package:photos/service_locator.dart";
import "package:photos/services/collections_service.dart";
import "package:photos/services/filter/db_filters.dart";
import "package:photos/theme/colors.dart";
@@ -25,7 +26,6 @@ import "package:photos/ui/components/title_bar_title_widget.dart";
import "package:photos/ui/viewer/gallery/gallery.dart";
import "package:photos/ui/viewer/gallery/state/gallery_files_inherited_widget.dart";
import "package:photos/utils/dialog_util.dart";
import "package:photos/utils/photo_manager_util.dart";
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
Future<dynamic> showAddPhotosSheet(
@@ -191,7 +191,8 @@ class AddPhotosPhotoWidget extends StatelessWidget {
}
} catch (e) {
if (e is StateError) {
final PermissionState ps = await requestPhotoMangerPermissions();
final PermissionState ps =
await permissionService.requestPhotoMangerPermissions();
if (ps != PermissionState.authorized && ps != PermissionState.limited) {
await showChoiceDialog(
context,

View File

@@ -1,12 +0,0 @@
import "package:photo_manager/photo_manager.dart";
Future<PermissionState> requestPhotoMangerPermissions() {
return PhotoManager.requestPermissionExtend(
requestOption: const PermissionRequestOption(
androidPermission: AndroidPermission(
type: RequestType.common,
mediaLocation: true,
),
),
);
}