feat: full local assets / album sync

This commit is contained in:
shenlong-tanwen
2024-10-17 23:33:00 +05:30
parent a09710ec7b
commit c91a2878dc
87 changed files with 2417 additions and 366 deletions
@@ -0,0 +1,8 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:immich_mobile/domain/models/user.model.dart';
class CurrentUserCubit extends Cubit<User> {
CurrentUserCubit(super.initialState);
void updateUser(User user) => emit(user);
}
@@ -0,0 +1,123 @@
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:permission_handler/permission_handler.dart';
enum GalleryPermissionStatus {
yetToRequest,
granted,
limited,
denied,
permanentlyDenied;
bool get isGranted => this == GalleryPermissionStatus.granted;
bool get isLimited => this == GalleryPermissionStatus.limited;
}
class GalleryPermissionNotifier extends ValueNotifier<GalleryPermissionStatus> {
GalleryPermissionNotifier() : super(GalleryPermissionStatus.yetToRequest) {
checkPermission();
}
bool get hasPermission => value.isGranted || value.isLimited;
/// Requests the gallery permission
Future<GalleryPermissionStatus> requestPermission() async {
PermissionStatus result;
// Android 32 and below uses Permission.storage
if (Platform.isAndroid) {
final androidInfo = await DeviceInfoPlugin().androidInfo;
if (androidInfo.version.sdkInt <= 32) {
// Android 32 and below need storage
final permission = await Permission.storage.request();
result = permission;
} else {
// Android 33 need photo & video
final photos = await Permission.photos.request();
if (!photos.isGranted) {
final state = _toGalleryPermissionStatus(photos);
// Don't ask twice for the same permission
value = state;
return state;
}
final videos = await Permission.videos.request();
// Return the joint result of those two permissions
if ((photos.isGranted && videos.isGranted) ||
(photos.isLimited && videos.isLimited)) {
result = PermissionStatus.granted;
} else if (photos.isDenied || videos.isDenied) {
result = PermissionStatus.denied;
} else if (photos.isPermanentlyDenied || videos.isPermanentlyDenied) {
result = PermissionStatus.permanentlyDenied;
} else {
result = PermissionStatus.denied;
}
}
if (result == PermissionStatus.granted &&
androidInfo.version.sdkInt >= 29) {
result = await Permission.accessMediaLocation.request();
}
} else {
// iOS can use photos
result = await Permission.photos.request();
}
value = _toGalleryPermissionStatus(result);
return value;
}
/// Checks the current state of the gallery permissions without
/// requesting them again
Future<GalleryPermissionStatus> checkPermission() async {
PermissionStatus result;
// Android 32 and below uses Permission.storage
if (Platform.isAndroid) {
final androidInfo = await DeviceInfoPlugin().androidInfo;
if (androidInfo.version.sdkInt <= 32) {
// Android 32 and below need storage
final permission = await Permission.storage.status;
result = permission;
} else {
// Android 33 needs photo & video
final photos = await Permission.photos.status;
final videos = await Permission.videos.status;
// Return the joint result of those two permissions
final PermissionStatus status;
if ((photos.isGranted && videos.isGranted) ||
(photos.isLimited && videos.isLimited)) {
status = PermissionStatus.granted;
} else if (photos.isDenied || videos.isDenied) {
status = PermissionStatus.denied;
} else if (photos.isPermanentlyDenied || videos.isPermanentlyDenied) {
status = PermissionStatus.permanentlyDenied;
} else {
status = PermissionStatus.denied;
}
result = status;
}
if (result == PermissionStatus.granted &&
androidInfo.version.sdkInt >= 29) {
result = await Permission.accessMediaLocation.status;
}
} else {
// iOS can use photos
result = await Permission.photos.status;
}
value = _toGalleryPermissionStatus(result);
return value;
}
}
GalleryPermissionStatus _toGalleryPermissionStatus(PermissionStatus status) =>
switch (status) {
PermissionStatus.granted => GalleryPermissionStatus.granted,
PermissionStatus.limited => GalleryPermissionStatus.limited,
PermissionStatus.denied => GalleryPermissionStatus.denied,
PermissionStatus.restricted ||
PermissionStatus.permanentlyDenied ||
PermissionStatus.provisional =>
GalleryPermissionStatus.permanentlyDenied,
};
@@ -0,0 +1,27 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:immich_mobile/domain/models/server-info/server_feature_config.model.dart';
import 'package:immich_mobile/domain/services/server_info.service.dart';
class ServerFeatureConfigCubit extends Cubit<ServerFeatureConfig> {
final ServerInfoService _serverInfoService;
ServerFeatureConfigCubit(this._serverInfoService)
: super(const ServerFeatureConfig.reset());
Future<void> getFeatures() async =>
await Future.wait([_getFeatures(), _getConfig()]);
Future<void> _getFeatures() async {
final features = await _serverInfoService.getServerFeatures();
if (features != null) {
emit(state.copyWith(features: features));
}
}
Future<void> _getConfig() async {
final config = await _serverInfoService.getServerConfig();
if (config != null) {
emit(state.copyWith(config: config));
}
}
}