diff --git a/mobile/lib/modules/asset_viewer/models/image_viewer_page_state.model.dart b/mobile/lib/modules/asset_viewer/models/image_viewer_page_state.model.dart index 8590ce6890..144e4b0cf7 100644 --- a/mobile/lib/modules/asset_viewer/models/image_viewer_page_state.model.dart +++ b/mobile/lib/modules/asset_viewer/models/image_viewer_page_state.model.dart @@ -28,22 +28,26 @@ class ImageViewerPageState { factory ImageViewerPageState.fromMap(Map map) { return ImageViewerPageState( - downloadAssetStatus: DownloadAssetStatus.values[map['downloadAssetStatus'] ?? 0], + downloadAssetStatus: + DownloadAssetStatus.values[map['downloadAssetStatus'] ?? 0], ); } String toJson() => json.encode(toMap()); - factory ImageViewerPageState.fromJson(String source) => ImageViewerPageState.fromMap(json.decode(source)); + factory ImageViewerPageState.fromJson(String source) => + ImageViewerPageState.fromMap(json.decode(source)); @override - String toString() => 'ImageViewerPageState(downloadAssetStatus: $downloadAssetStatus)'; + String toString() => + 'ImageViewerPageState(downloadAssetStatus: $downloadAssetStatus)'; @override bool operator ==(Object other) { if (identical(this, other)) return true; - return other is ImageViewerPageState && other.downloadAssetStatus == downloadAssetStatus; + return other is ImageViewerPageState && + other.downloadAssetStatus == downloadAssetStatus; } @override diff --git a/mobile/lib/modules/asset_viewer/providers/image_viewer_page_state.provider.dart b/mobile/lib/modules/asset_viewer/providers/image_viewer_page_state.provider.dart index 1ba0029388..a9e12b848e 100644 --- a/mobile/lib/modules/asset_viewer/providers/image_viewer_page_state.provider.dart +++ b/mobile/lib/modules/asset_viewer/providers/image_viewer_page_state.provider.dart @@ -9,7 +9,9 @@ import 'package:immich_mobile/shared/ui/immich_toast.dart'; class ImageViewerStateNotifier extends StateNotifier { final ImageViewerService _imageViewerService = ImageViewerService(); - ImageViewerStateNotifier() : super(ImageViewerPageState(downloadAssetStatus: DownloadAssetStatus.idle)); + ImageViewerStateNotifier() + : super(ImageViewerPageState( + downloadAssetStatus: DownloadAssetStatus.idle)); void downloadAsset(ImmichAsset asset, BuildContext context) async { state = state.copyWith(downloadAssetStatus: DownloadAssetStatus.loading); @@ -40,4 +42,5 @@ class ImageViewerStateNotifier extends StateNotifier { } final imageViewerStateProvider = - StateNotifierProvider(((ref) => ImageViewerStateNotifier())); + StateNotifierProvider( + ((ref) => ImageViewerStateNotifier())); diff --git a/mobile/lib/modules/asset_viewer/services/image_viewer.service.dart b/mobile/lib/modules/asset_viewer/services/image_viewer.service.dart index 08e766f4a9..31a057d35f 100644 --- a/mobile/lib/modules/asset_viewer/services/image_viewer.service.dart +++ b/mobile/lib/modules/asset_viewer/services/image_viewer.service.dart @@ -15,12 +15,14 @@ class ImageViewerService { try { String fileName = p.basename(asset.originalPath); var savedEndpoint = Hive.box(userInfoBox).get(serverEndpointKey); - Uri filePath = - Uri.parse("$savedEndpoint/asset/download?aid=${asset.deviceAssetId}&did=${asset.deviceId}&isThumb=false"); + Uri filePath = Uri.parse( + "$savedEndpoint/asset/download?aid=${asset.deviceAssetId}&did=${asset.deviceId}&isThumb=false"); var res = await http.get( filePath, - headers: {"Authorization": "Bearer ${Hive.box(userInfoBox).get(accessTokenKey)}"}, + headers: { + "Authorization": "Bearer ${Hive.box(userInfoBox).get(accessTokenKey)}" + }, ); final AssetEntity? entity; diff --git a/mobile/lib/modules/backup/models/available_album.model.dart b/mobile/lib/modules/backup/models/available_album.model.dart index d202efd19e..b3a4ab3fbc 100644 --- a/mobile/lib/modules/backup/models/available_album.model.dart +++ b/mobile/lib/modules/backup/models/available_album.model.dart @@ -21,13 +21,16 @@ class AvailableAlbum { } @override - String toString() => 'AvailableAlbum(albumEntity: $albumEntity, thumbnailData: $thumbnailData)'; + String toString() => + 'AvailableAlbum(albumEntity: $albumEntity, thumbnailData: $thumbnailData)'; @override bool operator ==(Object other) { if (identical(this, other)) return true; - return other is AvailableAlbum && other.albumEntity == albumEntity && other.thumbnailData == thumbnailData; + return other is AvailableAlbum && + other.albumEntity == albumEntity && + other.thumbnailData == thumbnailData; } @override diff --git a/mobile/lib/modules/backup/models/backup_state.model.dart b/mobile/lib/modules/backup/models/backup_state.model.dart index f24b2f408f..4848bf1e39 100644 --- a/mobile/lib/modules/backup/models/backup_state.model.dart +++ b/mobile/lib/modules/backup/models/backup_state.model.dart @@ -10,7 +10,7 @@ enum BackUpProgressEnum { idle, inProgress, done } class BackUpState extends Equatable { // enum final BackUpProgressEnum backupProgress; - final List allAssetOnDatabase; + final List allAssetsInDatabase; final double progressInPercentage; final CancellationToken cancelToken; final ServerInfo serverInfo; @@ -28,7 +28,7 @@ class BackUpState extends Equatable { const BackUpState({ required this.backupProgress, - required this.allAssetOnDatabase, + required this.allAssetsInDatabase, required this.progressInPercentage, required this.cancelToken, required this.serverInfo, @@ -41,7 +41,7 @@ class BackUpState extends Equatable { BackUpState copyWith({ BackUpProgressEnum? backupProgress, - List? allAssetOnDatabase, + List? allAssetsInDatabase, double? progressInPercentage, CancellationToken? cancelToken, ServerInfo? serverInfo, @@ -53,7 +53,7 @@ class BackUpState extends Equatable { }) { return BackUpState( backupProgress: backupProgress ?? this.backupProgress, - allAssetOnDatabase: allAssetOnDatabase ?? this.allAssetOnDatabase, + allAssetsInDatabase: allAssetsInDatabase ?? this.allAssetsInDatabase, progressInPercentage: progressInPercentage ?? this.progressInPercentage, cancelToken: cancelToken ?? this.cancelToken, serverInfo: serverInfo ?? this.serverInfo, @@ -61,20 +61,21 @@ class BackUpState extends Equatable { selectedBackupAlbums: selectedBackupAlbums ?? this.selectedBackupAlbums, excludedBackupAlbums: excludedBackupAlbums ?? this.excludedBackupAlbums, allUniqueAssets: allUniqueAssets ?? this.allUniqueAssets, - selectedAlbumsBackupAssetsIds: selectedAlbumsBackupAssetsIds ?? this.selectedAlbumsBackupAssetsIds, + selectedAlbumsBackupAssetsIds: + selectedAlbumsBackupAssetsIds ?? this.selectedAlbumsBackupAssetsIds, ); } @override String toString() { - return 'BackUpState(backupProgress: $backupProgress, allAssetOnDatabase: $allAssetOnDatabase, progressInPercentage: $progressInPercentage, cancelToken: $cancelToken, serverInfo: $serverInfo, availableAlbums: $availableAlbums, selectedBackupAlbums: $selectedBackupAlbums, excludedBackupAlbums: $excludedBackupAlbums, allUniqueAssets: $allUniqueAssets, selectedAlbumsBackupAssetsIds: $selectedAlbumsBackupAssetsIds)'; + return 'BackUpState(backupProgress: $backupProgress, allAssetsInDatabase: $allAssetsInDatabase, progressInPercentage: $progressInPercentage, cancelToken: $cancelToken, serverInfo: $serverInfo, availableAlbums: $availableAlbums, selectedBackupAlbums: $selectedBackupAlbums, excludedBackupAlbums: $excludedBackupAlbums, allUniqueAssets: $allUniqueAssets, selectedAlbumsBackupAssetsIds: $selectedAlbumsBackupAssetsIds)'; } @override List get props { return [ backupProgress, - allAssetOnDatabase, + allAssetsInDatabase, progressInPercentage, cancelToken, serverInfo, diff --git a/mobile/lib/modules/backup/models/hive_backup_albums.model.dart b/mobile/lib/modules/backup/models/hive_backup_albums.model.dart index 12ca3c1310..23f21331e9 100644 --- a/mobile/lib/modules/backup/models/hive_backup_albums.model.dart +++ b/mobile/lib/modules/backup/models/hive_backup_albums.model.dart @@ -19,7 +19,8 @@ class HiveBackupAlbums { }); @override - String toString() => 'HiveBackupAlbums(selectedAlbumIds: $selectedAlbumIds, excludedAlbumsIds: $excludedAlbumsIds)'; + String toString() => + 'HiveBackupAlbums(selectedAlbumIds: $selectedAlbumIds, excludedAlbumsIds: $excludedAlbumsIds)'; HiveBackupAlbums copyWith({ List? selectedAlbumIds, @@ -49,7 +50,8 @@ class HiveBackupAlbums { String toJson() => json.encode(toMap()); - factory HiveBackupAlbums.fromJson(String source) => HiveBackupAlbums.fromMap(json.decode(source)); + factory HiveBackupAlbums.fromJson(String source) => + HiveBackupAlbums.fromMap(json.decode(source)); @override bool operator ==(Object other) { diff --git a/mobile/lib/modules/backup/providers/backup.provider.dart b/mobile/lib/modules/backup/providers/backup.provider.dart index e8efaa0068..0bcdeaab53 100644 --- a/mobile/lib/modules/backup/providers/backup.provider.dart +++ b/mobile/lib/modules/backup/providers/backup.provider.dart @@ -18,7 +18,7 @@ class BackupNotifier extends StateNotifier { : super( BackUpState( backupProgress: BackUpProgressEnum.idle, - allAssetOnDatabase: const [], + allAssetsInDatabase: const [], progressInPercentage: 0, cancelToken: CancellationToken(), serverInfo: ServerInfo( @@ -36,7 +36,9 @@ class BackupNotifier extends StateNotifier { allUniqueAssets: const {}, selectedAlbumsBackupAssetsIds: const {}, ), - ); + ) { + getBackupInfo(); + } final BackupService _backupService; final ServerInfoService _serverInfoService; @@ -93,7 +95,7 @@ class BackupNotifier extends StateNotifier { /// If this is the first time performing backup - set the default selected album to be /// the one that has all assets (Recent on Android, Recents on iOS) /// - Future getBackupAlbumsInfo() async { + Future _getBackupAlbumsInfo() async { // Get all albums on the device List availableAlbums = []; List albums = await PhotoManager.getAssetPathList( @@ -177,7 +179,7 @@ class BackupNotifier extends StateNotifier { /// Find the assets that are not overlapping between the two sets /// Those assets are unique and are used as the total assets /// - void _updateBackupAssetCount() async { + Future _updateBackupAssetCount() async { Set assetsFromSelectedAlbums = {}; Set assetsFromExcludedAlbums = {}; @@ -195,27 +197,27 @@ class BackupNotifier extends StateNotifier { Set allUniqueAssets = assetsFromSelectedAlbums.difference(assetsFromExcludedAlbums); - List allAssetOnDatabase = + List allAssetsInDatabase = await _backupService.getDeviceBackupAsset(); // Find asset that were backup from selected albums Set selectedAlbumsBackupAssets = Set.from(allUniqueAssets.map((e) => e.id)); selectedAlbumsBackupAssets - .removeWhere((assetId) => !allAssetOnDatabase.contains(assetId)); + .removeWhere((assetId) => !allAssetsInDatabase.contains(assetId)); if (allUniqueAssets.isEmpty) { debugPrint("No Asset On Device"); state = state.copyWith( backupProgress: BackUpProgressEnum.idle, - allAssetOnDatabase: allAssetOnDatabase, + allAssetsInDatabase: allAssetsInDatabase, allUniqueAssets: {}, selectedAlbumsBackupAssetsIds: selectedAlbumsBackupAssets, ); return; } else { state = state.copyWith( - allAssetOnDatabase: allAssetOnDatabase, + allAssetsInDatabase: allAssetsInDatabase, allUniqueAssets: allUniqueAssets, selectedAlbumsBackupAssetsIds: selectedAlbumsBackupAssets, ); @@ -223,6 +225,8 @@ class BackupNotifier extends StateNotifier { // Save to persistent storage _updatePersistentAlbumsSelection(); + + return; } /// @@ -230,10 +234,10 @@ class BackupNotifier extends StateNotifier { /// which albums are selected or excluded /// and then update the UI according to those information /// - void getBackupInfo() async { - await getBackupAlbumsInfo(); - _updateServerInfo(); - _updateBackupAssetCount(); + Future getBackupInfo() async { + await _getBackupAlbumsInfo(); + await _updateServerInfo(); + await _updateBackupAssetCount(); } /// @@ -256,11 +260,10 @@ class BackupNotifier extends StateNotifier { /// Invoke backup process /// void startBackupProcess() async { - _updateServerInfo(); - _updateBackupAssetCount(); - state = state.copyWith(backupProgress: BackUpProgressEnum.inProgress); + await getBackupInfo(); + var authResult = await PhotoManager.requestPermissionExtend(); if (authResult.isAuth) { await PhotoManager.clearFileCache(); @@ -271,10 +274,10 @@ class BackupNotifier extends StateNotifier { return; } - Set assetsWillBeBackup = state.allUniqueAssets; + Set assetsWillBeBackup = Set.from(state.allUniqueAssets); // Remove item that has already been backed up - for (var assetId in state.allAssetOnDatabase) { + for (var assetId in state.allAssetsInDatabase) { assetsWillBeBackup.removeWhere((e) => e.id == assetId); } @@ -301,8 +304,8 @@ class BackupNotifier extends StateNotifier { state = state.copyWith(selectedAlbumsBackupAssetsIds: { ...state.selectedAlbumsBackupAssetsIds, deviceAssetId - }, allAssetOnDatabase: [ - ...state.allAssetOnDatabase, + }, allAssetsInDatabase: [ + ...state.allAssetsInDatabase, deviceAssetId ]); @@ -321,7 +324,7 @@ class BackupNotifier extends StateNotifier { progressInPercentage: (sent.toDouble() / total.toDouble() * 100)); } - void _updateServerInfo() async { + Future _updateServerInfo() async { var serverInfo = await _serverInfoService.getServerInfo(); // Update server info diff --git a/mobile/lib/modules/backup/ui/album_info_card.dart b/mobile/lib/modules/backup/ui/album_info_card.dart index f983f43e32..afafed5fa1 100644 --- a/mobile/lib/modules/backup/ui/album_info_card.dart +++ b/mobile/lib/modules/backup/ui/album_info_card.dart @@ -14,16 +14,22 @@ class AlbumInfoCard extends HookConsumerWidget { final Uint8List? imageData; final AssetPathEntity albumInfo; - const AlbumInfoCard({Key? key, this.imageData, required this.albumInfo}) : super(key: key); + const AlbumInfoCard({Key? key, this.imageData, required this.albumInfo}) + : super(key: key); @override Widget build(BuildContext context, WidgetRef ref) { - final bool isSelected = ref.watch(backupProvider).selectedBackupAlbums.contains(albumInfo); - final bool isExcluded = ref.watch(backupProvider).excludedBackupAlbums.contains(albumInfo); + final bool isSelected = + ref.watch(backupProvider).selectedBackupAlbums.contains(albumInfo); + final bool isExcluded = + ref.watch(backupProvider).excludedBackupAlbums.contains(albumInfo); - ColorFilter selectedFilter = ColorFilter.mode(Theme.of(context).primaryColor.withAlpha(100), BlendMode.darken); - ColorFilter excludedFilter = ColorFilter.mode(Colors.red.withAlpha(75), BlendMode.darken); - ColorFilter unselectedFilter = const ColorFilter.mode(Colors.black, BlendMode.color); + ColorFilter selectedFilter = ColorFilter.mode( + Theme.of(context).primaryColor.withAlpha(100), BlendMode.darken); + ColorFilter excludedFilter = + ColorFilter.mode(Colors.red.withAlpha(75), BlendMode.darken); + ColorFilter unselectedFilter = + const ColorFilter.mode(Colors.black, BlendMode.color); _buildSelectedTextBox() { if (isSelected) { @@ -32,7 +38,8 @@ class AlbumInfoCard extends HookConsumerWidget { shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)), label: const Text( "INCLUDED", - style: TextStyle(fontSize: 10, color: Colors.white, fontWeight: FontWeight.bold), + style: TextStyle( + fontSize: 10, color: Colors.white, fontWeight: FontWeight.bold), ), backgroundColor: Theme.of(context).primaryColor, ); @@ -42,7 +49,8 @@ class AlbumInfoCard extends HookConsumerWidget { shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)), label: const Text( "EXCLUDED", - style: TextStyle(fontSize: 10, color: Colors.white, fontWeight: FontWeight.bold), + style: TextStyle( + fontSize: 10, color: Colors.white, fontWeight: FontWeight.bold), ), backgroundColor: Colors.red[300], ); @@ -85,10 +93,15 @@ class AlbumInfoCard extends HookConsumerWidget { HapticFeedback.selectionClick(); if (isExcluded) { - ref.watch(backupProvider.notifier).removeExcludedAlbumForBackup(albumInfo); + ref + .watch(backupProvider.notifier) + .removeExcludedAlbumForBackup(albumInfo); } else { if (ref.watch(backupProvider).selectedBackupAlbums.length == 1 && - ref.watch(backupProvider).selectedBackupAlbums.contains(albumInfo)) { + ref + .watch(backupProvider) + .selectedBackupAlbums + .contains(albumInfo)) { ImmichToast.show( context: context, msg: "Cannot exclude the only album", @@ -98,7 +111,9 @@ class AlbumInfoCard extends HookConsumerWidget { return; } - ref.watch(backupProvider.notifier).addExcludedAlbumForBackup(albumInfo); + ref + .watch(backupProvider.notifier) + .addExcludedAlbumForBackup(albumInfo); } }, child: Card( @@ -121,12 +136,16 @@ class AlbumInfoCard extends HookConsumerWidget { width: 200, height: 200, decoration: BoxDecoration( - borderRadius: const BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(12), + topRight: Radius.circular(12)), image: DecorationImage( colorFilter: _buildImageFilter(), image: imageData != null ? MemoryImage(imageData!) - : const AssetImage('assets/immich-logo-no-outline.png') as ImageProvider, + : const AssetImage( + 'assets/immich-logo-no-outline.png') + as ImageProvider, fit: BoxFit.cover, ), ), @@ -150,13 +169,17 @@ class AlbumInfoCard extends HookConsumerWidget { Text( albumInfo.name, style: TextStyle( - fontSize: 14, color: Theme.of(context).primaryColor, fontWeight: FontWeight.bold), + fontSize: 14, + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.bold), ), Padding( padding: const EdgeInsets.only(top: 2.0), child: Text( - albumInfo.assetCount.toString() + (albumInfo.isAll ? " (ALL)" : ""), - style: TextStyle(fontSize: 12, color: Colors.grey[600]), + albumInfo.assetCount.toString() + + (albumInfo.isAll ? " (ALL)" : ""), + style: TextStyle( + fontSize: 12, color: Colors.grey[600]), ), ) ], @@ -165,7 +188,8 @@ class AlbumInfoCard extends HookConsumerWidget { ), IconButton( onPressed: () { - AutoRouter.of(context).push(AlbumPreviewRoute(album: albumInfo)); + AutoRouter.of(context) + .push(AlbumPreviewRoute(album: albumInfo)); }, icon: Icon( Icons.image_outlined, diff --git a/mobile/lib/modules/backup/ui/backup_info_card.dart b/mobile/lib/modules/backup/ui/backup_info_card.dart index d6f52fd354..e69ff0fc78 100644 --- a/mobile/lib/modules/backup/ui/backup_info_card.dart +++ b/mobile/lib/modules/backup/ui/backup_info_card.dart @@ -4,7 +4,12 @@ class BackupInfoCard extends StatelessWidget { final String title; final String subtitle; final String info; - const BackupInfoCard({Key? key, required this.title, required this.subtitle, required this.info}) : super(key: key); + const BackupInfoCard( + {Key? key, + required this.title, + required this.subtitle, + required this.info}) + : super(key: key); @override Widget build(BuildContext context) { diff --git a/mobile/lib/modules/backup/views/album_preview_page.dart b/mobile/lib/modules/backup/views/album_preview_page.dart index 754afdb4de..561d177b7b 100644 --- a/mobile/lib/modules/backup/views/album_preview_page.dart +++ b/mobile/lib/modules/backup/views/album_preview_page.dart @@ -16,7 +16,8 @@ class AlbumPreviewPage extends HookConsumerWidget { final assets = useState>([]); _getAssetsInAlbum() async { - assets.value = await album.getAssetListRange(start: 0, end: album.assetCount); + assets.value = + await album.getAssetListRange(start: 0, end: album.assetCount); } useEffect(() { @@ -37,7 +38,10 @@ class AlbumPreviewPage extends HookConsumerWidget { padding: const EdgeInsets.only(top: 4.0), child: Text( "ID ${album.id}", - style: TextStyle(fontSize: 10, color: Colors.grey[600], fontWeight: FontWeight.bold), + style: TextStyle( + fontSize: 10, + color: Colors.grey[600], + fontWeight: FontWeight.bold), ), ), ], @@ -55,8 +59,9 @@ class AlbumPreviewPage extends HookConsumerWidget { ), itemCount: assets.value.length, itemBuilder: (context, index) { - Future thumbData = - assets.value[index].thumbnailDataWithSize(const ThumbnailSize(200, 200), quality: 50); + Future thumbData = assets.value[index] + .thumbnailDataWithSize(const ThumbnailSize(200, 200), + quality: 50); return FutureBuilder( future: thumbData, diff --git a/mobile/lib/modules/backup/views/backup_album_selection_page.dart b/mobile/lib/modules/backup/views/backup_album_selection_page.dart index 100c61057a..df14764931 100644 --- a/mobile/lib/modules/backup/views/backup_album_selection_page.dart +++ b/mobile/lib/modules/backup/views/backup_album_selection_page.dart @@ -17,7 +17,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { final excludedBackupAlbums = ref.watch(backupProvider).excludedBackupAlbums; useEffect(() { - ref.read(backupProvider.notifier).getBackupAlbumsInfo(); + ref.read(backupProvider.notifier).getBackupInfo(); return null; }, []); @@ -37,8 +37,12 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { itemBuilder: ((context, index) { var thumbnailData = availableAlbums[index].thumbnailData; return Padding( - padding: index == 0 ? const EdgeInsets.only(left: 16.00) : const EdgeInsets.all(0), - child: AlbumInfoCard(imageData: thumbnailData, albumInfo: availableAlbums[index].albumEntity), + padding: index == 0 + ? const EdgeInsets.only(left: 16.00) + : const EdgeInsets.all(0), + child: AlbumInfoCard( + imageData: thumbnailData, + albumInfo: availableAlbums[index].albumEntity), ); }), ), @@ -67,10 +71,14 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { onTap: removeSelection, child: Chip( visualDensity: VisualDensity.compact, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5)), label: Text( album.name, - style: const TextStyle(fontSize: 10, color: Colors.white, fontWeight: FontWeight.bold), + style: const TextStyle( + fontSize: 10, + color: Colors.white, + fontWeight: FontWeight.bold), ), backgroundColor: Theme.of(context).primaryColor, deleteIconColor: Colors.white, @@ -88,7 +96,9 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { _buildExcludedAlbumNameChip() { return excludedBackupAlbums.map((album) { void removeSelection() { - ref.watch(backupProvider.notifier).removeExcludedAlbumForBackup(album); + ref + .watch(backupProvider.notifier) + .removeExcludedAlbumForBackup(album); } return GestureDetector( @@ -97,10 +107,14 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { padding: const EdgeInsets.only(right: 8.0), child: Chip( visualDensity: VisualDensity.compact, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5)), label: Text( album.name, - style: const TextStyle(fontSize: 10, color: Colors.white, fontWeight: FontWeight.bold), + style: const TextStyle( + fontSize: 10, + color: Colors.white, + fontWeight: FontWeight.bold), ), backgroundColor: Colors.red[300], deleteIconColor: Colors.white, @@ -142,7 +156,10 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: Wrap( - children: [..._buildSelectedAlbumNameChip(), ..._buildExcludedAlbumNameChip()], + children: [ + ..._buildSelectedAlbumNameChip(), + ..._buildExcludedAlbumNameChip() + ], ), ), @@ -165,10 +182,17 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { visualDensity: VisualDensity.compact, title: Text( "Total unique assets", - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14, color: Colors.grey[700]), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + color: Colors.grey[700]), ), trailing: Text( - ref.watch(backupProvider).allUniqueAssets.length.toString(), + ref + .watch(backupProvider) + .allUniqueAssets + .length + .toString(), style: const TextStyle(fontWeight: FontWeight.bold), ), ), @@ -206,7 +230,8 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { context: context, builder: (BuildContext context) { return AlertDialog( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12)), elevation: 5, title: Text( 'Selection Info', @@ -221,7 +246,8 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { children: [ Text( 'Assets can scatter across multiple albums. Thus, albums can be included or excluded during the backup process.', - style: TextStyle(fontSize: 14, color: Colors.grey[700]), + style: TextStyle( + fontSize: 14, color: Colors.grey[700]), ), ], ), diff --git a/mobile/lib/modules/backup/views/backup_controller_page.dart b/mobile/lib/modules/backup/views/backup_controller_page.dart index eebf65f6b8..ca91ce2b5d 100644 --- a/mobile/lib/modules/backup/views/backup_controller_page.dart +++ b/mobile/lib/modules/backup/views/backup_controller_page.dart @@ -26,7 +26,7 @@ class BackupControllerPage extends HookConsumerWidget { useEffect(() { if (backupState.backupProgress != BackUpProgressEnum.inProgress) { - ref.read(backupProvider.notifier).getBackupInfo(); + ref.watch(backupProvider.notifier).getBackupInfo(); } ref @@ -112,13 +112,15 @@ class BackupControllerPage extends HookConsumerWidget { ), ), onPressed: () { - isAutoBackup - ? ref - .watch(authenticationProvider.notifier) - .setAutoBackup(false) - : ref - .watch(authenticationProvider.notifier) - .setAutoBackup(true); + if (isAutoBackup) { + ref + .read(authenticationProvider.notifier) + .setAutoBackup(false); + } else { + ref + .read(authenticationProvider.notifier) + .setAutoBackup(true); + } }, child: Text("Turn $backupBtnText Backup", style: const TextStyle(fontWeight: FontWeight.bold)), @@ -212,7 +214,7 @@ class BackupControllerPage extends HookConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( - "Albums to be backup", + "Albums to be backed up", style: TextStyle(color: Color(0xFF808080), fontSize: 12), ), _buildSelectedAlbumName(), @@ -282,14 +284,12 @@ class BackupControllerPage extends HookConsumerWidget { ), BackupInfoCard( title: "Backup", - subtitle: - "Photos and videos from selected albums that are backup", + subtitle: "Backed up photos and videos", info: "${backupState.selectedAlbumsBackupAssetsIds.length}", ), BackupInfoCard( title: "Remainder", - subtitle: - "Photos and videos that has not been backing up from selected albums", + subtitle: "Remaining photos and albums to back up from selection", info: "${backupState.allUniqueAssets.length - backupState.selectedAlbumsBackupAssetsIds.length}", ), diff --git a/mobile/lib/modules/home/models/delete_asset_response.model.dart b/mobile/lib/modules/home/models/delete_asset_response.model.dart index 0a91d74595..6e9105941f 100644 --- a/mobile/lib/modules/home/models/delete_asset_response.model.dart +++ b/mobile/lib/modules/home/models/delete_asset_response.model.dart @@ -35,7 +35,8 @@ class DeleteAssetResponse { String toJson() => json.encode(toMap()); - factory DeleteAssetResponse.fromJson(String source) => DeleteAssetResponse.fromMap(json.decode(source)); + factory DeleteAssetResponse.fromJson(String source) => + DeleteAssetResponse.fromMap(json.decode(source)); @override String toString() => 'DeleteAssetResponse(id: $id, status: $status)'; @@ -44,7 +45,9 @@ class DeleteAssetResponse { bool operator ==(Object other) { if (identical(this, other)) return true; - return other is DeleteAssetResponse && other.id == id && other.status == status; + return other is DeleteAssetResponse && + other.id == id && + other.status == status; } @override diff --git a/mobile/lib/modules/home/models/get_all_asset_response.model.dart b/mobile/lib/modules/home/models/get_all_asset_response.model.dart index 8338405ca7..86b340ae36 100644 --- a/mobile/lib/modules/home/models/get_all_asset_response.model.dart +++ b/mobile/lib/modules/home/models/get_all_asset_response.model.dart @@ -31,13 +31,15 @@ class ImmichAssetGroupByDate { factory ImmichAssetGroupByDate.fromMap(Map map) { return ImmichAssetGroupByDate( date: map['date'] ?? '', - assets: List.from(map['assets']?.map((x) => ImmichAsset.fromMap(x))), + assets: List.from( + map['assets']?.map((x) => ImmichAsset.fromMap(x))), ); } String toJson() => json.encode(toMap()); - factory ImmichAssetGroupByDate.fromJson(String source) => ImmichAssetGroupByDate.fromMap(json.decode(source)); + factory ImmichAssetGroupByDate.fromJson(String source) => + ImmichAssetGroupByDate.fromMap(json.decode(source)); @override String toString() => 'ImmichAssetGroupByDate(date: $date, assets: $assets)'; @@ -46,7 +48,9 @@ class ImmichAssetGroupByDate { bool operator ==(Object other) { if (identical(this, other)) return true; - return other is ImmichAssetGroupByDate && other.date == date && listEquals(other.assets, assets); + return other is ImmichAssetGroupByDate && + other.date == date && + listEquals(other.assets, assets); } @override @@ -86,17 +90,20 @@ class GetAllAssetResponse { factory GetAllAssetResponse.fromMap(Map map) { return GetAllAssetResponse( count: map['count']?.toInt() ?? 0, - data: List.from(map['data']?.map((x) => ImmichAssetGroupByDate.fromMap(x))), + data: List.from( + map['data']?.map((x) => ImmichAssetGroupByDate.fromMap(x))), nextPageKey: map['nextPageKey'] ?? '', ); } String toJson() => json.encode(toMap()); - factory GetAllAssetResponse.fromJson(String source) => GetAllAssetResponse.fromMap(json.decode(source)); + factory GetAllAssetResponse.fromJson(String source) => + GetAllAssetResponse.fromMap(json.decode(source)); @override - String toString() => 'GetAllAssetResponse(count: $count, data: $data, nextPageKey: $nextPageKey)'; + String toString() => + 'GetAllAssetResponse(count: $count, data: $data, nextPageKey: $nextPageKey)'; @override bool operator ==(Object other) { diff --git a/mobile/lib/modules/home/models/home_page_state.model.dart b/mobile/lib/modules/home/models/home_page_state.model.dart index 6a094930c3..95621fc991 100644 --- a/mobile/lib/modules/home/models/home_page_state.model.dart +++ b/mobile/lib/modules/home/models/home_page_state.model.dart @@ -37,14 +37,16 @@ class HomePageState { factory HomePageState.fromMap(Map map) { return HomePageState( isMultiSelectEnable: map['isMultiSelectEnable'] ?? false, - selectedItems: Set.from(map['selectedItems']?.map((x) => ImmichAsset.fromMap(x))), + selectedItems: Set.from( + map['selectedItems']?.map((x) => ImmichAsset.fromMap(x))), selectedDateGroup: Set.from(map['selectedDateGroup']), ); } String toJson() => json.encode(toMap()); - factory HomePageState.fromJson(String source) => HomePageState.fromMap(json.decode(source)); + factory HomePageState.fromJson(String source) => + HomePageState.fromMap(json.decode(source)); @override String toString() => @@ -62,5 +64,8 @@ class HomePageState { } @override - int get hashCode => isMultiSelectEnable.hashCode ^ selectedItems.hashCode ^ selectedDateGroup.hashCode; + int get hashCode => + isMultiSelectEnable.hashCode ^ + selectedItems.hashCode ^ + selectedDateGroup.hashCode; } diff --git a/mobile/lib/modules/home/providers/home_page_state.provider.dart b/mobile/lib/modules/home/providers/home_page_state.provider.dart index 940737e9cd..6a9fb71760 100644 --- a/mobile/lib/modules/home/providers/home_page_state.provider.dart +++ b/mobile/lib/modules/home/providers/home_page_state.provider.dart @@ -13,7 +13,8 @@ class HomePageStateNotifier extends StateNotifier { ); void addSelectedDateGroup(String dateGroupTitle) { - state = state.copyWith(selectedDateGroup: {...state.selectedDateGroup, dateGroupTitle}); + state = state.copyWith( + selectedDateGroup: {...state.selectedDateGroup, dateGroupTitle}); } void removeSelectedDateGroup(String dateGroupTitle) { @@ -25,11 +26,13 @@ class HomePageStateNotifier extends StateNotifier { } void enableMultiSelect(Set selectedItems) { - state = state.copyWith(isMultiSelectEnable: true, selectedItems: selectedItems); + state = + state.copyWith(isMultiSelectEnable: true, selectedItems: selectedItems); } void disableMultiSelect() { - state = state.copyWith(isMultiSelectEnable: false, selectedItems: {}, selectedDateGroup: {}); + state = state.copyWith( + isMultiSelectEnable: false, selectedItems: {}, selectedDateGroup: {}); } void addSingleSelectedItem(ImmichAsset asset) { @@ -60,4 +63,5 @@ class HomePageStateNotifier extends StateNotifier { } final homePageStateProvider = - StateNotifierProvider(((ref) => HomePageStateNotifier())); + StateNotifierProvider( + ((ref) => HomePageStateNotifier())); diff --git a/mobile/lib/modules/home/ui/control_bottom_app_bar.dart b/mobile/lib/modules/home/ui/control_bottom_app_bar.dart index 7ad8f4119a..0ce5d6d20d 100644 --- a/mobile/lib/modules/home/ui/control_bottom_app_bar.dart +++ b/mobile/lib/modules/home/ui/control_bottom_app_bar.dart @@ -13,7 +13,8 @@ class ControlBottomAppBar extends StatelessWidget { width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height * 0.15, decoration: BoxDecoration( - borderRadius: const BorderRadius.only(topLeft: Radius.circular(15), topRight: Radius.circular(15)), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(15), topRight: Radius.circular(15)), color: Colors.grey[300]?.withOpacity(0.98), ), child: Column( @@ -46,7 +47,11 @@ class ControlBottomAppBar extends StatelessWidget { } class ControlBoxButton extends StatelessWidget { - const ControlBoxButton({Key? key, required this.label, required this.iconData, required this.onPressed}) + const ControlBoxButton( + {Key? key, + required this.label, + required this.iconData, + required this.onPressed}) : super(key: key); final String label; diff --git a/mobile/lib/modules/home/ui/daily_title_text.dart b/mobile/lib/modules/home/ui/daily_title_text.dart index bffe496b8c..870dacb3f0 100644 --- a/mobile/lib/modules/home/ui/daily_title_text.dart +++ b/mobile/lib/modules/home/ui/daily_title_text.dart @@ -18,9 +18,12 @@ class DailyTitleText extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { var currentYear = DateTime.now().year; var groupYear = DateTime.parse(isoDate).year; - var formatDateTemplate = currentYear == groupYear ? 'E, MMM dd' : 'E, MMM dd, yyyy'; - var dateText = DateFormat(formatDateTemplate).format(DateTime.parse(isoDate)); - var isMultiSelectEnable = ref.watch(homePageStateProvider).isMultiSelectEnable; + var formatDateTemplate = + currentYear == groupYear ? 'E, MMM dd' : 'E, MMM dd, yyyy'; + var dateText = + DateFormat(formatDateTemplate).format(DateTime.parse(isoDate)); + var isMultiSelectEnable = + ref.watch(homePageStateProvider).isMultiSelectEnable; var selectedDateGroup = ref.watch(homePageStateProvider).selectedDateGroup; var selectedItems = ref.watch(homePageStateProvider).selectedItems; @@ -35,23 +38,42 @@ class DailyTitleText extends ConsumerWidget { selectedDateGroup.contains(dateText) && selectedItems.length != assetGroup.length) { // Multi select is active - click again on the icon while it is not the only active group -> remove that group from selected group/items - ref.watch(homePageStateProvider.notifier).removeSelectedDateGroup(dateText); - ref.watch(homePageStateProvider.notifier).removeMultipleSelectedItem(assetGroup); - } else if (isMultiSelectEnable && selectedDateGroup.contains(dateText) && selectedDateGroup.length > 1) { - ref.watch(homePageStateProvider.notifier).removeSelectedDateGroup(dateText); - ref.watch(homePageStateProvider.notifier).removeMultipleSelectedItem(assetGroup); + ref + .watch(homePageStateProvider.notifier) + .removeSelectedDateGroup(dateText); + ref + .watch(homePageStateProvider.notifier) + .removeMultipleSelectedItem(assetGroup); + } else if (isMultiSelectEnable && + selectedDateGroup.contains(dateText) && + selectedDateGroup.length > 1) { + ref + .watch(homePageStateProvider.notifier) + .removeSelectedDateGroup(dateText); + ref + .watch(homePageStateProvider.notifier) + .removeMultipleSelectedItem(assetGroup); } else if (isMultiSelectEnable && !selectedDateGroup.contains(dateText)) { - ref.watch(homePageStateProvider.notifier).addSelectedDateGroup(dateText); - ref.watch(homePageStateProvider.notifier).addMultipleSelectedItems(assetGroup); + ref + .watch(homePageStateProvider.notifier) + .addSelectedDateGroup(dateText); + ref + .watch(homePageStateProvider.notifier) + .addMultipleSelectedItems(assetGroup); } else { - ref.watch(homePageStateProvider.notifier).enableMultiSelect(assetGroup.toSet()); - ref.watch(homePageStateProvider.notifier).addSelectedDateGroup(dateText); + ref + .watch(homePageStateProvider.notifier) + .enableMultiSelect(assetGroup.toSet()); + ref + .watch(homePageStateProvider.notifier) + .addSelectedDateGroup(dateText); } } return SliverToBoxAdapter( child: Padding( - padding: const EdgeInsets.only(top: 29.0, bottom: 29.0, left: 12.0, right: 12.0), + padding: const EdgeInsets.only( + top: 29.0, bottom: 29.0, left: 12.0, right: 12.0), child: Row( children: [ Text( diff --git a/mobile/lib/modules/home/ui/delete_diaglog.dart b/mobile/lib/modules/home/ui/delete_diaglog.dart index af6040da83..5d02303058 100644 --- a/mobile/lib/modules/home/ui/delete_diaglog.dart +++ b/mobile/lib/modules/home/ui/delete_diaglog.dart @@ -14,7 +14,8 @@ class DeleteDialog extends ConsumerWidget { backgroundColor: Colors.grey[200], shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), title: const Text("Delete Permanently"), - content: const Text("These items will be permanently deleted from Immich and from your device"), + content: const Text( + "These items will be permanently deleted from Immich and from your device"), actions: [ TextButton( onPressed: () { @@ -27,7 +28,9 @@ class DeleteDialog extends ConsumerWidget { ), TextButton( onPressed: () { - ref.watch(assetProvider.notifier).deleteAssets(homePageState.selectedItems); + ref + .watch(assetProvider.notifier) + .deleteAssets(homePageState.selectedItems); ref.watch(homePageStateProvider.notifier).disableMultiSelect(); Navigator.of(context).pop(); diff --git a/mobile/lib/modules/home/ui/image_grid.dart b/mobile/lib/modules/home/ui/image_grid.dart index 4a22811aac..706c05ae4b 100644 --- a/mobile/lib/modules/home/ui/image_grid.dart +++ b/mobile/lib/modules/home/ui/image_grid.dart @@ -33,7 +33,10 @@ class ImageGrid extends ConsumerWidget { child: Row( children: [ Text( - assetGroup[index].duration.toString().substring(0, 7), + assetGroup[index] + .duration + .toString() + .substring(0, 7), style: const TextStyle( color: Colors.white, fontSize: 10, diff --git a/mobile/lib/modules/home/ui/thumbnail_image.dart b/mobile/lib/modules/home/ui/thumbnail_image.dart index 023e12236d..1f4a09bae4 100644 --- a/mobile/lib/modules/home/ui/thumbnail_image.dart +++ b/mobile/lib/modules/home/ui/thumbnail_image.dart @@ -25,7 +25,8 @@ class ThumbnailImage extends HookConsumerWidget { '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}&isThumb=true'; var selectedAsset = ref.watch(homePageStateProvider).selectedItems; - var isMultiSelectEnable = ref.watch(homePageStateProvider).isMultiSelectEnable; + var isMultiSelectEnable = + ref.watch(homePageStateProvider).isMultiSelectEnable; var deviceId = ref.watch(authenticationProvider).deviceId; Widget _buildSelectionIcon(ImmichAsset asset) { @@ -45,12 +46,20 @@ class ThumbnailImage extends HookConsumerWidget { return GestureDetector( onTap: () { debugPrint("View ${asset.id}"); - if (isMultiSelectEnable && selectedAsset.contains(asset) && selectedAsset.length == 1) { + if (isMultiSelectEnable && + selectedAsset.contains(asset) && + selectedAsset.length == 1) { ref.watch(homePageStateProvider.notifier).disableMultiSelect(); - } else if (isMultiSelectEnable && selectedAsset.contains(asset) && selectedAsset.length > 1) { - ref.watch(homePageStateProvider.notifier).removeSingleSelectedItem(asset); + } else if (isMultiSelectEnable && + selectedAsset.contains(asset) && + selectedAsset.length > 1) { + ref + .watch(homePageStateProvider.notifier) + .removeSingleSelectedItem(asset); } else if (isMultiSelectEnable && !selectedAsset.contains(asset)) { - ref.watch(homePageStateProvider.notifier).addSingleSelectedItem(asset); + ref + .watch(homePageStateProvider.notifier) + .addSingleSelectedItem(asset); } else { if (asset.type == 'IMAGE') { AutoRouter.of(context).push( @@ -65,7 +74,8 @@ class ThumbnailImage extends HookConsumerWidget { } else { AutoRouter.of(context).push( VideoViewerRoute( - videoUrl: '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}', + videoUrl: + '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}', asset: asset), ); } @@ -83,7 +93,8 @@ class ThumbnailImage extends HookConsumerWidget { Container( decoration: BoxDecoration( border: isMultiSelectEnable && selectedAsset.contains(asset) - ? Border.all(color: Theme.of(context).primaryColorLight, width: 10) + ? Border.all( + color: Theme.of(context).primaryColorLight, width: 10) : const Border(), ), child: CachedNetworkImage( @@ -93,11 +104,15 @@ class ThumbnailImage extends HookConsumerWidget { memCacheHeight: asset.type == 'IMAGE' ? 250 : 400, fit: BoxFit.cover, imageUrl: thumbnailRequestUrl, - httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"}, + httpHeaders: { + "Authorization": "Bearer ${box.get(accessTokenKey)}" + }, fadeInDuration: const Duration(milliseconds: 250), - progressIndicatorBuilder: (context, url, downloadProgress) => Transform.scale( + progressIndicatorBuilder: (context, url, downloadProgress) => + Transform.scale( scale: 0.2, - child: CircularProgressIndicator(value: downloadProgress.progress), + child: CircularProgressIndicator( + value: downloadProgress.progress), ), errorWidget: (context, url, error) { return Icon( @@ -122,7 +137,9 @@ class ThumbnailImage extends HookConsumerWidget { right: 10, bottom: 5, child: Icon( - (deviceId != asset.deviceId) ? Icons.cloud_done_outlined : Icons.photo_library_rounded, + (deviceId != asset.deviceId) + ? Icons.cloud_done_outlined + : Icons.photo_library_rounded, color: Colors.white, size: 18, ), diff --git a/mobile/lib/modules/login/models/authentication_state.model.dart b/mobile/lib/modules/login/models/authentication_state.model.dart index 87459e8c33..aae86f6aba 100644 --- a/mobile/lib/modules/login/models/authentication_state.model.dart +++ b/mobile/lib/modules/login/models/authentication_state.model.dart @@ -98,7 +98,8 @@ class AuthenticationState { String toJson() => json.encode(toMap()); - factory AuthenticationState.fromJson(String source) => AuthenticationState.fromMap(json.decode(source)); + factory AuthenticationState.fromJson(String source) => + AuthenticationState.fromMap(json.decode(source)); @override bool operator ==(Object other) { diff --git a/mobile/lib/modules/login/models/hive_saved_login_info.model.dart b/mobile/lib/modules/login/models/hive_saved_login_info.model.dart index d77923d4b1..471e5df66c 100644 --- a/mobile/lib/modules/login/models/hive_saved_login_info.model.dart +++ b/mobile/lib/modules/login/models/hive_saved_login_info.model.dart @@ -16,5 +16,9 @@ class HiveSavedLoginInfo { @HiveField(3) bool isSaveLogin; - HiveSavedLoginInfo({required this.email, required this.password, required this.serverUrl, required this.isSaveLogin}); + HiveSavedLoginInfo( + {required this.email, + required this.password, + required this.serverUrl, + required this.isSaveLogin}); } diff --git a/mobile/lib/modules/login/models/login_response.model.dart b/mobile/lib/modules/login/models/login_response.model.dart index 0b4e833a82..2ba840e4dd 100644 --- a/mobile/lib/modules/login/models/login_response.model.dart +++ b/mobile/lib/modules/login/models/login_response.model.dart @@ -73,7 +73,8 @@ class LogInReponse { String toJson() => json.encode(toMap()); - factory LogInReponse.fromJson(String source) => LogInReponse.fromMap(json.decode(source)); + factory LogInReponse.fromJson(String source) => + LogInReponse.fromMap(json.decode(source)); @override String toString() { diff --git a/mobile/lib/modules/login/ui/login_form.dart b/mobile/lib/modules/login/ui/login_form.dart index 5dae8e4bdb..34260d9e3c 100644 --- a/mobile/lib/modules/login/ui/login_form.dart +++ b/mobile/lib/modules/login/ui/login_form.dart @@ -15,13 +15,17 @@ class LoginForm extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final usernameController = useTextEditingController.fromValue(TextEditingValue.empty); - final passwordController = useTextEditingController.fromValue(TextEditingValue.empty); - final serverEndpointController = useTextEditingController(text: 'http://your-server-ip:2283'); + final usernameController = + useTextEditingController.fromValue(TextEditingValue.empty); + final passwordController = + useTextEditingController.fromValue(TextEditingValue.empty); + final serverEndpointController = + useTextEditingController(text: 'http://your-server-ip:2283'); final isSaveLoginInfo = useState(false); useEffect(() { - var loginInfo = Hive.box(hiveLoginInfoBox).get(savedLoginInfoKey); + var loginInfo = + Hive.box(hiveLoginInfoBox).get(savedLoginInfoKey); if (loginInfo != null) { usernameController.text = loginInfo.email; @@ -64,11 +68,15 @@ class LoginForm extends HookConsumerWidget { contentPadding: const EdgeInsets.symmetric(horizontal: 8), dense: true, side: const BorderSide(color: Colors.grey, width: 1.5), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5)), enableFeedback: true, title: const Text( "Stay logged in", - style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.grey), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.grey), ), value: isSaveLoginInfo.value, onChanged: (switchValue) { @@ -94,11 +102,13 @@ class LoginForm extends HookConsumerWidget { class ServerEndpointInput extends StatelessWidget { final TextEditingController controller; - const ServerEndpointInput({Key? key, required this.controller}) : super(key: key); + const ServerEndpointInput({Key? key, required this.controller}) + : super(key: key); String? _validateInput(String? url) { if (url == null) return null; - if (!url.startsWith(RegExp(r'https?://'))) return 'Please specify http:// or https://'; + if (!url.startsWith(RegExp(r'https?://'))) + return 'Please specify http:// or https://'; return null; } @@ -107,7 +117,9 @@ class ServerEndpointInput extends StatelessWidget { return TextFormField( controller: controller, decoration: const InputDecoration( - labelText: 'Server Endpoint URL', border: OutlineInputBorder(), hintText: 'http://your-server-ip:port'), + labelText: 'Server Endpoint URL', + border: OutlineInputBorder(), + hintText: 'http://your-server-ip:port'), validator: _validateInput, autovalidateMode: AutovalidateMode.always, ); @@ -131,8 +143,10 @@ class EmailInput extends StatelessWidget { Widget build(BuildContext context) { return TextFormField( controller: controller, - decoration: - const InputDecoration(labelText: 'Email', border: OutlineInputBorder(), hintText: 'youremail@email.com'), + decoration: const InputDecoration( + labelText: 'Email', + border: OutlineInputBorder(), + hintText: 'youremail@email.com'), validator: _validateInput, autovalidateMode: AutovalidateMode.always, ); @@ -149,7 +163,10 @@ class PasswordInput extends StatelessWidget { return TextFormField( obscureText: true, controller: controller, - decoration: const InputDecoration(labelText: 'Password', border: OutlineInputBorder(), hintText: 'password'), + decoration: const InputDecoration( + labelText: 'Password', + border: OutlineInputBorder(), + hintText: 'password'), ); } } @@ -184,7 +201,8 @@ class LoginButton extends ConsumerWidget { var isAuthenticated = await ref .read(authenticationProvider.notifier) - .login(emailController.text, passwordController.text, serverEndpointController.text, isSavedLoginInfo); + .login(emailController.text, passwordController.text, + serverEndpointController.text, isSavedLoginInfo); if (isAuthenticated) { // Resume backup (if enable) then navigate @@ -193,7 +211,8 @@ class LoginButton extends ConsumerWidget { } else { ImmichToast.show( context: context, - msg: "Error logging you in, check server url, email and password!", + msg: + "Error logging you in, check server url, email and password!", toastType: ToastType.error, ); } diff --git a/mobile/lib/modules/search/models/curated_location.model.dart b/mobile/lib/modules/search/models/curated_location.model.dart index dfdcea95aa..a3baebbdf4 100644 --- a/mobile/lib/modules/search/models/curated_location.model.dart +++ b/mobile/lib/modules/search/models/curated_location.model.dart @@ -53,7 +53,8 @@ class CuratedLocation { String toJson() => json.encode(toMap()); - factory CuratedLocation.fromJson(String source) => CuratedLocation.fromMap(json.decode(source)); + factory CuratedLocation.fromJson(String source) => + CuratedLocation.fromMap(json.decode(source)); @override String toString() { @@ -74,6 +75,10 @@ class CuratedLocation { @override int get hashCode { - return id.hashCode ^ city.hashCode ^ resizePath.hashCode ^ deviceAssetId.hashCode ^ deviceId.hashCode; + return id.hashCode ^ + city.hashCode ^ + resizePath.hashCode ^ + deviceAssetId.hashCode ^ + deviceId.hashCode; } } diff --git a/mobile/lib/modules/search/models/curated_object.model.dart b/mobile/lib/modules/search/models/curated_object.model.dart index f5851c7e4c..c389aaf92e 100644 --- a/mobile/lib/modules/search/models/curated_object.model.dart +++ b/mobile/lib/modules/search/models/curated_object.model.dart @@ -54,7 +54,8 @@ class CuratedObject { String toJson() => json.encode(toMap()); - factory CuratedObject.fromJson(String source) => CuratedObject.fromMap(json.decode(source)); + factory CuratedObject.fromJson(String source) => + CuratedObject.fromMap(json.decode(source)); @override String toString() { @@ -75,6 +76,10 @@ class CuratedObject { @override int get hashCode { - return id.hashCode ^ object.hashCode ^ resizePath.hashCode ^ deviceAssetId.hashCode ^ deviceId.hashCode; + return id.hashCode ^ + object.hashCode ^ + resizePath.hashCode ^ + deviceAssetId.hashCode ^ + deviceId.hashCode; } } diff --git a/mobile/lib/modules/search/models/search_page_state.model.dart b/mobile/lib/modules/search/models/search_page_state.model.dart index 8ee09a6b54..e949817b98 100644 --- a/mobile/lib/modules/search/models/search_page_state.model.dart +++ b/mobile/lib/modules/search/models/search_page_state.model.dart @@ -25,7 +25,8 @@ class SearchPageState { searchTerm: searchTerm ?? this.searchTerm, isSearchEnabled: isSearchEnabled ?? this.isSearchEnabled, searchSuggestion: searchSuggestion ?? this.searchSuggestion, - userSuggestedSearchTerms: userSuggestedSearchTerms ?? this.userSuggestedSearchTerms, + userSuggestedSearchTerms: + userSuggestedSearchTerms ?? this.userSuggestedSearchTerms, ); } @@ -43,13 +44,15 @@ class SearchPageState { searchTerm: map['searchTerm'] ?? '', isSearchEnabled: map['isSearchEnabled'] ?? false, searchSuggestion: List.from(map['searchSuggestion']), - userSuggestedSearchTerms: List.from(map['userSuggestedSearchTerms']), + userSuggestedSearchTerms: + List.from(map['userSuggestedSearchTerms']), ); } String toJson() => json.encode(toMap()); - factory SearchPageState.fromJson(String source) => SearchPageState.fromMap(json.decode(source)); + factory SearchPageState.fromJson(String source) => + SearchPageState.fromMap(json.decode(source)); @override String toString() { diff --git a/mobile/lib/modules/search/models/search_result_page_state.model.dart b/mobile/lib/modules/search/models/search_result_page_state.model.dart index 7b7d1e30de..4911bb0e6f 100644 --- a/mobile/lib/modules/search/models/search_result_page_state.model.dart +++ b/mobile/lib/modules/search/models/search_result_page_state.model.dart @@ -44,13 +44,15 @@ class SearchResultPageState { isLoading: map['isLoading'] ?? false, isSuccess: map['isSuccess'] ?? false, isError: map['isError'] ?? false, - searchResult: List.from(map['searchResult']?.map((x) => ImmichAsset.fromMap(x))), + searchResult: List.from( + map['searchResult']?.map((x) => ImmichAsset.fromMap(x))), ); } String toJson() => json.encode(toMap()); - factory SearchResultPageState.fromJson(String source) => SearchResultPageState.fromMap(json.decode(source)); + factory SearchResultPageState.fromJson(String source) => + SearchResultPageState.fromMap(json.decode(source)); @override String toString() { @@ -71,6 +73,9 @@ class SearchResultPageState { @override int get hashCode { - return isLoading.hashCode ^ isSuccess.hashCode ^ isError.hashCode ^ searchResult.hashCode; + return isLoading.hashCode ^ + isSuccess.hashCode ^ + isError.hashCode ^ + searchResult.hashCode; } } diff --git a/mobile/lib/modules/search/ui/search_bar.dart b/mobile/lib/modules/search/ui/search_bar.dart index b3af1af4e2..3d6f3e85a1 100644 --- a/mobile/lib/modules/search/ui/search_bar.dart +++ b/mobile/lib/modules/search/ui/search_bar.dart @@ -4,7 +4,9 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart'; class SearchBar extends HookConsumerWidget with PreferredSizeWidget { - SearchBar({Key? key, required this.searchFocusNode, required this.onSubmitted}) : super(key: key); + SearchBar( + {Key? key, required this.searchFocusNode, required this.onSubmitted}) + : super(key: key); final FocusNode searchFocusNode; final Function(String) onSubmitted; diff --git a/mobile/lib/modules/search/ui/search_suggestion_list.dart b/mobile/lib/modules/search/ui/search_suggestion_list.dart index 7392cf6e81..95feb12005 100644 --- a/mobile/lib/modules/search/ui/search_suggestion_list.dart +++ b/mobile/lib/modules/search/ui/search_suggestion_list.dart @@ -3,16 +3,20 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart'; class SearchSuggestionList extends ConsumerWidget { - const SearchSuggestionList({Key? key, required this.onSubmitted}) : super(key: key); + const SearchSuggestionList({Key? key, required this.onSubmitted}) + : super(key: key); final Function(String) onSubmitted; @override Widget build(BuildContext context, WidgetRef ref) { final searchTerm = ref.watch(searchPageStateProvider).searchTerm; - final searchSuggestion = ref.watch(searchPageStateProvider).searchSuggestion; + final searchSuggestion = + ref.watch(searchPageStateProvider).searchSuggestion; return Container( - color: searchTerm.isEmpty ? Colors.black.withOpacity(0.5) : Theme.of(context).scaffoldBackgroundColor, + color: searchTerm.isEmpty + ? Colors.black.withOpacity(0.5) + : Theme.of(context).scaffoldBackgroundColor, child: CustomScrollView( slivers: [ SliverFillRemaining( diff --git a/mobile/lib/modules/search/ui/thumbnail_with_info.dart b/mobile/lib/modules/search/ui/thumbnail_with_info.dart index fe6912526b..e3d95e099d 100644 --- a/mobile/lib/modules/search/ui/thumbnail_with_info.dart +++ b/mobile/lib/modules/search/ui/thumbnail_with_info.dart @@ -5,7 +5,11 @@ import 'package:immich_mobile/constants/hive_box.dart'; import 'package:immich_mobile/utils/capitalize_first_letter.dart'; class ThumbnailWithInfo extends StatelessWidget { - const ThumbnailWithInfo({Key? key, required this.textInfo, required this.imageUrl, required this.onTap}) + const ThumbnailWithInfo( + {Key? key, + required this.textInfo, + required this.imageUrl, + required this.onTap}) : super(key: key); final String textInfo; @@ -39,7 +43,9 @@ class ThumbnailWithInfo extends StatelessWidget { height: 250, fit: BoxFit.cover, imageUrl: imageUrl, - httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"}, + httpHeaders: { + "Authorization": "Bearer ${box.get(accessTokenKey)}" + }, ), ), ), diff --git a/mobile/lib/modules/sharing/models/album_viewer_page_state.model.dart b/mobile/lib/modules/sharing/models/album_viewer_page_state.model.dart index bf2420e32d..1d1cc9f9ec 100644 --- a/mobile/lib/modules/sharing/models/album_viewer_page_state.model.dart +++ b/mobile/lib/modules/sharing/models/album_viewer_page_state.model.dart @@ -36,16 +36,20 @@ class AlbumViewerPageState { String toJson() => json.encode(toMap()); - factory AlbumViewerPageState.fromJson(String source) => AlbumViewerPageState.fromMap(json.decode(source)); + factory AlbumViewerPageState.fromJson(String source) => + AlbumViewerPageState.fromMap(json.decode(source)); @override - String toString() => 'AlbumViewerPageState(isEditAlbum: $isEditAlbum, editTitleText: $editTitleText)'; + String toString() => + 'AlbumViewerPageState(isEditAlbum: $isEditAlbum, editTitleText: $editTitleText)'; @override bool operator ==(Object other) { if (identical(this, other)) return true; - return other is AlbumViewerPageState && other.isEditAlbum == isEditAlbum && other.editTitleText == editTitleText; + return other is AlbumViewerPageState && + other.isEditAlbum == isEditAlbum && + other.editTitleText == editTitleText; } @override diff --git a/mobile/lib/modules/sharing/models/asset_selection_page_result.model.dart b/mobile/lib/modules/sharing/models/asset_selection_page_result.model.dart index e4c53e37fd..faea8d0eca 100644 --- a/mobile/lib/modules/sharing/models/asset_selection_page_result.model.dart +++ b/mobile/lib/modules/sharing/models/asset_selection_page_result.model.dart @@ -22,7 +22,8 @@ class AssetSelectionPageResult { }) { return AssetSelectionPageResult( selectedNewAsset: selectedNewAsset ?? this.selectedNewAsset, - selectedAdditionalAsset: selectedAdditionalAsset ?? this.selectedAdditionalAsset, + selectedAdditionalAsset: + selectedAdditionalAsset ?? this.selectedAdditionalAsset, isAlbumExist: isAlbumExist ?? this.isAlbumExist, ); } @@ -30,8 +31,12 @@ class AssetSelectionPageResult { Map toMap() { final result = {}; - result.addAll({'selectedNewAsset': selectedNewAsset.map((x) => x.toMap()).toList()}); - result.addAll({'selectedAdditionalAsset': selectedAdditionalAsset.map((x) => x.toMap()).toList()}); + result.addAll( + {'selectedNewAsset': selectedNewAsset.map((x) => x.toMap()).toList()}); + result.addAll({ + 'selectedAdditionalAsset': + selectedAdditionalAsset.map((x) => x.toMap()).toList() + }); result.addAll({'isAlbumExist': isAlbumExist}); return result; @@ -39,16 +44,18 @@ class AssetSelectionPageResult { factory AssetSelectionPageResult.fromMap(Map map) { return AssetSelectionPageResult( - selectedNewAsset: Set.from(map['selectedNewAsset']?.map((x) => ImmichAsset.fromMap(x))), - selectedAdditionalAsset: - Set.from(map['selectedAdditionalAsset']?.map((x) => ImmichAsset.fromMap(x))), + selectedNewAsset: Set.from( + map['selectedNewAsset']?.map((x) => ImmichAsset.fromMap(x))), + selectedAdditionalAsset: Set.from( + map['selectedAdditionalAsset']?.map((x) => ImmichAsset.fromMap(x))), isAlbumExist: map['isAlbumExist'] ?? false, ); } String toJson() => json.encode(toMap()); - factory AssetSelectionPageResult.fromJson(String source) => AssetSelectionPageResult.fromMap(json.decode(source)); + factory AssetSelectionPageResult.fromJson(String source) => + AssetSelectionPageResult.fromMap(json.decode(source)); @override String toString() => @@ -66,5 +73,8 @@ class AssetSelectionPageResult { } @override - int get hashCode => selectedNewAsset.hashCode ^ selectedAdditionalAsset.hashCode ^ isAlbumExist.hashCode; + int get hashCode => + selectedNewAsset.hashCode ^ + selectedAdditionalAsset.hashCode ^ + isAlbumExist.hashCode; } diff --git a/mobile/lib/modules/sharing/models/asset_selection_state.model.dart b/mobile/lib/modules/sharing/models/asset_selection_state.model.dart index 33e312362e..7520bc2a59 100644 --- a/mobile/lib/modules/sharing/models/asset_selection_state.model.dart +++ b/mobile/lib/modules/sharing/models/asset_selection_state.model.dart @@ -32,9 +32,12 @@ class AssetSelectionState { }) { return AssetSelectionState( selectedMonths: selectedMonths ?? this.selectedMonths, - selectedNewAssetsForAlbum: selectedNewAssetsForAlbum ?? this.selectedNewAssetsForAlbum, - selectedAdditionalAssetsForAlbum: selectedAdditionalAssetsForAlbum ?? this.selectedAdditionalAssetsForAlbum, - selectedAssetsInAlbumViewer: selectedAssetsInAlbumViewer ?? this.selectedAssetsInAlbumViewer, + selectedNewAssetsForAlbum: + selectedNewAssetsForAlbum ?? this.selectedNewAssetsForAlbum, + selectedAdditionalAssetsForAlbum: selectedAdditionalAssetsForAlbum ?? + this.selectedAdditionalAssetsForAlbum, + selectedAssetsInAlbumViewer: + selectedAssetsInAlbumViewer ?? this.selectedAssetsInAlbumViewer, isMultiselectEnable: isMultiselectEnable ?? this.isMultiselectEnable, isAlbumExist: isAlbumExist ?? this.isAlbumExist, ); @@ -44,10 +47,18 @@ class AssetSelectionState { final result = {}; result.addAll({'selectedMonths': selectedMonths.toList()}); - result.addAll({'selectedNewAssetsForAlbum': selectedNewAssetsForAlbum.map((x) => x.toMap()).toList()}); - result - .addAll({'selectedAdditionalAssetsForAlbum': selectedAdditionalAssetsForAlbum.map((x) => x.toMap()).toList()}); - result.addAll({'selectedAssetsInAlbumViewer': selectedAssetsInAlbumViewer.map((x) => x.toMap()).toList()}); + result.addAll({ + 'selectedNewAssetsForAlbum': + selectedNewAssetsForAlbum.map((x) => x.toMap()).toList() + }); + result.addAll({ + 'selectedAdditionalAssetsForAlbum': + selectedAdditionalAssetsForAlbum.map((x) => x.toMap()).toList() + }); + result.addAll({ + 'selectedAssetsInAlbumViewer': + selectedAssetsInAlbumViewer.map((x) => x.toMap()).toList() + }); result.addAll({'isMultiselectEnable': isMultiselectEnable}); result.addAll({'isAlbumExist': isAlbumExist}); @@ -57,12 +68,14 @@ class AssetSelectionState { factory AssetSelectionState.fromMap(Map map) { return AssetSelectionState( selectedMonths: Set.from(map['selectedMonths']), - selectedNewAssetsForAlbum: - Set.from(map['selectedNewAssetsForAlbum']?.map((x) => ImmichAsset.fromMap(x))), - selectedAdditionalAssetsForAlbum: - Set.from(map['selectedAdditionalAssetsForAlbum']?.map((x) => ImmichAsset.fromMap(x))), - selectedAssetsInAlbumViewer: - Set.from(map['selectedAssetsInAlbumViewer']?.map((x) => ImmichAsset.fromMap(x))), + selectedNewAssetsForAlbum: Set.from( + map['selectedNewAssetsForAlbum']?.map((x) => ImmichAsset.fromMap(x))), + selectedAdditionalAssetsForAlbum: Set.from( + map['selectedAdditionalAssetsForAlbum'] + ?.map((x) => ImmichAsset.fromMap(x))), + selectedAssetsInAlbumViewer: Set.from( + map['selectedAssetsInAlbumViewer'] + ?.map((x) => ImmichAsset.fromMap(x))), isMultiselectEnable: map['isMultiselectEnable'] ?? false, isAlbumExist: map['isAlbumExist'] ?? false, ); @@ -70,7 +83,8 @@ class AssetSelectionState { String toJson() => json.encode(toMap()); - factory AssetSelectionState.fromJson(String source) => AssetSelectionState.fromMap(json.decode(source)); + factory AssetSelectionState.fromJson(String source) => + AssetSelectionState.fromMap(json.decode(source)); @override String toString() { @@ -85,8 +99,10 @@ class AssetSelectionState { return other is AssetSelectionState && setEquals(other.selectedMonths, selectedMonths) && setEquals(other.selectedNewAssetsForAlbum, selectedNewAssetsForAlbum) && - setEquals(other.selectedAdditionalAssetsForAlbum, selectedAdditionalAssetsForAlbum) && - setEquals(other.selectedAssetsInAlbumViewer, selectedAssetsInAlbumViewer) && + setEquals(other.selectedAdditionalAssetsForAlbum, + selectedAdditionalAssetsForAlbum) && + setEquals( + other.selectedAssetsInAlbumViewer, selectedAssetsInAlbumViewer) && other.isMultiselectEnable == isMultiselectEnable && other.isAlbumExist == isAlbumExist; } diff --git a/mobile/lib/modules/sharing/models/shared_album.model.dart b/mobile/lib/modules/sharing/models/shared_album.model.dart index c3f2b82c7f..d8f1468927 100644 --- a/mobile/lib/modules/sharing/models/shared_album.model.dart +++ b/mobile/lib/modules/sharing/models/shared_album.model.dart @@ -38,7 +38,8 @@ class SharedAlbum { ownerId: ownerId ?? this.ownerId, albumName: albumName ?? this.albumName, createdAt: createdAt ?? this.createdAt, - albumThumbnailAssetId: albumThumbnailAssetId ?? this.albumThumbnailAssetId, + albumThumbnailAssetId: + albumThumbnailAssetId ?? this.albumThumbnailAssetId, sharedUsers: sharedUsers ?? this.sharedUsers, assets: assets ?? this.assets, ); @@ -69,16 +70,19 @@ class SharedAlbum { albumName: map['albumName'] ?? '', createdAt: map['createdAt'] ?? '', albumThumbnailAssetId: map['albumThumbnailAssetId'], - sharedUsers: List.from(map['sharedUsers']?.map((x) => User.fromMap(x))), + sharedUsers: + List.from(map['sharedUsers']?.map((x) => User.fromMap(x))), assets: map['assets'] != null - ? List.from(map['assets']?.map((x) => ImmichAsset.fromMap(x))) + ? List.from( + map['assets']?.map((x) => ImmichAsset.fromMap(x))) : null, ); } String toJson() => json.encode(toMap()); - factory SharedAlbum.fromJson(String source) => SharedAlbum.fromMap(json.decode(source)); + factory SharedAlbum.fromJson(String source) => + SharedAlbum.fromMap(json.decode(source)); @override String toString() { diff --git a/mobile/lib/modules/sharing/providers/album_title.provider.dart b/mobile/lib/modules/sharing/providers/album_title.provider.dart index bf812a01d8..5ccc82d401 100644 --- a/mobile/lib/modules/sharing/providers/album_title.provider.dart +++ b/mobile/lib/modules/sharing/providers/album_title.provider.dart @@ -12,4 +12,5 @@ class AlbumTitleNotifier extends StateNotifier { } } -final albumTitleProvider = StateNotifierProvider((ref) => AlbumTitleNotifier()); +final albumTitleProvider = StateNotifierProvider( + (ref) => AlbumTitleNotifier()); diff --git a/mobile/lib/modules/sharing/providers/asset_selection.provider.dart b/mobile/lib/modules/sharing/providers/asset_selection.provider.dart index bd8dcc4a85..c87a59aa25 100644 --- a/mobile/lib/modules/sharing/providers/asset_selection.provider.dart +++ b/mobile/lib/modules/sharing/providers/asset_selection.provider.dart @@ -18,35 +18,48 @@ class AssetSelectionNotifier extends StateNotifier { state = state.copyWith(isAlbumExist: isAlbumExist); } - void removeAssetsInMonth(String removedMonth, List assetsInMonth) { + void removeAssetsInMonth( + String removedMonth, List assetsInMonth) { Set currentAssetList = state.selectedNewAssetsForAlbum; Set currentMonthList = state.selectedMonths; - currentMonthList.removeWhere((selectedMonth) => selectedMonth == removedMonth); + currentMonthList + .removeWhere((selectedMonth) => selectedMonth == removedMonth); for (ImmichAsset asset in assetsInMonth) { currentAssetList.removeWhere((e) => e.id == asset.id); } - state = state.copyWith(selectedNewAssetsForAlbum: currentAssetList, selectedMonths: currentMonthList); + state = state.copyWith( + selectedNewAssetsForAlbum: currentAssetList, + selectedMonths: currentMonthList); } void addAdditionalAssets(List assets) { state = state.copyWith( - selectedAdditionalAssetsForAlbum: {...state.selectedAdditionalAssetsForAlbum, ...assets}, + selectedAdditionalAssetsForAlbum: { + ...state.selectedAdditionalAssetsForAlbum, + ...assets + }, ); } void addAllAssetsInMonth(String month, List assetsInMonth) { state = state.copyWith( selectedMonths: {...state.selectedMonths, month}, - selectedNewAssetsForAlbum: {...state.selectedNewAssetsForAlbum, ...assetsInMonth}, + selectedNewAssetsForAlbum: { + ...state.selectedNewAssetsForAlbum, + ...assetsInMonth + }, ); } void addNewAssets(List assets) { state = state.copyWith( - selectedNewAssetsForAlbum: {...state.selectedNewAssetsForAlbum, ...assets}, + selectedNewAssetsForAlbum: { + ...state.selectedNewAssetsForAlbum, + ...assets + }, ); } @@ -93,7 +106,10 @@ class AssetSelectionNotifier extends StateNotifier { void addAssetsInAlbumViewer(List assets) { state = state.copyWith( - selectedAssetsInAlbumViewer: {...state.selectedAssetsInAlbumViewer, ...assets}, + selectedAssetsInAlbumViewer: { + ...state.selectedAssetsInAlbumViewer, + ...assets + }, ); } @@ -108,6 +124,7 @@ class AssetSelectionNotifier extends StateNotifier { } } -final assetSelectionProvider = StateNotifierProvider((ref) { +final assetSelectionProvider = + StateNotifierProvider((ref) { return AssetSelectionNotifier(); }); diff --git a/mobile/lib/modules/sharing/ui/album_action_outlined_button.dart b/mobile/lib/modules/sharing/ui/album_action_outlined_button.dart index f694349a34..3a4a351cfb 100644 --- a/mobile/lib/modules/sharing/ui/album_action_outlined_button.dart +++ b/mobile/lib/modules/sharing/ui/album_action_outlined_button.dart @@ -5,7 +5,11 @@ class AlbumActionOutlinedButton extends StatelessWidget { final String labelText; final IconData iconData; - const AlbumActionOutlinedButton({Key? key, this.onPressed, required this.labelText, required this.iconData}) + const AlbumActionOutlinedButton( + {Key? key, + this.onPressed, + required this.labelText, + required this.iconData}) : super(key: key); @override @@ -26,7 +30,8 @@ class AlbumActionOutlinedButton extends StatelessWidget { icon: Icon(iconData, size: 15), label: Text( labelText, - style: const TextStyle(fontSize: 12, fontWeight: FontWeight.bold, color: Colors.black87), + style: const TextStyle( + fontSize: 12, fontWeight: FontWeight.bold, color: Colors.black87), ), onPressed: onPressed, ), diff --git a/mobile/lib/modules/sharing/ui/album_title_text_field.dart b/mobile/lib/modules/sharing/ui/album_title_text_field.dart index f777e2863f..8eca564307 100644 --- a/mobile/lib/modules/sharing/ui/album_title_text_field.dart +++ b/mobile/lib/modules/sharing/ui/album_title_text_field.dart @@ -29,7 +29,8 @@ class AlbumTitleTextField extends ConsumerWidget { ref.watch(albumTitleProvider.notifier).setAlbumTitle(v); }, focusNode: albumTitleTextFieldFocusNode, - style: TextStyle(fontSize: 28, color: Colors.grey[700], fontWeight: FontWeight.bold), + style: TextStyle( + fontSize: 28, color: Colors.grey[700], fontWeight: FontWeight.bold), controller: albumTitleController, onTap: () { isAlbumTitleTextFieldFocus.value = true; diff --git a/mobile/lib/modules/sharing/ui/album_viewer_editable_title.dart b/mobile/lib/modules/sharing/ui/album_viewer_editable_title.dart index 191b5de1a4..7a9b0127b1 100644 --- a/mobile/lib/modules/sharing/ui/album_viewer_editable_title.dart +++ b/mobile/lib/modules/sharing/ui/album_viewer_editable_title.dart @@ -7,11 +7,14 @@ import 'package:immich_mobile/modules/sharing/providers/album_viewer.provider.da class AlbumViewerEditableTitle extends HookConsumerWidget { final SharedAlbum albumInfo; final FocusNode titleFocusNode; - const AlbumViewerEditableTitle({Key? key, required this.albumInfo, required this.titleFocusNode}) : super(key: key); + const AlbumViewerEditableTitle( + {Key? key, required this.albumInfo, required this.titleFocusNode}) + : super(key: key); @override Widget build(BuildContext context, WidgetRef ref) { - final titleTextEditController = useTextEditingController(text: albumInfo.albumName); + final titleTextEditController = + useTextEditingController(text: albumInfo.albumName); void onFocusModeChange() { if (!titleFocusNode.hasFocus && titleTextEditController.text.isEmpty) { @@ -40,7 +43,9 @@ class AlbumViewerEditableTitle extends HookConsumerWidget { onTap: () { FocusScope.of(context).requestFocus(titleFocusNode); - ref.watch(albumViewerProvider.notifier).setEditTitleText(albumInfo.albumName); + ref + .watch(albumViewerProvider.notifier) + .setEditTitleText(albumInfo.albumName); ref.watch(albumViewerProvider.notifier).enableEditAlbum(); if (titleTextEditController.text == 'Untitled') { diff --git a/mobile/lib/modules/sharing/ui/album_viewer_thumbnail.dart b/mobile/lib/modules/sharing/ui/album_viewer_thumbnail.dart index cf7e99b71e..c6e87b3aaa 100644 --- a/mobile/lib/modules/sharing/ui/album_viewer_thumbnail.dart +++ b/mobile/lib/modules/sharing/ui/album_viewer_thumbnail.dart @@ -22,8 +22,10 @@ class AlbumViewerThumbnail extends HookConsumerWidget { var thumbnailRequestUrl = '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}&isThumb=true'; var deviceId = ref.watch(authenticationProvider).deviceId; - final selectedAssetsInAlbumViewer = ref.watch(assetSelectionProvider).selectedAssetsInAlbumViewer; - final isMultiSelectionEnable = ref.watch(assetSelectionProvider).isMultiselectEnable; + final selectedAssetsInAlbumViewer = + ref.watch(assetSelectionProvider).selectedAssetsInAlbumViewer; + final isMultiSelectionEnable = + ref.watch(assetSelectionProvider).isMultiselectEnable; _viewAsset() { if (asset.type == 'IMAGE') { @@ -39,7 +41,8 @@ class AlbumViewerThumbnail extends HookConsumerWidget { } else { AutoRouter.of(context).push( VideoViewerRoute( - videoUrl: '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}', + videoUrl: + '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}', asset: asset), ); } @@ -58,7 +61,9 @@ class AlbumViewerThumbnail extends HookConsumerWidget { _enableMultiSelection() { ref.watch(assetSelectionProvider.notifier).enableMultiselection(); - ref.watch(assetSelectionProvider.notifier).addAssetsInAlbumViewer([asset]); + ref + .watch(assetSelectionProvider.notifier) + .addAssetsInAlbumViewer([asset]); } _disableMultiSelection() { @@ -96,7 +101,9 @@ class AlbumViewerThumbnail extends HookConsumerWidget { right: 10, bottom: 5, child: Icon( - (deviceId != asset.deviceId) ? Icons.cloud_done_outlined : Icons.photo_library_rounded, + (deviceId != asset.deviceId) + ? Icons.cloud_done_outlined + : Icons.photo_library_rounded, color: Colors.white, size: 18, ), @@ -136,7 +143,8 @@ class AlbumViewerThumbnail extends HookConsumerWidget { imageUrl: thumbnailRequestUrl, httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"}, fadeInDuration: const Duration(milliseconds: 250), - progressIndicatorBuilder: (context, url, downloadProgress) => Transform.scale( + progressIndicatorBuilder: (context, url, downloadProgress) => + Transform.scale( scale: 0.2, child: CircularProgressIndicator(value: downloadProgress.progress), ), @@ -152,13 +160,17 @@ class AlbumViewerThumbnail extends HookConsumerWidget { _handleSelectionGesture() { if (selectedAssetsInAlbumViewer.contains(asset)) { - ref.watch(assetSelectionProvider.notifier).removeAssetsInAlbumViewer([asset]); + ref + .watch(assetSelectionProvider.notifier) + .removeAssetsInAlbumViewer([asset]); if (selectedAssetsInAlbumViewer.isEmpty) { _disableMultiSelection(); } } else { - ref.watch(assetSelectionProvider.notifier).addAssetsInAlbumViewer([asset]); + ref + .watch(assetSelectionProvider.notifier) + .addAssetsInAlbumViewer([asset]); } } diff --git a/mobile/lib/modules/sharing/ui/asset_grid_by_month.dart b/mobile/lib/modules/sharing/ui/asset_grid_by_month.dart index acc4749d78..8d719bac57 100644 --- a/mobile/lib/modules/sharing/ui/asset_grid_by_month.dart +++ b/mobile/lib/modules/sharing/ui/asset_grid_by_month.dart @@ -5,7 +5,8 @@ import 'package:immich_mobile/shared/models/immich_asset.model.dart'; class AssetGridByMonth extends HookConsumerWidget { final List assetGroup; - const AssetGridByMonth({Key? key, required this.assetGroup}) : super(key: key); + const AssetGridByMonth({Key? key, required this.assetGroup}) + : super(key: key); @override Widget build(BuildContext context, WidgetRef ref) { return SliverGrid( diff --git a/mobile/lib/modules/sharing/ui/month_group_title.dart b/mobile/lib/modules/sharing/ui/month_group_title.dart index 297127aa51..71e160664c 100644 --- a/mobile/lib/modules/sharing/ui/month_group_title.dart +++ b/mobile/lib/modules/sharing/ui/month_group_title.dart @@ -8,12 +8,15 @@ class MonthGroupTitle extends HookConsumerWidget { final String month; final List assetGroup; - const MonthGroupTitle({Key? key, required this.month, required this.assetGroup}) : super(key: key); + const MonthGroupTitle( + {Key? key, required this.month, required this.assetGroup}) + : super(key: key); @override Widget build(BuildContext context, WidgetRef ref) { final selectedDateGroup = ref.watch(assetSelectionProvider).selectedMonths; - final selectedAssets = ref.watch(assetSelectionProvider).selectedNewAssetsForAlbum; + final selectedAssets = + ref.watch(assetSelectionProvider).selectedNewAssetsForAlbum; final isAlbumExist = ref.watch(assetSelectionProvider).isAlbumExist; _handleTitleIconClick() { @@ -21,10 +24,16 @@ class MonthGroupTitle extends HookConsumerWidget { if (isAlbumExist) { if (selectedDateGroup.contains(month)) { - ref.watch(assetSelectionProvider.notifier).removeAssetsInMonth(month, []); - ref.watch(assetSelectionProvider.notifier).removeSelectedAdditionalAssets(assetGroup); + ref + .watch(assetSelectionProvider.notifier) + .removeAssetsInMonth(month, []); + ref + .watch(assetSelectionProvider.notifier) + .removeSelectedAdditionalAssets(assetGroup); } else { - ref.watch(assetSelectionProvider.notifier).addAllAssetsInMonth(month, []); + ref + .watch(assetSelectionProvider.notifier) + .addAllAssetsInMonth(month, []); // Deep clone assetGroup var assetGroupWithNewItems = [...assetGroup]; @@ -33,13 +42,19 @@ class MonthGroupTitle extends HookConsumerWidget { assetGroupWithNewItems.removeWhere((a) => a.id == selectedAsset.id); } - ref.watch(assetSelectionProvider.notifier).addAdditionalAssets(assetGroupWithNewItems); + ref + .watch(assetSelectionProvider.notifier) + .addAdditionalAssets(assetGroupWithNewItems); } } else { if (selectedDateGroup.contains(month)) { - ref.watch(assetSelectionProvider.notifier).removeAssetsInMonth(month, assetGroup); + ref + .watch(assetSelectionProvider.notifier) + .removeAssetsInMonth(month, assetGroup); } else { - ref.watch(assetSelectionProvider.notifier).addAllAssetsInMonth(month, assetGroup); + ref + .watch(assetSelectionProvider.notifier) + .addAllAssetsInMonth(month, assetGroup); } } } @@ -59,7 +74,8 @@ class MonthGroupTitle extends HookConsumerWidget { return SliverToBoxAdapter( child: Padding( - padding: const EdgeInsets.only(top: 29.0, bottom: 29.0, left: 14.0, right: 8.0), + padding: const EdgeInsets.only( + top: 29.0, bottom: 29.0, left: 14.0, right: 8.0), child: Row( children: [ GestureDetector( diff --git a/mobile/lib/modules/sharing/ui/selection_thumbnail_image.dart b/mobile/lib/modules/sharing/ui/selection_thumbnail_image.dart index 81feedc66f..c82ebea491 100644 --- a/mobile/lib/modules/sharing/ui/selection_thumbnail_image.dart +++ b/mobile/lib/modules/sharing/ui/selection_thumbnail_image.dart @@ -10,7 +10,8 @@ import 'package:immich_mobile/shared/models/immich_asset.model.dart'; class SelectionThumbnailImage extends HookConsumerWidget { final ImmichAsset asset; - const SelectionThumbnailImage({Key? key, required this.asset}) : super(key: key); + const SelectionThumbnailImage({Key? key, required this.asset}) + : super(key: key); @override Widget build(BuildContext context, WidgetRef ref) { @@ -18,8 +19,10 @@ class SelectionThumbnailImage extends HookConsumerWidget { var box = Hive.box(userInfoBox); var thumbnailRequestUrl = '${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}&isThumb=true'; - var selectedAsset = ref.watch(assetSelectionProvider).selectedNewAssetsForAlbum; - var newAssetsForAlbum = ref.watch(assetSelectionProvider).selectedAdditionalAssetsForAlbum; + var selectedAsset = + ref.watch(assetSelectionProvider).selectedNewAssetsForAlbum; + var newAssetsForAlbum = + ref.watch(assetSelectionProvider).selectedAdditionalAssetsForAlbum; var isAlbumExist = ref.watch(assetSelectionProvider).isAlbumExist; Widget _buildSelectionIcon(ImmichAsset asset) { @@ -72,15 +75,21 @@ class SelectionThumbnailImage extends HookConsumerWidget { // Operation for existing album if (!selectedAsset.contains(asset)) { if (newAssetsForAlbum.contains(asset)) { - ref.watch(assetSelectionProvider.notifier).removeSelectedAdditionalAssets([asset]); + ref + .watch(assetSelectionProvider.notifier) + .removeSelectedAdditionalAssets([asset]); } else { - ref.watch(assetSelectionProvider.notifier).addAdditionalAssets([asset]); + ref + .watch(assetSelectionProvider.notifier) + .addAdditionalAssets([asset]); } } } else { // Operation for new album if (selectedAsset.contains(asset)) { - ref.watch(assetSelectionProvider.notifier).removeSelectedNewAssets([asset]); + ref + .watch(assetSelectionProvider.notifier) + .removeSelectedNewAssets([asset]); } else { ref.watch(assetSelectionProvider.notifier).addNewAssets([asset]); } @@ -97,11 +106,15 @@ class SelectionThumbnailImage extends HookConsumerWidget { memCacheHeight: asset.type == 'IMAGE' ? 150 : 150, fit: BoxFit.cover, imageUrl: thumbnailRequestUrl, - httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"}, + httpHeaders: { + "Authorization": "Bearer ${box.get(accessTokenKey)}" + }, fadeInDuration: const Duration(milliseconds: 250), - progressIndicatorBuilder: (context, url, downloadProgress) => Transform.scale( + progressIndicatorBuilder: (context, url, downloadProgress) => + Transform.scale( scale: 0.2, - child: CircularProgressIndicator(value: downloadProgress.progress), + child: + CircularProgressIndicator(value: downloadProgress.progress), ), errorWidget: (context, url, error) { return Icon( diff --git a/mobile/lib/modules/sharing/ui/shared_album_thumbnail_image.dart b/mobile/lib/modules/sharing/ui/shared_album_thumbnail_image.dart index 91f6336a73..b6b75d65ab 100644 --- a/mobile/lib/modules/sharing/ui/shared_album_thumbnail_image.dart +++ b/mobile/lib/modules/sharing/ui/shared_album_thumbnail_image.dart @@ -9,7 +9,8 @@ import 'package:immich_mobile/shared/models/immich_asset.model.dart'; class SharedAlbumThumbnailImage extends HookConsumerWidget { final ImmichAsset asset; - const SharedAlbumThumbnailImage({Key? key, required this.asset}) : super(key: key); + const SharedAlbumThumbnailImage({Key? key, required this.asset}) + : super(key: key); @override Widget build(BuildContext context, WidgetRef ref) { @@ -34,9 +35,11 @@ class SharedAlbumThumbnailImage extends HookConsumerWidget { imageUrl: thumbnailRequestUrl, httpHeaders: {"Authorization": "Bearer ${box.get(accessTokenKey)}"}, fadeInDuration: const Duration(milliseconds: 250), - progressIndicatorBuilder: (context, url, downloadProgress) => Transform.scale( + progressIndicatorBuilder: (context, url, downloadProgress) => + Transform.scale( scale: 0.2, - child: CircularProgressIndicator(value: downloadProgress.progress), + child: + CircularProgressIndicator(value: downloadProgress.progress), ), errorWidget: (context, url, error) { return Icon( diff --git a/mobile/lib/modules/sharing/ui/sharing_sliver_appbar.dart b/mobile/lib/modules/sharing/ui/sharing_sliver_appbar.dart index 60ffd92911..aeea51ee18 100644 --- a/mobile/lib/modules/sharing/ui/sharing_sliver_appbar.dart +++ b/mobile/lib/modules/sharing/ui/sharing_sliver_appbar.dart @@ -37,11 +37,13 @@ class SharingSliverAppBar extends StatelessWidget { padding: const EdgeInsets.only(right: 4.0), child: TextButton.icon( style: ButtonStyle( - backgroundColor: MaterialStateProperty.all(Theme.of(context).primaryColor.withAlpha(20)), + backgroundColor: MaterialStateProperty.all( + Theme.of(context).primaryColor.withAlpha(20)), // foregroundColor: MaterialStateProperty.all(Colors.white), ), onPressed: () { - AutoRouter.of(context).push(const CreateSharedAlbumRoute()); + AutoRouter.of(context) + .push(const CreateSharedAlbumRoute()); }, icon: const Icon( Icons.photo_album_outlined, @@ -49,7 +51,8 @@ class SharingSliverAppBar extends StatelessWidget { ), label: const Text( "Create shared album", - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12), + style: + TextStyle(fontWeight: FontWeight.bold, fontSize: 12), ), ), ), @@ -59,7 +62,8 @@ class SharingSliverAppBar extends StatelessWidget { padding: const EdgeInsets.only(left: 4.0), child: TextButton.icon( style: ButtonStyle( - backgroundColor: MaterialStateProperty.all(Theme.of(context).primaryColor.withAlpha(20)), + backgroundColor: MaterialStateProperty.all( + Theme.of(context).primaryColor.withAlpha(20)), // foregroundColor: MaterialStateProperty.all(Colors.white), ), onPressed: null, @@ -69,7 +73,8 @@ class SharingSliverAppBar extends StatelessWidget { ), label: const Text( "Share with partner", - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12), + style: + TextStyle(fontWeight: FontWeight.bold, fontSize: 12), ), ), ), diff --git a/mobile/lib/modules/sharing/views/select_additional_user_for_sharing_page.dart b/mobile/lib/modules/sharing/views/select_additional_user_for_sharing_page.dart index d01693aae6..87ba9b6ba0 100644 --- a/mobile/lib/modules/sharing/views/select_additional_user_for_sharing_page.dart +++ b/mobile/lib/modules/sharing/views/select_additional_user_for_sharing_page.dart @@ -10,15 +10,18 @@ import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart'; class SelectAdditionalUserForSharingPage extends HookConsumerWidget { final SharedAlbum albumInfo; - const SelectAdditionalUserForSharingPage({Key? key, required this.albumInfo}) : super(key: key); + const SelectAdditionalUserForSharingPage({Key? key, required this.albumInfo}) + : super(key: key); @override Widget build(BuildContext context, WidgetRef ref) { - AsyncValue> suggestedShareUsers = ref.watch(suggestedSharedUsersProvider); + AsyncValue> suggestedShareUsers = + ref.watch(suggestedSharedUsersProvider); final sharedUsersList = useState>({}); _addNewUsersHandler() { - AutoRouter.of(context).pop(sharedUsersList.value.map((e) => e.id).toList()); + AutoRouter.of(context) + .pop(sharedUsersList.value.map((e) => e.id).toList()); } _buildTileIcon(User user) { @@ -32,7 +35,8 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget { ); } else { return CircleAvatar( - backgroundImage: const AssetImage('assets/immich-logo-no-outline.png'), + backgroundImage: + const AssetImage('assets/immich-logo-no-outline.png'), backgroundColor: Theme.of(context).primaryColor.withAlpha(50), ); } @@ -49,7 +53,10 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget { backgroundColor: Theme.of(context).primaryColor.withOpacity(0.15), label: Text( user.email, - style: const TextStyle(fontSize: 12, color: Colors.black87, fontWeight: FontWeight.bold), + style: const TextStyle( + fontSize: 12, + color: Colors.black87, + fontWeight: FontWeight.bold), ), ), ), @@ -65,7 +72,10 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget { padding: EdgeInsets.all(16.0), child: Text( 'Suggestions', - style: TextStyle(fontSize: 14, color: Colors.grey, fontWeight: FontWeight.bold), + style: TextStyle( + fontSize: 14, + color: Colors.grey, + fontWeight: FontWeight.bold), ), ), ListView.builder( @@ -75,14 +85,20 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget { leading: _buildTileIcon(users[index]), title: Text( users[index].email, - style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold), + style: const TextStyle( + fontSize: 14, fontWeight: FontWeight.bold), ), onTap: () { if (sharedUsersList.value.contains(users[index])) { - sharedUsersList.value = - sharedUsersList.value.where((selectedUser) => selectedUser.id != users[index].id).toSet(); + sharedUsersList.value = sharedUsersList.value + .where((selectedUser) => + selectedUser.id != users[index].id) + .toSet(); } else { - sharedUsersList.value = {...sharedUsersList.value, users[index]}; + sharedUsersList.value = { + ...sharedUsersList.value, + users[index] + }; } }, ); @@ -109,7 +125,8 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget { ), actions: [ TextButton( - onPressed: sharedUsersList.value.isEmpty ? null : _addNewUsersHandler, + onPressed: + sharedUsersList.value.isEmpty ? null : _addNewUsersHandler, child: const Text( "Add", style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), @@ -120,7 +137,8 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget { body: suggestedShareUsers.when( data: (users) { for (var sharedUsers in albumInfo.sharedUsers) { - users.removeWhere((u) => u.id == sharedUsers.id || u.id == albumInfo.ownerId); + users.removeWhere( + (u) => u.id == sharedUsers.id || u.id == albumInfo.ownerId); } return _buildUserList(users); diff --git a/mobile/lib/modules/sharing/views/sharing_page.dart b/mobile/lib/modules/sharing/views/sharing_page.dart index cad49e4ad9..45a717de91 100644 --- a/mobile/lib/modules/sharing/views/sharing_page.dart +++ b/mobile/lib/modules/sharing/views/sharing_page.dart @@ -29,12 +29,14 @@ class SharingPage extends HookConsumerWidget { return SliverList( delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { - String thumbnailUrl = sharedAlbums[index].albumThumbnailAssetId != null + String thumbnailUrl = sharedAlbums[index].albumThumbnailAssetId != + null ? "$thumbnailRequestUrl/${sharedAlbums[index].albumThumbnailAssetId}" : "https://images.unsplash.com/photo-1612178537253-bccd437b730e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NXx8Ymxhbmt8ZW58MHx8MHx8&auto=format&fit=crop&w=700&q=60"; return ListTile( - contentPadding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12), + contentPadding: + const EdgeInsets.symmetric(vertical: 12, horizontal: 12), leading: ClipRRect( borderRadius: BorderRadius.circular(8), child: FadeInImage( @@ -44,7 +46,9 @@ class SharingPage extends HookConsumerWidget { placeholder: MemoryImage(kTransparentImage), image: NetworkImage( thumbnailUrl, - headers: {"Authorization": "Bearer ${box.get(accessTokenKey)}"}, + headers: { + "Authorization": "Bearer ${box.get(accessTokenKey)}" + }, ), fadeInDuration: const Duration(milliseconds: 200), fadeOutDuration: const Duration(milliseconds: 200), @@ -54,10 +58,14 @@ class SharingPage extends HookConsumerWidget { sharedAlbums[index].albumName, maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.grey.shade800), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.grey.shade800), ), onTap: () { - AutoRouter.of(context).push(AlbumViewerRoute(albumId: sharedAlbums[index].id)); + AutoRouter.of(context) + .push(AlbumViewerRoute(albumId: sharedAlbums[index].id)); }, ); }, @@ -134,7 +142,9 @@ class SharingPage extends HookConsumerWidget { ), ), ), - sharedAlbums.isNotEmpty ? _buildAlbumList() : _buildEmptyListIndication() + sharedAlbums.isNotEmpty + ? _buildAlbumList() + : _buildEmptyListIndication() ], ), ); diff --git a/mobile/lib/shared/models/exif.model.dart b/mobile/lib/shared/models/exif.model.dart index 40f08d537c..7d8528b363 100644 --- a/mobile/lib/shared/models/exif.model.dart +++ b/mobile/lib/shared/models/exif.model.dart @@ -149,7 +149,8 @@ class ImmichExif { String toJson() => json.encode(toMap()); - factory ImmichExif.fromJson(String source) => ImmichExif.fromMap(json.decode(source)); + factory ImmichExif.fromJson(String source) => + ImmichExif.fromMap(json.decode(source)); @override String toString() { diff --git a/mobile/lib/shared/models/immich_asset.model.dart b/mobile/lib/shared/models/immich_asset.model.dart index 95ceab6ce0..558c19f2b5 100644 --- a/mobile/lib/shared/models/immich_asset.model.dart +++ b/mobile/lib/shared/models/immich_asset.model.dart @@ -95,7 +95,8 @@ class ImmichAsset extends Equatable { String toJson() => json.encode(toMap()); - factory ImmichAsset.fromJson(String source) => ImmichAsset.fromMap(json.decode(source)); + factory ImmichAsset.fromJson(String source) => + ImmichAsset.fromMap(json.decode(source)); @override String toString() { diff --git a/mobile/lib/shared/models/immich_asset_with_exif.model.dart b/mobile/lib/shared/models/immich_asset_with_exif.model.dart index 538b6921ae..88ff974373 100644 --- a/mobile/lib/shared/models/immich_asset_with_exif.model.dart +++ b/mobile/lib/shared/models/immich_asset_with_exif.model.dart @@ -85,13 +85,15 @@ class ImmichAssetWithExif { originalPath: map['originalPath'] ?? '', isFavorite: map['isFavorite'] ?? false, duration: map['duration'], - exifInfo: map['exifInfo'] != null ? ImmichExif.fromMap(map['exifInfo']) : null, + exifInfo: + map['exifInfo'] != null ? ImmichExif.fromMap(map['exifInfo']) : null, ); } String toJson() => json.encode(toMap()); - factory ImmichAssetWithExif.fromJson(String source) => ImmichAssetWithExif.fromMap(json.decode(source)); + factory ImmichAssetWithExif.fromJson(String source) => + ImmichAssetWithExif.fromMap(json.decode(source)); @override String toString() { diff --git a/mobile/lib/shared/models/mapbox_info.model.dart b/mobile/lib/shared/models/mapbox_info.model.dart index e3d4c4b912..f3407bab32 100644 --- a/mobile/lib/shared/models/mapbox_info.model.dart +++ b/mobile/lib/shared/models/mapbox_info.model.dart @@ -34,16 +34,20 @@ class MapboxInfo { String toJson() => json.encode(toMap()); - factory MapboxInfo.fromJson(String source) => MapboxInfo.fromMap(json.decode(source)); + factory MapboxInfo.fromJson(String source) => + MapboxInfo.fromMap(json.decode(source)); @override - String toString() => 'MapboxInfo(isEnable: $isEnable, mapboxSecret: $mapboxSecret)'; + String toString() => + 'MapboxInfo(isEnable: $isEnable, mapboxSecret: $mapboxSecret)'; @override bool operator ==(Object other) { if (identical(this, other)) return true; - return other is MapboxInfo && other.isEnable == isEnable && other.mapboxSecret == mapboxSecret; + return other is MapboxInfo && + other.isEnable == isEnable && + other.mapboxSecret == mapboxSecret; } @override diff --git a/mobile/lib/shared/models/server_info.model.dart b/mobile/lib/shared/models/server_info.model.dart index 7cb2c77c13..7343fbe961 100644 --- a/mobile/lib/shared/models/server_info.model.dart +++ b/mobile/lib/shared/models/server_info.model.dart @@ -64,7 +64,8 @@ class ServerInfo { String toJson() => json.encode(toMap()); - factory ServerInfo.fromJson(String source) => ServerInfo.fromMap(json.decode(source)); + factory ServerInfo.fromJson(String source) => + ServerInfo.fromMap(json.decode(source)); @override String toString() { diff --git a/mobile/lib/shared/models/server_info_state.model.dart b/mobile/lib/shared/models/server_info_state.model.dart index 5c6074ee74..f82beb7949 100644 --- a/mobile/lib/shared/models/server_info_state.model.dart +++ b/mobile/lib/shared/models/server_info_state.model.dart @@ -26,7 +26,8 @@ class ServerInfoState { mapboxInfo: mapboxInfo ?? this.mapboxInfo, serverVersion: serverVersion ?? this.serverVersion, isVersionMismatch: isVersionMismatch ?? this.isVersionMismatch, - versionMismatchErrorMessage: versionMismatchErrorMessage ?? this.versionMismatchErrorMessage, + versionMismatchErrorMessage: + versionMismatchErrorMessage ?? this.versionMismatchErrorMessage, ); } @@ -50,7 +51,8 @@ class ServerInfoState { String toJson() => json.encode(toMap()); - factory ServerInfoState.fromJson(String source) => ServerInfoState.fromMap(json.decode(source)); + factory ServerInfoState.fromJson(String source) => + ServerInfoState.fromMap(json.decode(source)); @override String toString() { diff --git a/mobile/lib/shared/models/server_version.model.dart b/mobile/lib/shared/models/server_version.model.dart index 176e939808..d41fb1e133 100644 --- a/mobile/lib/shared/models/server_version.model.dart +++ b/mobile/lib/shared/models/server_version.model.dart @@ -47,7 +47,8 @@ class ServerVersion { String toJson() => json.encode(toMap()); - factory ServerVersion.fromJson(String source) => ServerVersion.fromMap(json.decode(source)); + factory ServerVersion.fromJson(String source) => + ServerVersion.fromMap(json.decode(source)); @override String toString() { diff --git a/mobile/lib/shared/models/upload_profile_image_repsonse.model.dart b/mobile/lib/shared/models/upload_profile_image_repsonse.model.dart index da4a2f6bf3..fb25d356ed 100644 --- a/mobile/lib/shared/models/upload_profile_image_repsonse.model.dart +++ b/mobile/lib/shared/models/upload_profile_image_repsonse.model.dart @@ -36,16 +36,20 @@ class UploadProfileImageResponse { String toJson() => json.encode(toMap()); - factory UploadProfileImageResponse.fromJson(String source) => UploadProfileImageResponse.fromMap(json.decode(source)); + factory UploadProfileImageResponse.fromJson(String source) => + UploadProfileImageResponse.fromMap(json.decode(source)); @override - String toString() => 'UploadProfileImageReponse(userId: $userId, profileImagePath: $profileImagePath)'; + String toString() => + 'UploadProfileImageReponse(userId: $userId, profileImagePath: $profileImagePath)'; @override bool operator ==(Object other) { if (identical(this, other)) return true; - return other is UploadProfileImageResponse && other.userId == userId && other.profileImagePath == profileImagePath; + return other is UploadProfileImageResponse && + other.userId == userId && + other.profileImagePath == profileImagePath; } @override diff --git a/mobile/lib/shared/models/user.model.dart b/mobile/lib/shared/models/user.model.dart index e8a29cf8be..99b0ce6cc0 100644 --- a/mobile/lib/shared/models/user.model.dart +++ b/mobile/lib/shared/models/user.model.dart @@ -56,18 +56,19 @@ class User { factory User.fromJson(String source) => User.fromMap(json.decode(source)); @override - String toString() => 'UserInfo(id: $id, email: $email, createdAt: $createdAt)'; + String toString() => + 'UserInfo(id: $id, email: $email, createdAt: $createdAt)'; @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is User && - other.id == id && - other.email == email && - other.createdAt == createdAt && - other.firstName == firstName && - other.lastName == lastName; + other.id == id && + other.email == email && + other.createdAt == createdAt && + other.firstName == firstName && + other.lastName == lastName; } @override diff --git a/mobile/lib/shared/providers/asset.provider.dart b/mobile/lib/shared/providers/asset.provider.dart index b1a6b6c671..bb42fbd1eb 100644 --- a/mobile/lib/shared/providers/asset.provider.dart +++ b/mobile/lib/shared/providers/asset.provider.dart @@ -45,7 +45,7 @@ class AssetNotifier extends StateNotifier> { } } } - + try { await PhotoManager.editor.deleteWithIds(deleteIdList); } catch (e) { diff --git a/mobile/lib/shared/providers/websocket.provider.dart b/mobile/lib/shared/providers/websocket.provider.dart index e837eb983e..3fff0a748b 100644 --- a/mobile/lib/shared/providers/websocket.provider.dart +++ b/mobile/lib/shared/providers/websocket.provider.dart @@ -29,13 +29,16 @@ class WebscoketState { } @override - String toString() => 'WebscoketState(socket: $socket, isConnected: $isConnected)'; + String toString() => + 'WebscoketState(socket: $socket, isConnected: $isConnected)'; @override bool operator ==(Object other) { if (identical(this, other)) return true; - return other is WebscoketState && other.socket == socket && other.isConnected == isConnected; + return other is WebscoketState && + other.socket == socket && + other.isConnected == isConnected; } @override @@ -43,7 +46,8 @@ class WebscoketState { } class WebsocketNotifier extends StateNotifier { - WebsocketNotifier(this.ref) : super(WebscoketState(socket: null, isConnected: false)) { + WebsocketNotifier(this.ref) + : super(WebscoketState(socket: null, isConnected: false)) { debugPrint("Init websocket instance"); } @@ -122,6 +126,7 @@ class WebsocketNotifier extends StateNotifier { } } -final websocketProvider = StateNotifierProvider((ref) { +final websocketProvider = + StateNotifierProvider((ref) { return WebsocketNotifier(ref); }); diff --git a/mobile/lib/shared/ui/immich_sliver_persistent_app_bar_delegate.dart b/mobile/lib/shared/ui/immich_sliver_persistent_app_bar_delegate.dart index 6ca358dade..85a67daa2c 100644 --- a/mobile/lib/shared/ui/immich_sliver_persistent_app_bar_delegate.dart +++ b/mobile/lib/shared/ui/immich_sliver_persistent_app_bar_delegate.dart @@ -2,7 +2,8 @@ import 'dart:math'; import 'package:flutter/material.dart'; -class ImmichSliverPersistentAppBarDelegate extends SliverPersistentHeaderDelegate { +class ImmichSliverPersistentAppBarDelegate + extends SliverPersistentHeaderDelegate { final double minHeight; final double maxHeight; final Widget child; @@ -20,12 +21,15 @@ class ImmichSliverPersistentAppBarDelegate extends SliverPersistentHeaderDelegat double get maxExtent => max(maxHeight, minHeight); @override - Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { + Widget build( + BuildContext context, double shrinkOffset, bool overlapsContent) { return SizedBox.expand(child: child); } @override bool shouldRebuild(ImmichSliverPersistentAppBarDelegate oldDelegate) { - return maxHeight != oldDelegate.maxHeight || minHeight != oldDelegate.minHeight || child != oldDelegate.child; + return maxHeight != oldDelegate.maxHeight || + minHeight != oldDelegate.minHeight || + child != oldDelegate.child; } } diff --git a/mobile/lib/shared/views/splash_screen.dart b/mobile/lib/shared/views/splash_screen.dart index 206d8c17a3..dd39bc1271 100644 --- a/mobile/lib/shared/views/splash_screen.dart +++ b/mobile/lib/shared/views/splash_screen.dart @@ -15,12 +15,14 @@ class SplashScreenPage extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - HiveSavedLoginInfo? loginInfo = Hive.box(hiveLoginInfoBox).get(savedLoginInfoKey); + HiveSavedLoginInfo? loginInfo = + Hive.box(hiveLoginInfoBox).get(savedLoginInfoKey); void performLoggingIn() async { var isAuthenticated = await ref .read(authenticationProvider.notifier) - .login(loginInfo!.email, loginInfo.password, loginInfo.serverUrl, true); + .login( + loginInfo!.email, loginInfo.password, loginInfo.serverUrl, true); if (isAuthenticated) { // Resume backup (if enable) then navigate diff --git a/mobile/lib/shared/views/tab_controller_page.dart b/mobile/lib/shared/views/tab_controller_page.dart index 2c303c39af..c099c15c09 100644 --- a/mobile/lib/shared/views/tab_controller_page.dart +++ b/mobile/lib/shared/views/tab_controller_page.dart @@ -9,7 +9,8 @@ class TabControllerPage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - var isMultiSelectEnable = ref.watch(homePageStateProvider).isMultiSelectEnable; + var isMultiSelectEnable = + ref.watch(homePageStateProvider).isMultiSelectEnable; return AutoTabsRouter( routes: [ @@ -32,16 +33,21 @@ class TabControllerPage extends ConsumerWidget { bottomNavigationBar: isMultiSelectEnable ? null : BottomNavigationBar( - selectedLabelStyle: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600), - unselectedLabelStyle: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600), + selectedLabelStyle: const TextStyle( + fontSize: 15, fontWeight: FontWeight.w600), + unselectedLabelStyle: const TextStyle( + fontSize: 15, fontWeight: FontWeight.w600), currentIndex: tabsRouter.activeIndex, onTap: (index) { tabsRouter.setActiveIndex(index); }, items: const [ - BottomNavigationBarItem(label: 'Photos', icon: Icon(Icons.photo)), - BottomNavigationBarItem(label: 'Search', icon: Icon(Icons.search)), - BottomNavigationBarItem(label: 'Sharing', icon: Icon(Icons.group_outlined)), + BottomNavigationBarItem( + label: 'Photos', icon: Icon(Icons.photo)), + BottomNavigationBarItem( + label: 'Search', icon: Icon(Icons.search)), + BottomNavigationBarItem( + label: 'Sharing', icon: Icon(Icons.group_outlined)), ], ), ),