diff --git a/.idea/libraries/Flutter_Plugins.xml b/.idea/libraries/Flutter_Plugins.xml index 6b4d06b..393d7ec 100644 --- a/.idea/libraries/Flutter_Plugins.xml +++ b/.idea/libraries/Flutter_Plugins.xml @@ -1,30 +1,30 @@ - - - - - - + - + - - + + + + + + + + - diff --git a/data/.flutter-plugins-dependencies b/data/.flutter-plugins-dependencies index 9c1ad5d..cae2096 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":"flutter_local_notifications","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/flutter_local_notifications-18.0.1/","native_build":true,"dependencies":[]},{"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":"sqflite_darwin","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/sqflite_darwin-2.4.1/","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.2/","native_build":true,"dependencies":[]}],"android":[{"name":"flutter_local_notifications","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/flutter_local_notifications-18.0.1/","native_build":true,"dependencies":[]},{"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":"sqflite_android","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/sqflite_android-2.4.0/","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":"flutter_local_notifications","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/flutter_local_notifications-18.0.1/","native_build":true,"dependencies":[]},{"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":"sqflite_darwin","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/sqflite_darwin-2.4.1/","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.2/","native_build":true,"dependencies":[]}],"linux":[{"name":"flutter_local_notifications_linux","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/flutter_local_notifications_linux-5.0.0/","native_build":false,"dependencies":[]},{"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":"flutter_local_notifications","dependencies":["flutter_local_notifications_linux"]},{"name":"flutter_local_notifications_linux","dependencies":[]},{"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":"sqflite","dependencies":["sqflite_android","sqflite_darwin"]},{"name":"sqflite_android","dependencies":[]},{"name":"sqflite_darwin","dependencies":[]},{"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-12-11 09:53:39.001252","version":"3.24.5","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":"flutter_local_notifications","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/flutter_local_notifications-18.0.1/","native_build":true,"dependencies":[]},{"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":"sqflite_darwin","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/sqflite_darwin-2.4.1/","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.2/","native_build":true,"dependencies":[]}],"android":[{"name":"flutter_local_notifications","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/flutter_local_notifications-18.0.1/","native_build":true,"dependencies":[]},{"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":"sqflite_android","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/sqflite_android-2.4.0/","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":"flutter_local_notifications","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/flutter_local_notifications-18.0.1/","native_build":true,"dependencies":[]},{"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":"sqflite_darwin","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/sqflite_darwin-2.4.1/","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.2/","native_build":true,"dependencies":[]}],"linux":[{"name":"flutter_local_notifications_linux","path":"/Users/pratikcanopas/.pub-cache/hosted/pub.dev/flutter_local_notifications_linux-5.0.0/","native_build":false,"dependencies":[]},{"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":"flutter_local_notifications","dependencies":["flutter_local_notifications_linux"]},{"name":"flutter_local_notifications_linux","dependencies":[]},{"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":"sqflite","dependencies":["sqflite_android","sqflite_darwin"]},{"name":"sqflite_android","dependencies":[]},{"name":"sqflite_darwin","dependencies":[]},{"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-12-11 14:35:21.894664","version":"3.24.5","swift_package_manager_enabled":false} \ No newline at end of file diff --git a/data/lib/errors/app_error.dart b/data/lib/errors/app_error.dart index 4b991c6..aadd9e3 100644 --- a/data/lib/errors/app_error.dart +++ b/data/lib/errors/app_error.dart @@ -1,7 +1,6 @@ import 'dart:io'; -import 'dart:math'; import 'l10n_error_codes.dart'; -import 'package:dio/dio.dart' show DioException, DioExceptionType; +import 'package:dio/dio.dart' show DioException; class AppError implements Exception { final String? message; @@ -21,9 +20,6 @@ class AppError implements Exception { } else if (error is SocketException) { return const NoConnectionError(); } else if (error is DioException) { - if (error.type == DioExceptionType.cancel) { - return const RequestCancelledByUser(); - } return SomethingWentWrongError( message: error.message, statusCode: error.response?.statusCode, @@ -51,13 +47,6 @@ class UserGoogleSignInAccountNotFound extends AppError { ); } -class RequestCancelledByUser extends AppError { - const RequestCancelledByUser() - : super( - message: "Request cancelled", - ); -} - class BackUpFolderNotFound extends AppError { const BackUpFolderNotFound() : super( @@ -82,12 +71,12 @@ class SomethingWentWrongError extends AppError { ); } -class AuthSessionExpiredError extends AppError { - const AuthSessionExpiredError() +class DropboxAuthSessionExpiredError extends AppError { + const DropboxAuthSessionExpiredError() : super( l10nCode: AppErrorL10nCodes.authSessionExpiredError, message: - "User authentication session expired. Unable to get access token.", + "User authentication session expired. Unable to get dropbox access token.", statusCode: 401, ); } diff --git a/data/lib/handlers/connectivity_handler.dart b/data/lib/handlers/connectivity_handler.dart index ededf56..b8add91 100644 --- a/data/lib/handlers/connectivity_handler.dart +++ b/data/lib/handlers/connectivity_handler.dart @@ -1,6 +1,30 @@ import 'dart:io'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; -/// -Future internetLookUp() async { - await InternetAddress.lookup('google.com'); -} \ No newline at end of file +import '../apis/network/urls.dart'; + +final connectivityHandlerProvider = Provider((ref) { + return ConnectivityHandler(); +}); + +class ConnectivityHandler { + Future lookUpDropbox() async { + await InternetAddress.lookup(BaseURL.dropboxV2); + } + + Future lookUpGoogleDrive() async { + await InternetAddress.lookup(BaseURL.googleDriveV3); + } + + Future hasInternetAccess() async { + try { + final result = await InternetAddress.lookup('example.com'); + if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) { + return true; // Internet access + } + } on SocketException catch (_) { + return false; // No Internet access + } + return false; + } +} diff --git a/data/lib/repositories/media_process_repository.dart b/data/lib/repositories/media_process_repository.dart index b2e00a9..dc68bb0 100644 --- a/data/lib/repositories/media_process_repository.dart +++ b/data/lib/repositories/media_process_repository.dart @@ -504,7 +504,7 @@ class MediaProcessRepo extends ChangeNotifier { await clearUploadProcessResponse(id: process.id); } catch (e) { - if (e is RequestCancelledByUser) { + if (e is DioException && e.type == DioExceptionType.cancel) { showNotification('Upload to Google Drive cancelled'); return; } @@ -593,7 +593,7 @@ class MediaProcessRepo extends ChangeNotifier { await clearUploadProcessResponse(id: process.id); } catch (e) { - if (e is RequestCancelledByUser) { + if (e is DioException && e.type == DioExceptionType.cancel) { showNotification('Upload to Dropbox cancelled'); return; } @@ -820,7 +820,7 @@ class MediaProcessRepo extends ChangeNotifier { await clearDownloadProcessResponse(id: process.id); } catch (error) { - if (error is RequestCancelledByUser) { + if (error is DioException && error.type == DioExceptionType.cancel) { showNotification('Download from Google Drive cancelled'); return; } @@ -938,7 +938,7 @@ class MediaProcessRepo extends ChangeNotifier { await clearDownloadProcessResponse(id: process.id); } catch (error) { - if (error is RequestCancelledByUser) { + if (error is DioException && error.type == DioExceptionType.cancel) { showNotification('Download from Dropbox cancelled'); return; } diff --git a/data/lib/services/auth_service.dart b/data/lib/services/auth_service.dart index ce93618..67803c5 100644 --- a/data/lib/services/auth_service.dart +++ b/data/lib/services/auth_service.dart @@ -74,84 +74,66 @@ class AuthService { } Future signInSilently() async { - try { - await _googleSignIn.signInSilently(suppressErrors: true); - } catch (e) { - throw AppError.fromError(e); - } + await _googleSignIn.signInSilently(suppressErrors: true); } Future signInWithGoogle() async { - try { - final googleSignInAccount = await _googleSignIn.signIn(); - if (googleSignInAccount != null) { - await googleSignInAccount.authentication; - } - } catch (e) { - throw AppError.fromError(e); + final googleSignInAccount = await _googleSignIn.signIn(); + if (googleSignInAccount != null) { + await googleSignInAccount.authentication; } } Future signOutWithGoogle() async { - try { - await _googleSignIn.signOut(); - _googleDriveAutoBackUpController.state = false; - } catch (e) { - throw AppError.fromError(e); - } + await _googleSignIn.signOut(); + _googleDriveAutoBackUpController.state = false; } /// Launches the URL in the browser for OAuth 2 authentication with Dropbox. - /// Retrieves the access token using the Proof of Key Code Exchange (PKCE) flow. + /// Retrieves the code to fetch access token using the Proof of Key Code Exchange (PKCE) flow. Future signInWithDropBox() async { - try { - final codeVerifier = _oauth2.generateCodeVerifier; - _dropboxCodeVerifierPrefProvider.state = codeVerifier; - final authorizationUrl = _oauth2.getAuthorizationUrl( - clientId: AppSecretes.dropBoxAppKey, - authorizationEndpoint: - Uri.parse('${BaseURL.dropboxOAuth2Web}/authorize'), - additionalParameters: {'token_access_type': 'offline'}, - redirectUri: RedirectURL.auth, - codeVerifier: codeVerifier, - ); - await launchUrl(authorizationUrl); - } catch (e) { - throw AppError.fromError(e); - } + final codeVerifier = _oauth2.generateCodeVerifier; + _dropboxCodeVerifierPrefProvider.state = codeVerifier; + final authorizationUrl = _oauth2.getAuthorizationUrl( + clientId: AppSecretes.dropBoxAppKey, + authorizationEndpoint: Uri.parse('${BaseURL.dropboxOAuth2Web}/authorize'), + additionalParameters: {'token_access_type': 'offline'}, + redirectUri: RedirectURL.auth, + codeVerifier: codeVerifier, + ); + await launchUrl(authorizationUrl); } + /// Fetch dropbox access token using the code using the Proof of Key Code Exchange (PKCE) flow. Future setDropboxTokenFromCode({required String code}) async { - try { - if (_dropboxCodeVerifierPrefProvider.state == null) { - throw const SomethingWentWrongError( - message: "Dropbox code verifier is missing", - ); - } - final res = await _dio.req( - DropboxTokenEndpoint( - code: code, - codeVerifier: _dropboxCodeVerifierPrefProvider.state!, - clientId: AppSecretes.dropBoxAppKey, - redirectUrl: RedirectURL.auth, - clientSecret: AppSecretes.dropBoxAppSecret, - ), + if (_dropboxCodeVerifierPrefProvider.state == null) { + throw const SomethingWentWrongError( + message: "Dropbox code verifier is missing", ); - if (res.data != null) { - _dropboxTokenController.state = DropboxToken( - access_token: res.data['access_token'], - token_type: res.data['token_type'], - refresh_token: res.data['refresh_token'], - expires_in: - DateTime.now().add(Duration(seconds: res.data['expires_in'])), - account_id: res.data['account_id'], - scope: res.data['scope'], - uid: res.data['uid'], - ); - _dropboxCodeVerifierPrefProvider.state = null; - } - } catch (e) { - throw AppError.fromError(e); + } + final res = await _dio.req( + DropboxTokenEndpoint( + code: code, + codeVerifier: _dropboxCodeVerifierPrefProvider.state!, + clientId: AppSecretes.dropBoxAppKey, + redirectUrl: RedirectURL.auth, + clientSecret: AppSecretes.dropBoxAppSecret, + ), + ); + if (res.statusCode == 200) { + _dropboxTokenController.state = DropboxToken( + access_token: res.data['access_token'], + token_type: res.data['token_type'], + refresh_token: res.data['refresh_token'], + expires_in: + DateTime.now().add(Duration(seconds: res.data['expires_in'])), + account_id: res.data['account_id'], + scope: res.data['scope'], + uid: res.data['uid'], + ); + _dropboxCodeVerifierPrefProvider.state = null; + } else { + throw const DropboxAuthSessionExpiredError(); } } @@ -163,15 +145,15 @@ class AuthService { } Future refreshDropboxToken() async { - try { - if (_dropboxTokenController.state != null) { - final res = await _dio.req( - DropboxRefreshTokenEndpoint( - refreshToken: _dropboxTokenController.state!.refresh_token, - clientId: AppSecretes.dropBoxAppKey, - clientSecret: AppSecretes.dropBoxAppSecret, - ), - ); + if (_dropboxTokenController.state != null) { + final res = await _dio.req( + DropboxRefreshTokenEndpoint( + refreshToken: _dropboxTokenController.state!.refresh_token, + clientId: AppSecretes.dropBoxAppKey, + clientSecret: AppSecretes.dropBoxAppSecret, + ), + ); + if (res.statusCode == 200) { _dropboxTokenController.state = _dropboxTokenController.state!.copyWith( access_token: res.data['access_token'], expires_in: DateTime.now().add( @@ -181,12 +163,10 @@ class AuthService { ), token_type: res.data['token_type'], ); - } else { - throw const AuthSessionExpiredError(); + return; } - } catch (e) { - throw AppError.fromError(e); } + throw DropboxAuthSessionExpiredError(); } bool get signedInWithGoogle => _googleSignIn.currentUser != null; diff --git a/data/lib/services/base/cloud_provider_service.dart b/data/lib/services/base/cloud_provider_service.dart index a1f82fa..b1c1804 100644 --- a/data/lib/services/base/cloud_provider_service.dart +++ b/data/lib/services/base/cloud_provider_service.dart @@ -1,5 +1,5 @@ import 'package:dio/dio.dart'; -import '../models/media/media.dart'; +import '../../models/media/media.dart'; abstract class CloudProviderService { const CloudProviderService(); diff --git a/data/lib/services/dropbox_services.dart b/data/lib/services/dropbox_services.dart index cec601a..b2f454f 100644 --- a/data/lib/services/dropbox_services.dart +++ b/data/lib/services/dropbox_services.dart @@ -12,7 +12,7 @@ import 'package:dio/dio.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../apis/dropbox/dropbox_auth_endpoints.dart'; import '../storage/provider/preferences_provider.dart'; -import 'cloud_provider_service.dart'; +import 'base/cloud_provider_service.dart'; final dropboxServiceProvider = Provider((ref) { return DropboxService( @@ -35,55 +35,67 @@ class DropboxService extends CloudProviderService { ); Future setCurrentUserAccount() async { - try { - final res = await _dropboxAuthenticatedDio - .req(const DropboxGetUserAccountEndpoint()); + final res = await _dropboxAuthenticatedDio + .req(const DropboxGetUserAccountEndpoint()); + if (res.statusCode == 200) { _dropboxAccountController.state = DropboxAccount.fromJson(res.data); - } catch (e) { - AppError.fromError(e); + } else { + throw SomethingWentWrongError( + statusCode: res.statusCode, + message: res.statusMessage, + ); } } Future setFileIdAppPropertyTemplate() async { - try { - // Get all the app property templates - final res = await _dropboxAuthenticatedDio - .req(const DropboxGetAppPropertyTemplate()); + // Get all the app property templates + final res = await _dropboxAuthenticatedDio + .req(const DropboxGetAppPropertyTemplate()); - if (res.statusCode == 200) { - final templateIds = res.data['template_ids'] as List; + if (res.statusCode == 200) { + final templateIds = res.data['template_ids'] as List; - // Find the template id for the app - String? appTemplateId; - for (final templateId in templateIds) { - final res = await _dropboxAuthenticatedDio.req( - DropboxGetAppPropertiesTemplateDetails(templateId), - ); + // Find the template id for the app + String? appTemplateId; + for (final templateId in templateIds) { + final res = await _dropboxAuthenticatedDio.req( + DropboxGetAppPropertiesTemplateDetails(templateId), + ); - if (res.statusCode == 200) { - if (res.data is Map && - res.data['name'] == ProviderConstants.dropboxAppTemplateName) { - appTemplateId = templateId; - break; - } - } + if (res.statusCode == 200 && + res.data?['name'] == ProviderConstants.dropboxAppTemplateName) { + appTemplateId = templateId; + break; + } else { + throw SomethingWentWrongError( + statusCode: res.statusCode, + message: res.statusMessage, + ); } + } - // If the template id is found, set it else create a new one - if (appTemplateId != null) { - _dropboxFileIdAppPropertyTemplateIdController.state = appTemplateId; + // If the template id is found, set it else create a new one + if (appTemplateId != null) { + _dropboxFileIdAppPropertyTemplateIdController.state = appTemplateId; + } else { + final res = await _dropboxAuthenticatedDio.req( + DropboxCreateAppPropertyTemplate(), + ); + if (res.statusCode == 200) { + _dropboxFileIdAppPropertyTemplateIdController.state = + res.data['template_id']; } else { - final res = await _dropboxAuthenticatedDio.req( - DropboxCreateAppPropertyTemplate(), + throw SomethingWentWrongError( + statusCode: res.statusCode, + message: res.statusMessage, ); - if (res.statusCode == 200) { - _dropboxFileIdAppPropertyTemplateIdController.state = - res.data['template_id']; - } } } - } catch (e) { - AppError.fromError(e); + } else { + throw SomethingWentWrongError( + statusCode: res.statusCode, + message: res.statusMessage, + ); } } @@ -120,13 +132,22 @@ class DropboxService extends CloudProviderService { .toList(), ); } else { - throw AppError.fromError(response.statusMessage ?? ''); + throw SomethingWentWrongError( + statusCode: response.statusCode, + message: response.statusMessage, + ); } } return medias; } catch (e) { - throw AppError.fromError(e); + if (e is DioException && + e.response?.statusCode == 409 && + e.response?.data?['error']?['path']?['.tag'] == 'not_found') { + await createFolder(ProviderConstants.backupFolderName); + return getAllMedias(folder: folder); + } + rethrow; } } @@ -196,7 +217,7 @@ class DropboxService extends CloudProviderService { pageSize: pageSize, ); } - throw AppError.fromError(e); + rethrow; } } @@ -210,7 +231,10 @@ class DropboxService extends CloudProviderService { return response.data['metadata']['id']; } - throw AppError.fromError(response.statusMessage ?? ''); + throw SomethingWentWrongError( + statusCode: response.statusCode, + message: response.statusMessage, + ); } @override @@ -226,37 +250,46 @@ class DropboxService extends CloudProviderService { await setFileIdAppPropertyTemplate(); } final localFile = File(path); - try { - final res = await _dropboxAuthenticatedDio.req( - DropboxUploadEndpoint( - appPropertyTemplateId: - _dropboxFileIdAppPropertyTemplateIdController.state!, - localRefId: localRefId, - content: AppMediaContent( - stream: localFile.openRead(), - length: localFile.lengthSync(), - contentType: 'application/octet-stream', - ), - filePath: - "/${ProviderConstants.backupFolderName}/${localFile.path.split('/').last}", - onProgress: onProgress, - cancellationToken: cancelToken, + + final res = await _dropboxAuthenticatedDio.req( + DropboxUploadEndpoint( + appPropertyTemplateId: + _dropboxFileIdAppPropertyTemplateIdController.state!, + localRefId: localRefId, + content: AppMediaContent( + stream: localFile.openRead(), + length: localFile.lengthSync(), + contentType: 'application/octet-stream', ), - ); - final metadata = await _dropboxAuthenticatedDio.req( - DropboxGetFileMetadata(id: res.data['id']), - ); + filePath: + "/${ProviderConstants.backupFolderName}/${localFile.path.split('/').last}", + onProgress: onProgress, + cancellationToken: cancelToken, + ), + ); - if (res.statusCode == 200) { - return AppMedia.fromDropboxJson( - json: res.data, - metadataJson: metadata.data, + if (res.statusCode == 200) { + // Get the metadata of the uploaded file + try { + final metadata = await _dropboxAuthenticatedDio.req( + DropboxGetFileMetadata(id: res.data['id']), ); - } - throw AppError.fromError(res.statusMessage ?? ''); - } catch (error) { - throw AppError.fromError(error); + + if (metadata.statusCode == 200) { + return AppMedia.fromDropboxJson( + json: res.data, + metadataJson: metadata.data, + ); + } + } catch (_) {} + + // If metadata is not available, return the uploaded file + return AppMedia.fromDropboxJson(json: res.data); } + throw SomethingWentWrongError( + statusCode: res.statusCode, + message: res.statusMessage, + ); } @override @@ -266,18 +299,21 @@ class DropboxService extends CloudProviderService { CancelToken? cancelToken, void Function(int sent, int total)? onProgress, }) async { - try { - await _dropboxAuthenticatedDio.downloadReq( - DropboxDownloadEndpoint( - filePath: id, - storagePath: saveLocation, - cancellationToken: cancelToken, - onProgress: onProgress, - ), - ); - } catch (e) { - throw AppError.fromError(e); - } + final res = await _dropboxAuthenticatedDio.downloadReq( + DropboxDownloadEndpoint( + filePath: id, + storagePath: saveLocation, + cancellationToken: cancelToken, + onProgress: onProgress, + ), + ); + + if (res.statusCode == 200) return; + + throw SomethingWentWrongError( + statusCode: res.statusCode, + message: res.statusMessage, + ); } Future updateAppProperties({ @@ -285,19 +321,22 @@ class DropboxService extends CloudProviderService { required String localRefId, CancelToken? cancelToken, }) async { - try { - await _dropboxAuthenticatedDio.req( - DropboxUpdateAppPropertyEndpoint( - id: id, - cancellationToken: cancelToken, - appPropertyTemplateId: - _dropboxFileIdAppPropertyTemplateIdController.state!, - localRefId: localRefId, - ), - ); - } catch (e) { - throw AppError.fromError(e); - } + final res = await _dropboxAuthenticatedDio.req( + DropboxUpdateAppPropertyEndpoint( + id: id, + cancellationToken: cancelToken, + appPropertyTemplateId: + _dropboxFileIdAppPropertyTemplateIdController.state!, + localRefId: localRefId, + ), + ); + + if (res.statusCode == 200) return; + + throw SomethingWentWrongError( + statusCode: res.statusCode, + message: res.statusMessage, + ); } @override @@ -305,28 +344,17 @@ class DropboxService extends CloudProviderService { required String id, CancelToken? cancelToken, }) async { - try { - final res = await _dropboxAuthenticatedDio.req( - DropboxDeleteEndpoint( - id: id, - cancellationToken: cancelToken, - ), - ); - if (res.statusCode == 200) return; + final res = await _dropboxAuthenticatedDio.req( + DropboxDeleteEndpoint( + id: id, + cancellationToken: cancelToken, + ), + ); + if (res.statusCode == 200) return; - throw AppError.fromError(res.statusMessage ?? ''); - } catch (e) { - throw AppError.fromError(e); - } + throw SomethingWentWrongError( + statusCode: res.statusCode, + message: res.statusMessage, + ); } } - -class DropboxMediaListResponse { - final List medias; - final String? cursor; - - const DropboxMediaListResponse({ - required this.medias, - required this.cursor, - }); -} diff --git a/data/lib/services/google_drive_service.dart b/data/lib/services/google_drive_service.dart index caa6760..ce33ed7 100644 --- a/data/lib/services/google_drive_service.dart +++ b/data/lib/services/google_drive_service.dart @@ -1,5 +1,4 @@ import 'dart:async'; - import 'dart:io'; import '../apis/google_drive/google_drive_endpoint.dart'; import '../apis/network/client.dart'; @@ -13,7 +12,7 @@ import 'package:google_sign_in/google_sign_in.dart'; import 'package:googleapis/drive/v3.dart' as drive; import '../errors/app_error.dart'; import 'auth_service.dart'; -import 'cloud_provider_service.dart'; +import 'base/cloud_provider_service.dart'; final backUpFolderIdProvider = StateNotifierProvider((ref) { @@ -76,68 +75,60 @@ class GoogleDriveService extends CloudProviderService { Future> getAllMedias({ required String folder, }) async { - try { - final driveApi = await _getGoogleDriveAPI(); - - bool hasMore = true; - String? pageToken; - final List medias = []; - - while (hasMore) { - final response = await driveApi.files.list( - q: "'$folder' in parents and trashed=false", - $fields: - "files(id, name, description, mimeType, thumbnailLink, webContentLink, createdTime, modifiedTime, size, imageMediaMetadata, videoMediaMetadata, appProperties)", - pageSize: 1000, - pageToken: pageToken, - orderBy: "createdTime desc", - ); - hasMore = response.nextPageToken != null; - pageToken = response.nextPageToken; - medias.addAll( - (response.files ?? []) - .map( - (e) => AppMedia.fromGoogleDriveFile(e), - ) - .toList(), - ); - } - - return medias; - } catch (e) { - throw AppError.fromError(e); - } - } + final driveApi = await _getGoogleDriveAPI(); - @override - Future getPaginatedMedias({ - required String folder, - String? nextPageToken, - int pageSize = 30, - }) async { - try { - final driveApi = await _getGoogleDriveAPI(); + bool hasMore = true; + String? pageToken; + final List medias = []; + while (hasMore) { final response = await driveApi.files.list( q: "'$folder' in parents and trashed=false", - orderBy: "createdTime desc", $fields: "files(id, name, description, mimeType, thumbnailLink, webContentLink, createdTime, modifiedTime, size, imageMediaMetadata, videoMediaMetadata, appProperties)", - pageSize: pageSize, - pageToken: nextPageToken, + pageSize: 1000, + pageToken: pageToken, + orderBy: "createdTime desc", ); - - return GetPaginatedMediasResponse( - nextPageToken: response.nextPageToken, - medias: (response.files ?? []) + hasMore = response.nextPageToken != null; + pageToken = response.nextPageToken; + medias.addAll( + (response.files ?? []) .map( (e) => AppMedia.fromGoogleDriveFile(e), ) .toList(), ); - } catch (e) { - throw AppError.fromError(e); } + + return medias; + } + + @override + Future getPaginatedMedias({ + required String folder, + String? nextPageToken, + int pageSize = 30, + }) async { + final driveApi = await _getGoogleDriveAPI(); + + final response = await driveApi.files.list( + q: "'$folder' in parents and trashed=false", + orderBy: "createdTime desc", + $fields: + "files(id, name, description, mimeType, thumbnailLink, webContentLink, createdTime, modifiedTime, size, imageMediaMetadata, videoMediaMetadata, appProperties)", + pageSize: pageSize, + pageToken: nextPageToken, + ); + + return GetPaginatedMediasResponse( + nextPageToken: response.nextPageToken, + medias: (response.files ?? []) + .map( + (e) => AppMedia.fromGoogleDriveFile(e), + ) + .toList(), + ); } @override @@ -145,53 +136,41 @@ class GoogleDriveService extends CloudProviderService { required String id, CancelToken? cancelToken, }) async { - try { - final driveApi = await _getGoogleDriveAPI(); - await driveApi.files.delete(id); - } catch (e) { - throw AppError.fromError(e); - } + final driveApi = await _getGoogleDriveAPI(); + await driveApi.files.delete(id); } Future getBackUpFolderId() async { - try { - final driveApi = await _getGoogleDriveAPI(); + final driveApi = await _getGoogleDriveAPI(); - final response = await driveApi.files.list( - q: "name='${ProviderConstants.backupFolderName}' and trashed=false and mimeType='application/vnd.google-apps.folder'", - ); - - if (response.files?.isNotEmpty ?? false) { - return response.files?.first.id; - } else { - final folder = drive.File( - name: ProviderConstants.backupFolderName, - mimeType: 'application/vnd.google-apps.folder', - ); - final googleDriveFolder = await driveApi.files.create(folder); - return googleDriveFolder.id; - } - } catch (e) { - throw AppError.fromError(e); - } - } - - @override - Future createFolder(String folderName) async { - try { - final driveApi = await _getGoogleDriveAPI(); + final response = await driveApi.files.list( + q: "name='${ProviderConstants.backupFolderName}' and trashed=false and mimeType='application/vnd.google-apps.folder'", + ); + if (response.files?.isNotEmpty ?? false) { + return response.files?.first.id; + } else { final folder = drive.File( - name: folderName, + name: ProviderConstants.backupFolderName, mimeType: 'application/vnd.google-apps.folder', ); final googleDriveFolder = await driveApi.files.create(folder); return googleDriveFolder.id; - } catch (e) { - throw AppError.fromError(e); } } + @override + Future createFolder(String folderName) async { + final driveApi = await _getGoogleDriveAPI(); + + final folder = drive.File( + name: folderName, + mimeType: 'application/vnd.google-apps.folder', + ); + final googleDriveFolder = await driveApi.files.create(folder); + return googleDriveFolder.id; + } + @override Future uploadMedia({ required String folderId, @@ -202,36 +181,36 @@ class GoogleDriveService extends CloudProviderService { void Function(int sent, int total)? onProgress, }) async { final localFile = File(path); - try { - final file = drive.File( - name: localFile.path.split('/').last, - mimeType: mimeType, - appProperties: { - ProviderConstants.localRefIdKey: localRefId, - }, - parents: [folderId], - ); + final file = drive.File( + name: localFile.path.split('/').last, + mimeType: mimeType, + appProperties: { + ProviderConstants.localRefIdKey: localRefId, + }, + parents: [folderId], + ); - final res = await _client.req( - GoogleDriveUploadEndpoint( - request: file, - content: AppMediaContent( - stream: localFile.openRead(), - length: localFile.lengthSync(), - contentType: 'application/octet-stream', - ), - onProgress: onProgress, - cancellationToken: cancelToken, + final res = await _client.req( + GoogleDriveUploadEndpoint( + request: file, + content: AppMediaContent( + stream: localFile.openRead(), + length: localFile.lengthSync(), + contentType: 'application/octet-stream', ), - ); + onProgress: onProgress, + cancellationToken: cancelToken, + ), + ); + if (res.statusCode == 200) { return AppMedia.fromGoogleDriveFile(drive.File.fromJson(res.data)); - } catch (error) { - if (error is AppError && error.statusCode == 404) { - throw const BackUpFolderNotFound(); - } - throw AppError.fromError(error); } + + throw SomethingWentWrongError( + statusCode: res.statusCode, + message: res.statusMessage, + ); } @override @@ -241,18 +220,21 @@ class GoogleDriveService extends CloudProviderService { CancelToken? cancelToken, void Function(int sent, int total)? onProgress, }) async { - try { - await _client.downloadReq( - GoogleDriveDownloadEndpoint( - id: id, - cancellationToken: cancelToken, - saveLocation: saveLocation, - onProgress: onProgress, - ), - ); - } catch (e) { - throw AppError.fromError(e); - } + final res = await _client.downloadReq( + GoogleDriveDownloadEndpoint( + id: id, + cancellationToken: cancelToken, + saveLocation: saveLocation, + onProgress: onProgress, + ), + ); + + if (res.statusCode == 200) return; + + throw SomethingWentWrongError( + statusCode: res.statusCode, + message: res.statusMessage, + ); } Future updateAppProperties({ @@ -260,26 +242,19 @@ class GoogleDriveService extends CloudProviderService { required String localRefId, CancelToken? cancelToken, }) async { - try { - await _client.req( - GoogleDriveUpdateAppPropertiesEndpoint( - id: id, - cancellationToken: cancelToken, - localFileId: localRefId, - ), - ); - } catch (e) { - throw AppError.fromError(e); - } - } -} + final res = await _client.req( + GoogleDriveUpdateAppPropertiesEndpoint( + id: id, + cancellationToken: cancelToken, + localFileId: localRefId, + ), + ); -class GoogleDriveListResponse { - final List medias; - final String? pageToken; + if (res.statusCode == 200) return; - const GoogleDriveListResponse({ - required this.medias, - required this.pageToken, - }); + throw SomethingWentWrongError( + statusCode: res.statusCode, + message: res.statusMessage, + ); + } } diff --git a/data/lib/services/local_media_service.dart b/data/lib/services/local_media_service.dart index 8c2e266..b892742 100644 --- a/data/lib/services/local_media_service.dart +++ b/data/lib/services/local_media_service.dart @@ -4,7 +4,6 @@ import 'package:collection/collection.dart'; import '../models/media/media.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:photo_manager/photo_manager.dart'; -import '../errors/app_error.dart'; final localMediaServiceProvider = Provider( (ref) => const LocalMediaService(), @@ -35,55 +34,43 @@ 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); - } + 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(); } Future> getLocalMedia({ required int start, required int end, }) async { - try { - final assets = await PhotoManager.getAssetListRange( - start: start, - end: end, - 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); - } + final assets = await PhotoManager.getAssetListRange( + start: start, + end: end, + filterOption: FilterOptionGroup( + orders: [const OrderOption(type: OrderOptionType.createDate)], + ), + ); + final files = await Future.wait( + assets.map( + (asset) => AppMedia.fromAssetEntity(asset), + ), + ); + return files.whereNotNull().toList(); } Future> deleteMedias(List medias) async { - try { - return await PhotoManager.editor.deleteWithIds(medias); - } catch (e) { - throw AppError.fromError(e); - } + return await PhotoManager.editor.deleteWithIds(medias); } Future saveInGallery({ @@ -91,21 +78,17 @@ class LocalMediaService { required AppMediaType type, }) async { AssetEntity? asset; - try { - if (type.isVideo) { - asset = await PhotoManager.editor.saveVideo( - File(saveFromLocation), - title: saveFromLocation.split('/').last, - ); - } else if (type.isImage) { - asset = await PhotoManager.editor.saveImageWithPath( - saveFromLocation, - title: saveFromLocation.split('/').last, - ); - } - return asset != null ? AppMedia.fromAssetEntity(asset) : null; - } catch (e) { - throw AppError.fromError(e); + if (type.isVideo) { + asset = await PhotoManager.editor.saveVideo( + File(saveFromLocation), + title: saveFromLocation.split('/').last, + ); + } else if (type.isImage) { + asset = await PhotoManager.editor.saveImageWithPath( + saveFromLocation, + title: saveFromLocation.split('/').last, + ); } + return asset != null ? AppMedia.fromAssetEntity(asset) : null; } } diff --git a/data/lib/storage/provider/preferences_provider.dart b/data/lib/storage/provider/preferences_provider.dart index 647729f..4113279 100644 --- a/data/lib/storage/provider/preferences_provider.dart +++ b/data/lib/storage/provider/preferences_provider.dart @@ -1,5 +1,4 @@ import 'dart:convert'; - import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart';