diff --git a/.idea/libraries/Dart_Packages.xml b/.idea/libraries/Dart_Packages.xml index 5b84c32..5017247 100644 --- a/.idea/libraries/Dart_Packages.xml +++ b/.idea/libraries/Dart_Packages.xml @@ -1170,6 +1170,7 @@ @@ -1177,6 +1178,7 @@ @@ -1184,6 +1186,7 @@ @@ -1191,6 +1194,7 @@ @@ -1198,6 +1202,7 @@ @@ -1583,10 +1588,15 @@ + + + + + diff --git a/.idea/libraries/Flutter_Plugins.xml b/.idea/libraries/Flutter_Plugins.xml index 70cf51d..f3628d3 100644 --- a/.idea/libraries/Flutter_Plugins.xml +++ b/.idea/libraries/Flutter_Plugins.xml @@ -14,6 +14,8 @@ + + @@ -29,7 +31,6 @@ - @@ -46,7 +47,6 @@ - diff --git a/app/lib/components/thumbnail_builder.dart b/app/lib/components/thumbnail_builder.dart index bbae314..803f825 100644 --- a/app/lib/components/thumbnail_builder.dart +++ b/app/lib/components/thumbnail_builder.dart @@ -25,7 +25,7 @@ class AppMediaImage extends StatelessWidget { child: Hero( tag: heroTag ?? '', child: Image( - image: AppMediaImageProvider(media: media, thumbnailSize: size), + image: AppMediaImageProvider(media: media, thumbnailSize: size * 2), loadingBuilder: (context, child, loadingProgress) { if (loadingProgress != null) { return AppMediaPlaceHolder( diff --git a/app/lib/ui/flow/home/home_screen.dart b/app/lib/ui/flow/home/home_screen.dart index a3e6a98..8039dcd 100644 --- a/app/lib/ui/flow/home/home_screen.dart +++ b/app/lib/ui/flow/home/home_screen.dart @@ -117,8 +117,9 @@ class _HomeScreenState extends ConsumerState { tapTargetSize: MaterialTapTargetSize.shrinkWrap, size: 36, backgroundColor: context.colorScheme.containerNormal, - onPressed: () { - TransferRoute().push(context); + onPressed: () async { + await TransferRoute().push(context); + _notifier.loadMedias(); }, icon: Icon( CupertinoIcons.arrow_up_arrow_down, @@ -137,8 +138,9 @@ class _HomeScreenState extends ConsumerState { size: 36, backgroundColor: context.colorScheme.containerNormal, tapTargetSize: MaterialTapTargetSize.shrinkWrap, - onPressed: () { - AccountRoute().push(context); + onPressed: () async { + await AccountRoute().push(context); + _notifier.loadMedias(); }, icon: Icon( CupertinoIcons.person, @@ -261,7 +263,7 @@ class _HomeScreenState extends ConsumerState { startFrom: media.id, ), ).push(context); - _notifier.loadLocalMedia(); + _notifier.loadMedias(); } }, onLongTap: () { diff --git a/app/lib/ui/flow/home/home_screen_view_model.dart b/app/lib/ui/flow/home/home_screen_view_model.dart index 9339a1a..654aa1b 100644 --- a/app/lib/ui/flow/home/home_screen_view_model.dart +++ b/app/lib/ui/flow/home/home_screen_view_model.dart @@ -1,7 +1,6 @@ import 'dart:async'; import '../../../domain/extensions/map_extensions.dart'; import '../../../domain/extensions/media_list_extension.dart'; -import 'package:collection/collection.dart'; import 'package:data/models/app_process/app_process.dart'; import 'package:data/models/media/media.dart'; import 'package:data/models/media/media_extension.dart'; @@ -61,7 +60,7 @@ class HomeViewStateNotifier extends StateNotifier _listenUserGoogleAccount(); _googleDriveProcessRepo.setBackUpFolderId(_backUpFolderId); _googleDriveProcessRepo.addListener(_listenGoogleDriveProcess); - _loadInitialMedia(); + loadMedias(); _checkAutoBackUp(); } @@ -75,17 +74,7 @@ class HomeViewStateNotifier extends StateNotifier void _checkAutoBackUp() { if (_autoBackUpStatus) { - _googleDriveProcessRepo.uploadMediasInGoogleDrive( - medias: state.medias.valuesWhere( - (element) => - element.isLocalStored && - state.mediaProcesses.firstWhereOrNull( - (process) => process.id == element.id, - ) == - null, - ), - isFromAutoBackup: true, - ); + _googleDriveProcessRepo.autoBackInGoogleDrive(); } } @@ -157,8 +146,8 @@ class HomeViewStateNotifier extends StateNotifier ); } - Future _loadInitialMedia() async { - state = state.copyWith(loading: true, error: null); + Future loadMedias() async { + state = state.copyWith(loading: state.medias.isEmpty, error: null); final hasAccess = await _localMediaService.requestPermission(); state = state.copyWith(hasLocalMediaAccess: hasAccess, loading: false); if (hasAccess) { @@ -364,9 +353,7 @@ class HomeViewStateNotifier extends StateNotifier ) .toList(); - _googleDriveProcessRepo.uploadMediasInGoogleDrive( - medias: medias, - ); + _googleDriveProcessRepo.uploadMedia(medias); state = state.copyWith(selectedMedias: []); } catch (error) { state = state.copyWith(error: error); diff --git a/app/lib/ui/flow/media_preview/media_preview_view_model.dart b/app/lib/ui/flow/media_preview/media_preview_view_model.dart index 1394019..f83e2ae 100644 --- a/app/lib/ui/flow/media_preview/media_preview_view_model.dart +++ b/app/lib/ui/flow/media_preview/media_preview_view_model.dart @@ -110,7 +110,7 @@ class MediaPreviewStateNotifier extends StateNotifier { } Future uploadMediaInGoogleDrive({required AppMedia media}) async { - _googleDriveProcessRepo.uploadMediasInGoogleDrive(medias: [media]); + _googleDriveProcessRepo.uploadMedia([media]); } void updateVideoPosition(Duration position) { diff --git a/data/.flutter-plugins-dependencies b/data/.flutter-plugins-dependencies index 5232ece..d7885b4 100644 --- a/data/.flutter-plugins-dependencies +++ b/data/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"google_sign_in_ios","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/google_sign_in_ios-5.7.8/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/package_info_plus-8.1.1/","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"photo_manager","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/photo_manager-3.6.2/","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.3/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"url_launcher_ios","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/url_launcher_ios-6.3.1/","native_build":true,"dependencies":[]}],"android":[{"name":"google_sign_in_android","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/google_sign_in_android-6.1.33/","native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/package_info_plus-8.1.1/","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/path_provider_android-2.2.12/","native_build":true,"dependencies":[]},{"name":"photo_manager","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/photo_manager-3.6.2/","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/shared_preferences_android-2.3.3/","native_build":true,"dependencies":[]},{"name":"url_launcher_android","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/url_launcher_android-6.3.14/","native_build":true,"dependencies":[]}],"macos":[{"name":"google_sign_in_ios","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/google_sign_in_ios-5.7.8/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/package_info_plus-8.1.1/","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"photo_manager","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/photo_manager-3.6.2/","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.3/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"url_launcher_macos","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/url_launcher_macos-3.2.1/","native_build":true,"dependencies":[]}],"linux":[{"name":"package_info_plus","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/package_info_plus-8.1.1/","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"]},{"name":"url_launcher_linux","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/url_launcher_linux-3.2.1/","native_build":true,"dependencies":[]}],"windows":[{"name":"package_info_plus","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/package_info_plus-8.1.1/","native_build":false,"dependencies":[]},{"name":"path_provider_windows","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"]},{"name":"url_launcher_windows","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.3/","native_build":true,"dependencies":[]}],"web":[{"name":"google_sign_in_web","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/google_sign_in_web-0.12.4+3/","dependencies":[]},{"name":"package_info_plus","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/package_info_plus-8.1.1/","dependencies":[]},{"name":"shared_preferences_web","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.2/","dependencies":[]},{"name":"url_launcher_web","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/url_launcher_web-2.3.3/","dependencies":[]}]},"dependencyGraph":[{"name":"google_sign_in","dependencies":["google_sign_in_android","google_sign_in_ios","google_sign_in_web"]},{"name":"google_sign_in_android","dependencies":[]},{"name":"google_sign_in_ios","dependencies":[]},{"name":"google_sign_in_web","dependencies":[]},{"name":"package_info_plus","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"photo_manager","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"url_launcher","dependencies":["url_launcher_android","url_launcher_ios","url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_android","dependencies":[]},{"name":"url_launcher_ios","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2024-11-15 10:45:14.730523","version":"3.24.4","swift_package_manager_enabled":false} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"google_sign_in_ios","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/google_sign_in_ios-5.7.8/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/package_info_plus-8.1.1/","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"photo_manager","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/photo_manager-3.6.2/","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.3/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"url_launcher_ios","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/url_launcher_ios-6.3.1/","native_build":true,"dependencies":[]}],"android":[{"name":"google_sign_in_android","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/google_sign_in_android-6.1.33/","native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/package_info_plus-8.1.1/","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/path_provider_android-2.2.12/","native_build":true,"dependencies":[]},{"name":"photo_manager","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/photo_manager-3.6.2/","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/shared_preferences_android-2.3.3/","native_build":true,"dependencies":[]},{"name":"url_launcher_android","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/url_launcher_android-6.3.14/","native_build":true,"dependencies":[]}],"macos":[{"name":"google_sign_in_ios","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/google_sign_in_ios-5.7.8/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/package_info_plus-8.1.1/","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"photo_manager","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/photo_manager-3.6.2/","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.3/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"url_launcher_macos","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/url_launcher_macos-3.2.1/","native_build":true,"dependencies":[]}],"linux":[{"name":"package_info_plus","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/package_info_plus-8.1.1/","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"]},{"name":"url_launcher_linux","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/url_launcher_linux-3.2.1/","native_build":true,"dependencies":[]}],"windows":[{"name":"package_info_plus","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/package_info_plus-8.1.1/","native_build":false,"dependencies":[]},{"name":"path_provider_windows","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"]},{"name":"url_launcher_windows","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.3/","native_build":true,"dependencies":[]}],"web":[{"name":"google_sign_in_web","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/google_sign_in_web-0.12.4+3/","dependencies":[]},{"name":"package_info_plus","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/package_info_plus-8.1.1/","dependencies":[]},{"name":"shared_preferences_web","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.2/","dependencies":[]},{"name":"url_launcher_web","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/url_launcher_web-2.3.3/","dependencies":[]}]},"dependencyGraph":[{"name":"google_sign_in","dependencies":["google_sign_in_android","google_sign_in_ios","google_sign_in_web"]},{"name":"google_sign_in_android","dependencies":[]},{"name":"google_sign_in_ios","dependencies":[]},{"name":"google_sign_in_web","dependencies":[]},{"name":"package_info_plus","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"photo_manager","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"url_launcher","dependencies":["url_launcher_android","url_launcher_ios","url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_android","dependencies":[]},{"name":"url_launcher_ios","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2024-11-19 10:29:04.046577","version":"3.24.4","swift_package_manager_enabled":false} \ No newline at end of file diff --git a/data/lib/repositories/google_drive_process_repo.dart b/data/lib/repositories/google_drive_process_repo.dart index f9662f2..8a4f3bc 100644 --- a/data/lib/repositories/google_drive_process_repo.dart +++ b/data/lib/repositories/google_drive_process_repo.dart @@ -46,14 +46,43 @@ class GoogleDriveProcessRepo extends ChangeNotifier { _backUpFolderID = backUpFolderId; } - void uploadMediasInGoogleDrive({ - required List medias, - bool isFromAutoBackup = false, - }) { + Future autoBackInGoogleDrive() async { + final localMedias = await _localMediaService.getAllLocalMedia(); + + final dgMedias = await _googleDriveService.getDriveMedias( + backUpFolderId: _backUpFolderID!, + ); + + for (AppMedia localMedia in localMedias.toList()) { + if (_uploadQueue + .where((element) => element.id == localMedia.id) + .isNotEmpty || + dgMedias + .where((gdMedia) => gdMedia.path == localMedia.id) + .isNotEmpty) { + localMedias.removeWhere((media) => media.id == localMedia.id); + } + } + + _uploadQueue.addAll( + localMedias.map( + (media) => AppProcess( + isFromAutoBackup: true, + id: media.id, + media: media, + status: AppProcessStatus.waiting, + ), + ), + ); + notifyListeners(); + if (!_uploadQueueRunning) _startUploadQueueLoop(); + } + + Future uploadMedia(List medias) async { _uploadQueue.addAll( medias.map( (media) => AppProcess( - isFromAutoBackup: isFromAutoBackup, + isFromAutoBackup: false, id: media.id, media: media, status: AppProcessStatus.waiting, diff --git a/data/lib/services/local_media_service.dart b/data/lib/services/local_media_service.dart index a1824ca..8c2e266 100644 --- a/data/lib/services/local_media_service.dart +++ b/data/lib/services/local_media_service.dart @@ -34,6 +34,27 @@ class LocalMediaService { ); } + Future> getAllLocalMedia() async { + try { + final count = await PhotoManager.getAssetCount(); + final assets = await PhotoManager.getAssetListRange( + start: 0, + end: count, + filterOption: FilterOptionGroup( + orders: [const OrderOption(type: OrderOptionType.createDate)], + ), + ); + final files = await Future.wait( + assets.map( + (asset) => AppMedia.fromAssetEntity(asset), + ), + ); + return files.whereNotNull().toList(); + } catch (e) { + throw AppError.fromError(e); + } + } + Future> getLocalMedia({ required int start, required int end,