chore: bump line length to 120 (#20191)

This commit is contained in:
shenlong
2025-07-25 08:07:22 +05:30
committed by GitHub
parent 977c9b96ba
commit ad65e9011a
517 changed files with 4520 additions and 9514 deletions
+4 -12
View File
@@ -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;
}
+5 -10
View File
@@ -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);
});
+2 -4
View File
@@ -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);
});
+2 -4
View File
@@ -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(
+5 -11
View File
@@ -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),
);
+1 -2
View File
@@ -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(),
);
+1 -2
View File
@@ -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)));
+3 -6
View File
@@ -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();
});
+6 -12
View File
@@ -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,
);
+7 -19
View File
@@ -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);
});
+3 -6
View File
@@ -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))),
);
+3 -6
View File
@@ -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));
});
+26 -65
View File
@@ -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);
});