chore: bump line length to 120 (#20191)
This commit is contained in:
@@ -11,9 +11,7 @@ part 'activity.provider.g.dart';
|
||||
class AlbumActivity extends _$AlbumActivity {
|
||||
@override
|
||||
Future<List<Activity>> build(String albumId, [String? assetId]) async {
|
||||
return ref
|
||||
.watch(activityServiceProvider)
|
||||
.getAllActivities(albumId, assetId: assetId);
|
||||
return ref.watch(activityServiceProvider).getAllActivities(albumId, assetId: assetId);
|
||||
}
|
||||
|
||||
Future<void> removeActivity(String id) async {
|
||||
@@ -24,17 +22,13 @@ class AlbumActivity extends _$AlbumActivity {
|
||||
state = AsyncData(activities);
|
||||
// Decrement activity count only for comments
|
||||
if (removedActivity.type == ActivityType.comment) {
|
||||
ref
|
||||
.watch(activityStatisticsProvider(albumId, assetId).notifier)
|
||||
.removeActivity();
|
||||
ref.watch(activityStatisticsProvider(albumId, assetId).notifier).removeActivity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> addLike() async {
|
||||
final activity = await ref
|
||||
.watch(activityServiceProvider)
|
||||
.addActivity(albumId, ActivityType.like, assetId: assetId);
|
||||
final activity = await ref.watch(activityServiceProvider).addActivity(albumId, ActivityType.like, assetId: assetId);
|
||||
if (activity.hasValue) {
|
||||
final activities = state.asData?.value ?? [];
|
||||
state = AsyncData([...activities, activity.requireValue]);
|
||||
@@ -52,9 +46,7 @@ class AlbumActivity extends _$AlbumActivity {
|
||||
if (activity.hasValue) {
|
||||
final activities = state.valueOrNull ?? [];
|
||||
state = AsyncData([...activities, activity.requireValue]);
|
||||
ref
|
||||
.watch(activityStatisticsProvider(albumId, assetId).notifier)
|
||||
.addActivity();
|
||||
ref.watch(activityStatisticsProvider(albumId, assetId).notifier).addActivity();
|
||||
// The previous addActivity call would increase the count of an asset if assetId != null
|
||||
// To also increase the activity count of the album, calling it once again with assetId set to null
|
||||
if (assetId != null) {
|
||||
|
||||
@@ -6,5 +6,4 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'activity_service.provider.g.dart';
|
||||
|
||||
@riverpod
|
||||
ActivityService activityService(Ref ref) =>
|
||||
ActivityService(ref.watch(activityApiRepositoryProvider));
|
||||
ActivityService activityService(Ref ref) => ActivityService(ref.watch(activityApiRepositoryProvider));
|
||||
|
||||
@@ -9,10 +9,7 @@ part 'activity_statistics.provider.g.dart';
|
||||
class ActivityStatistics extends _$ActivityStatistics {
|
||||
@override
|
||||
int build(String albumId, [String? assetId]) {
|
||||
ref
|
||||
.watch(activityServiceProvider)
|
||||
.getStatistics(albumId, assetId: assetId)
|
||||
.then((stats) => state = stats.comments);
|
||||
ref.watch(activityServiceProvider).getStatistics(albumId, assetId: assetId).then((stats) => state = stats.comments);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@ class AlbumNotifier extends StateNotifier<List<Album>> {
|
||||
}
|
||||
});
|
||||
|
||||
_streamSub =
|
||||
albumService.watchRemoteAlbums().listen((data) => state = data);
|
||||
_streamSub = albumService.watchRemoteAlbums().listen((data) => state = data);
|
||||
}
|
||||
|
||||
final AlbumService albumService;
|
||||
@@ -114,8 +113,7 @@ class AlbumNotifier extends StateNotifier<List<Album>> {
|
||||
}
|
||||
|
||||
Future<Album?> toggleSortOrder(Album album) {
|
||||
final order =
|
||||
album.sortOrder == SortOrder.asc ? SortOrder.desc : SortOrder.asc;
|
||||
final order = album.sortOrder == SortOrder.asc ? SortOrder.desc : SortOrder.asc;
|
||||
|
||||
return albumService.updateSortOrder(album, order);
|
||||
}
|
||||
@@ -127,16 +125,14 @@ class AlbumNotifier extends StateNotifier<List<Album>> {
|
||||
}
|
||||
}
|
||||
|
||||
final albumProvider =
|
||||
StateNotifierProvider.autoDispose<AlbumNotifier, List<Album>>((ref) {
|
||||
final albumProvider = StateNotifierProvider.autoDispose<AlbumNotifier, List<Album>>((ref) {
|
||||
return AlbumNotifier(
|
||||
ref.watch(albumServiceProvider),
|
||||
ref,
|
||||
);
|
||||
});
|
||||
|
||||
final albumWatcher =
|
||||
StreamProvider.autoDispose.family<Album, int>((ref, id) async* {
|
||||
final albumWatcher = StreamProvider.autoDispose.family<Album, int>((ref, id) async* {
|
||||
final albumService = ref.watch(albumServiceProvider);
|
||||
|
||||
final album = await albumService.getAlbumById(id);
|
||||
@@ -172,7 +168,6 @@ class LocalAlbumsNotifier extends StateNotifier<List<Album>> {
|
||||
}
|
||||
}
|
||||
|
||||
final localAlbumsProvider =
|
||||
StateNotifierProvider.autoDispose<LocalAlbumsNotifier, List<Album>>((ref) {
|
||||
final localAlbumsProvider = StateNotifierProvider.autoDispose<LocalAlbumsNotifier, List<Album>>((ref) {
|
||||
return LocalAlbumsNotifier(ref.watch(albumServiceProvider));
|
||||
});
|
||||
|
||||
@@ -31,8 +31,7 @@ class _AlbumSortHandlers {
|
||||
|
||||
static const AlbumSortFn assetCount = _sortByAssetCount;
|
||||
static List<Album> _sortByAssetCount(List<Album> albums, bool isReverse) {
|
||||
final sorted =
|
||||
albums.sorted((a, b) => a.assetCount.compareTo(b.assetCount));
|
||||
final sorted = albums.sorted((a, b) => a.assetCount.compareTo(b.assetCount));
|
||||
return (isReverse ? sorted.reversed : sorted).toList();
|
||||
}
|
||||
|
||||
@@ -104,9 +103,7 @@ enum AlbumSortMode {
|
||||
class AlbumSortByOptions extends _$AlbumSortByOptions {
|
||||
@override
|
||||
AlbumSortMode build() {
|
||||
final sortOpt = ref
|
||||
.watch(appSettingsServiceProvider)
|
||||
.getSetting(AppSettingsEnum.selectedAlbumSortOrder);
|
||||
final sortOpt = ref.watch(appSettingsServiceProvider).getSetting(AppSettingsEnum.selectedAlbumSortOrder);
|
||||
return AlbumSortMode.values.firstWhere(
|
||||
(e) => e.storeIndex == sortOpt,
|
||||
orElse: () => AlbumSortMode.title,
|
||||
@@ -126,15 +123,11 @@ class AlbumSortByOptions extends _$AlbumSortByOptions {
|
||||
class AlbumSortOrder extends _$AlbumSortOrder {
|
||||
@override
|
||||
bool build() {
|
||||
return ref
|
||||
.watch(appSettingsServiceProvider)
|
||||
.getSetting(AppSettingsEnum.selectedAlbumSortReverse);
|
||||
return ref.watch(appSettingsServiceProvider).getSetting(AppSettingsEnum.selectedAlbumSortReverse);
|
||||
}
|
||||
|
||||
void changeSortDirection(bool isReverse) {
|
||||
state = isReverse;
|
||||
ref
|
||||
.watch(appSettingsServiceProvider)
|
||||
.setSetting(AppSettingsEnum.selectedAlbumSortReverse, isReverse);
|
||||
ref.watch(appSettingsServiceProvider).setSetting(AppSettingsEnum.selectedAlbumSortReverse, isReverse);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,6 @@ class AlbumViewerNotifier extends StateNotifier<AlbumViewerPageState> {
|
||||
}
|
||||
}
|
||||
|
||||
final albumViewerProvider =
|
||||
StateNotifierProvider<AlbumViewerNotifier, AlbumViewerPageState>((ref) {
|
||||
final albumViewerProvider = StateNotifierProvider<AlbumViewerNotifier, AlbumViewerPageState>((ref) {
|
||||
return AlbumViewerNotifier(ref);
|
||||
});
|
||||
|
||||
@@ -4,8 +4,7 @@ import 'package:immich_mobile/domain/services/user.service.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
|
||||
import 'package:immich_mobile/providers/user.provider.dart';
|
||||
|
||||
final otherUsersProvider =
|
||||
FutureProvider.autoDispose<List<UserDto>>((ref) async {
|
||||
final otherUsersProvider = FutureProvider.autoDispose<List<UserDto>>((ref) async {
|
||||
UserService userService = ref.watch(userServiceProvider);
|
||||
final currentUser = ref.watch(currentUserProvider);
|
||||
|
||||
|
||||
@@ -58,8 +58,7 @@ class AppLifeCycleNotifier extends StateNotifier<AppLifeCycleEnum> {
|
||||
// Needs to be logged in
|
||||
if (isAuthenticated) {
|
||||
// switch endpoint if needed
|
||||
final endpoint =
|
||||
await _ref.read(authProvider.notifier).setOpenApiServiceEndpoint();
|
||||
final endpoint = await _ref.read(authProvider.notifier).setOpenApiServiceEndpoint();
|
||||
if (kDebugMode) {
|
||||
debugPrint("Using server URL: $endpoint");
|
||||
}
|
||||
@@ -96,8 +95,7 @@ class AppLifeCycleNotifier extends StateNotifier<AppLifeCycleEnum> {
|
||||
await Future.wait([
|
||||
backgroundManager.syncLocal().then(
|
||||
(_) {
|
||||
Logger("AppLifeCycleNotifier")
|
||||
.fine("Hashing assets after syncLocal");
|
||||
Logger("AppLifeCycleNotifier").fine("Hashing assets after syncLocal");
|
||||
// Check if app is still active before hashing
|
||||
if (state == AppLifeCycleEnum.resumed) {
|
||||
backgroundManager.hashAssets();
|
||||
@@ -106,9 +104,7 @@ class AppLifeCycleNotifier extends StateNotifier<AppLifeCycleEnum> {
|
||||
),
|
||||
backgroundManager.syncRemote(),
|
||||
]).then((_) async {
|
||||
final isEnableBackup = _ref
|
||||
.read(appSettingsServiceProvider)
|
||||
.getSetting(AppSettingsEnum.enableBackup);
|
||||
final isEnableBackup = _ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableBackup);
|
||||
|
||||
if (isEnableBackup) {
|
||||
final currentUser = _ref.read(currentUserProvider);
|
||||
@@ -116,9 +112,7 @@ class AppLifeCycleNotifier extends StateNotifier<AppLifeCycleEnum> {
|
||||
return;
|
||||
}
|
||||
|
||||
await _ref
|
||||
.read(driftBackupProvider.notifier)
|
||||
.handleBackupResume(currentUser.id);
|
||||
await _ref.read(driftBackupProvider.notifier).handleBackupResume(currentUser.id);
|
||||
}
|
||||
});
|
||||
} catch (e, stackTrace) {
|
||||
@@ -132,13 +126,9 @@ class AppLifeCycleNotifier extends StateNotifier<AppLifeCycleEnum> {
|
||||
|
||||
_ref.read(websocketProvider.notifier).connect();
|
||||
|
||||
await _ref
|
||||
.read(notificationPermissionProvider.notifier)
|
||||
.getNotificationPermission();
|
||||
await _ref.read(notificationPermissionProvider.notifier).getNotificationPermission();
|
||||
|
||||
await _ref
|
||||
.read(galleryPermissionNotifier.notifier)
|
||||
.getGalleryPermissionStatus();
|
||||
await _ref.read(galleryPermissionNotifier.notifier).getGalleryPermissionStatus();
|
||||
|
||||
if (!Store.isBetaTimelineEnabled) {
|
||||
await _ref.read(iOSBackgroundSettingsProvider.notifier).refresh();
|
||||
@@ -159,8 +149,7 @@ class AppLifeCycleNotifier extends StateNotifier<AppLifeCycleEnum> {
|
||||
if (_ref.read(authProvider).isAuthenticated) {
|
||||
if (!Store.isBetaTimelineEnabled) {
|
||||
// Do not cancel backup if manual upload is in progress
|
||||
if (_ref.read(backupProvider.notifier).backupProgress !=
|
||||
BackUpProgressEnum.manualInProgress) {
|
||||
if (_ref.read(backupProvider.notifier).backupProgress != BackUpProgressEnum.manualInProgress) {
|
||||
_ref.read(backupProvider.notifier).cancelBackup();
|
||||
}
|
||||
}
|
||||
@@ -213,7 +202,6 @@ class AppLifeCycleNotifier extends StateNotifier<AppLifeCycleEnum> {
|
||||
}
|
||||
}
|
||||
|
||||
final appStateProvider =
|
||||
StateNotifierProvider<AppLifeCycleNotifier, AppLifeCycleEnum>((ref) {
|
||||
final appStateProvider = StateNotifierProvider<AppLifeCycleNotifier, AppLifeCycleEnum>((ref) {
|
||||
return AppLifeCycleNotifier(ref);
|
||||
});
|
||||
|
||||
@@ -182,8 +182,7 @@ class AssetNotifier extends StateNotifier<bool> {
|
||||
}
|
||||
}
|
||||
|
||||
final assetDetailProvider =
|
||||
StreamProvider.autoDispose.family<Asset, Asset>((ref, asset) async* {
|
||||
final assetDetailProvider = StreamProvider.autoDispose.family<Asset, Asset>((ref, asset) async* {
|
||||
final assetService = ref.watch(assetServiceProvider);
|
||||
yield await assetService.loadExif(asset);
|
||||
|
||||
@@ -194,8 +193,7 @@ final assetDetailProvider =
|
||||
}
|
||||
});
|
||||
|
||||
final assetWatcher =
|
||||
StreamProvider.autoDispose.family<Asset?, Asset>((ref, asset) {
|
||||
final assetWatcher = StreamProvider.autoDispose.family<Asset?, Asset>((ref, asset) {
|
||||
final assetService = ref.watch(assetServiceProvider);
|
||||
return assetService.watchAsset(asset.id, fireImmediately: true);
|
||||
});
|
||||
|
||||
@@ -17,9 +17,7 @@ class AssetPeopleNotifier extends _$AssetPeopleNotifier {
|
||||
return [];
|
||||
}
|
||||
|
||||
final list = await ref
|
||||
.watch(assetServiceProvider)
|
||||
.getRemotePeopleOfAsset(asset.remoteId!);
|
||||
final list = await ref.watch(assetServiceProvider).getRemotePeopleOfAsset(asset.remoteId!);
|
||||
if (list == null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -32,10 +32,8 @@ class AssetStackNotifier extends StateNotifier<List<Asset>> {
|
||||
}
|
||||
}
|
||||
|
||||
final assetStackStateProvider = StateNotifierProvider.autoDispose
|
||||
.family<AssetStackNotifier, List<Asset>, String>(
|
||||
(ref, stackId) =>
|
||||
AssetStackNotifier(ref.watch(assetServiceProvider), stackId),
|
||||
final assetStackStateProvider = StateNotifierProvider.autoDispose.family<AssetStackNotifier, List<Asset>, String>(
|
||||
(ref, stackId) => AssetStackNotifier(ref.watch(assetServiceProvider), stackId),
|
||||
);
|
||||
|
||||
@riverpod
|
||||
|
||||
@@ -62,8 +62,7 @@ class DownloadStateNotifier extends StateNotifier<DownloadState> {
|
||||
if (update.task.metaData.isEmpty) {
|
||||
return;
|
||||
}
|
||||
final livePhotosId =
|
||||
LivePhotosMetadata.fromJson(update.task.metaData).id;
|
||||
final livePhotosId = LivePhotosMetadata.fromJson(update.task.metaData).id;
|
||||
_downloadService.saveLivePhotos(update.task, livePhotosId);
|
||||
_onDownloadComplete(update.task.taskId);
|
||||
break;
|
||||
@@ -191,8 +190,7 @@ class DownloadStateNotifier extends StateNotifier<DownloadState> {
|
||||
}
|
||||
}
|
||||
|
||||
final downloadStateProvider =
|
||||
StateNotifierProvider<DownloadStateNotifier, DownloadState>(
|
||||
final downloadStateProvider = StateNotifierProvider<DownloadStateNotifier, DownloadState>(
|
||||
((ref) => DownloadStateNotifier(
|
||||
ref.watch(downloadServiceProvider),
|
||||
ref.watch(shareServiceProvider),
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
/// Whether to display the video part of a motion photo
|
||||
final isPlayingMotionVideoProvider =
|
||||
StateNotifierProvider<IsPlayingMotionVideo, bool>((ref) {
|
||||
final isPlayingMotionVideoProvider = StateNotifierProvider<IsPlayingMotionVideo, bool>((ref) {
|
||||
return IsPlayingMotionVideo(ref);
|
||||
});
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
enum RenderListStatusEnum { complete, empty, error, loading }
|
||||
|
||||
final renderListStatusProvider =
|
||||
StateNotifierProvider<RenderListStatus, RenderListStatusEnum>((ref) {
|
||||
final renderListStatusProvider = StateNotifierProvider<RenderListStatus, RenderListStatusEnum>((ref) {
|
||||
return RenderListStatus(ref);
|
||||
});
|
||||
|
||||
|
||||
@@ -9,8 +9,7 @@ import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/services/share_intent_service.dart';
|
||||
import 'package:immich_mobile/services/upload.service.dart';
|
||||
|
||||
final shareIntentUploadProvider = StateNotifierProvider<
|
||||
ShareIntentUploadStateNotifier, List<ShareIntentAttachment>>(
|
||||
final shareIntentUploadProvider = StateNotifierProvider<ShareIntentUploadStateNotifier, List<ShareIntentAttachment>>(
|
||||
((ref) => ShareIntentUploadStateNotifier(
|
||||
ref.watch(appRouterProvider),
|
||||
ref.watch(uploadServiceProvider),
|
||||
@@ -18,8 +17,7 @@ final shareIntentUploadProvider = StateNotifierProvider<
|
||||
)),
|
||||
);
|
||||
|
||||
class ShareIntentUploadStateNotifier
|
||||
extends StateNotifier<List<ShareIntentAttachment>> {
|
||||
class ShareIntentUploadStateNotifier extends StateNotifier<List<ShareIntentAttachment>> {
|
||||
final AppRouter router;
|
||||
final UploadService _uploadService;
|
||||
final ShareIntentService _shareIntentService;
|
||||
@@ -53,8 +51,7 @@ class ShareIntentUploadStateNotifier
|
||||
}
|
||||
|
||||
void removeAttachment(ShareIntentAttachment attachment) {
|
||||
final updatedState =
|
||||
state.where((element) => element != attachment).toList();
|
||||
final updatedState = state.where((element) => element != attachment).toList();
|
||||
if (updatedState.length != state.length) {
|
||||
state = updatedState;
|
||||
}
|
||||
@@ -87,27 +84,20 @@ class ShareIntentUploadStateNotifier
|
||||
|
||||
state = [
|
||||
for (final attachment in state)
|
||||
if (attachment.id == taskId.toInt())
|
||||
attachment.copyWith(status: uploadStatus)
|
||||
else
|
||||
attachment,
|
||||
if (attachment.id == taskId.toInt()) attachment.copyWith(status: uploadStatus) else attachment,
|
||||
];
|
||||
}
|
||||
|
||||
void _taskProgressCallback(TaskProgressUpdate update) {
|
||||
// Ignore if the task is canceled or completed
|
||||
if (update.progress == downloadFailed ||
|
||||
update.progress == downloadCompleted) {
|
||||
if (update.progress == downloadFailed || update.progress == downloadCompleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
final taskId = update.task.taskId;
|
||||
state = [
|
||||
for (final attachment in state)
|
||||
if (attachment.id == taskId.toInt())
|
||||
attachment.copyWith(uploadProgress: update.progress)
|
||||
else
|
||||
attachment,
|
||||
if (attachment.id == taskId.toInt()) attachment.copyWith(uploadProgress: update.progress) else attachment,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -13,13 +13,11 @@ class VideoPlaybackControls {
|
||||
final bool restarted;
|
||||
}
|
||||
|
||||
final videoPlayerControlsProvider =
|
||||
StateNotifierProvider<VideoPlayerControls, VideoPlaybackControls>((ref) {
|
||||
final videoPlayerControlsProvider = StateNotifierProvider<VideoPlayerControls, VideoPlaybackControls>((ref) {
|
||||
return VideoPlayerControls(ref);
|
||||
});
|
||||
|
||||
const videoPlayerControlsDefault =
|
||||
VideoPlaybackControls(position: 0, pause: false);
|
||||
const videoPlayerControlsDefault = VideoPlaybackControls(position: 0, pause: false);
|
||||
|
||||
class VideoPlayerControls extends StateNotifier<VideoPlaybackControls> {
|
||||
VideoPlayerControls(this.ref) : super(videoPlayerControlsDefault);
|
||||
@@ -64,17 +62,14 @@ class VideoPlayerControls extends StateNotifier<VideoPlaybackControls> {
|
||||
}
|
||||
|
||||
void togglePlay() {
|
||||
state =
|
||||
VideoPlaybackControls(position: state.position, pause: !state.pause);
|
||||
state = VideoPlaybackControls(position: state.position, pause: !state.pause);
|
||||
}
|
||||
|
||||
void restart() {
|
||||
state =
|
||||
const VideoPlaybackControls(position: 0, pause: false, restarted: true);
|
||||
ref.read(videoPlaybackValueProvider.notifier).value =
|
||||
ref.read(videoPlaybackValueProvider.notifier).value.copyWith(
|
||||
state: VideoPlaybackState.playing,
|
||||
position: Duration.zero,
|
||||
);
|
||||
state = const VideoPlaybackControls(position: 0, pause: false, restarted: true);
|
||||
ref.read(videoPlaybackValueProvider.notifier).value = ref.read(videoPlaybackValueProvider.notifier).value.copyWith(
|
||||
state: VideoPlaybackState.playing,
|
||||
position: Duration.zero,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,8 +75,7 @@ const VideoPlaybackValue videoPlaybackValueDefault = VideoPlaybackValue(
|
||||
volume: 0.0,
|
||||
);
|
||||
|
||||
final videoPlaybackValueProvider =
|
||||
StateNotifierProvider<VideoPlaybackValueState, VideoPlaybackValue>((ref) {
|
||||
final videoPlaybackValueProvider = StateNotifierProvider<VideoPlaybackValueState, VideoPlaybackValue>((ref) {
|
||||
return VideoPlaybackValueState(ref);
|
||||
});
|
||||
|
||||
|
||||
@@ -124,14 +124,12 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
||||
);
|
||||
|
||||
// Get the deviceid from the store if it exists, otherwise generate a new one
|
||||
String deviceId =
|
||||
Store.tryGet(StoreKey.deviceId) ?? await FlutterUdid.consistentUdid;
|
||||
String deviceId = Store.tryGet(StoreKey.deviceId) ?? await FlutterUdid.consistentUdid;
|
||||
|
||||
UserDto? user = _userService.tryGetMyUser();
|
||||
|
||||
try {
|
||||
final serverUser =
|
||||
await _userService.refreshMyUser().timeout(_timeoutDuration);
|
||||
final serverUser = await _userService.refreshMyUser().timeout(_timeoutDuration);
|
||||
if (serverUser == null) {
|
||||
_log.severe("Unable to get user information from the server.");
|
||||
} else {
|
||||
|
||||
@@ -34,8 +34,7 @@ import 'package:logging/logging.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:photo_manager/photo_manager.dart' show PMProgressHandler;
|
||||
|
||||
final backupProvider =
|
||||
StateNotifierProvider<BackupNotifier, BackUpState>((ref) {
|
||||
final backupProvider = StateNotifierProvider<BackupNotifier, BackUpState>((ref) {
|
||||
return BackupNotifier(
|
||||
ref.watch(backupServiceProvider),
|
||||
ref.watch(serverInfoServiceProvider),
|
||||
@@ -74,8 +73,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
autoBackup: Store.get(StoreKey.autoBackup, false),
|
||||
backgroundBackup: Store.get(StoreKey.backgroundBackup, false),
|
||||
backupRequireWifi: Store.get(StoreKey.backupRequireWifi, true),
|
||||
backupRequireCharging:
|
||||
Store.get(StoreKey.backupRequireCharging, false),
|
||||
backupRequireCharging: Store.get(StoreKey.backupRequireCharging, false),
|
||||
backupTriggerDelay: Store.get(StoreKey.backupTriggerDelay, 5000),
|
||||
serverInfo: const ServerDiskInfo(
|
||||
diskAvailable: "0",
|
||||
@@ -124,16 +122,14 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
removeExcludedAlbumForBackup(album);
|
||||
}
|
||||
|
||||
state = state
|
||||
.copyWith(selectedBackupAlbums: {...state.selectedBackupAlbums, album});
|
||||
state = state.copyWith(selectedBackupAlbums: {...state.selectedBackupAlbums, album});
|
||||
}
|
||||
|
||||
void addExcludedAlbumForBackup(AvailableAlbum album) {
|
||||
if (state.selectedBackupAlbums.contains(album)) {
|
||||
removeAlbumForBackup(album);
|
||||
}
|
||||
state = state
|
||||
.copyWith(excludedBackupAlbums: {...state.excludedBackupAlbums, album});
|
||||
state = state.copyWith(excludedBackupAlbums: {...state.excludedBackupAlbums, album});
|
||||
}
|
||||
|
||||
void removeAlbumForBackup(AvailableAlbum album) {
|
||||
@@ -180,10 +176,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
required void Function() onBatteryInfo,
|
||||
}) async {
|
||||
assert(
|
||||
enabled != null ||
|
||||
requireWifi != null ||
|
||||
requireCharging != null ||
|
||||
triggerDelay != null,
|
||||
enabled != null || requireWifi != null || requireCharging != null || triggerDelay != null,
|
||||
);
|
||||
final bool wasEnabled = state.backgroundBackup;
|
||||
final bool wasWifi = state.backupRequireWifi;
|
||||
@@ -257,9 +250,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
for (Album album in albums) {
|
||||
AvailableAlbum availableAlbum = AvailableAlbum(
|
||||
album: album,
|
||||
assetCount: await ref
|
||||
.read(albumMediaRepositoryProvider)
|
||||
.getAssetCount(album.localId!),
|
||||
assetCount: await ref.read(albumMediaRepositoryProvider).getAssetCount(album.localId!),
|
||||
);
|
||||
|
||||
availableAlbums.add(availableAlbum);
|
||||
@@ -268,10 +259,8 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
}
|
||||
state = state.copyWith(availableAlbums: availableAlbums);
|
||||
|
||||
final List<BackupAlbum> excludedBackupAlbums =
|
||||
await _backupAlbumService.getAllBySelection(BackupSelection.exclude);
|
||||
final List<BackupAlbum> selectedBackupAlbums =
|
||||
await _backupAlbumService.getAllBySelection(BackupSelection.select);
|
||||
final List<BackupAlbum> excludedBackupAlbums = await _backupAlbumService.getAllBySelection(BackupSelection.exclude);
|
||||
final List<BackupAlbum> selectedBackupAlbums = await _backupAlbumService.getAllBySelection(BackupSelection.select);
|
||||
|
||||
final Set<AvailableAlbum> selectedAlbums = {};
|
||||
for (final BackupAlbum ba in selectedBackupAlbums) {
|
||||
@@ -281,8 +270,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
selectedAlbums.add(
|
||||
AvailableAlbum(
|
||||
album: albumAsset,
|
||||
assetCount:
|
||||
await _albumMediaRepository.getAssetCount(albumAsset.localId!),
|
||||
assetCount: await _albumMediaRepository.getAssetCount(albumAsset.localId!),
|
||||
lastBackup: ba.lastBackup,
|
||||
),
|
||||
);
|
||||
@@ -299,9 +287,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
excludedAlbums.add(
|
||||
AvailableAlbum(
|
||||
album: albumAsset,
|
||||
assetCount: await ref
|
||||
.read(albumMediaRepositoryProvider)
|
||||
.getAssetCount(albumAsset.localId!),
|
||||
assetCount: await ref.read(albumMediaRepositoryProvider).getAssetCount(albumAsset.localId!),
|
||||
lastBackup: ba.lastBackup,
|
||||
),
|
||||
);
|
||||
@@ -335,17 +321,13 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
final Set<BackupCandidate> assetsFromExcludedAlbums = {};
|
||||
|
||||
for (final album in state.selectedBackupAlbums) {
|
||||
final assetCount = await ref
|
||||
.read(albumMediaRepositoryProvider)
|
||||
.getAssetCount(album.album.localId!);
|
||||
final assetCount = await ref.read(albumMediaRepositoryProvider).getAssetCount(album.album.localId!);
|
||||
|
||||
if (assetCount == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final assets = await ref
|
||||
.read(albumMediaRepositoryProvider)
|
||||
.getAssets(album.album.localId!);
|
||||
final assets = await ref.read(albumMediaRepositoryProvider).getAssets(album.album.localId!);
|
||||
|
||||
// Add album's name to the asset info
|
||||
for (final asset in assets) {
|
||||
@@ -370,17 +352,13 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
}
|
||||
|
||||
for (final album in state.excludedBackupAlbums) {
|
||||
final assetCount = await ref
|
||||
.read(albumMediaRepositoryProvider)
|
||||
.getAssetCount(album.album.localId!);
|
||||
final assetCount = await ref.read(albumMediaRepositoryProvider).getAssetCount(album.album.localId!);
|
||||
|
||||
if (assetCount == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final assets = await ref
|
||||
.read(albumMediaRepositoryProvider)
|
||||
.getAssets(album.album.localId!);
|
||||
final assets = await ref.read(albumMediaRepositoryProvider).getAssets(album.album.localId!);
|
||||
|
||||
for (final asset in assets) {
|
||||
assetsFromExcludedAlbums.add(
|
||||
@@ -389,8 +367,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
}
|
||||
}
|
||||
|
||||
final Set<BackupCandidate> allUniqueAssets =
|
||||
assetsFromSelectedAlbums.difference(assetsFromExcludedAlbums);
|
||||
final Set<BackupCandidate> allUniqueAssets = assetsFromSelectedAlbums.difference(assetsFromExcludedAlbums);
|
||||
|
||||
final allAssetsInDatabase = await _backupService.getDeviceBackupAsset();
|
||||
|
||||
@@ -399,11 +376,9 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
}
|
||||
|
||||
// Find asset that were backup from selected albums
|
||||
final Set<String> selectedAlbumsBackupAssets =
|
||||
Set.from(allUniqueAssets.map((e) => e.asset.localId));
|
||||
final Set<String> selectedAlbumsBackupAssets = Set.from(allUniqueAssets.map((e) => e.asset.localId));
|
||||
|
||||
selectedAlbumsBackupAssets
|
||||
.removeWhere((assetId) => !allAssetsInDatabase.contains(assetId));
|
||||
selectedAlbumsBackupAssets.removeWhere((assetId) => !allAssetsInDatabase.contains(assetId));
|
||||
|
||||
// Remove duplicated asset from all unique assets
|
||||
allUniqueAssets.removeWhere(
|
||||
@@ -459,8 +434,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
final candidates = selected.followedBy(excluded).toList();
|
||||
candidates.sortBy((e) => e.id);
|
||||
|
||||
final savedBackupAlbums =
|
||||
await _backupAlbumService.getAll(sort: BackupAlbumSort.id);
|
||||
final savedBackupAlbums = await _backupAlbumService.getAll(sort: BackupAlbumSort.id);
|
||||
final List<int> toDelete = [];
|
||||
final List<BackupAlbum> toUpsert = [];
|
||||
|
||||
@@ -469,8 +443,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
candidates,
|
||||
compare: (BackupAlbum a, BackupAlbum b) => a.id.compareTo(b.id),
|
||||
both: (BackupAlbum a, BackupAlbum b) {
|
||||
b.lastBackup =
|
||||
a.lastBackup.isAfter(b.lastBackup) ? a.lastBackup : b.lastBackup;
|
||||
b.lastBackup = a.lastBackup.isAfter(b.lastBackup) ? a.lastBackup : b.lastBackup;
|
||||
toUpsert.add(b);
|
||||
return true;
|
||||
},
|
||||
@@ -569,8 +542,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
state = state.copyWith(
|
||||
allUniqueAssets: state.allUniqueAssets
|
||||
.where(
|
||||
(candidate) =>
|
||||
candidate.asset.localId != result.candidate.asset.localId,
|
||||
(candidate) => candidate.asset.localId != result.candidate.asset.localId,
|
||||
)
|
||||
.toSet(),
|
||||
);
|
||||
@@ -587,21 +559,13 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
);
|
||||
}
|
||||
|
||||
if (state.allUniqueAssets.length -
|
||||
state.selectedAlbumsBackupAssetsIds.length ==
|
||||
0) {
|
||||
final latestAssetBackup = state.allUniqueAssets
|
||||
.map((candidate) => candidate.asset.fileModifiedAt)
|
||||
.reduce(
|
||||
if (state.allUniqueAssets.length - state.selectedAlbumsBackupAssetsIds.length == 0) {
|
||||
final latestAssetBackup = state.allUniqueAssets.map((candidate) => candidate.asset.fileModifiedAt).reduce(
|
||||
(v, e) => e.isAfter(v) ? e : v,
|
||||
);
|
||||
state = state.copyWith(
|
||||
selectedBackupAlbums: state.selectedBackupAlbums
|
||||
.map((e) => e.copyWith(lastBackup: latestAssetBackup))
|
||||
.toSet(),
|
||||
excludedBackupAlbums: state.excludedBackupAlbums
|
||||
.map((e) => e.copyWith(lastBackup: latestAssetBackup))
|
||||
.toSet(),
|
||||
selectedBackupAlbums: state.selectedBackupAlbums.map((e) => e.copyWith(lastBackup: latestAssetBackup)).toSet(),
|
||||
excludedBackupAlbums: state.excludedBackupAlbums.map((e) => e.copyWith(lastBackup: latestAssetBackup)).toSet(),
|
||||
backupProgress: BackUpProgressEnum.done,
|
||||
progressInPercentage: 0.0,
|
||||
progressInFileSize: "0 B / 0 B",
|
||||
@@ -696,10 +660,8 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
}
|
||||
|
||||
Future<void> resumeBackup() async {
|
||||
final List<BackupAlbum> selectedBackupAlbums =
|
||||
await _backupAlbumService.getAllBySelection(BackupSelection.select);
|
||||
final List<BackupAlbum> excludedBackupAlbums =
|
||||
await _backupAlbumService.getAllBySelection(BackupSelection.exclude);
|
||||
final List<BackupAlbum> selectedBackupAlbums = await _backupAlbumService.getAllBySelection(BackupSelection.select);
|
||||
final List<BackupAlbum> excludedBackupAlbums = await _backupAlbumService.getAllBySelection(BackupSelection.exclude);
|
||||
Set<AvailableAlbum> selectedAlbums = state.selectedBackupAlbums;
|
||||
Set<AvailableAlbum> excludedAlbums = state.excludedBackupAlbums;
|
||||
if (selectedAlbums.isNotEmpty) {
|
||||
|
||||
@@ -4,8 +4,7 @@ import 'package:immich_mobile/domain/services/local_album.service.dart';
|
||||
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
||||
|
||||
final backupAlbumProvider =
|
||||
StateNotifierProvider<BackupAlbumNotifier, List<LocalAlbum>>(
|
||||
final backupAlbumProvider = StateNotifierProvider<BackupAlbumNotifier, List<LocalAlbum>>(
|
||||
(ref) => BackupAlbumNotifier(
|
||||
ref.watch(localAlbumServiceProvider),
|
||||
),
|
||||
@@ -19,8 +18,7 @@ class BackupAlbumNotifier extends StateNotifier<List<LocalAlbum>> {
|
||||
final LocalAlbumService _localAlbumService;
|
||||
|
||||
Future<void> getAll() async {
|
||||
state =
|
||||
await _localAlbumService.getAll(sortBy: {SortLocalAlbumsBy.assetCount});
|
||||
state = await _localAlbumService.getAll(sortBy: {SortLocalAlbumsBy.assetCount});
|
||||
}
|
||||
|
||||
Future<void> selectAlbum(LocalAlbum album) async {
|
||||
@@ -42,9 +40,8 @@ class BackupAlbumNotifier extends StateNotifier<List<LocalAlbum>> {
|
||||
|
||||
state = state
|
||||
.map(
|
||||
(currentAlbum) => currentAlbum.id == album.id
|
||||
? currentAlbum.copyWith(backupSelection: BackupSelection.none)
|
||||
: currentAlbum,
|
||||
(currentAlbum) =>
|
||||
currentAlbum.id == album.id ? currentAlbum.copyWith(backupSelection: BackupSelection.none) : currentAlbum,
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -23,8 +23,7 @@ class BackupVerification extends _$BackupVerification {
|
||||
state = true;
|
||||
final backupState = ref.read(backupProvider);
|
||||
|
||||
if (backupState.allUniqueAssets.length >
|
||||
backupState.selectedAlbumsBackupAssetsIds.length) {
|
||||
if (backupState.allUniqueAssets.length > backupState.selectedAlbumsBackupAssetsIds.length) {
|
||||
if (context.mounted) {
|
||||
ImmichToast.show(
|
||||
context: context,
|
||||
@@ -48,9 +47,7 @@ class BackupVerification extends _$BackupVerification {
|
||||
WakelockPlus.enable();
|
||||
|
||||
const limit = 100;
|
||||
final toDelete = await ref
|
||||
.read(backupVerificationServiceProvider)
|
||||
.findWronglyBackedUpAssets(limit: limit);
|
||||
final toDelete = await ref.read(backupVerificationServiceProvider).findWronglyBackedUpAssets(limit: limit);
|
||||
if (toDelete.isEmpty) {
|
||||
if (context.mounted) {
|
||||
ImmichToast.show(
|
||||
@@ -67,8 +64,7 @@ class BackupVerification extends _$BackupVerification {
|
||||
onOk: () => _performDeletion(context, toDelete),
|
||||
title: "Corrupt backups!",
|
||||
ok: "Delete",
|
||||
content:
|
||||
"Found ${toDelete.length} (max $limit at once) corrupt asset backups. "
|
||||
content: "Found ${toDelete.length} (max $limit at once) corrupt asset backups. "
|
||||
"Run the check again to find more.\n"
|
||||
"Do you want to delete the corrupt asset backups now?",
|
||||
),
|
||||
|
||||
@@ -31,8 +31,7 @@ class EnqueueStatus {
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'EnqueueStatus(enqueueCount: $enqueueCount, totalCount: $totalCount)';
|
||||
String toString() => 'EnqueueStatus(enqueueCount: $enqueueCount, totalCount: $totalCount)';
|
||||
}
|
||||
|
||||
class DriftUploadStatus {
|
||||
@@ -198,8 +197,7 @@ class DriftBackupState {
|
||||
}
|
||||
}
|
||||
|
||||
final driftBackupProvider =
|
||||
StateNotifierProvider<ExpBackupNotifier, DriftBackupState>((ref) {
|
||||
final driftBackupProvider = StateNotifierProvider<ExpBackupNotifier, DriftBackupState>((ref) {
|
||||
return ExpBackupNotifier(
|
||||
ref.watch(driftBackupServiceProvider),
|
||||
ref.watch(uploadServiceProvider),
|
||||
@@ -235,8 +233,7 @@ class ExpBackupNotifier extends StateNotifier<DriftBackupState> {
|
||||
/// Remove upload item from state
|
||||
void _removeUploadItem(String taskId) {
|
||||
if (state.uploadItems.containsKey(taskId)) {
|
||||
final updatedItems =
|
||||
Map<String, DriftUploadStatus>.from(state.uploadItems);
|
||||
final updatedItems = Map<String, DriftUploadStatus>.from(state.uploadItems);
|
||||
updatedItems.remove(taskId);
|
||||
state = state.copyWith(uploadItems: updatedItems);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ class ErrorBackupListNotifier extends StateNotifier<Set<ErrorUploadAsset>> {
|
||||
}
|
||||
}
|
||||
|
||||
final errorBackupListProvider =
|
||||
StateNotifierProvider<ErrorBackupListNotifier, Set<ErrorUploadAsset>>(
|
||||
final errorBackupListProvider = StateNotifierProvider<ErrorBackupListNotifier, Set<ErrorUploadAsset>>(
|
||||
(ref) => ErrorBackupListNotifier(),
|
||||
);
|
||||
|
||||
@@ -15,21 +15,17 @@ class IOSBackgroundSettings {
|
||||
});
|
||||
}
|
||||
|
||||
class IOSBackgroundSettingsNotifier
|
||||
extends StateNotifier<IOSBackgroundSettings?> {
|
||||
class IOSBackgroundSettingsNotifier extends StateNotifier<IOSBackgroundSettings?> {
|
||||
final BackgroundService _service;
|
||||
IOSBackgroundSettingsNotifier(this._service) : super(null);
|
||||
|
||||
IOSBackgroundSettings? get settings => state;
|
||||
|
||||
Future<IOSBackgroundSettings> refresh() async {
|
||||
final lastFetchTime =
|
||||
await _service.getIOSBackupLastRun(IosBackgroundTask.fetch);
|
||||
final lastProcessingTime =
|
||||
await _service.getIOSBackupLastRun(IosBackgroundTask.processing);
|
||||
final lastFetchTime = await _service.getIOSBackupLastRun(IosBackgroundTask.fetch);
|
||||
final lastProcessingTime = await _service.getIOSBackupLastRun(IosBackgroundTask.processing);
|
||||
int numberOfProcesses = await _service.getIOSBackupNumberOfProcesses();
|
||||
final appRefreshEnabled =
|
||||
await _service.getIOSBackgroundAppRefreshEnabled();
|
||||
final appRefreshEnabled = await _service.getIOSBackgroundAppRefreshEnabled();
|
||||
|
||||
// If this is enabled and there are no background processes,
|
||||
// the user just enabled app refresh in Settings.
|
||||
@@ -53,7 +49,6 @@ class IOSBackgroundSettingsNotifier
|
||||
}
|
||||
}
|
||||
|
||||
final iOSBackgroundSettingsProvider = StateNotifierProvider<
|
||||
IOSBackgroundSettingsNotifier, IOSBackgroundSettings?>(
|
||||
final iOSBackgroundSettingsProvider = StateNotifierProvider<IOSBackgroundSettingsNotifier, IOSBackgroundSettings?>(
|
||||
(ref) => IOSBackgroundSettingsNotifier(ref.watch(backgroundServiceProvider)),
|
||||
);
|
||||
|
||||
@@ -31,8 +31,7 @@ import 'package:logging/logging.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:photo_manager/photo_manager.dart' show PMProgressHandler;
|
||||
|
||||
final manualUploadProvider =
|
||||
StateNotifierProvider<ManualUploadNotifier, ManualUploadState>((ref) {
|
||||
final manualUploadProvider = StateNotifierProvider<ManualUploadNotifier, ManualUploadState>((ref) {
|
||||
return ManualUploadNotifier(
|
||||
ref.watch(localNotificationService),
|
||||
ref.watch(backupProvider.notifier),
|
||||
@@ -82,8 +81,7 @@ class ManualUploadNotifier extends StateNotifier<ManualUploadState> {
|
||||
String? _lastPrintedDetailTitle;
|
||||
|
||||
static const notifyInterval = Duration(milliseconds: 500);
|
||||
late final ThrottleProgressUpdate _throttledNotifiy =
|
||||
ThrottleProgressUpdate(_updateProgress, notifyInterval);
|
||||
late final ThrottleProgressUpdate _throttledNotifiy = ThrottleProgressUpdate(_updateProgress, notifyInterval);
|
||||
late final ThrottleProgressUpdate _throttledDetailNotify =
|
||||
ThrottleProgressUpdate(_updateDetailProgress, notifyInterval);
|
||||
|
||||
@@ -106,11 +104,9 @@ class ManualUploadNotifier extends StateNotifier<ManualUploadState> {
|
||||
void _updateDetailProgress(String? title, int progress, int total) {
|
||||
// Guard against throttling calling this method after the upload is done
|
||||
if (_backupProvider.backupProgress == BackUpProgressEnum.manualInProgress) {
|
||||
final String msg =
|
||||
total > 0 ? humanReadableBytesProgress(progress, total) : "";
|
||||
final String msg = total > 0 ? humanReadableBytesProgress(progress, total) : "";
|
||||
// only update if message actually differs (to stop many useless notification updates on large assets or slow connections)
|
||||
if (msg != _lastPrintedDetailContent ||
|
||||
title != _lastPrintedDetailTitle) {
|
||||
if (msg != _lastPrintedDetailContent || title != _lastPrintedDetailTitle) {
|
||||
_lastPrintedDetailContent = msg;
|
||||
_lastPrintedDetailTitle = title;
|
||||
_localNotificationService.showOrUpdateManualUploadStatus(
|
||||
@@ -184,9 +180,8 @@ class ManualUploadNotifier extends StateNotifier<ManualUploadState> {
|
||||
_throttledNotifiy();
|
||||
}
|
||||
if (state.showDetailedNotification) {
|
||||
_throttledDetailNotify.title =
|
||||
"backup_background_service_current_upload_notification"
|
||||
.tr(namedArgs: {'filename': currentUploadAsset.fileName});
|
||||
_throttledDetailNotify.title = "backup_background_service_current_upload_notification"
|
||||
.tr(namedArgs: {'filename': currentUploadAsset.fileName});
|
||||
_throttledDetailNotify.progress = 0;
|
||||
_throttledDetailNotify.total = 0;
|
||||
}
|
||||
@@ -200,8 +195,7 @@ class ManualUploadNotifier extends StateNotifier<ManualUploadState> {
|
||||
if (ref.read(galleryPermissionNotifier.notifier).hasPermission) {
|
||||
await ref.read(fileMediaRepositoryProvider).clearFileCache();
|
||||
|
||||
final allAssetsFromDevice =
|
||||
allManualUploads.where((e) => e.isLocal && !e.isRemote).toList();
|
||||
final allAssetsFromDevice = allManualUploads.where((e) => e.isLocal && !e.isRemote).toList();
|
||||
|
||||
if (allAssetsFromDevice.length != allManualUploads.length) {
|
||||
_log.warning(
|
||||
@@ -209,14 +203,11 @@ class ManualUploadNotifier extends StateNotifier<ManualUploadState> {
|
||||
);
|
||||
}
|
||||
|
||||
final selectedBackupAlbums =
|
||||
await _backupAlbumService.getAllBySelection(BackupSelection.select);
|
||||
final excludedBackupAlbums = await _backupAlbumService
|
||||
.getAllBySelection(BackupSelection.exclude);
|
||||
final selectedBackupAlbums = await _backupAlbumService.getAllBySelection(BackupSelection.select);
|
||||
final excludedBackupAlbums = await _backupAlbumService.getAllBySelection(BackupSelection.exclude);
|
||||
|
||||
// Get candidates from selected albums and excluded albums
|
||||
Set<BackupCandidate> candidates =
|
||||
await _backupService.buildUploadCandidates(
|
||||
Set<BackupCandidate> candidates = await _backupService.buildUploadCandidates(
|
||||
selectedBackupAlbums,
|
||||
excludedBackupAlbums,
|
||||
useTimeFilter: false,
|
||||
@@ -260,13 +251,11 @@ class ManualUploadNotifier extends StateNotifier<ManualUploadState> {
|
||||
}
|
||||
|
||||
// Show detailed asset if enabled in settings or if a single asset is uploaded
|
||||
bool showDetailedNotification =
|
||||
ref.read(appSettingsServiceProvider).getSetting<bool>(
|
||||
AppSettingsEnum.backgroundBackupSingleProgress,
|
||||
) ||
|
||||
state.totalAssetsToUpload == 1;
|
||||
state =
|
||||
state.copyWith(showDetailedNotification: showDetailedNotification);
|
||||
bool showDetailedNotification = ref.read(appSettingsServiceProvider).getSetting<bool>(
|
||||
AppSettingsEnum.backgroundBackupSingleProgress,
|
||||
) ||
|
||||
state.totalAssetsToUpload == 1;
|
||||
state = state.copyWith(showDetailedNotification: showDetailedNotification);
|
||||
final pmProgressHandler = Platform.isIOS ? PMProgressHandler() : null;
|
||||
|
||||
final bool ok = await ref.read(backupServiceProvider).backupAsset(
|
||||
@@ -297,8 +286,7 @@ class ManualUploadNotifier extends StateNotifier<ManualUploadState> {
|
||||
presentBanner: true,
|
||||
);
|
||||
hasErrors = true;
|
||||
} else if (state.successfulUploads == 0 ||
|
||||
(!ok && !state.cancelToken.isCancelled)) {
|
||||
} else if (state.successfulUploads == 0 || (!ok && !state.cancelToken.isCancelled)) {
|
||||
await _localNotificationService.showOrUpdateManualUploadStatus(
|
||||
"backup_manual_title".tr(),
|
||||
"failed".tr(),
|
||||
@@ -334,8 +322,7 @@ class ManualUploadNotifier extends StateNotifier<ManualUploadState> {
|
||||
final appState = ref.read(appStateProvider.notifier).getAppState();
|
||||
// The app is currently in background. Perform the necessary cleanups which
|
||||
// are on-hold for upload completion
|
||||
if (appState != AppLifeCycleEnum.active &&
|
||||
appState != AppLifeCycleEnum.resumed) {
|
||||
if (appState != AppLifeCycleEnum.active && appState != AppLifeCycleEnum.resumed) {
|
||||
ref.read(backupProvider.notifier).cancelBackup();
|
||||
}
|
||||
}
|
||||
@@ -364,8 +351,7 @@ class ManualUploadNotifier extends StateNotifier<ManualUploadState> {
|
||||
) async {
|
||||
// assumes the background service is currently running and
|
||||
// waits until it has stopped to start the backup.
|
||||
final bool hasLock =
|
||||
await ref.read(backgroundServiceProvider).acquireLock();
|
||||
final bool hasLock = await ref.read(backgroundServiceProvider).acquireLock();
|
||||
if (!hasLock) {
|
||||
debugPrint("[uploadAssets] could not acquire lock, exiting");
|
||||
ImmichToast.show(
|
||||
|
||||
@@ -22,9 +22,7 @@ class FolderStructureNotifier extends StateNotifier<AsyncValue<RootFolder>> {
|
||||
}
|
||||
}
|
||||
|
||||
final folderStructureProvider =
|
||||
StateNotifierProvider<FolderStructureNotifier, AsyncValue<RootFolder>>(
|
||||
(ref) {
|
||||
final folderStructureProvider = StateNotifierProvider<FolderStructureNotifier, AsyncValue<RootFolder>>((ref) {
|
||||
return FolderStructureNotifier(
|
||||
ref.watch(folderServiceProvider),
|
||||
);
|
||||
@@ -35,14 +33,12 @@ class FolderRenderListNotifier extends StateNotifier<AsyncValue<RenderList>> {
|
||||
final RootFolder _folder;
|
||||
final Logger _log = Logger("FolderAssetsNotifier");
|
||||
|
||||
FolderRenderListNotifier(this._folderService, this._folder)
|
||||
: super(const AsyncLoading());
|
||||
FolderRenderListNotifier(this._folderService, this._folder) : super(const AsyncLoading());
|
||||
|
||||
Future<void> fetchAssets(SortOrder order) async {
|
||||
try {
|
||||
final assets = await _folderService.getFolderAssets(_folder, order);
|
||||
final renderList =
|
||||
await RenderList.fromAssets(assets, GroupAssetsBy.none);
|
||||
final renderList = await RenderList.fromAssets(assets, GroupAssetsBy.none);
|
||||
state = AsyncData(renderList);
|
||||
} catch (e, stack) {
|
||||
_log.severe("Failed to fetch folder assets", e, stack);
|
||||
@@ -51,10 +47,8 @@ class FolderRenderListNotifier extends StateNotifier<AsyncValue<RenderList>> {
|
||||
}
|
||||
}
|
||||
|
||||
final folderRenderListProvider = StateNotifierProvider.family<
|
||||
FolderRenderListNotifier,
|
||||
AsyncValue<RenderList>,
|
||||
RootFolder>((ref, folder) {
|
||||
final folderRenderListProvider =
|
||||
StateNotifierProvider.family<FolderRenderListNotifier, AsyncValue<RenderList>, RootFolder>((ref, folder) {
|
||||
return FolderRenderListNotifier(
|
||||
ref.watch(folderServiceProvider),
|
||||
folder,
|
||||
|
||||
@@ -5,8 +5,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
class GalleryPermissionNotifier extends StateNotifier<PermissionStatus> {
|
||||
GalleryPermissionNotifier()
|
||||
: super(PermissionStatus.denied) // Denied is the initial state
|
||||
GalleryPermissionNotifier() : super(PermissionStatus.denied) // Denied is the initial state
|
||||
{
|
||||
// Sets the initial state
|
||||
getGalleryPermissionStatus();
|
||||
@@ -36,8 +35,7 @@ class GalleryPermissionNotifier extends StateNotifier<PermissionStatus> {
|
||||
|
||||
// Return the joint result of those two permissions
|
||||
final PermissionStatus status;
|
||||
if ((photos.isGranted && videos.isGranted) ||
|
||||
(photos.isLimited && videos.isLimited)) {
|
||||
if ((photos.isGranted && videos.isGranted) || (photos.isLimited && videos.isLimited)) {
|
||||
status = PermissionStatus.granted;
|
||||
} else if (photos.isDenied || videos.isDenied) {
|
||||
status = PermissionStatus.denied;
|
||||
@@ -49,8 +47,7 @@ class GalleryPermissionNotifier extends StateNotifier<PermissionStatus> {
|
||||
|
||||
result = status;
|
||||
}
|
||||
if (result == PermissionStatus.granted &&
|
||||
androidInfo.version.sdkInt >= 29) {
|
||||
if (result == PermissionStatus.granted && androidInfo.version.sdkInt >= 29) {
|
||||
result = await Permission.accessMediaLocation.request();
|
||||
}
|
||||
} else {
|
||||
@@ -80,8 +77,7 @@ class GalleryPermissionNotifier extends StateNotifier<PermissionStatus> {
|
||||
|
||||
// Return the joint result of those two permissions
|
||||
final PermissionStatus status;
|
||||
if ((photos.isGranted && videos.isGranted) ||
|
||||
(photos.isLimited && videos.isLimited)) {
|
||||
if ((photos.isGranted && videos.isGranted) || (photos.isLimited && videos.isLimited)) {
|
||||
status = PermissionStatus.granted;
|
||||
} else if (photos.isDenied || videos.isDenied) {
|
||||
status = PermissionStatus.denied;
|
||||
@@ -93,8 +89,7 @@ class GalleryPermissionNotifier extends StateNotifier<PermissionStatus> {
|
||||
|
||||
result = status;
|
||||
}
|
||||
if (state == PermissionStatus.granted &&
|
||||
androidInfo.version.sdkInt >= 29) {
|
||||
if (state == PermissionStatus.granted && androidInfo.version.sdkInt >= 29) {
|
||||
result = await Permission.accessMediaLocation.status;
|
||||
}
|
||||
} else {
|
||||
@@ -107,7 +102,6 @@ class GalleryPermissionNotifier extends StateNotifier<PermissionStatus> {
|
||||
}
|
||||
}
|
||||
|
||||
final galleryPermissionNotifier =
|
||||
StateNotifierProvider<GalleryPermissionNotifier, PermissionStatus>(
|
||||
final galleryPermissionNotifier = StateNotifierProvider<GalleryPermissionNotifier, PermissionStatus>(
|
||||
(ref) => GalleryPermissionNotifier(),
|
||||
);
|
||||
|
||||
@@ -3,8 +3,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
||||
import 'package:immich_mobile/services/app_settings.service.dart';
|
||||
|
||||
final hapticFeedbackProvider =
|
||||
StateNotifierProvider<HapticNotifier, void>((ref) {
|
||||
final hapticFeedbackProvider = StateNotifierProvider<HapticNotifier, void>((ref) {
|
||||
return HapticNotifier(ref);
|
||||
});
|
||||
|
||||
@@ -15,41 +14,31 @@ class HapticNotifier extends StateNotifier<void> {
|
||||
HapticNotifier(this._ref) : super(null);
|
||||
|
||||
selectionClick() {
|
||||
if (_ref
|
||||
.read(appSettingsServiceProvider)
|
||||
.getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
if (_ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
HapticFeedback.selectionClick();
|
||||
}
|
||||
}
|
||||
|
||||
lightImpact() {
|
||||
if (_ref
|
||||
.read(appSettingsServiceProvider)
|
||||
.getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
if (_ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
HapticFeedback.lightImpact();
|
||||
}
|
||||
}
|
||||
|
||||
mediumImpact() {
|
||||
if (_ref
|
||||
.read(appSettingsServiceProvider)
|
||||
.getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
if (_ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
HapticFeedback.mediumImpact();
|
||||
}
|
||||
}
|
||||
|
||||
heavyImpact() {
|
||||
if (_ref
|
||||
.read(appSettingsServiceProvider)
|
||||
.getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
if (_ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
HapticFeedback.heavyImpact();
|
||||
}
|
||||
}
|
||||
|
||||
vibrate() {
|
||||
if (_ref
|
||||
.read(appSettingsServiceProvider)
|
||||
.getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
if (_ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableHapticFeedback)) {
|
||||
HapticFeedback.vibrate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,7 @@ import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||
/// The cache manager for thumbnail images [ImmichRemoteThumbnailProvider]
|
||||
class ThumbnailImageCacheManager extends CacheManager {
|
||||
static const key = 'thumbnailImageCacheKey';
|
||||
static final ThumbnailImageCacheManager _instance =
|
||||
ThumbnailImageCacheManager._();
|
||||
static final ThumbnailImageCacheManager _instance = ThumbnailImageCacheManager._();
|
||||
|
||||
factory ThumbnailImageCacheManager() {
|
||||
return _instance;
|
||||
|
||||
@@ -13,8 +13,7 @@ import 'package:logging/logging.dart';
|
||||
|
||||
/// The local image provider for an asset
|
||||
/// Only viable
|
||||
class ImmichLocalThumbnailProvider
|
||||
extends ImageProvider<ImmichLocalThumbnailProvider> {
|
||||
class ImmichLocalThumbnailProvider extends ImageProvider<ImmichLocalThumbnailProvider> {
|
||||
final Asset asset;
|
||||
final int height;
|
||||
final int width;
|
||||
@@ -60,13 +59,11 @@ class ImmichLocalThumbnailProvider
|
||||
CacheManager cache,
|
||||
ImageDecoderCallback decode,
|
||||
) async* {
|
||||
final cacheKey =
|
||||
'$userId${assetData.localId}${assetData.checksum}$width$height';
|
||||
final cacheKey = '$userId${assetData.localId}${assetData.checksum}$width$height';
|
||||
final fileFromCache = await cache.getFileFromCache(cacheKey);
|
||||
if (fileFromCache != null) {
|
||||
try {
|
||||
final buffer =
|
||||
await ui.ImmutableBuffer.fromFilePath(fileFromCache.file.path);
|
||||
final buffer = await ui.ImmutableBuffer.fromFilePath(fileFromCache.file.path);
|
||||
final codec = await decode(buffer);
|
||||
yield codec;
|
||||
return;
|
||||
|
||||
@@ -15,8 +15,7 @@ import 'package:immich_mobile/entities/store.entity.dart';
|
||||
import 'package:immich_mobile/utils/image_url_builder.dart';
|
||||
|
||||
/// The remote image provider for full size remote images
|
||||
class ImmichRemoteImageProvider
|
||||
extends ImageProvider<ImmichRemoteImageProvider> {
|
||||
class ImmichRemoteImageProvider extends ImageProvider<ImmichRemoteImageProvider> {
|
||||
/// The [Asset.remoteId] of the asset to fetch
|
||||
final String assetId;
|
||||
|
||||
|
||||
@@ -13,8 +13,7 @@ import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
import 'package:immich_mobile/utils/image_url_builder.dart';
|
||||
|
||||
/// The remote image provider
|
||||
class ImmichRemoteThumbnailProvider
|
||||
extends ImageProvider<ImmichRemoteThumbnailProvider> {
|
||||
class ImmichRemoteThumbnailProvider extends ImageProvider<ImmichRemoteThumbnailProvider> {
|
||||
/// The [Asset.remoteId] of the asset to fetch
|
||||
final String assetId;
|
||||
|
||||
|
||||
@@ -26,8 +26,7 @@ class ActionResult {
|
||||
const ActionResult({required this.count, required this.success, this.error});
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'ActionResult(count: $count, success: $success, error: $error)';
|
||||
String toString() => 'ActionResult(count: $count, success: $success, error: $error)';
|
||||
}
|
||||
|
||||
class ActionNotifier extends Notifier<void> {
|
||||
@@ -44,10 +43,7 @@ class ActionNotifier extends Notifier<void> {
|
||||
}
|
||||
|
||||
List<String> _getRemoteIdsForSource(ActionSource source) {
|
||||
return _getAssets(source)
|
||||
.whereType<RemoteAsset>()
|
||||
.toIds()
|
||||
.toList(growable: false);
|
||||
return _getAssets(source).whereType<RemoteAsset>().toIds().toList(growable: false);
|
||||
}
|
||||
|
||||
List<String> _getLocalIdsForSource(ActionSource source) {
|
||||
@@ -67,11 +63,7 @@ class ActionNotifier extends Notifier<void> {
|
||||
|
||||
List<String> _getOwnedRemoteIdsForSource(ActionSource source) {
|
||||
final ownerId = ref.read(currentUserProvider)?.id;
|
||||
return _getAssets(source)
|
||||
.whereType<RemoteAsset>()
|
||||
.ownedAssets(ownerId)
|
||||
.toIds()
|
||||
.toList(growable: false);
|
||||
return _getAssets(source).whereType<RemoteAsset>().ownedAssets(ownerId).toIds().toList(growable: false);
|
||||
}
|
||||
|
||||
List<RemoteAsset> _getOwnedRemoteAssetsForSource(ActionSource source) {
|
||||
@@ -355,8 +347,7 @@ class ActionNotifier extends Notifier<void> {
|
||||
}
|
||||
|
||||
Future<ActionResult> downloadAll(ActionSource source) async {
|
||||
final assets =
|
||||
_getAssets(source).whereType<RemoteAsset>().toList(growable: false);
|
||||
final assets = _getAssets(source).whereType<RemoteAsset>().toList(growable: false);
|
||||
|
||||
try {
|
||||
final didEnqueue = await _service.downloadAll(assets);
|
||||
|
||||
@@ -22,8 +22,7 @@ final localAlbumProvider = FutureProvider<List<LocalAlbum>>(
|
||||
);
|
||||
|
||||
final localAlbumThumbnailProvider = FutureProvider.family<LocalAsset?, String>(
|
||||
(ref, albumId) =>
|
||||
LocalAlbumService(ref.watch(localAlbumRepository)).getThumbnail(albumId),
|
||||
(ref, albumId) => LocalAlbumService(ref.watch(localAlbumRepository)).getThumbnail(albumId),
|
||||
);
|
||||
|
||||
final remoteAlbumRepository = Provider<DriftRemoteAlbumRepository>(
|
||||
@@ -38,8 +37,7 @@ final remoteAlbumServiceProvider = Provider<RemoteAlbumService>(
|
||||
dependencies: [remoteAlbumRepository],
|
||||
);
|
||||
|
||||
final remoteAlbumProvider =
|
||||
NotifierProvider<RemoteAlbumNotifier, RemoteAlbumState>(
|
||||
final remoteAlbumProvider = NotifierProvider<RemoteAlbumNotifier, RemoteAlbumState>(
|
||||
RemoteAlbumNotifier.new,
|
||||
dependencies: [remoteAlbumServiceProvider],
|
||||
);
|
||||
|
||||
@@ -4,8 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||
|
||||
final currentAssetNotifier =
|
||||
AutoDisposeNotifierProvider<CurrentAssetNotifier, BaseAsset?>(
|
||||
final currentAssetNotifier = AutoDisposeNotifierProvider<CurrentAssetNotifier, BaseAsset?>(
|
||||
CurrentAssetNotifier.new,
|
||||
);
|
||||
|
||||
@@ -20,10 +19,7 @@ class CurrentAssetNotifier extends AutoDisposeNotifier<BaseAsset?> {
|
||||
_keepAliveLink?.close();
|
||||
_assetSubscription?.cancel();
|
||||
state = asset;
|
||||
_assetSubscription = ref
|
||||
.watch(assetServiceProvider)
|
||||
.watchAsset(asset)
|
||||
.listen((updatedAsset) {
|
||||
_assetSubscription = ref.watch(assetServiceProvider).watchAsset(asset).listen((updatedAsset) {
|
||||
if (updatedAsset != null) {
|
||||
state = updatedAsset;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/album/album.model.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
||||
|
||||
final currentRemoteAlbumProvider =
|
||||
AutoDisposeNotifierProvider<CurrentAlbumNotifier, RemoteAlbum?>(
|
||||
final currentRemoteAlbumProvider = AutoDisposeNotifierProvider<CurrentAlbumNotifier, RemoteAlbum?>(
|
||||
CurrentAlbumNotifier.new,
|
||||
);
|
||||
|
||||
@@ -21,10 +20,7 @@ class CurrentAlbumNotifier extends AutoDisposeNotifier<RemoteAlbum?> {
|
||||
_assetSubscription?.cancel();
|
||||
state = album;
|
||||
|
||||
_assetSubscription = ref
|
||||
.watch(remoteAlbumServiceProvider)
|
||||
.watchAlbum(album.id)
|
||||
.listen((updatedAlbum) {
|
||||
_assetSubscription = ref.watch(remoteAlbumServiceProvider).watchAlbum(album.id).listen((updatedAlbum) {
|
||||
if (updatedAlbum != null) {
|
||||
state = updatedAlbum;
|
||||
}
|
||||
|
||||
@@ -6,5 +6,4 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'exif.provider.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
IsarExifRepository exifRepository(Ref ref) =>
|
||||
IsarExifRepository(ref.watch(isarProvider));
|
||||
IsarExifRepository exifRepository(Ref ref) => IsarExifRepository(ref.watch(isarProvider));
|
||||
|
||||
@@ -14,8 +14,7 @@ final driftMemoryServiceProvider = Provider<DriftMemoryService>(
|
||||
(ref) => DriftMemoryService(ref.watch(driftMemoryRepositoryProvider)),
|
||||
);
|
||||
|
||||
final driftMemoryFutureProvider =
|
||||
FutureProvider.autoDispose<List<DriftMemory>>((ref) async {
|
||||
final driftMemoryFutureProvider = FutureProvider.autoDispose<List<DriftMemory>>((ref) async {
|
||||
final user = ref.watch(currentUserProvider);
|
||||
if (user == null) {
|
||||
return [];
|
||||
|
||||
@@ -59,20 +59,16 @@ class PartnerNotifier extends Notifier<List<PartnerUserDto>> {
|
||||
}
|
||||
}
|
||||
|
||||
final driftAvailablePartnerProvider =
|
||||
FutureProvider.autoDispose<List<PartnerUserDto>>((ref) {
|
||||
final driftAvailablePartnerProvider = FutureProvider.autoDispose<List<PartnerUserDto>>((ref) {
|
||||
final currentUser = ref.watch(currentUserProvider);
|
||||
if (currentUser == null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return ref
|
||||
.watch(driftPartnerServiceProvider)
|
||||
.getAvailablePartners(currentUser.id);
|
||||
return ref.watch(driftPartnerServiceProvider).getAvailablePartners(currentUser.id);
|
||||
});
|
||||
|
||||
final driftSharedByPartnerProvider =
|
||||
FutureProvider.autoDispose<List<PartnerUserDto>>((ref) {
|
||||
final driftSharedByPartnerProvider = FutureProvider.autoDispose<List<PartnerUserDto>>((ref) {
|
||||
final currentUser = ref.watch(currentUserProvider);
|
||||
if (currentUser == null) {
|
||||
return [];
|
||||
@@ -81,8 +77,7 @@ final driftSharedByPartnerProvider =
|
||||
return ref.watch(driftPartnerServiceProvider).getSharedBy(currentUser.id);
|
||||
});
|
||||
|
||||
final driftSharedWithPartnerProvider =
|
||||
FutureProvider.autoDispose<List<PartnerUserDto>>((ref) {
|
||||
final driftSharedWithPartnerProvider = FutureProvider.autoDispose<List<PartnerUserDto>>((ref) {
|
||||
final currentUser = ref.watch(currentUserProvider);
|
||||
if (currentUser == null) {
|
||||
return [];
|
||||
|
||||
@@ -31,16 +31,14 @@ class RemoteAlbumState {
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'RemoteAlbumState(albums: ${albums.length}, filteredAlbums: ${filteredAlbums.length})';
|
||||
String toString() => 'RemoteAlbumState(albums: ${albums.length}, filteredAlbums: ${filteredAlbums.length})';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant RemoteAlbumState other) {
|
||||
if (identical(this, other)) return true;
|
||||
final listEquals = const DeepCollectionEquality().equals;
|
||||
|
||||
return listEquals(other.albums, albums) &&
|
||||
listEquals(other.filteredAlbums, filteredAlbums);
|
||||
return listEquals(other.albums, albums) && listEquals(other.filteredAlbums, filteredAlbums);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -101,8 +99,7 @@ class RemoteAlbumNotifier extends Notifier<RemoteAlbumState> {
|
||||
RemoteAlbumSortMode sortMode, {
|
||||
bool isReverse = false,
|
||||
}) {
|
||||
final sortedAlbums = _remoteAlbumService
|
||||
.sortAlbums(state.filteredAlbums, sortMode, isReverse: isReverse);
|
||||
final sortedAlbums = _remoteAlbumService.sortAlbums(state.filteredAlbums, sortMode, isReverse: isReverse);
|
||||
state = state.copyWith(filteredAlbums: sortedAlbums);
|
||||
}
|
||||
|
||||
@@ -169,12 +166,9 @@ class RemoteAlbumNotifier extends Notifier<RemoteAlbumState> {
|
||||
}
|
||||
|
||||
Future<RemoteAlbum?> toggleAlbumOrder(String albumId) async {
|
||||
final currentAlbum =
|
||||
state.albums.firstWhere((album) => album.id == albumId);
|
||||
final currentAlbum = state.albums.firstWhere((album) => album.id == albumId);
|
||||
|
||||
final newOrder = currentAlbum.order == AlbumAssetOrder.asc
|
||||
? AlbumAssetOrder.desc
|
||||
: AlbumAssetOrder.asc;
|
||||
final newOrder = currentAlbum.order == AlbumAssetOrder.asc ? AlbumAssetOrder.desc : AlbumAssetOrder.asc;
|
||||
|
||||
return updateAlbum(albumId, order: newOrder);
|
||||
}
|
||||
@@ -182,10 +176,8 @@ class RemoteAlbumNotifier extends Notifier<RemoteAlbumState> {
|
||||
Future<void> deleteAlbum(String albumId) async {
|
||||
await _remoteAlbumService.deleteAlbum(albumId);
|
||||
|
||||
final updatedAlbums =
|
||||
state.albums.where((album) => album.id != albumId).toList();
|
||||
final updatedFilteredAlbums =
|
||||
state.filteredAlbums.where((album) => album.id != albumId).toList();
|
||||
final updatedAlbums = state.albums.where((album) => album.id != albumId).toList();
|
||||
final updatedFilteredAlbums = state.filteredAlbums.where((album) => album.id != albumId).toList();
|
||||
|
||||
state = state.copyWith(
|
||||
albums: updatedAlbums,
|
||||
@@ -212,16 +204,14 @@ class RemoteAlbumNotifier extends Notifier<RemoteAlbumState> {
|
||||
}
|
||||
}
|
||||
|
||||
final remoteAlbumDateRangeProvider =
|
||||
FutureProvider.family<(DateTime, DateTime), String>(
|
||||
final remoteAlbumDateRangeProvider = FutureProvider.family<(DateTime, DateTime), String>(
|
||||
(ref, albumId) async {
|
||||
final service = ref.watch(remoteAlbumServiceProvider);
|
||||
return service.getDateRange(albumId);
|
||||
},
|
||||
);
|
||||
|
||||
final remoteAlbumSharedUsersProvider =
|
||||
FutureProvider.autoDispose.family<List<UserDto>, String>(
|
||||
final remoteAlbumSharedUsersProvider = FutureProvider.autoDispose.family<List<UserDto>, String>(
|
||||
(ref, albumId) async {
|
||||
final link = ref.keepAlive();
|
||||
ref.onDispose(() => link.close());
|
||||
|
||||
@@ -5,8 +5,7 @@ import 'package:immich_mobile/providers/infrastructure/store.provider.dart';
|
||||
|
||||
class SettingsNotifier extends Notifier<SettingsService> {
|
||||
@override
|
||||
SettingsService build() =>
|
||||
SettingsService(storeService: ref.read(storeServiceProvider));
|
||||
SettingsService build() => SettingsService(storeService: ref.read(storeServiceProvider));
|
||||
|
||||
T get<T>(Setting<T> setting) => state.get(setting);
|
||||
|
||||
@@ -18,5 +17,4 @@ class SettingsNotifier extends Notifier<SettingsService> {
|
||||
Stream<T> watch<T>(Setting<T> setting) => state.watch(setting);
|
||||
}
|
||||
|
||||
final settingsProvider =
|
||||
NotifierProvider<SettingsNotifier, SettingsService>(SettingsNotifier.new);
|
||||
final settingsProvider = NotifierProvider<SettingsNotifier, SettingsService>(SettingsNotifier.new);
|
||||
|
||||
@@ -7,8 +7,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'store.provider.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
IsarStoreRepository storeRepository(Ref ref) =>
|
||||
IsarStoreRepository(ref.watch(isarProvider));
|
||||
IsarStoreRepository storeRepository(Ref ref) => IsarStoreRepository(ref.watch(isarProvider));
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
StoreService storeService(Ref _) => StoreService.I;
|
||||
|
||||
@@ -11,15 +11,13 @@ final timelineRepositoryProvider = Provider<DriftTimelineRepository>(
|
||||
);
|
||||
|
||||
final timelineArgsProvider = Provider.autoDispose<TimelineArgs>(
|
||||
(ref) =>
|
||||
throw UnimplementedError('Will be overridden through a ProviderScope.'),
|
||||
(ref) => throw UnimplementedError('Will be overridden through a ProviderScope.'),
|
||||
);
|
||||
|
||||
final timelineServiceProvider = Provider<TimelineService>(
|
||||
(ref) {
|
||||
final timelineUsers = ref.watch(timelineUsersProvider).valueOrNull ?? [];
|
||||
final timelineService =
|
||||
ref.watch(timelineFactoryProvider).main(timelineUsers);
|
||||
final timelineService = ref.watch(timelineFactoryProvider).main(timelineUsers);
|
||||
ref.onDispose(timelineService.dispose);
|
||||
return timelineService;
|
||||
},
|
||||
@@ -42,8 +40,6 @@ final timelineUsersProvider = StreamProvider<List<String>>(
|
||||
return Stream.value([]);
|
||||
}
|
||||
|
||||
return ref
|
||||
.watch(timelineRepositoryProvider)
|
||||
.watchTimelineUserIds(currentUserId);
|
||||
return ref.watch(timelineRepositoryProvider).watchTimelineUserIds(currentUserId);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -15,12 +15,10 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'user.provider.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
IsarUserRepository userRepository(Ref ref) =>
|
||||
IsarUserRepository(ref.watch(isarProvider));
|
||||
IsarUserRepository userRepository(Ref ref) => IsarUserRepository(ref.watch(isarProvider));
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
UserApiRepository userApiRepository(Ref ref) =>
|
||||
UserApiRepository(ref.watch(apiServiceProvider).usersApi);
|
||||
UserApiRepository userApiRepository(Ref ref) => UserApiRepository(ref.watch(apiServiceProvider).usersApi);
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
UserService userService(Ref ref) => UserService(
|
||||
@@ -41,7 +39,6 @@ final driftPartnerServiceProvider = Provider<DriftPartnerService>(
|
||||
),
|
||||
);
|
||||
|
||||
final partnerUsersProvider =
|
||||
NotifierProvider<PartnerNotifier, List<PartnerUserDto>>(
|
||||
final partnerUsersProvider = NotifierProvider<PartnerNotifier, List<PartnerUserDto>>(
|
||||
PartnerNotifier.new,
|
||||
);
|
||||
|
||||
@@ -9,8 +9,7 @@ import 'package:immich_mobile/services/local_auth.service.dart';
|
||||
import 'package:immich_mobile/services/secure_storage.service.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
final localAuthProvider =
|
||||
StateNotifierProvider<LocalAuthNotifier, BiometricStatus>((ref) {
|
||||
final localAuthProvider = StateNotifierProvider<LocalAuthNotifier, BiometricStatus>((ref) {
|
||||
return LocalAuthNotifier(
|
||||
ref.watch(localAuthServiceProvider),
|
||||
ref.watch(secureStorageServiceProvider),
|
||||
@@ -39,8 +38,7 @@ class LocalAuthNotifier extends StateNotifier<BiometricStatus> {
|
||||
}
|
||||
|
||||
Future<bool> registerBiometric(BuildContext context, String pinCode) async {
|
||||
final isAuthenticated =
|
||||
await authenticate(context, 'Authenticate to enable biometrics');
|
||||
final isAuthenticated = await authenticate(context, 'Authenticate to enable biometrics');
|
||||
|
||||
if (!isAuthenticated) {
|
||||
return false;
|
||||
|
||||
@@ -16,8 +16,7 @@ Future<List<MapMarker>> mapMarkers(Ref ref) async {
|
||||
bool isWithPartners = mapState.withPartners;
|
||||
|
||||
if (mapState.relativeTime != 0) {
|
||||
fileCreatedAfter =
|
||||
DateTime.now().subtract(Duration(days: mapState.relativeTime));
|
||||
fileCreatedAfter = DateTime.now().subtract(Duration(days: mapState.relativeTime));
|
||||
}
|
||||
|
||||
if (mapState.showFavoriteOnly) {
|
||||
|
||||
@@ -13,22 +13,15 @@ class MapStateNotifier extends _$MapStateNotifier {
|
||||
MapState build() {
|
||||
final appSettingsProvider = ref.read(appSettingsServiceProvider);
|
||||
|
||||
final lightStyleUrl =
|
||||
ref.read(serverInfoProvider).serverConfig.mapLightStyleUrl;
|
||||
final darkStyleUrl =
|
||||
ref.read(serverInfoProvider).serverConfig.mapDarkStyleUrl;
|
||||
final lightStyleUrl = ref.read(serverInfoProvider).serverConfig.mapLightStyleUrl;
|
||||
final darkStyleUrl = ref.read(serverInfoProvider).serverConfig.mapDarkStyleUrl;
|
||||
|
||||
return MapState(
|
||||
themeMode: ThemeMode.values[
|
||||
appSettingsProvider.getSetting<int>(AppSettingsEnum.mapThemeMode)],
|
||||
showFavoriteOnly: appSettingsProvider
|
||||
.getSetting<bool>(AppSettingsEnum.mapShowFavoriteOnly),
|
||||
includeArchived: appSettingsProvider
|
||||
.getSetting<bool>(AppSettingsEnum.mapIncludeArchived),
|
||||
withPartners:
|
||||
appSettingsProvider.getSetting<bool>(AppSettingsEnum.mapwithPartners),
|
||||
relativeTime:
|
||||
appSettingsProvider.getSetting<int>(AppSettingsEnum.mapRelativeDate),
|
||||
themeMode: ThemeMode.values[appSettingsProvider.getSetting<int>(AppSettingsEnum.mapThemeMode)],
|
||||
showFavoriteOnly: appSettingsProvider.getSetting<bool>(AppSettingsEnum.mapShowFavoriteOnly),
|
||||
includeArchived: appSettingsProvider.getSetting<bool>(AppSettingsEnum.mapIncludeArchived),
|
||||
withPartners: appSettingsProvider.getSetting<bool>(AppSettingsEnum.mapwithPartners),
|
||||
relativeTime: appSettingsProvider.getSetting<int>(AppSettingsEnum.mapRelativeDate),
|
||||
lightStyleFetched: AsyncData(lightStyleUrl),
|
||||
darkStyleFetched: AsyncData(darkStyleUrl),
|
||||
);
|
||||
|
||||
@@ -2,8 +2,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/models/memories/memory.model.dart';
|
||||
import 'package:immich_mobile/services/memory.service.dart';
|
||||
|
||||
final memoryFutureProvider =
|
||||
FutureProvider.autoDispose<List<Memory>?>((ref) async {
|
||||
final memoryFutureProvider = FutureProvider.autoDispose<List<Memory>?>((ref) async {
|
||||
final service = ref.watch(memoryServiceProvider);
|
||||
|
||||
return await service.getMemoryLane();
|
||||
|
||||
@@ -6,9 +6,7 @@ import 'package:permission_handler/permission_handler.dart';
|
||||
class NotificationPermissionNotifier extends StateNotifier<PermissionStatus> {
|
||||
NotificationPermissionNotifier()
|
||||
: super(
|
||||
Platform.isAndroid
|
||||
? PermissionStatus.granted
|
||||
: PermissionStatus.restricted,
|
||||
Platform.isAndroid ? PermissionStatus.granted : PermissionStatus.restricted,
|
||||
) {
|
||||
// Sets the initial state
|
||||
getNotificationPermission().then((p) => state = p);
|
||||
@@ -40,7 +38,6 @@ class NotificationPermissionNotifier extends StateNotifier<PermissionStatus> {
|
||||
}
|
||||
}
|
||||
|
||||
final notificationPermissionProvider =
|
||||
StateNotifierProvider<NotificationPermissionNotifier, PermissionStatus>(
|
||||
final notificationPermissionProvider = StateNotifierProvider<NotificationPermissionNotifier, PermissionStatus>(
|
||||
(ref) => NotificationPermissionNotifier(),
|
||||
);
|
||||
|
||||
@@ -2,5 +2,4 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/services/oauth.service.dart';
|
||||
import 'package:immich_mobile/providers/api.provider.dart';
|
||||
|
||||
final oAuthServiceProvider =
|
||||
Provider((ref) => OAuthService(ref.watch(apiServiceProvider)));
|
||||
final oAuthServiceProvider = Provider((ref) => OAuthService(ref.watch(apiServiceProvider)));
|
||||
|
||||
@@ -38,8 +38,7 @@ class PartnerSharedWithNotifier extends StateNotifier<List<UserDto>> {
|
||||
}
|
||||
}
|
||||
|
||||
final partnerSharedWithProvider =
|
||||
StateNotifierProvider<PartnerSharedWithNotifier, List<UserDto>>((ref) {
|
||||
final partnerSharedWithProvider = StateNotifierProvider<PartnerSharedWithNotifier, List<UserDto>>((ref) {
|
||||
return PartnerSharedWithNotifier(
|
||||
ref.watch(partnerServiceProvider),
|
||||
);
|
||||
@@ -73,13 +72,11 @@ class PartnerSharedByNotifier extends StateNotifier<List<UserDto>> {
|
||||
}
|
||||
}
|
||||
|
||||
final partnerSharedByProvider =
|
||||
StateNotifierProvider<PartnerSharedByNotifier, List<UserDto>>((ref) {
|
||||
final partnerSharedByProvider = StateNotifierProvider<PartnerSharedByNotifier, List<UserDto>>((ref) {
|
||||
return PartnerSharedByNotifier(ref.watch(partnerServiceProvider));
|
||||
});
|
||||
|
||||
final partnerAvailableProvider =
|
||||
FutureProvider.autoDispose<List<UserDto>>((ref) async {
|
||||
final partnerAvailableProvider = FutureProvider.autoDispose<List<UserDto>>((ref) async {
|
||||
final otherUsers = await ref.watch(otherUsersProvider.future);
|
||||
final currentPartners = ref.watch(partnerSharedByProvider);
|
||||
final available = Set<UserDto>.of(otherUsers);
|
||||
|
||||
@@ -8,16 +8,14 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'paginated_search.provider.g.dart';
|
||||
|
||||
final paginatedSearchProvider =
|
||||
StateNotifierProvider<PaginatedSearchNotifier, SearchResult>(
|
||||
final paginatedSearchProvider = StateNotifierProvider<PaginatedSearchNotifier, SearchResult>(
|
||||
(ref) => PaginatedSearchNotifier(ref.watch(searchServiceProvider)),
|
||||
);
|
||||
|
||||
class PaginatedSearchNotifier extends StateNotifier<SearchResult> {
|
||||
final SearchService _searchService;
|
||||
|
||||
PaginatedSearchNotifier(this._searchService)
|
||||
: super(const SearchResult(assets: [], nextPage: 1));
|
||||
PaginatedSearchNotifier(this._searchService) : super(const SearchResult(assets: [], nextPage: 1));
|
||||
|
||||
Future<bool> search(SearchFilter filter) async {
|
||||
if (state.nextPage == null) {
|
||||
|
||||
@@ -25,8 +25,7 @@ Future<RenderList> personAssets(Ref ref, String personId) async {
|
||||
final assets = await personService.getPersonAssets(personId);
|
||||
|
||||
final settings = ref.read(appSettingsServiceProvider);
|
||||
final groupBy =
|
||||
GroupAssetsBy.values[settings.getSetting(AppSettingsEnum.groupAssetsBy)];
|
||||
final groupBy = GroupAssetsBy.values[settings.getSetting(AppSettingsEnum.groupAssetsBy)];
|
||||
return await RenderList.fromAssets(assets, groupBy);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@ import 'package:immich_mobile/models/search/search_curated_content.model.dart';
|
||||
|
||||
import 'package:immich_mobile/services/search.service.dart';
|
||||
|
||||
final getPreviewPlacesProvider =
|
||||
FutureProvider.autoDispose<List<SearchCuratedContent>>((ref) async {
|
||||
final getPreviewPlacesProvider = FutureProvider.autoDispose<List<SearchCuratedContent>>((ref) async {
|
||||
final SearchService searchService = ref.watch(searchServiceProvider);
|
||||
|
||||
final exploreData = await searchService.getExploreData();
|
||||
@@ -13,8 +12,7 @@ final getPreviewPlacesProvider =
|
||||
return [];
|
||||
}
|
||||
|
||||
final locations =
|
||||
exploreData.firstWhere((data) => data.fieldName == "exifInfo.city").items;
|
||||
final locations = exploreData.firstWhere((data) => data.fieldName == "exifInfo.city").items;
|
||||
|
||||
final curatedContent = locations
|
||||
.map(
|
||||
@@ -28,8 +26,7 @@ final getPreviewPlacesProvider =
|
||||
return curatedContent;
|
||||
});
|
||||
|
||||
final getAllPlacesProvider =
|
||||
FutureProvider.autoDispose<List<SearchCuratedContent>>((ref) async {
|
||||
final getAllPlacesProvider = FutureProvider.autoDispose<List<SearchCuratedContent>>((ref) async {
|
||||
final SearchService searchService = ref.watch(searchServiceProvider);
|
||||
|
||||
final assetPlaces = await searchService.getAllPlaces();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
final secureStorageProvider =
|
||||
StateNotifierProvider<SecureStorageProvider, void>((ref) {
|
||||
final secureStorageProvider = StateNotifierProvider<SecureStorageProvider, void>((ref) {
|
||||
return SecureStorageProvider();
|
||||
});
|
||||
|
||||
|
||||
@@ -33,8 +33,7 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
|
||||
trashDays: 30,
|
||||
oauthButtonText: '',
|
||||
externalDomain: '',
|
||||
mapLightStyleUrl:
|
||||
'https://tiles.immich.cloud/v1/style/light.json',
|
||||
mapLightStyleUrl: 'https://tiles.immich.cloud/v1/style/light.json',
|
||||
mapDarkStyleUrl: 'https://tiles.immich.cloud/v1/style/dark.json',
|
||||
),
|
||||
serverDiskInfo: ServerDiskInfo(
|
||||
@@ -90,8 +89,7 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
|
||||
if (appVersion["major"]! > serverVersion.major) {
|
||||
state = state.copyWith(
|
||||
isVersionMismatch: true,
|
||||
versionMismatchErrorMessage:
|
||||
"profile_drawer_server_out_of_date_major".tr(),
|
||||
versionMismatchErrorMessage: "profile_drawer_server_out_of_date_major".tr(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -99,8 +97,7 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
|
||||
if (appVersion["major"]! < serverVersion.major) {
|
||||
state = state.copyWith(
|
||||
isVersionMismatch: true,
|
||||
versionMismatchErrorMessage:
|
||||
"profile_drawer_client_out_of_date_major".tr(),
|
||||
versionMismatchErrorMessage: "profile_drawer_client_out_of_date_major".tr(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -108,8 +105,7 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
|
||||
if (appVersion["minor"]! > serverVersion.minor) {
|
||||
state = state.copyWith(
|
||||
isVersionMismatch: true,
|
||||
versionMismatchErrorMessage:
|
||||
"profile_drawer_server_out_of_date_minor".tr(),
|
||||
versionMismatchErrorMessage: "profile_drawer_server_out_of_date_minor".tr(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -117,8 +113,7 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
|
||||
if (appVersion["minor"]! < serverVersion.minor) {
|
||||
state = state.copyWith(
|
||||
isVersionMismatch: true,
|
||||
versionMismatchErrorMessage:
|
||||
"profile_drawer_client_out_of_date_minor".tr(),
|
||||
versionMismatchErrorMessage: "profile_drawer_client_out_of_date_minor".tr(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -179,7 +174,6 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
|
||||
}
|
||||
}
|
||||
|
||||
final serverInfoProvider =
|
||||
StateNotifierProvider<ServerInfoNotifier, ServerInfo>((ref) {
|
||||
final serverInfoProvider = StateNotifierProvider<ServerInfoNotifier, ServerInfo>((ref) {
|
||||
return ServerInfoNotifier(ref.read(serverInfoServiceProvider));
|
||||
});
|
||||
|
||||
@@ -20,9 +20,7 @@ class SharedLinksNotifier extends StateNotifier<AsyncValue<List<SharedLink>>> {
|
||||
}
|
||||
}
|
||||
|
||||
final sharedLinksStateProvider =
|
||||
StateNotifierProvider<SharedLinksNotifier, AsyncValue<List<SharedLink>>>(
|
||||
(ref) {
|
||||
final sharedLinksStateProvider = StateNotifierProvider<SharedLinksNotifier, AsyncValue<List<SharedLink>>>((ref) {
|
||||
return SharedLinksNotifier(
|
||||
ref.watch(sharedLinkServiceProvider),
|
||||
);
|
||||
|
||||
@@ -92,8 +92,7 @@ class SyncStatusNotifier extends Notifier<SyncStatusState> {
|
||||
|
||||
void startRemoteSync() => setRemoteSyncStatus(SyncStatus.syncing);
|
||||
void completeRemoteSync() => setRemoteSyncStatus(SyncStatus.success);
|
||||
void errorRemoteSync(String error) =>
|
||||
setRemoteSyncStatus(SyncStatus.error, error);
|
||||
void errorRemoteSync(String error) => setRemoteSyncStatus(SyncStatus.error, error);
|
||||
|
||||
///
|
||||
/// Local Sync
|
||||
@@ -108,8 +107,7 @@ class SyncStatusNotifier extends Notifier<SyncStatusState> {
|
||||
|
||||
void startLocalSync() => setLocalSyncStatus(SyncStatus.syncing);
|
||||
void completeLocalSync() => setLocalSyncStatus(SyncStatus.success);
|
||||
void errorLocalSync(String error) =>
|
||||
setLocalSyncStatus(SyncStatus.error, error);
|
||||
void errorLocalSync(String error) => setLocalSyncStatus(SyncStatus.error, error);
|
||||
|
||||
///
|
||||
/// Hash Job
|
||||
@@ -127,7 +125,6 @@ class SyncStatusNotifier extends Notifier<SyncStatusState> {
|
||||
void errorHashJob(String error) => setHashJobStatus(SyncStatus.error, error);
|
||||
}
|
||||
|
||||
final syncStatusProvider =
|
||||
NotifierProvider<SyncStatusNotifier, SyncStatusState>(
|
||||
final syncStatusProvider = NotifierProvider<SyncStatusNotifier, SyncStatusState>(
|
||||
SyncStatusNotifier.new,
|
||||
);
|
||||
|
||||
@@ -9,9 +9,7 @@ import 'package:immich_mobile/providers/app_settings.provider.dart';
|
||||
import 'package:immich_mobile/services/app_settings.service.dart';
|
||||
|
||||
final immichThemeModeProvider = StateProvider<ThemeMode>((ref) {
|
||||
final themeMode = ref
|
||||
.watch(appSettingsServiceProvider)
|
||||
.getSetting(AppSettingsEnum.themeMode);
|
||||
final themeMode = ref.watch(appSettingsServiceProvider).getSetting(AppSettingsEnum.themeMode);
|
||||
|
||||
debugPrint("Current themeMode $themeMode");
|
||||
|
||||
@@ -26,14 +24,12 @@ final immichThemeModeProvider = StateProvider<ThemeMode>((ref) {
|
||||
|
||||
final immichThemePresetProvider = StateProvider<ImmichColorPreset>((ref) {
|
||||
final appSettingsProvider = ref.watch(appSettingsServiceProvider);
|
||||
final primaryColorPreset =
|
||||
appSettingsProvider.getSetting(AppSettingsEnum.primaryColor);
|
||||
final primaryColorPreset = appSettingsProvider.getSetting(AppSettingsEnum.primaryColor);
|
||||
|
||||
debugPrint("Current theme preset $primaryColorPreset");
|
||||
|
||||
try {
|
||||
return ImmichColorPreset.values
|
||||
.firstWhere((e) => e.name == primaryColorPreset);
|
||||
return ImmichColorPreset.values.firstWhere((e) => e.name == primaryColorPreset);
|
||||
} catch (e) {
|
||||
debugPrint(
|
||||
"Theme preset $primaryColorPreset not found. Applying default preset.",
|
||||
@@ -47,15 +43,11 @@ final immichThemePresetProvider = StateProvider<ImmichColorPreset>((ref) {
|
||||
});
|
||||
|
||||
final dynamicThemeSettingProvider = StateProvider<bool>((ref) {
|
||||
return ref
|
||||
.watch(appSettingsServiceProvider)
|
||||
.getSetting(AppSettingsEnum.dynamicTheme);
|
||||
return ref.watch(appSettingsServiceProvider).getSetting(AppSettingsEnum.dynamicTheme);
|
||||
});
|
||||
|
||||
final colorfulInterfaceSettingProvider = StateProvider<bool>((ref) {
|
||||
return ref
|
||||
.watch(appSettingsServiceProvider)
|
||||
.getSetting(AppSettingsEnum.colorfulInterface);
|
||||
return ref.watch(appSettingsServiceProvider).getSetting(AppSettingsEnum.colorfulInterface);
|
||||
});
|
||||
|
||||
// Provider for current selected theme
|
||||
@@ -64,11 +56,7 @@ final immichThemeProvider = StateProvider<ImmichTheme>((ref) {
|
||||
final useSystemColor = ref.watch(dynamicThemeSettingProvider);
|
||||
final useColorfulInterface = ref.watch(colorfulInterfaceSettingProvider);
|
||||
final ImmichTheme? dynamicTheme = DynamicTheme.theme;
|
||||
final currentTheme = (useSystemColor && dynamicTheme != null)
|
||||
? dynamicTheme
|
||||
: primaryColorPreset.themeOfPreset;
|
||||
final currentTheme = (useSystemColor && dynamicTheme != null) ? dynamicTheme : primaryColorPreset.themeOfPreset;
|
||||
|
||||
return useColorfulInterface
|
||||
? currentTheme
|
||||
: decolorizeSurfaces(theme: currentTheme);
|
||||
return useColorfulInterface ? currentTheme : decolorizeSurfaces(theme: currentTheme);
|
||||
});
|
||||
|
||||
@@ -18,8 +18,7 @@ final singleUserTimelineProvider = StreamProvider.family<RenderList, String?>(
|
||||
dependencies: [localeProvider],
|
||||
);
|
||||
|
||||
final multiUsersTimelineProvider =
|
||||
StreamProvider.family<RenderList, List<String>>(
|
||||
final multiUsersTimelineProvider = StreamProvider.family<RenderList, List<String>>(
|
||||
(ref, userIds) {
|
||||
ref.watch(localeProvider);
|
||||
final timelineService = ref.watch(timelineServiceProvider);
|
||||
@@ -28,8 +27,7 @@ final multiUsersTimelineProvider =
|
||||
dependencies: [localeProvider],
|
||||
);
|
||||
|
||||
final albumTimelineProvider =
|
||||
StreamProvider.autoDispose.family<RenderList, int>((ref, id) {
|
||||
final albumTimelineProvider = StreamProvider.autoDispose.family<RenderList, int>((ref, id) {
|
||||
final album = ref.watch(albumWatcher(id)).value;
|
||||
final timelineService = ref.watch(timelineServiceProvider);
|
||||
|
||||
@@ -65,8 +63,7 @@ final assetSelectionTimelineProvider = StreamProvider<RenderList>((ref) {
|
||||
return timelineService.watchAssetSelectionTimeline();
|
||||
});
|
||||
|
||||
final assetsTimelineProvider =
|
||||
FutureProvider.family<RenderList, List<Asset>>((ref, assets) {
|
||||
final assetsTimelineProvider = FutureProvider.family<RenderList, List<Asset>>((ref, assets) {
|
||||
final timelineService = ref.watch(timelineServiceProvider);
|
||||
return timelineService.getTimelineFromAssets(
|
||||
assets,
|
||||
|
||||
@@ -5,8 +5,7 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
import 'package:immich_mobile/domain/services/timeline.service.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
||||
|
||||
final multiSelectProvider =
|
||||
NotifierProvider<MultiSelectNotifier, MultiSelectState>(
|
||||
final multiSelectProvider = NotifierProvider<MultiSelectNotifier, MultiSelectState>(
|
||||
MultiSelectNotifier.new,
|
||||
dependencies: [timelineServiceProvider],
|
||||
);
|
||||
@@ -26,9 +25,7 @@ class MultiSelectState {
|
||||
|
||||
/// Cloud only
|
||||
bool get hasRemote => selectedAssets.any(
|
||||
(asset) =>
|
||||
asset.storage == AssetState.remote ||
|
||||
asset.storage == AssetState.merged,
|
||||
(asset) => asset.storage == AssetState.remote || asset.storage == AssetState.merged,
|
||||
);
|
||||
|
||||
bool get hasLocal => selectedAssets.any(
|
||||
@@ -46,8 +43,7 @@ class MultiSelectState {
|
||||
}) {
|
||||
return MultiSelectState(
|
||||
selectedAssets: selectedAssets ?? this.selectedAssets,
|
||||
lockedSelectionAssets:
|
||||
lockedSelectionAssets ?? this.lockedSelectionAssets,
|
||||
lockedSelectionAssets: lockedSelectionAssets ?? this.lockedSelectionAssets,
|
||||
forceEnable: forceEnable ?? this.forceEnable,
|
||||
);
|
||||
}
|
||||
@@ -67,10 +63,7 @@ class MultiSelectState {
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
selectedAssets.hashCode ^
|
||||
lockedSelectionAssets.hashCode ^
|
||||
forceEnable.hashCode;
|
||||
int get hashCode => selectedAssets.hashCode ^ lockedSelectionAssets.hashCode ^ forceEnable.hashCode;
|
||||
}
|
||||
|
||||
class MultiSelectNotifier extends Notifier<MultiSelectState> {
|
||||
@@ -155,8 +148,7 @@ class MultiSelectNotifier extends Notifier<MultiSelectState> {
|
||||
if (bucketAssets.isEmpty) return;
|
||||
|
||||
// Check if all assets in this bucket are currently selected
|
||||
final allSelected =
|
||||
bucketAssets.every((asset) => state.selectedAssets.contains(asset));
|
||||
final allSelected = bucketAssets.every((asset) => state.selectedAssets.contains(asset));
|
||||
|
||||
final selectedAssets = state.selectedAssets.toSet();
|
||||
|
||||
@@ -180,8 +172,7 @@ class MultiSelectNotifier extends Notifier<MultiSelectState> {
|
||||
|
||||
final bucketSelectionProvider = Provider.family<bool, List<BaseAsset>>(
|
||||
(ref, bucketAssets) {
|
||||
final selectedAssets =
|
||||
ref.watch(multiSelectProvider.select((s) => s.selectedAssets));
|
||||
final selectedAssets = ref.watch(multiSelectProvider.select((s) => s.selectedAssets));
|
||||
|
||||
if (bucketAssets.isEmpty) return false;
|
||||
|
||||
|
||||
@@ -50,28 +50,23 @@ class UploadProfileImageState {
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory UploadProfileImageState.fromJson(String source) =>
|
||||
UploadProfileImageState.fromMap(json.decode(source));
|
||||
factory UploadProfileImageState.fromJson(String source) => UploadProfileImageState.fromMap(json.decode(source));
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'UploadProfileImageState(status: $status, profileImagePath: $profileImagePath)';
|
||||
String toString() => 'UploadProfileImageState(status: $status, profileImagePath: $profileImagePath)';
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is UploadProfileImageState &&
|
||||
other.status == status &&
|
||||
other.profileImagePath == profileImagePath;
|
||||
return other is UploadProfileImageState && other.status == status && other.profileImagePath == profileImagePath;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => status.hashCode ^ profileImagePath.hashCode;
|
||||
}
|
||||
|
||||
class UploadProfileImageNotifier
|
||||
extends StateNotifier<UploadProfileImageState> {
|
||||
class UploadProfileImageNotifier extends StateNotifier<UploadProfileImageState> {
|
||||
UploadProfileImageNotifier(this._userService)
|
||||
: super(
|
||||
const UploadProfileImageState(
|
||||
@@ -104,7 +99,6 @@ class UploadProfileImageNotifier
|
||||
}
|
||||
}
|
||||
|
||||
final uploadProfileImageProvider =
|
||||
StateNotifierProvider<UploadProfileImageNotifier, UploadProfileImageState>(
|
||||
final uploadProfileImageProvider = StateNotifierProvider<UploadProfileImageNotifier, UploadProfileImageState>(
|
||||
((ref) => UploadProfileImageNotifier(ref.watch(userServiceProvider))),
|
||||
);
|
||||
|
||||
@@ -10,8 +10,7 @@ import 'package:immich_mobile/services/timeline.service.dart';
|
||||
class CurrentUserProvider extends StateNotifier<UserDto?> {
|
||||
CurrentUserProvider(this._userService) : super(null) {
|
||||
state = _userService.tryGetMyUser();
|
||||
streamSub =
|
||||
_userService.watchMyUser().listen((user) => state = user ?? state);
|
||||
streamSub = _userService.watchMyUser().listen((user) => state = user ?? state);
|
||||
}
|
||||
|
||||
final UserService _userService;
|
||||
@@ -30,8 +29,7 @@ class CurrentUserProvider extends StateNotifier<UserDto?> {
|
||||
}
|
||||
}
|
||||
|
||||
final currentUserProvider =
|
||||
StateNotifierProvider<CurrentUserProvider, UserDto?>((ref) {
|
||||
final currentUserProvider = StateNotifierProvider<CurrentUserProvider, UserDto?>((ref) {
|
||||
return CurrentUserProvider(ref.watch(userServiceProvider));
|
||||
});
|
||||
|
||||
@@ -56,7 +54,6 @@ class TimelineUserIdsProvider extends StateNotifier<List<String>> {
|
||||
}
|
||||
}
|
||||
|
||||
final timelineUsersIdsProvider =
|
||||
StateNotifierProvider<TimelineUserIdsProvider, List<String>>((ref) {
|
||||
final timelineUsersIdsProvider = StateNotifierProvider<TimelineUserIdsProvider, List<String>>((ref) {
|
||||
return TimelineUserIdsProvider(ref.watch(timelineServiceProvider));
|
||||
});
|
||||
|
||||
@@ -78,16 +78,13 @@ class WebsocketState {
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'WebsocketState(socket: $socket, isConnected: $isConnected)';
|
||||
String toString() => 'WebsocketState(socket: $socket, isConnected: $isConnected)';
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is WebsocketState &&
|
||||
other.socket == socket &&
|
||||
other.isConnected == isConnected;
|
||||
return other is WebsocketState && other.socket == socket && other.isConnected == isConnected;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -106,8 +103,7 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
|
||||
final _log = Logger('WebsocketNotifier');
|
||||
final Ref _ref;
|
||||
final Debouncer _debounce =
|
||||
Debouncer(interval: const Duration(milliseconds: 500));
|
||||
final Debouncer _debounce = Debouncer(interval: const Duration(milliseconds: 500));
|
||||
|
||||
final Debouncer _batchDebouncer = Debouncer(
|
||||
interval: const Duration(seconds: 5),
|
||||
@@ -131,8 +127,7 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
final endpoint = Uri.parse(Store.get(StoreKey.serverEndpoint));
|
||||
final headers = ApiService.getRequestHeaders();
|
||||
if (endpoint.userInfo.isNotEmpty) {
|
||||
headers["Authorization"] =
|
||||
"Basic ${base64.encode(utf8.encode(endpoint.userInfo))}";
|
||||
headers["Authorization"] = "Basic ${base64.encode(utf8.encode(endpoint.userInfo))}";
|
||||
}
|
||||
|
||||
debugPrint("Attempting to connect to websocket");
|
||||
@@ -262,49 +257,34 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
}
|
||||
|
||||
Future<void> _handlePendingTrashes() async {
|
||||
final trashChanges = state.pendingChanges
|
||||
.where((c) => c.action == PendingAction.assetTrash)
|
||||
.toList();
|
||||
final trashChanges = state.pendingChanges.where((c) => c.action == PendingAction.assetTrash).toList();
|
||||
if (trashChanges.isNotEmpty) {
|
||||
List<String> remoteIds = trashChanges
|
||||
.expand((a) => (a.value as List).map((e) => e.toString()))
|
||||
.toList();
|
||||
List<String> remoteIds = trashChanges.expand((a) => (a.value as List).map((e) => e.toString())).toList();
|
||||
|
||||
await _ref.read(syncServiceProvider).handleRemoteAssetRemoval(remoteIds);
|
||||
await _ref.read(assetProvider.notifier).getAllAsset();
|
||||
|
||||
state = state.copyWith(
|
||||
pendingChanges: state.pendingChanges
|
||||
.whereNot((c) => trashChanges.contains(c))
|
||||
.toList(),
|
||||
pendingChanges: state.pendingChanges.whereNot((c) => trashChanges.contains(c)).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _handlePendingDeletes() async {
|
||||
final deleteChanges = state.pendingChanges
|
||||
.where((c) => c.action == PendingAction.assetDelete)
|
||||
.toList();
|
||||
final deleteChanges = state.pendingChanges.where((c) => c.action == PendingAction.assetDelete).toList();
|
||||
if (deleteChanges.isNotEmpty) {
|
||||
List<String> remoteIds =
|
||||
deleteChanges.map((a) => a.value.toString()).toList();
|
||||
List<String> remoteIds = deleteChanges.map((a) => a.value.toString()).toList();
|
||||
await _ref.read(syncServiceProvider).handleRemoteAssetRemoval(remoteIds);
|
||||
state = state.copyWith(
|
||||
pendingChanges: state.pendingChanges
|
||||
.whereNot((c) => deleteChanges.contains(c))
|
||||
.toList(),
|
||||
pendingChanges: state.pendingChanges.whereNot((c) => deleteChanges.contains(c)).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _handlePendingUploaded() async {
|
||||
final uploadedChanges = state.pendingChanges
|
||||
.where((c) => c.action == PendingAction.assetUploaded)
|
||||
.toList();
|
||||
final uploadedChanges = state.pendingChanges.where((c) => c.action == PendingAction.assetUploaded).toList();
|
||||
if (uploadedChanges.isNotEmpty) {
|
||||
List<AssetResponseDto?> remoteAssets = uploadedChanges
|
||||
.map((a) => AssetResponseDto.fromJson(a.value))
|
||||
.toList();
|
||||
List<AssetResponseDto?> remoteAssets = uploadedChanges.map((a) => AssetResponseDto.fromJson(a.value)).toList();
|
||||
for (final dto in remoteAssets) {
|
||||
if (dto != null) {
|
||||
final newAsset = Asset.remote(dto);
|
||||
@@ -312,27 +292,20 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
}
|
||||
}
|
||||
state = state.copyWith(
|
||||
pendingChanges: state.pendingChanges
|
||||
.whereNot((c) => uploadedChanges.contains(c))
|
||||
.toList(),
|
||||
pendingChanges: state.pendingChanges.whereNot((c) => uploadedChanges.contains(c)).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _handlingPendingHidden() async {
|
||||
final hiddenChanges = state.pendingChanges
|
||||
.where((c) => c.action == PendingAction.assetHidden)
|
||||
.toList();
|
||||
final hiddenChanges = state.pendingChanges.where((c) => c.action == PendingAction.assetHidden).toList();
|
||||
if (hiddenChanges.isNotEmpty) {
|
||||
List<String> remoteIds =
|
||||
hiddenChanges.map((a) => a.value.toString()).toList();
|
||||
List<String> remoteIds = hiddenChanges.map((a) => a.value.toString()).toList();
|
||||
final db = _ref.watch(dbProvider);
|
||||
await db.writeTxn(() => db.assets.deleteAllByRemoteId(remoteIds));
|
||||
|
||||
state = state.copyWith(
|
||||
pendingChanges: state.pendingChanges
|
||||
.whereNot((c) => hiddenChanges.contains(c))
|
||||
.toList(),
|
||||
pendingChanges: state.pendingChanges.whereNot((c) => hiddenChanges.contains(c)).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -354,18 +327,15 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
_ref.read(assetProvider.notifier).getAllAsset();
|
||||
}
|
||||
|
||||
void _handleOnUploadSuccess(dynamic data) =>
|
||||
addPendingChange(PendingAction.assetUploaded, data);
|
||||
void _handleOnUploadSuccess(dynamic data) => addPendingChange(PendingAction.assetUploaded, data);
|
||||
|
||||
void _handleOnAssetDelete(dynamic data) =>
|
||||
addPendingChange(PendingAction.assetDelete, data);
|
||||
void _handleOnAssetDelete(dynamic data) => addPendingChange(PendingAction.assetDelete, data);
|
||||
|
||||
void _handleOnAssetTrash(dynamic data) {
|
||||
addPendingChange(PendingAction.assetTrash, data);
|
||||
}
|
||||
|
||||
void _handleOnAssetHidden(dynamic data) =>
|
||||
addPendingChange(PendingAction.assetHidden, data);
|
||||
void _handleOnAssetHidden(dynamic data) => addPendingChange(PendingAction.assetHidden, data);
|
||||
|
||||
_handleReleaseUpdates(dynamic data) {
|
||||
// Json guard
|
||||
@@ -374,27 +344,21 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
}
|
||||
|
||||
final json = data.cast<String, dynamic>();
|
||||
final serverVersionJson =
|
||||
json.containsKey('serverVersion') ? json['serverVersion'] : null;
|
||||
final releaseVersionJson =
|
||||
json.containsKey('releaseVersion') ? json['releaseVersion'] : null;
|
||||
final serverVersionJson = json.containsKey('serverVersion') ? json['serverVersion'] : null;
|
||||
final releaseVersionJson = json.containsKey('releaseVersion') ? json['releaseVersion'] : null;
|
||||
if (serverVersionJson == null || releaseVersionJson == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final serverVersionDto =
|
||||
ServerVersionResponseDto.fromJson(serverVersionJson);
|
||||
final releaseVersionDto =
|
||||
ServerVersionResponseDto.fromJson(releaseVersionJson);
|
||||
final serverVersionDto = ServerVersionResponseDto.fromJson(serverVersionJson);
|
||||
final releaseVersionDto = ServerVersionResponseDto.fromJson(releaseVersionJson);
|
||||
if (serverVersionDto == null || releaseVersionDto == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final serverVersion = ServerVersion.fromDto(serverVersionDto);
|
||||
final releaseVersion = ServerVersion.fromDto(releaseVersionDto);
|
||||
_ref
|
||||
.read(serverInfoProvider.notifier)
|
||||
.handleNewRelease(serverVersion, releaseVersion);
|
||||
_ref.read(serverInfoProvider.notifier).handleNewRelease(serverVersion, releaseVersion);
|
||||
}
|
||||
|
||||
void _handleSyncAssetUploadReady(dynamic data) {
|
||||
@@ -409,9 +373,7 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
|
||||
try {
|
||||
unawaited(
|
||||
_ref
|
||||
.read(backgroundSyncProvider)
|
||||
.syncWebsocketBatch(_batchedAssetUploadReady.toList()),
|
||||
_ref.read(backgroundSyncProvider).syncWebsocketBatch(_batchedAssetUploadReady.toList()),
|
||||
);
|
||||
} catch (error) {
|
||||
_log.severe("Error processing batched AssetUploadReadyV1 events: $error");
|
||||
@@ -421,7 +383,6 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
||||
}
|
||||
}
|
||||
|
||||
final websocketProvider =
|
||||
StateNotifierProvider<WebsocketNotifier, WebsocketState>((ref) {
|
||||
final websocketProvider = StateNotifierProvider<WebsocketNotifier, WebsocketState>((ref) {
|
||||
return WebsocketNotifier(ref);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user