You've already forked immich
							
							
				mirror of
				https://github.com/immich-app/immich.git
				synced 2025-10-31 00:18:28 +02:00 
			
		
		
		
	chore(mobile): Bump to Flutter 3.13 (#3767)
* Bump to Flutter 3.13.0 * Updates permission status * Adds hidden to app livecycle state * Updates and switches to WakelockPlus * bump flutter version github action * mobile test version * fix format * video player * video uri * ios test * Update android target sdk requirement to PlayStore --------- Co-authored-by: Alex Tran <Alex.Tran@conductix.com> Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
		
							
								
								
									
										2
									
								
								.github/workflows/build-mobile.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build-mobile.yml
									
									
									
									
										vendored
									
									
								
							| @@ -45,7 +45,7 @@ jobs: | ||||
|         uses: subosito/flutter-action@v2 | ||||
|         with: | ||||
|           channel: "stable" | ||||
|           flutter-version: "3.10.5" | ||||
|           flutter-version: "3.13.0" | ||||
|           cache: true | ||||
|  | ||||
|       - name: Create the Keystore | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/static_analysis.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/static_analysis.yml
									
									
									
									
										vendored
									
									
								
							| @@ -23,7 +23,7 @@ jobs: | ||||
|         uses: subosito/flutter-action@v2 | ||||
|         with: | ||||
|           channel: "stable" | ||||
|           flutter-version: "3.10.5" | ||||
|           flutter-version: "3.13.0" | ||||
|  | ||||
|       - name: Install dependencies | ||||
|         run: dart pub get | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							| @@ -149,7 +149,7 @@ jobs: | ||||
|         uses: subosito/flutter-action@v2 | ||||
|         with: | ||||
|           channel: "stable" | ||||
|           flutter-version: "3.10.5" | ||||
|           flutter-version: "3.13.0" | ||||
|       - name: Run tests | ||||
|         working-directory: ./mobile | ||||
|         run: flutter test -j 1 | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| { | ||||
|   "flutterSdkVersion": "3.10.5", | ||||
|   "flutterSdkVersion": "3.13.0", | ||||
|   "flavors": {} | ||||
| } | ||||
|   | ||||
| @@ -52,7 +52,7 @@ android { | ||||
|     defaultConfig { | ||||
|         // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). | ||||
|         applicationId "app.alextran.immich" | ||||
|         minSdkVersion 23 | ||||
|         minSdkVersion 26 | ||||
|         targetSdkVersion 33 | ||||
|         versionCode flutterVersionCode.toInteger() | ||||
|         versionName flutterVersionName | ||||
|   | ||||
| @@ -56,7 +56,7 @@ | ||||
|  | ||||
|   <uses-permission android:name="android.permission.INTERNET" /> | ||||
|   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> | ||||
|   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> | ||||
|   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/> | ||||
|   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | ||||
|   <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" /> | ||||
|   <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> | ||||
|   | ||||
| @@ -33,7 +33,7 @@ PODS: | ||||
|     - FlutterMacOS | ||||
|   - path_provider_ios (0.0.1): | ||||
|     - Flutter | ||||
|   - permission_handler_apple (9.0.4): | ||||
|   - permission_handler_apple (9.1.1): | ||||
|     - Flutter | ||||
|   - photo_manager (2.0.0): | ||||
|     - Flutter | ||||
| @@ -53,7 +53,7 @@ PODS: | ||||
|     - Flutter | ||||
|   - video_player_avfoundation (0.0.1): | ||||
|     - Flutter | ||||
|   - wakelock (0.0.1): | ||||
|   - wakelock_plus (0.0.1): | ||||
|     - Flutter | ||||
|  | ||||
| DEPENDENCIES: | ||||
| @@ -78,7 +78,7 @@ DEPENDENCIES: | ||||
|   - sqflite (from `.symlinks/plugins/sqflite/ios`) | ||||
|   - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) | ||||
|   - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`) | ||||
|   - wakelock (from `.symlinks/plugins/wakelock/ios`) | ||||
|   - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`) | ||||
|  | ||||
| SPEC REPOS: | ||||
|   trunk: | ||||
| @@ -130,8 +130,8 @@ EXTERNAL SOURCES: | ||||
|     :path: ".symlinks/plugins/url_launcher_ios/ios" | ||||
|   video_player_avfoundation: | ||||
|     :path: ".symlinks/plugins/video_player_avfoundation/ios" | ||||
|   wakelock: | ||||
|     :path: ".symlinks/plugins/wakelock/ios" | ||||
|   wakelock_plus: | ||||
|     :path: ".symlinks/plugins/wakelock_plus/ios" | ||||
|  | ||||
| SPEC CHECKSUMS: | ||||
|   connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a | ||||
| @@ -141,26 +141,26 @@ SPEC CHECKSUMS: | ||||
|   flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef | ||||
|   flutter_udid: 0848809dbed4c055175747ae6a45a8b4f6771e1c | ||||
|   flutter_web_auth: c25208760459cec375a3c39f6a8759165ca0fa4d | ||||
|   fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0 | ||||
|   fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c | ||||
|   FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a | ||||
|   image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5 | ||||
|   integration_test: 13825b8a9334a850581300559b8839134b124670 | ||||
|   isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073 | ||||
|   package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e | ||||
|   path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8 | ||||
|   package_info_plus: fd030dabf36271f146f1f3beacd48f564b0f17f7 | ||||
|   path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 | ||||
|   path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 | ||||
|   permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce | ||||
|   permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 | ||||
|   photo_manager: 4f6810b7dfc4feb03b461ac1a70dacf91fba7604 | ||||
|   ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 | ||||
|   SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c | ||||
|   share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 | ||||
|   shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c | ||||
|   share_plus: 599aa54e4ea31d4b4c0e9c911bcc26c55e791028 | ||||
|   shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 | ||||
|   sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a | ||||
|   Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 | ||||
|   url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 | ||||
|   video_player_avfoundation: 81e49bb3d9fb63dccf9fa0f6d877dc3ddbeac126 | ||||
|   wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f | ||||
|   wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47 | ||||
|  | ||||
| PODFILE CHECKSUM: 599d8aeb73728400c15364e734525722250a5382 | ||||
|  | ||||
| COCOAPODS: 1.12.1 | ||||
| COCOAPODS: 1.11.3 | ||||
|   | ||||
| @@ -171,7 +171,7 @@ | ||||
| 		97C146E61CF9000F007C117D /* Project object */ = { | ||||
| 			isa = PBXProject; | ||||
| 			attributes = { | ||||
| 				LastUpgradeCheck = 1300; | ||||
| 				LastUpgradeCheck = 1430; | ||||
| 				ORGANIZATIONNAME = ""; | ||||
| 				TargetAttributes = { | ||||
| 					97C146ED1CF9000F007C117D = { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Scheme | ||||
|    LastUpgradeVersion = "1300" | ||||
|    LastUpgradeVersion = "1430" | ||||
|    version = "1.3"> | ||||
|    <BuildAction | ||||
|       parallelizeBuildables = "YES" | ||||
|   | ||||
| @@ -139,6 +139,10 @@ class ImmichAppState extends ConsumerState<ImmichApp> | ||||
|         debugPrint("[APP STATE] detached"); | ||||
|         ref.read(appStateProvider.notifier).handleAppDetached(); | ||||
|         break; | ||||
|       case AppLifecycleState.hidden: | ||||
|         debugPrint("[APP STATE] hidden"); | ||||
|         ref.read(appStateProvider.notifier).handleAppHidden(); | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -49,7 +49,7 @@ class AlbumThumbnailListTile extends StatelessWidget { | ||||
|           type: ThumbnailFormat.JPEG, | ||||
|         ), | ||||
|         httpHeaders: { | ||||
|           "Authorization": "Bearer ${Store.get(StoreKey.accessToken)}" | ||||
|           "Authorization": "Bearer ${Store.get(StoreKey.accessToken)}", | ||||
|         }, | ||||
|         cacheKey: getAlbumThumbNailCacheKey(album, type: ThumbnailFormat.JPEG), | ||||
|         errorWidget: (context, url, error) => | ||||
| @@ -105,9 +105,9 @@ class AlbumThumbnailListTile extends StatelessWidget { | ||||
|                           style: TextStyle( | ||||
|                             fontSize: 12, | ||||
|                           ), | ||||
|                         ).tr() | ||||
|                         ).tr(), | ||||
|                     ], | ||||
|                   ) | ||||
|                   ), | ||||
|                 ], | ||||
|               ), | ||||
|             ), | ||||
|   | ||||
| @@ -250,7 +250,7 @@ class AlbumViewerAppbar extends HookConsumerWidget | ||||
|                   if (selected.isEmpty && | ||||
|                       onAddPhotos != null && | ||||
|                       userId == album.ownerId) | ||||
|                     ...ownerActions | ||||
|                     ...ownerActions, | ||||
|                 ], | ||||
|               ), | ||||
|             ), | ||||
|   | ||||
| @@ -60,7 +60,7 @@ class LibraryPage extends HookConsumerWidget { | ||||
|     Widget buildSortButton() { | ||||
|       final options = [ | ||||
|         "library_page_sort_created".tr(), | ||||
|         "library_page_sort_title".tr() | ||||
|         "library_page_sort_title".tr(), | ||||
|       ]; | ||||
|  | ||||
|       return PopupMenuButton( | ||||
| @@ -87,7 +87,7 @@ class LibraryPage extends HookConsumerWidget { | ||||
|                       color: selected ? Theme.of(context).primaryColor : null, | ||||
|                       fontSize: 12.0, | ||||
|                     ), | ||||
|                   ) | ||||
|                   ), | ||||
|                 ], | ||||
|               ), | ||||
|             ); | ||||
|   | ||||
| @@ -102,7 +102,7 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget { | ||||
|                   } else { | ||||
|                     sharedUsersList.value = { | ||||
|                       ...sharedUsersList.value, | ||||
|                       users[index] | ||||
|                       users[index], | ||||
|                     }; | ||||
|                   } | ||||
|                 }, | ||||
| @@ -135,7 +135,7 @@ class SelectAdditionalUserForSharingPage extends HookConsumerWidget { | ||||
|               "share_add", | ||||
|               style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), | ||||
|             ).tr(), | ||||
|           ) | ||||
|           ), | ||||
|         ], | ||||
|       ), | ||||
|       body: suggestedShareUsers.when( | ||||
|   | ||||
| @@ -123,7 +123,7 @@ class SelectUserForSharingPage extends HookConsumerWidget { | ||||
|                   } else { | ||||
|                     sharedUsersList.value = { | ||||
|                       ...sharedUsersList.value, | ||||
|                       users[index] | ||||
|                       users[index], | ||||
|                     }; | ||||
|                   } | ||||
|                 }, | ||||
| @@ -163,7 +163,7 @@ class SelectUserForSharingPage extends HookConsumerWidget { | ||||
|                 // color: Theme.of(context).primaryColor, | ||||
|               ), | ||||
|             ).tr(), | ||||
|           ) | ||||
|           ), | ||||
|         ], | ||||
|       ), | ||||
|       body: suggestedShareUsers.when( | ||||
|   | ||||
| @@ -160,7 +160,7 @@ class SharingPage extends HookConsumerWidget { | ||||
|                   maxLines: 1, | ||||
|                 ).tr(), | ||||
|               ), | ||||
|             ) | ||||
|             ), | ||||
|           ], | ||||
|         ), | ||||
|       ); | ||||
|   | ||||
| @@ -91,7 +91,7 @@ class ArchivePage extends HookConsumerWidget { | ||||
|                               selectionEnabledHook.value = false; | ||||
|                             } | ||||
|                           }, | ||||
|                   ) | ||||
|                   ), | ||||
|                 ], | ||||
|               ), | ||||
|             ), | ||||
| @@ -124,7 +124,7 @@ class ArchivePage extends HookConsumerWidget { | ||||
|                   ), | ||||
|                   if (selectionEnabledHook.value) buildBottomBar(), | ||||
|                   if (processing.value) | ||||
|                     const Center(child: ImmichLoadingIndicator()) | ||||
|                     const Center(child: ImmichLoadingIndicator()), | ||||
|                 ], | ||||
|               ), | ||||
|       ), | ||||
|   | ||||
| @@ -199,7 +199,7 @@ class ExifBottomSheet extends HookConsumerWidget { | ||||
|               Text( | ||||
|                 "${exifInfo!.latitude!.toStringAsFixed(4)}, ${exifInfo.longitude!.toStringAsFixed(4)}", | ||||
|                 style: const TextStyle(fontSize: 12), | ||||
|               ) | ||||
|               ), | ||||
|             ], | ||||
|           ), | ||||
|         ], | ||||
|   | ||||
| @@ -128,7 +128,7 @@ class TopControlAppBar extends HookConsumerWidget { | ||||
|         if (asset.isLocal && !asset.isRemote) buildUploadButton(), | ||||
|         if (asset.isRemote && !asset.isLocal) buildDownloadButton(), | ||||
|         if (asset.isRemote) buildAddToAlbumButtom(), | ||||
|         buildMoreInfoButton() | ||||
|         buildMoreInfoButton(), | ||||
|       ], | ||||
|     ); | ||||
|   } | ||||
|   | ||||
| @@ -11,7 +11,7 @@ import 'package:immich_mobile/shared/models/store.dart'; | ||||
| import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart'; | ||||
| import 'package:photo_manager/photo_manager.dart'; | ||||
| import 'package:video_player/video_player.dart'; | ||||
| import 'package:wakelock/wakelock.dart'; | ||||
| import 'package:wakelock_plus/wakelock_plus.dart'; | ||||
|  | ||||
| // ignore: must_be_immutable | ||||
| class VideoViewerPage extends HookConsumerWidget { | ||||
| @@ -136,16 +136,16 @@ class _VideoPlayerState extends State<VideoPlayer> { | ||||
|     videoPlayerController.addListener(() { | ||||
|       if (videoPlayerController.value.isInitialized) { | ||||
|         if (videoPlayerController.value.isPlaying) { | ||||
|           Wakelock.enable(); | ||||
|           WakelockPlus.enable(); | ||||
|           widget.onPlaying?.call(); | ||||
|         } else if (!videoPlayerController.value.isPlaying) { | ||||
|           Wakelock.disable(); | ||||
|           WakelockPlus.disable(); | ||||
|           widget.onPaused?.call(); | ||||
|         } | ||||
|  | ||||
|         if (videoPlayerController.value.position == | ||||
|             videoPlayerController.value.duration) { | ||||
|           Wakelock.disable(); | ||||
|           WakelockPlus.disable(); | ||||
|           widget.onVideoEnded(); | ||||
|         } | ||||
|       } | ||||
| @@ -155,8 +155,8 @@ class _VideoPlayerState extends State<VideoPlayer> { | ||||
|   Future<void> initializePlayer() async { | ||||
|     try { | ||||
|       videoPlayerController = widget.file == null | ||||
|           ? VideoPlayerController.network( | ||||
|               widget.url!, | ||||
|           ? VideoPlayerController.networkUrl( | ||||
|               Uri.parse(widget.url!), | ||||
|               httpHeaders: {"Authorization": "Bearer ${widget.jwtToken}"}, | ||||
|             ) | ||||
|           : VideoPlayerController.file(widget.file!); | ||||
| @@ -210,8 +210,7 @@ class _VideoPlayerState extends State<VideoPlayer> { | ||||
|         child: Center( | ||||
|           child: Stack( | ||||
|             children: [ | ||||
|               if (widget.placeholder != null) | ||||
|                 widget.placeholder!, | ||||
|               if (widget.placeholder != null) widget.placeholder!, | ||||
|               const Center( | ||||
|                 child: ImmichLoadingIndicator(), | ||||
|               ), | ||||
|   | ||||
| @@ -90,7 +90,7 @@ class BackgroundService { | ||||
|           requireUnmetered, | ||||
|           requireCharging, | ||||
|           triggerUpdateDelay, | ||||
|           triggerMaxDelay | ||||
|           triggerMaxDelay, | ||||
|         ], | ||||
|       ); | ||||
|       return ok; | ||||
|   | ||||
| @@ -511,7 +511,7 @@ class BackupNotifier extends StateNotifier<BackUpState> { | ||||
|       state = state.copyWith( | ||||
|         selectedAlbumsBackupAssetsIds: { | ||||
|           ...state.selectedAlbumsBackupAssetsIds, | ||||
|           deviceAssetId | ||||
|           deviceAssetId, | ||||
|         }, | ||||
|         allAssetsInDatabase: [...state.allAssetsInDatabase, deviceAssetId], | ||||
|       ); | ||||
|   | ||||
| @@ -174,7 +174,7 @@ class AlbumInfoCard extends HookConsumerWidget { | ||||
|                     bottom: 10, | ||||
|                     right: 25, | ||||
|                     child: buildSelectedTextBox(), | ||||
|                   ) | ||||
|                   ), | ||||
|                 ], | ||||
|               ), | ||||
|             ), | ||||
| @@ -218,7 +218,7 @@ class AlbumInfoCard extends HookConsumerWidget { | ||||
|                             }), | ||||
|                             future: albumInfo.assetCount, | ||||
|                           ), | ||||
|                         ) | ||||
|                         ), | ||||
|                       ], | ||||
|                     ), | ||||
|                   ), | ||||
|   | ||||
| @@ -212,7 +212,7 @@ class CurrentUploadingAssetInfoBox extends HookConsumerWidget { | ||||
|                   Text( | ||||
|                     " ${uploadProgress.toStringAsFixed(0)}%", | ||||
|                     style: const TextStyle(fontSize: 12), | ||||
|                   ) | ||||
|                   ), | ||||
|                 ], | ||||
|               ), | ||||
|             ), | ||||
|   | ||||
| @@ -247,7 +247,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { | ||||
|                   child: Wrap( | ||||
|                     children: [ | ||||
|                       ...buildSelectedAlbumNameChip(), | ||||
|                       ...buildExcludedAlbumNameChip() | ||||
|                       ...buildExcludedAlbumNameChip(), | ||||
|                     ], | ||||
|                   ), | ||||
|                 ), | ||||
| @@ -301,7 +301,7 @@ class BackupAlbumSelectionPage extends HookConsumerWidget { | ||||
|                             .watch(backupProvider) | ||||
|                             .availableAlbums | ||||
|                             .length | ||||
|                             .toString() | ||||
|                             .toString(), | ||||
|                       ], | ||||
|                     ), | ||||
|                     style: const TextStyle( | ||||
|   | ||||
| @@ -26,7 +26,7 @@ import 'package:immich_mobile/shared/ui/confirm_dialog.dart'; | ||||
| import 'package:immich_mobile/shared/ui/immich_toast.dart'; | ||||
| import 'package:permission_handler/permission_handler.dart'; | ||||
| import 'package:url_launcher/url_launcher.dart'; | ||||
| import 'package:wakelock/wakelock.dart'; | ||||
| import 'package:wakelock_plus/wakelock_plus.dart'; | ||||
|  | ||||
| class BackupControllerPage extends HookConsumerWidget { | ||||
|   const BackupControllerPage({Key? key}) : super(key: key); | ||||
| @@ -114,7 +114,7 @@ class BackupControllerPage extends HookConsumerWidget { | ||||
|           ); | ||||
|           return; | ||||
|         } | ||||
|         Wakelock.enable(); | ||||
|         WakelockPlus.enable(); | ||||
|         const limit = 100; | ||||
|         final toDelete = await ref | ||||
|             .read(backupVerificationServiceProvider) | ||||
| @@ -140,7 +140,7 @@ class BackupControllerPage extends HookConsumerWidget { | ||||
|           ); | ||||
|         } | ||||
|       } finally { | ||||
|         Wakelock.disable(); | ||||
|         WakelockPlus.disable(); | ||||
|         checkInProgress.value = false; | ||||
|       } | ||||
|     } | ||||
| @@ -202,7 +202,7 @@ class BackupControllerPage extends HookConsumerWidget { | ||||
|                 child: const Text('backup_controller_page_storage_format').tr( | ||||
|                   args: [ | ||||
|                     backupState.serverInfo.diskUse, | ||||
|                     backupState.serverInfo.diskSize | ||||
|                     backupState.serverInfo.diskSize, | ||||
|                   ], | ||||
|                 ), | ||||
|               ), | ||||
| @@ -256,7 +256,7 @@ class BackupControllerPage extends HookConsumerWidget { | ||||
|                     ), | ||||
|                   ), | ||||
|                 ), | ||||
|               ) | ||||
|               ), | ||||
|             ], | ||||
|           ), | ||||
|         ), | ||||
| @@ -624,7 +624,7 @@ class BackupControllerPage extends HookConsumerWidget { | ||||
|                   style: TextStyle(fontSize: 12), | ||||
|                 ).tr(), | ||||
|                 buildSelectedAlbumName(), | ||||
|                 buildExcludedAlbumName() | ||||
|                 buildExcludedAlbumName(), | ||||
|               ], | ||||
|             ), | ||||
|           ), | ||||
| @@ -776,7 +776,7 @@ class BackupControllerPage extends HookConsumerWidget { | ||||
|             const Divider(), | ||||
|             const CurrentUploadingAssetInfoBox(), | ||||
|             if (!hasExclusiveAccess) buildBackgroundBackupInfo(), | ||||
|             buildBackupButton() | ||||
|             buildBackupButton(), | ||||
|           ], | ||||
|         ), | ||||
|       ), | ||||
|   | ||||
| @@ -129,7 +129,7 @@ class FailedBackupStatusPage extends HookConsumerWidget { | ||||
|                         ], | ||||
|                       ), | ||||
|                     ), | ||||
|                   ) | ||||
|                   ), | ||||
|                 ], | ||||
|               ), | ||||
|             ), | ||||
|   | ||||
| @@ -83,7 +83,7 @@ class FavoritesPage extends HookConsumerWidget { | ||||
|                       style: TextStyle(fontSize: 14), | ||||
|                     ), | ||||
|                     onTap: processing.value ? null : unfavorite, | ||||
|                   ) | ||||
|                   ), | ||||
|                 ], | ||||
|               ), | ||||
|             ), | ||||
| @@ -108,7 +108,7 @@ class FavoritesPage extends HookConsumerWidget { | ||||
|                         selectionActive: selectionEnabledHook.value, | ||||
|                         listener: selectionListener, | ||||
|                       ), | ||||
|                       if (selectionEnabledHook.value) buildBottomBar() | ||||
|                       if (selectionEnabledHook.value) buildBottomBar(), | ||||
|                     ], | ||||
|                   ), | ||||
|           ), | ||||
|   | ||||
| @@ -57,7 +57,7 @@ class GroupDividerTitle extends ConsumerWidget { | ||||
|                     Icons.check_circle_outline_rounded, | ||||
|                     color: Colors.grey, | ||||
|                   ), | ||||
|           ) | ||||
|           ), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   | ||||
| @@ -89,7 +89,7 @@ class ImmichAssetGrid extends HookConsumerWidget { | ||||
|                 perRow.value = 7 - scaleFactor.value.toInt(); | ||||
|               } | ||||
|             }; | ||||
|           }) | ||||
|           }), | ||||
|         }, | ||||
|         child: ImmichAssetGridView( | ||||
|           onRefresh: onRefresh, | ||||
|   | ||||
| @@ -225,7 +225,7 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> { | ||||
|               right: i + 1 == num ? 0.0 : widget.margin, | ||||
|             ), | ||||
|             color: Colors.grey, | ||||
|           ) | ||||
|           ), | ||||
|       ], | ||||
|     ); | ||||
|   } | ||||
|   | ||||
| @@ -155,7 +155,7 @@ class ControlBottomAppBar extends ConsumerWidget { | ||||
|               if (hasRemote) | ||||
|                 const SliverToBoxAdapter( | ||||
|                   child: SizedBox(height: 200), | ||||
|                 ) | ||||
|                 ), | ||||
|             ], | ||||
|           ), | ||||
|         ); | ||||
|   | ||||
| @@ -108,7 +108,7 @@ class ProfileDrawer extends HookConsumerWidget { | ||||
|               buildSignOutButton(), | ||||
|             ], | ||||
|           ), | ||||
|           const ServerInfoBox() | ||||
|           const ServerInfoBox(), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   | ||||
| @@ -156,7 +156,7 @@ class ProfileDrawerHeader extends HookConsumerWidget { | ||||
|           Text( | ||||
|             authState.userEmail, | ||||
|             style: Theme.of(context).textTheme.labelMedium, | ||||
|           ) | ||||
|           ), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   | ||||
| @@ -221,7 +221,7 @@ class HomePage extends HookConsumerWidget { | ||||
|                   namedArgs: { | ||||
|                     "album": album.name, | ||||
|                     "added": result.successfullyAdded.toString(), | ||||
|                     "failed": result.alreadyInAlbum.length.toString() | ||||
|                     "failed": result.alreadyInAlbum.length.toString(), | ||||
|                   }, | ||||
|                 ), | ||||
|               ); | ||||
| @@ -323,7 +323,7 @@ class HomePage extends HookConsumerWidget { | ||||
|                     ).tr(), | ||||
|                   ), | ||||
|                 ), | ||||
|               ) | ||||
|               ), | ||||
|             ], | ||||
|           ), | ||||
|         ); | ||||
| @@ -365,7 +365,7 @@ class HomePage extends HookConsumerWidget { | ||||
|                 enabled: !processing.value, | ||||
|                 selectionAssetState: selectionAssetState.value, | ||||
|               ), | ||||
|             if (processing.value) const Center(child: ImmichLoadingIndicator()) | ||||
|             if (processing.value) const Center(child: ImmichLoadingIndicator()), | ||||
|           ], | ||||
|         ), | ||||
|       ); | ||||
|   | ||||
| @@ -94,7 +94,7 @@ class ChangePasswordForm extends HookConsumerWidget { | ||||
|                     ), | ||||
|                   ], | ||||
|                 ), | ||||
|               ) | ||||
|               ), | ||||
|             ], | ||||
|           ), | ||||
|         ), | ||||
|   | ||||
| @@ -110,7 +110,7 @@ class MemoryCard extends HookConsumerWidget { | ||||
|               left: 18.0, | ||||
|               bottom: 18.0, | ||||
|               child: buildTitle(), | ||||
|             ) | ||||
|             ), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   | ||||
| @@ -153,6 +153,7 @@ class PermissionOnboardingPage extends HookConsumerWidget { | ||||
|         child = buildRequestPermission(); | ||||
|         break; | ||||
|       case PermissionStatus.granted: | ||||
|       case PermissionStatus.provisional: | ||||
|         child = buildPermissionGranted(); | ||||
|         break; | ||||
|       case PermissionStatus.restricted: | ||||
| @@ -183,7 +184,7 @@ class PermissionOnboardingPage extends HookConsumerWidget { | ||||
|                 ), | ||||
|                 TextButton( | ||||
|                   child: const Text('permission_onboarding_log_out').tr(), | ||||
|                   onPressed: () {  | ||||
|                   onPressed: () { | ||||
|                     ref.read(authenticationProvider.notifier).logout(); | ||||
|                     AutoRouter.of(context).replace( | ||||
|                       const LoginRoute(), | ||||
|   | ||||
| @@ -44,7 +44,7 @@ class PartnerPage extends HookConsumerWidget { | ||||
|                       Text("${u.firstName} ${u.lastName}"), | ||||
|                     ], | ||||
|                   ), | ||||
|                 ) | ||||
|                 ), | ||||
|             ], | ||||
|           ); | ||||
|         }, | ||||
| @@ -151,7 +151,7 @@ class PartnerPage extends HookConsumerWidget { | ||||
|                 availableUsers.whenOrNull(data: (data) => addNewUsersHandler), | ||||
|             icon: const Icon(Icons.person_add), | ||||
|             tooltip: "partner_page_add_partner".tr(), | ||||
|           ) | ||||
|           ), | ||||
|         ], | ||||
|       ), | ||||
|       body: buildUserList(partners), | ||||
|   | ||||
| @@ -50,7 +50,7 @@ class CuratedPeopleRow extends StatelessWidget { | ||||
|       itemBuilder: (context, index) { | ||||
|         final person = content[index]; | ||||
|         final headers = { | ||||
|           "Authorization": "Bearer ${Store.get(StoreKey.accessToken)}" | ||||
|           "Authorization": "Bearer ${Store.get(StoreKey.accessToken)}", | ||||
|         }; | ||||
|         return Padding( | ||||
|           padding: const EdgeInsets.only(right: 18.0), | ||||
| @@ -102,7 +102,7 @@ class CuratedPeopleRow extends StatelessWidget { | ||||
|                         fontSize: 13.0, | ||||
|                       ), | ||||
|                     ), | ||||
|                   ) | ||||
|                   ), | ||||
|               ], | ||||
|             ), | ||||
|           ), | ||||
|   | ||||
| @@ -39,7 +39,7 @@ class SearchSuggestionList extends ConsumerWidget { | ||||
|                               color: Theme.of(context).primaryColor, | ||||
|                               fontWeight: FontWeight.bold, | ||||
|                             ), | ||||
|                       ) | ||||
|                       ), | ||||
|                     ], | ||||
|                   ), | ||||
|                 ), | ||||
|   | ||||
| @@ -46,7 +46,7 @@ class ThumbnailWithInfo extends StatelessWidget { | ||||
|                       imageUrl: imageUrl!, | ||||
|                       httpHeaders: { | ||||
|                         "Authorization": | ||||
|                             "Bearer ${Store.get(StoreKey.accessToken)}" | ||||
|                             "Bearer ${Store.get(StoreKey.accessToken)}", | ||||
|                       }, | ||||
|                       errorWidget: (context, url, error) => | ||||
|                           const Icon(Icons.image_not_supported_outlined), | ||||
|   | ||||
| @@ -56,7 +56,7 @@ class PersonResultPage extends HookConsumerWidget { | ||||
|                     style: TextStyle(fontWeight: FontWeight.bold), | ||||
|                   ), | ||||
|                   onTap: showEditNameDialog, | ||||
|                 ) | ||||
|                 ), | ||||
|               ], | ||||
|             ), | ||||
|           ); | ||||
| @@ -134,7 +134,7 @@ class PersonResultPage extends HookConsumerWidget { | ||||
|                               getFaceThumbnailUrl(personId), | ||||
|                               headers: { | ||||
|                                 "Authorization": | ||||
|                                     "Bearer ${isar_store.Store.get(isar_store.StoreKey.accessToken)}" | ||||
|                                     "Bearer ${isar_store.Store.get(isar_store.StoreKey.accessToken)}", | ||||
|                               }, | ||||
|                             ), | ||||
|                           ), | ||||
|   | ||||
| @@ -42,7 +42,7 @@ class SettingsPage extends HookConsumerWidget { | ||||
|               const AssetListSettings(), | ||||
|               const NotificationSetting(), | ||||
|               // const ExperimentalSettings(), | ||||
|               const AdvancedSettings() | ||||
|               const AdvancedSettings(), | ||||
|             ], | ||||
|           ).toList(), | ||||
|         ], | ||||
|   | ||||
| @@ -75,7 +75,7 @@ part 'router.gr.dart'; | ||||
|         AutoRoute(page: HomePage, guards: [AuthGuard, DuplicateGuard]), | ||||
|         AutoRoute(page: SearchPage, guards: [AuthGuard, DuplicateGuard]), | ||||
|         AutoRoute(page: SharingPage, guards: [AuthGuard, DuplicateGuard]), | ||||
|         AutoRoute(page: LibraryPage, guards: [AuthGuard, DuplicateGuard]) | ||||
|         AutoRoute(page: LibraryPage, guards: [AuthGuard, DuplicateGuard]), | ||||
|       ], | ||||
|       transitionsBuilder: TransitionsBuilders.fadeIn, | ||||
|     ), | ||||
|   | ||||
| @@ -157,7 +157,7 @@ User _userDeserialize( | ||||
|     isPartnerSharedBy: reader.readBoolOrNull(offsets[4]) ?? false, | ||||
|     isPartnerSharedWith: reader.readBoolOrNull(offsets[5]) ?? false, | ||||
|     lastName: reader.readString(offsets[6]), | ||||
|     memoryEnabled: reader.readBoolOrNull(offsets[7]) ?? true, | ||||
|     memoryEnabled: reader.readBoolOrNull(offsets[7]), | ||||
|     profileImagePath: reader.readStringOrNull(offsets[8]) ?? '', | ||||
|     updatedAt: reader.readDateTime(offsets[9]), | ||||
|   ); | ||||
| @@ -186,7 +186,7 @@ P _userDeserializeProp<P>( | ||||
|     case 6: | ||||
|       return (reader.readString(offset)) as P; | ||||
|     case 7: | ||||
|       return (reader.readBoolOrNull(offset) ?? true) as P; | ||||
|       return (reader.readBoolOrNull(offset)) as P; | ||||
|     case 8: | ||||
|       return (reader.readStringOrNull(offset) ?? '') as P; | ||||
|     case 9: | ||||
| @@ -979,8 +979,24 @@ extension UserQueryFilter on QueryBuilder<User, User, QFilterCondition> { | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   QueryBuilder<User, User, QAfterFilterCondition> memoryEnabledIsNull() { | ||||
|     return QueryBuilder.apply(this, (query) { | ||||
|       return query.addFilterCondition(const FilterCondition.isNull( | ||||
|         property: r'memoryEnabled', | ||||
|       )); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   QueryBuilder<User, User, QAfterFilterCondition> memoryEnabledIsNotNull() { | ||||
|     return QueryBuilder.apply(this, (query) { | ||||
|       return query.addFilterCondition(const FilterCondition.isNotNull( | ||||
|         property: r'memoryEnabled', | ||||
|       )); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   QueryBuilder<User, User, QAfterFilterCondition> memoryEnabledEqualTo( | ||||
|       bool value) { | ||||
|       bool? value) { | ||||
|     return QueryBuilder.apply(this, (query) { | ||||
|       return query.addFilterCondition(FilterCondition.equalTo( | ||||
|         property: r'memoryEnabled', | ||||
| @@ -1661,7 +1677,7 @@ extension UserQueryProperty on QueryBuilder<User, User, QQueryProperty> { | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   QueryBuilder<User, bool, QQueryOperations> memoryEnabledProperty() { | ||||
|   QueryBuilder<User, bool?, QQueryOperations> memoryEnabledProperty() { | ||||
|     return QueryBuilder.apply(this, (query) { | ||||
|       return query.addPropertyName(r'memoryEnabled'); | ||||
|     }); | ||||
|   | ||||
| @@ -21,6 +21,7 @@ enum AppStateEnum { | ||||
|   paused, | ||||
|   resumed, | ||||
|   detached, | ||||
|   hidden, | ||||
| } | ||||
|  | ||||
| class AppStateNotiifer extends StateNotifier<AppStateEnum> { | ||||
| @@ -84,6 +85,10 @@ class AppStateNotiifer extends StateNotifier<AppStateEnum> { | ||||
|     state = AppStateEnum.detached; | ||||
|     ref.watch(manualUploadProvider.notifier).cancelBackup(); | ||||
|   } | ||||
|  | ||||
|   void handleAppHidden() { | ||||
|     state = AppStateEnum.hidden; | ||||
|   } | ||||
| } | ||||
|  | ||||
| final appStateProvider = | ||||
|   | ||||
| @@ -102,7 +102,7 @@ class LocalNotificationService { | ||||
|                       cancelUploadActionID, | ||||
|                       'Cancel', | ||||
|                       showsUserInterface: true, | ||||
|                     ) | ||||
|                     ), | ||||
|                   ] | ||||
|                 : null, | ||||
|           ) | ||||
|   | ||||
| @@ -16,7 +16,7 @@ class IgnorableChangeNotifier extends ChangeNotifier { | ||||
|       if (_ignorableListeners == null) { | ||||
|         AssertionError([ | ||||
|           'A $runtimeType was used after being disposed.', | ||||
|           'Once you have called dispose() on a $runtimeType, it can no longer be used.' | ||||
|           'Once you have called dispose() on a $runtimeType, it can no longer be used.', | ||||
|         ]); | ||||
|       } | ||||
|       return true; | ||||
|   | ||||
| @@ -15,7 +15,7 @@ class ShareDialog extends StatelessWidget { | ||||
|             margin: const EdgeInsets.only(top: 12), | ||||
|             child: const Text('share_dialog_preparing') | ||||
|                 .tr(), | ||||
|           ) | ||||
|           ), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   | ||||
| @@ -62,7 +62,7 @@ class UserCircleAvatar extends ConsumerWidget { | ||||
|                 image: NetworkImage( | ||||
|                   profileImageUrl, | ||||
|                   headers: { | ||||
|                     "Authorization": "Bearer ${Store.get(StoreKey.accessToken)}" | ||||
|                     "Authorization": "Bearer ${Store.get(StoreKey.accessToken)}", | ||||
|                   }, | ||||
|                 ), | ||||
|                 fadeInDuration: const Duration(milliseconds: 200), | ||||
|   | ||||
| @@ -47,7 +47,7 @@ class AppLogDetailPage extends HookConsumerWidget { | ||||
|                     size: 16.0, | ||||
|                     color: Theme.of(context).primaryColor, | ||||
|                   ), | ||||
|                 ) | ||||
|                 ), | ||||
|               ], | ||||
|             ), | ||||
|             Container( | ||||
| @@ -106,7 +106,7 @@ class AppLogDetailPage extends HookConsumerWidget { | ||||
|                     size: 16.0, | ||||
|                     color: Theme.of(context).primaryColor, | ||||
|                   ), | ||||
|                 ) | ||||
|                 ), | ||||
|               ], | ||||
|             ), | ||||
|             Container( | ||||
| @@ -181,7 +181,7 @@ class AppLogDetailPage extends HookConsumerWidget { | ||||
|             if (logMessage.context1 != null) | ||||
|               buildLogContext1(logMessage.context1.toString()), | ||||
|             if (logMessage.context2 != null) | ||||
|               buildStackMessage(logMessage.context2.toString()) | ||||
|               buildStackMessage(logMessage.context2.toString()), | ||||
|           ], | ||||
|         ), | ||||
|       ), | ||||
|   | ||||
| @@ -148,7 +148,7 @@ class TabControllerPage extends HookConsumerWidget { | ||||
|                 color: Theme.of(context).primaryColor, | ||||
|               ), | ||||
|             ), | ||||
|           ) | ||||
|           ), | ||||
|         ], | ||||
|       ); | ||||
|     } | ||||
| @@ -159,7 +159,7 @@ class TabControllerPage extends HookConsumerWidget { | ||||
|         const HomeRoute(), | ||||
|         SearchRoute(), | ||||
|         const SharingRoute(), | ||||
|         const LibraryRoute() | ||||
|         const LibraryRoute(), | ||||
|       ], | ||||
|       builder: (context, child, animation) { | ||||
|         final tabsRouter = AutoTabsRouter.of(context); | ||||
|   | ||||
| @@ -99,7 +99,7 @@ class VersionAnnouncementOverlay extends HookConsumerWidget { | ||||
|                                       text: | ||||
|                                           "version_announcement_overlay_text_3" | ||||
|                                               .tr(), | ||||
|                                     ) | ||||
|                                     ), | ||||
|                                   ], | ||||
|                                 ), | ||||
|                               ), | ||||
| @@ -126,7 +126,7 @@ class VersionAnnouncementOverlay extends HookConsumerWidget { | ||||
|                                   ), | ||||
|                                 ).tr(), | ||||
|                               ), | ||||
|                             ) | ||||
|                             ), | ||||
|                           ], | ||||
|                         ), | ||||
|                       ), | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -20,19 +20,19 @@ dependencies: | ||||
|   flutter_cache_manager: ^3.3.0 | ||||
|   intl: ^0.18.0 | ||||
|   auto_route: ^5.0.1 | ||||
|   fluttertoast: ^8.0.8 | ||||
|   fluttertoast: ^8.2.2 | ||||
|   video_player: ^2.2.18 | ||||
|   chewie: ^1.4.0 | ||||
|   badges: ^2.0.2 | ||||
|   socket_io_client: ^2.0.0-beta.4-nullsafety.0 | ||||
|   flutter_map: ^4.0.0 | ||||
|   flutter_udid: ^2.0.0 | ||||
|   package_info_plus: ^3.1.2 | ||||
|   package_info_plus: ^4.1.0 | ||||
|   url_launcher: ^6.1.3 | ||||
|   http: 0.13.5 | ||||
|   cancellation_token_http: ^1.1.0 | ||||
|   easy_localization: ^3.0.1 | ||||
|   share_plus: ^6.3.0 | ||||
|   share_plus: ^7.1.0 | ||||
|   flutter_displaymode: ^0.4.0 | ||||
|   scrollable_positioned_list: ^0.3.4 | ||||
|   path: ^1.8.1 | ||||
| @@ -48,7 +48,7 @@ dependencies: | ||||
|   device_info_plus: ^8.1.0 | ||||
|   connectivity_plus: ^4.0.1 | ||||
|   crypto: ^3.0.3 # TODO remove once native crypto is used on iOS | ||||
|   wakelock: ^0.6.2 | ||||
|   wakelock_plus: ^1.1.1 | ||||
|   flutter_local_notifications: ^15.1.0+1 | ||||
|  | ||||
|   openapi: | ||||
|   | ||||
| @@ -45,7 +45,7 @@ void main() { | ||||
|         AlbumSchema, | ||||
|         UserSchema, | ||||
|         StoreValueSchema, | ||||
|         LoggerMessageSchema | ||||
|         LoggerMessageSchema, | ||||
|       ], | ||||
|       maxSizeMiB: 256, | ||||
|       directory: ".", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user