diff --git a/analysis_options.yaml b/analysis_options.yaml index cd8667940..026369f64 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -14,6 +14,7 @@ linter: - prefer_const_constructors_in_immutables - prefer_const_declarations - prefer_const_literals_to_create_immutables + - require_trailing_commas - sized_box_for_whitespace - use_full_hex_values_for_flutter_colors - use_key_in_widget_constructors diff --git a/lib/app.dart b/lib/app.dart index 2583f473e..30996bc10 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -24,7 +24,9 @@ final lightThemeData = ThemeData( iconTheme: IconThemeData(color: Colors.black), primaryIconTheme: IconThemeData(color: Colors.red, opacity: 1.0, size: 50.0), colorScheme: ColorScheme.light( - primary: Colors.black, secondary: Color.fromARGB(255, 163, 163, 163)), + primary: Colors.black, + secondary: Color.fromARGB(255, 163, 163, 163), + ), accentColor: Color.fromRGBO(0, 0, 0, 0.6), buttonColor: Color.fromRGBO(45, 194, 98, 1.0), outlinedButtonTheme: buildOutlinedButtonThemeData( @@ -34,7 +36,9 @@ final lightThemeData = ThemeData( fgEnabled: Colors.white, ), elevatedButtonTheme: buildElevatedButtonThemeData( - onPrimary: Colors.white, primary: Colors.black), + onPrimary: Colors.white, + primary: Colors.black, + ), toggleableActiveColor: Colors.green[400], scaffoldBackgroundColor: Colors.white, backgroundColor: Colors.white, @@ -47,19 +51,25 @@ final lightThemeData = ThemeData( //https://api.flutter.dev/flutter/material/TextTheme-class.html textTheme: _buildTextTheme(Colors.black), primaryTextTheme: TextTheme().copyWith( - bodyText2: TextStyle(color: Colors.yellow), - bodyText1: TextStyle(color: Colors.orange)), + bodyText2: TextStyle(color: Colors.yellow), + bodyText1: TextStyle(color: Colors.orange), + ), cardColor: Color.fromRGBO(250, 250, 250, 1.0), dialogTheme: DialogTheme().copyWith( - backgroundColor: Color.fromRGBO(250, 250, 250, 1.0), // - titleTextStyle: TextStyle( - color: Colors.black, fontSize: 24, fontWeight: FontWeight.w600), - contentTextStyle: TextStyle( - fontFamily: 'Inter-Medium', - color: Colors.black, - fontSize: 16, - fontWeight: FontWeight.w500), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8))), + backgroundColor: Color.fromRGBO(250, 250, 250, 1.0), // + titleTextStyle: TextStyle( + color: Colors.black, + fontSize: 24, + fontWeight: FontWeight.w600, + ), + contentTextStyle: TextStyle( + fontFamily: 'Inter-Medium', + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + ), inputDecorationTheme: InputDecorationTheme().copyWith( focusedBorder: UnderlineInputBorder( borderSide: BorderSide( @@ -101,12 +111,15 @@ final darkThemeData = ThemeData( textTheme: _buildTextTheme(Colors.white), toggleableActiveColor: Colors.green[400], outlinedButtonTheme: buildOutlinedButtonThemeData( - bgDisabled: Colors.grey.shade500, - bgEnabled: Colors.white, - fgDisabled: Colors.white, - fgEnabled: Colors.black), + bgDisabled: Colors.grey.shade500, + bgEnabled: Colors.white, + fgDisabled: Colors.white, + fgEnabled: Colors.black, + ), elevatedButtonTheme: buildElevatedButtonThemeData( - onPrimary: Colors.black, primary: Colors.white), + onPrimary: Colors.black, + primary: Colors.white, + ), scaffoldBackgroundColor: Colors.black, backgroundColor: Colors.black, appBarTheme: AppBarTheme().copyWith( diff --git a/lib/core/cache/thumbnail_cache.dart b/lib/core/cache/thumbnail_cache.dart index 59fbf64ca..5fc654cd7 100644 --- a/lib/core/cache/thumbnail_cache.dart +++ b/lib/core/cache/thumbnail_cache.dart @@ -8,9 +8,11 @@ class ThumbnailLruCache { static final LRUMap _map = LRUMap(1000); static Uint8List get(File photo, [int size]) { - return _map.get(photo.generatedID.toString() + - "_" + - (size != null ? size.toString() : kThumbnailLargeSize.toString())); + return _map.get( + photo.generatedID.toString() + + "_" + + (size != null ? size.toString() : kThumbnailLargeSize.toString()), + ); } static void put( @@ -19,16 +21,19 @@ class ThumbnailLruCache { int size, ]) { _map.put( - photo.generatedID.toString() + - "_" + - (size != null ? size.toString() : kThumbnailLargeSize.toString()), - imageData); + photo.generatedID.toString() + + "_" + + (size != null ? size.toString() : kThumbnailLargeSize.toString()), + imageData, + ); } static void clearCache(File file) { _map.remove( - file.generatedID.toString() + "_" + kThumbnailLargeSize.toString()); + file.generatedID.toString() + "_" + kThumbnailLargeSize.toString(), + ); _map.remove( - file.generatedID.toString() + "_" + kThumbnailSmallSize.toString()); + file.generatedID.toString() + "_" + kThumbnailSmallSize.toString(), + ); } } diff --git a/lib/core/configuration.dart b/lib/core/configuration.dart index b16528d4f..43f9cef14 100644 --- a/lib/core/configuration.dart +++ b/lib/core/configuration.dart @@ -187,8 +187,11 @@ class Configuration { Sodium.bin2base64(encryptedRecoveryKey.encryptedData), Sodium.bin2base64(encryptedRecoveryKey.nonce), ); - final privateAttributes = PrivateKeyAttributes(Sodium.bin2base64(masterKey), - Sodium.bin2hex(recoveryKey), Sodium.bin2base64(keyPair.sk)); + final privateAttributes = PrivateKeyAttributes( + Sodium.bin2base64(masterKey), + Sodium.bin2hex(recoveryKey), + Sodium.bin2base64(keyPair.sk), + ); return KeyGenResult(attributes, privateAttributes); } @@ -218,7 +221,9 @@ class Configuration { } Future decryptAndSaveSecrets( - String password, KeyAttributes attributes) async { + String password, + KeyAttributes attributes, + ) async { final kek = await CryptoUtil.deriveKey( utf8.encode(password), Sodium.base642bin(attributes.kekSalt), @@ -227,23 +232,29 @@ class Configuration { ); Uint8List key; try { - key = CryptoUtil.decryptSync(Sodium.base642bin(attributes.encryptedKey), - kek, Sodium.base642bin(attributes.keyDecryptionNonce)); + key = CryptoUtil.decryptSync( + Sodium.base642bin(attributes.encryptedKey), + kek, + Sodium.base642bin(attributes.keyDecryptionNonce), + ); } catch (e) { throw Exception("Incorrect password"); } await setKey(Sodium.bin2base64(key)); final secretKey = CryptoUtil.decryptSync( - Sodium.base642bin(attributes.encryptedSecretKey), - key, - Sodium.base642bin(attributes.secretKeyDecryptionNonce)); + Sodium.base642bin(attributes.encryptedSecretKey), + key, + Sodium.base642bin(attributes.secretKeyDecryptionNonce), + ); await setSecretKey(Sodium.bin2base64(secretKey)); final token = CryptoUtil.openSealSync( - Sodium.base642bin(getEncryptedToken()), - Sodium.base642bin(attributes.publicKey), - secretKey); + Sodium.base642bin(getEncryptedToken()), + Sodium.base642bin(attributes.publicKey), + secretKey, + ); await setToken( - Sodium.bin2base64(token, variant: Sodium.base64VariantUrlsafe)); + Sodium.bin2base64(token, variant: Sodium.base64VariantUrlsafe), + ); } Future createNewRecoveryKey() async { @@ -272,7 +283,8 @@ class Configuration { if (recoveryKey.contains(' ')) { if (recoveryKey.split(' ').length != kMnemonicKeyWordCount) { throw AssertionError( - 'recovery code should have $kMnemonicKeyWordCount words'); + 'recovery code should have $kMnemonicKeyWordCount words', + ); } recoveryKey = bip39.mnemonicToEntropy(recoveryKey); } @@ -280,25 +292,29 @@ class Configuration { Uint8List masterKey; try { masterKey = await CryptoUtil.decrypt( - Sodium.base642bin(attributes.masterKeyEncryptedWithRecoveryKey), - Sodium.hex2bin(recoveryKey), - Sodium.base642bin(attributes.masterKeyDecryptionNonce)); + Sodium.base642bin(attributes.masterKeyEncryptedWithRecoveryKey), + Sodium.hex2bin(recoveryKey), + Sodium.base642bin(attributes.masterKeyDecryptionNonce), + ); } catch (e) { _logger.severe(e); rethrow; } await setKey(Sodium.bin2base64(masterKey)); final secretKey = CryptoUtil.decryptSync( - Sodium.base642bin(attributes.encryptedSecretKey), - masterKey, - Sodium.base642bin(attributes.secretKeyDecryptionNonce)); + Sodium.base642bin(attributes.encryptedSecretKey), + masterKey, + Sodium.base642bin(attributes.secretKeyDecryptionNonce), + ); await setSecretKey(Sodium.bin2base64(secretKey)); final token = CryptoUtil.openSealSync( - Sodium.base642bin(getEncryptedToken()), - Sodium.base642bin(attributes.publicKey), - secretKey); + Sodium.base642bin(getEncryptedToken()), + Sodium.base642bin(attributes.publicKey), + secretKey, + ); await setToken( - Sodium.bin2base64(token, variant: Sodium.base64VariantUrlsafe)); + Sodium.bin2base64(token, variant: Sodium.base64VariantUrlsafe), + ); } String getHttpEndpoint() { @@ -428,9 +444,10 @@ class Configuration { Uint8List getRecoveryKey() { final keyAttributes = getKeyAttributes(); return CryptoUtil.decryptSync( - Sodium.base642bin(keyAttributes.recoveryKeyEncryptedWithMasterKey), - getKey(), - Sodium.base642bin(keyAttributes.recoveryKeyDecryptionNonce)); + Sodium.base642bin(keyAttributes.recoveryKeyEncryptedWithMasterKey), + getKey(), + Sodium.base642bin(keyAttributes.recoveryKeyDecryptionNonce), + ); } String getDocumentsDirectory() { @@ -551,7 +568,9 @@ class Configuration { iOptions: _secureStorageOptionsIOS, ); await _preferences.setBool( - hasMigratedSecureStorageToFirstUnlockKey, true); + hasMigratedSecureStorageToFirstUnlockKey, + true, + ); } } diff --git a/lib/core/error-reporting/tunneled_transport.dart b/lib/core/error-reporting/tunneled_transport.dart index da9737600..e2df02c52 100644 --- a/lib/core/error-reporting/tunneled_transport.dart +++ b/lib/core/error-reporting/tunneled_transport.dart @@ -63,7 +63,8 @@ class TunneledTransport implements Transport { } Future _createStreamedRequest( - SentryEnvelope envelope) async { + SentryEnvelope envelope, + ) async { final streamedRequest = StreamedRequest('POST', _tunnel); envelope .envelopeStream(_options) @@ -88,7 +89,10 @@ class _CredentialBuilder { _clock = clock; factory _CredentialBuilder( - Dsn dsn, String sdkIdentifier, ClockProvider clock) { + Dsn dsn, + String sdkIdentifier, + ClockProvider clock, + ) { final authHeader = _buildAuthHeader( publicKey: dsn.publicKey, secretKey: dsn.secretKey, diff --git a/lib/core/network.dart b/lib/core/network.dart index 854a0dbd4..b4b0a3ea3 100644 --- a/lib/core/network.dart +++ b/lib/core/network.dart @@ -17,11 +17,16 @@ class Network { _alice = Alice(darkTheme: true, showNotification: kDebugMode); await FkUserAgent.init(); final packageInfo = await PackageInfo.fromPlatform(); - _dio = Dio(BaseOptions(connectTimeout: kConnectTimeout, headers: { - HttpHeaders.userAgentHeader: FkUserAgent.userAgent, - 'X-Client-Version': packageInfo.version, - 'X-Client-Package': packageInfo.packageName, - })); + _dio = Dio( + BaseOptions( + connectTimeout: kConnectTimeout, + headers: { + HttpHeaders.userAgentHeader: FkUserAgent.userAgent, + 'X-Client-Version': packageInfo.version, + 'X-Client-Package': packageInfo.packageName, + }, + ), + ); _dio.interceptors.add(RequestIdInterceptor()); _dio.interceptors.add(_alice.getDioInterceptor()); } diff --git a/lib/db/collections_db.dart b/lib/db/collections_db.dart index c4397a9cf..a12f1f5f4 100644 --- a/lib/db/collections_db.dart +++ b/lib/db/collections_db.dart @@ -44,7 +44,9 @@ class CollectionsDB { ]; final dbConfig = MigrationConfig( - initializationScript: intitialScript, migrationScripts: migrationScripts); + initializationScript: intitialScript, + migrationScripts: migrationScripts, + ); CollectionsDB._privateConstructor(); @@ -157,8 +159,11 @@ class CollectionsDB { final db = await instance.database; var batch = db.batch(); for (final collection in collections) { - batch.insert(table, _getRowForCollection(collection), - conflictAlgorithm: ConflictAlgorithm.replace); + batch.insert( + table, + _getRowForCollection(collection), + conflictAlgorithm: ConflictAlgorithm.replace, + ); } return await batch.commit(); } @@ -239,12 +244,15 @@ class CollectionsDB { pathDecryptionNonce: row[columnPathDecryptionNonce], version: row[columnVersion], ), - List.from((json.decode(row[columnSharees]) as List) - .map((x) => User.fromMap(x))), + List.from( + (json.decode(row[columnSharees]) as List).map((x) => User.fromMap(x)), + ), row[columnPublicURLs] == null ? [] - : List.from((json.decode(row[columnPublicURLs]) as List) - .map((x) => PublicURL.fromMap(x))), + : List.from( + (json.decode(row[columnPublicURLs]) as List) + .map((x) => PublicURL.fromMap(x)), + ), int.parse(row[columnUpdationTime]), // default to False is columnIsDeleted is not set isDeleted: (row[columnIsDeleted] ?? _sqlBoolFalse) == _sqlBoolTrue, diff --git a/lib/db/file_migration_db.dart b/lib/db/file_migration_db.dart index 9f7ad0bf9..7a188cfa4 100644 --- a/lib/db/file_migration_db.dart +++ b/lib/db/file_migration_db.dart @@ -14,12 +14,14 @@ class FilesMigrationDB { static final columnLocalID = 'local_id'; Future _onCreate(Database db, int version) async { - await db.execute(''' + await db.execute( + ''' CREATE TABLE $tableName ( $columnLocalID TEXT NOT NULL, UNIQUE($columnLocalID) ); - '''); + ''', + ); } FilesMigrationDB._privateConstructor(); @@ -73,10 +75,13 @@ class FilesMigrationDB { await batch.commit(noResult: true); final endTime = DateTime.now(); final duration = Duration( - microseconds: - endTime.microsecondsSinceEpoch - startTime.microsecondsSinceEpoch); - _logger.info("Batch insert of ${fileLocalIDs.length} " - "took ${duration.inMilliseconds} ms."); + microseconds: + endTime.microsecondsSinceEpoch - startTime.microsecondsSinceEpoch, + ); + _logger.info( + "Batch insert of ${fileLocalIDs.length} " + "took ${duration.inMilliseconds} ms.", + ); } Future deleteByLocalIDs(List localIDs) async { diff --git a/lib/db/files_db.dart b/lib/db/files_db.dart index 5483412b7..174ab5267 100644 --- a/lib/db/files_db.dart +++ b/lib/db/files_db.dart @@ -76,8 +76,9 @@ class FilesDB { ]; final dbConfig = MigrationConfig( - initializationScript: initializationScript, - migrationScripts: migrationScripts); + initializationScript: initializationScript, + migrationScripts: migrationScripts, + ); // make this a singleton class FilesDB._privateConstructor(); @@ -319,13 +320,16 @@ class FilesDB { await batch.commit(noResult: true); final endTime = DateTime.now(); final duration = Duration( - microseconds: - endTime.microsecondsSinceEpoch - startTime.microsecondsSinceEpoch); - _logger.info("Batch insert of " + - files.length.toString() + - " took " + - duration.inMilliseconds.toString() + - "ms."); + microseconds: + endTime.microsecondsSinceEpoch - startTime.microsecondsSinceEpoch, + ); + _logger.info( + "Batch insert of " + + files.length.toString() + + " took " + + duration.inMilliseconds.toString() + + "ms.", + ); } Future insert(File file) async { @@ -339,8 +343,11 @@ class FilesDB { Future getFile(int generatedID) async { final db = await instance.database; - final results = await db.query(table, - where: '$columnGeneratedID = ?', whereArgs: [generatedID]); + final results = await db.query( + table, + where: '$columnGeneratedID = ?', + whereArgs: [generatedID], + ); if (results.isEmpty) { return null; } @@ -398,11 +405,14 @@ class FilesDB { } Future getAllUploadedFiles( - int startTime, int endTime, int ownerID, - {int limit, - bool asc, - int visibility = kVisibilityVisible, - Set ignoredCollectionIDs}) async { + int startTime, + int endTime, + int ownerID, { + int limit, + bool asc, + int visibility = kVisibilityVisible, + Set ignoredCollectionIDs, + }) async { final db = await instance.database; final order = (asc ?? false ? 'ASC' : 'DESC'); final results = await db.query( @@ -422,8 +432,13 @@ class FilesDB { } Future getAllLocalAndUploadedFiles( - int startTime, int endTime, int ownerID, - {int limit, bool asc, Set ignoredCollectionIDs}) async { + int startTime, + int endTime, + int ownerID, { + int limit, + bool asc, + Set ignoredCollectionIDs, + }) async { final db = await instance.database; final order = (asc ?? false ? 'ASC' : 'DESC'); final results = await db.query( @@ -443,8 +458,14 @@ class FilesDB { } Future getImportantFiles( - int startTime, int endTime, int ownerID, List paths, - {int limit, bool asc, Set ignoredCollectionIDs}) async { + int startTime, + int endTime, + int ownerID, + List paths, { + int limit, + bool asc, + Set ignoredCollectionIDs, + }) async { final db = await instance.database; String inParam = ""; for (final path in paths) { @@ -469,7 +490,9 @@ class FilesDB { } List _deduplicatedAndFilterIgnoredFiles( - List files, Set ignoredCollectionIDs) { + List files, + Set ignoredCollectionIDs, + ) { final uploadedFileIDs = {}; final List deduplicatedFiles = []; for (final file in files) { @@ -488,8 +511,12 @@ class FilesDB { } Future getFilesInCollection( - int collectionID, int startTime, int endTime, - {int limit, bool asc}) async { + int collectionID, + int startTime, + int endTime, { + int limit, + bool asc, + }) async { final db = await instance.database; final order = (asc ?? false ? 'ASC' : 'DESC'); final results = await db.query( @@ -506,8 +533,13 @@ class FilesDB { return FileLoadResult(files, files.length == limit); } - Future getFilesInPath(String path, int startTime, int endTime, - {int limit, bool asc}) async { + Future getFilesInPath( + String path, + int startTime, + int endTime, { + int limit, + bool asc, + }) async { final db = await instance.database; final order = (asc ?? false ? 'ASC' : 'DESC'); final results = await db.query( @@ -547,7 +579,8 @@ class FilesDB { } Future> getFilesCreatedWithinDurations( - List> durations) async { + List> durations, + ) async { final db = await instance.database; String whereClause = ""; for (int index = 0; index < durations.length; index++) { @@ -569,7 +602,8 @@ class FilesDB { } Future> getFilesToBeUploadedWithinFolders( - Set folders) async { + Set folders, + ) async { if (folders.isEmpty) { return []; } @@ -604,10 +638,12 @@ class FilesDB { var files = _convertToFiles(results); // future-safe filter just to ensure that the query doesn't end up returning files // which should not be backed up - files.removeWhere((e) => - e.collectionID == null || - e.localID == null || - e.uploadedFileID != null); + files.removeWhere( + (e) => + e.collectionID == null || + e.localID == null || + e.uploadedFileID != null, + ); return files; } @@ -801,11 +837,13 @@ class FilesDB { } inParam = inParam.substring(0, inParam.length - 1); final db = await instance.database; - await db.rawQuery(''' + await db.rawQuery( + ''' UPDATE $table SET $columnLocalID = NULL WHERE $columnLocalID IN ($inParam); - '''); + ''', + ); } Future> getLocalFiles(List localIDs) async { @@ -846,7 +884,9 @@ class FilesDB { } Future deleteFilesFromCollection( - int collectionID, List uploadedFileIDs) async { + int collectionID, + List uploadedFileIDs, + ) async { final db = await instance.database; return db.delete( table, @@ -858,15 +898,21 @@ class FilesDB { Future collectionFileCount(int collectionID) async { final db = await instance.database; - var count = Sqflite.firstIntValue(await db.rawQuery( - 'SELECT COUNT(*) FROM $table where $columnCollectionID = $collectionID')); + var count = Sqflite.firstIntValue( + await db.rawQuery( + 'SELECT COUNT(*) FROM $table where $columnCollectionID = $collectionID', + ), + ); return count; } Future fileCountWithVisibility(int visibility, int ownerID) async { final db = await instance.database; - var count = Sqflite.firstIntValue(await db.rawQuery( - 'SELECT COUNT(*) FROM $table where $columnMMdVisibility = $visibility AND $columnOwnerID = $ownerID')); + var count = Sqflite.firstIntValue( + await db.rawQuery( + 'SELECT COUNT(*) FROM $table where $columnMMdVisibility = $visibility AND $columnOwnerID = $ownerID', + ), + ); return count; } @@ -891,7 +937,8 @@ class FilesDB { Future> getLatestLocalFiles() async { final db = await instance.database; - final rows = await db.rawQuery(''' + final rows = await db.rawQuery( + ''' SELECT $table.* FROM $table INNER JOIN @@ -903,7 +950,8 @@ class FilesDB { ) latest_files ON $table.$columnDeviceFolder = latest_files.$columnDeviceFolder AND $table.$columnCreationTime = latest_files.max_creation_time; - '''); + ''', + ); final files = _convertToFiles(rows); // TODO: Do this de-duplication within the SQL Query final folderMap = {}; @@ -920,7 +968,8 @@ class FilesDB { Future> getLatestCollectionFiles() async { final db = await instance.database; - final rows = await db.rawQuery(''' + final rows = await db.rawQuery( + ''' SELECT $table.* FROM $table INNER JOIN @@ -932,7 +981,8 @@ class FilesDB { ) latest_files ON $table.$columnCollectionID = latest_files.$columnCollectionID AND $table.$columnCreationTime = latest_files.max_creation_time; - '''); + ''', + ); final files = _convertToFiles(rows); // TODO: Do this de-duplication within the SQL Query final collectionMap = {}; @@ -965,12 +1015,14 @@ class FilesDB { Future> getFileCountInDeviceFolders() async { final db = await instance.database; - final rows = await db.rawQuery(''' + final rows = await db.rawQuery( + ''' SELECT COUNT($columnGeneratedID) as count, $columnDeviceFolder FROM $table WHERE $columnLocalID IS NOT NULL GROUP BY $columnDeviceFolder - '''); + ''', + ); final result = {}; for (final row in rows) { result[row[columnDeviceFolder]] = row["count"]; @@ -1005,16 +1057,20 @@ class FilesDB { } inParam = inParam.substring(0, inParam.length - 1); final db = await instance.database; - await db.rawUpdate(''' + await db.rawUpdate( + ''' UPDATE $table SET $columnUpdationTime = NULL WHERE $columnLocalID IN ($inParam) AND ($columnLatitude IS NULL OR $columnLongitude IS NULL OR $columnLongitude = 0.0 or $columnLongitude = 0.0); - '''); + ''', + ); } Future doesFileExistInCollection( - int uploadedFileID, int collectionID) async { + int uploadedFileID, + int collectionID, + ) async { final db = await instance.database; final rows = await db.query( table, diff --git a/lib/db/ignored_files_db.dart b/lib/db/ignored_files_db.dart index 2f3103777..783d97b41 100644 --- a/lib/db/ignored_files_db.dart +++ b/lib/db/ignored_files_db.dart @@ -22,7 +22,8 @@ class IgnoredFilesDB { static final columnReason = 'reason'; Future _onCreate(Database db, int version) async { - await db.execute(''' + await db.execute( + ''' CREATE TABLE $tableName ( $columnLocalID TEXT NOT NULL, $columnTitle TEXT NOT NULL, @@ -32,7 +33,8 @@ class IgnoredFilesDB { ); CREATE INDEX IF NOT EXISTS local_id_index ON $tableName($columnLocalID); CREATE INDEX IF NOT EXISTS device_folder_index ON $tableName($columnDeviceFolder); - '''); + ''', + ); } IgnoredFilesDB._privateConstructor(); @@ -85,10 +87,13 @@ class IgnoredFilesDB { await batch.commit(noResult: true); final endTime = DateTime.now(); final duration = Duration( - microseconds: - endTime.microsecondsSinceEpoch - startTime.microsecondsSinceEpoch); - _logger.info("Batch insert of ${ignoredFiles.length} " - "took ${duration.inMilliseconds} ms."); + microseconds: + endTime.microsecondsSinceEpoch - startTime.microsecondsSinceEpoch, + ); + _logger.info( + "Batch insert of ${ignoredFiles.length} " + "took ${duration.inMilliseconds} ms.", + ); } Future> getAll() async { @@ -102,8 +107,12 @@ class IgnoredFilesDB { } IgnoredFile _getIgnoredFileFromRow(Map row) { - return IgnoredFile(row[columnLocalID], row[columnTitle], - row[columnDeviceFolder], row[columnReason]); + return IgnoredFile( + row[columnLocalID], + row[columnTitle], + row[columnDeviceFolder], + row[columnReason], + ); } Map _getRowForIgnoredFile(IgnoredFile ignoredFile) { diff --git a/lib/db/memories_db.dart b/lib/db/memories_db.dart index ebe1a841a..f945211e1 100644 --- a/lib/db/memories_db.dart +++ b/lib/db/memories_db.dart @@ -35,12 +35,14 @@ class MemoriesDB { } Future _onCreate(Database db, int version) async { - await db.execute(''' + await db.execute( + ''' CREATE TABLE $table ( $columnFileID INTEGER PRIMARY KEY NOT NULL, $columnSeenTime TEXT NOT NULL ) - '''); + ''', + ); } Future clearTable() async { @@ -59,8 +61,11 @@ class MemoriesDB { Future markMemoryAsSeen(Memory memory, int timestamp) async { final db = await instance.database; - return await db.insert(table, _getRowForSeenMemory(memory, timestamp), - conflictAlgorithm: ConflictAlgorithm.replace); + return await db.insert( + table, + _getRowForSeenMemory(memory, timestamp), + conflictAlgorithm: ConflictAlgorithm.replace, + ); } Future> getSeenTimes() async { diff --git a/lib/db/public_keys_db.dart b/lib/db/public_keys_db.dart index 5d61b266a..2e5edf958 100644 --- a/lib/db/public_keys_db.dart +++ b/lib/db/public_keys_db.dart @@ -36,12 +36,14 @@ class PublicKeysDB { } Future _onCreate(Database db, int version) async { - await db.execute(''' + await db.execute( + ''' CREATE TABLE $table ( $columnEmail TEXT PRIMARY KEY NOT NULL, $columnPublicKey TEXT NOT NULL ) - '''); + ''', + ); } Future clearTable() async { @@ -51,17 +53,22 @@ class PublicKeysDB { Future setKey(PublicKey key) async { final db = await instance.database; - return db.insert(table, _getRow(key), - conflictAlgorithm: ConflictAlgorithm.replace); + return db.insert( + table, + _getRow(key), + conflictAlgorithm: ConflictAlgorithm.replace, + ); } Future> searchByEmail(String email) async { final db = await instance.database; - return _convertRows(await db.query( - table, - where: '$columnEmail LIKE ?', - whereArgs: ['%$email%'], - )); + return _convertRows( + await db.query( + table, + where: '$columnEmail LIKE ?', + whereArgs: ['%$email%'], + ), + ); } Map _getRow(PublicKey key) { diff --git a/lib/db/trash_db.dart b/lib/db/trash_db.dart index ce6fafb29..fda03cc12 100644 --- a/lib/db/trash_db.dart +++ b/lib/db/trash_db.dart @@ -42,7 +42,8 @@ class TrashDB { static final columnPubMMdVersion = 'pub_mmd_ver'; Future _onCreate(Database db, int version) async { - await db.execute(''' + await db.execute( + ''' CREATE TABLE $tableName ( $columnUploadedFileID INTEGER PRIMARY KEY NOT NULL, $columnCollectionID INTEGER NOT NULL, @@ -65,7 +66,8 @@ class TrashDB { CREATE INDEX IF NOT EXISTS creation_time_index ON $tableName($columnCreationTime); CREATE INDEX IF NOT EXISTS delete_by_time_index ON $tableName($columnTrashDeleteBy); CREATE INDEX IF NOT EXISTS updated_at_time_index ON $tableName($columnTrashUpdatedAt); - '''); + ''', + ); } TrashDB._privateConstructor(); @@ -101,8 +103,11 @@ class TrashDB { // getRecentlyTrashedFile returns the file which was trashed recently Future getRecentlyTrashedFile() async { final db = await instance.database; - var rows = await db.query(tableName, - orderBy: '$columnTrashDeleteBy DESC', limit: 1); + var rows = await db.query( + tableName, + orderBy: '$columnTrashDeleteBy DESC', + limit: 1, + ); if (rows == null || rows.isEmpty) { return null; } @@ -112,7 +117,8 @@ class TrashDB { Future count() async { final db = await instance.database; var count = Sqflite.firstIntValue( - await db.rawQuery('SELECT COUNT(*) FROM $tableName')); + await db.rawQuery('SELECT COUNT(*) FROM $tableName'), + ); return count; } @@ -137,13 +143,16 @@ class TrashDB { await batch.commit(noResult: true); final endTime = DateTime.now(); final duration = Duration( - microseconds: - endTime.microsecondsSinceEpoch - startTime.microsecondsSinceEpoch); - _logger.info("Batch insert of " + - trashFiles.length.toString() + - " took " + - duration.inMilliseconds.toString() + - "ms."); + microseconds: + endTime.microsecondsSinceEpoch - startTime.microsecondsSinceEpoch, + ); + _logger.info( + "Batch insert of " + + trashFiles.length.toString() + + " took " + + duration.inMilliseconds.toString() + + "ms.", + ); } Future insert(TrashFile trash) async { @@ -173,8 +182,12 @@ class TrashDB { ); } - Future getTrashedFiles(int startTime, int endTime, - {int limit, bool asc}) async { + Future getTrashedFiles( + int startTime, + int endTime, { + int limit, + bool asc, + }) async { final db = await instance.database; final order = (asc ?? false ? 'ASC' : 'DESC'); final results = await db.query( diff --git a/lib/db/upload_locks_db.dart b/lib/db/upload_locks_db.dart index 5e4314acd..18a42cda4 100644 --- a/lib/db/upload_locks_db.dart +++ b/lib/db/upload_locks_db.dart @@ -34,13 +34,15 @@ class UploadLocksDB { } Future _onCreate(Database db, int version) async { - await db.execute(''' + await db.execute( + ''' CREATE TABLE $_table ( $_columnID TEXT PRIMARY KEY NOT NULL, $_columnOwner TEXT NOT NULL, $_columnTime TEXT NOT NULL ) - '''); + ''', + ); } Future clearTable() async { diff --git a/lib/ente_theme_data.dart b/lib/ente_theme_data.dart index 4d569ad32..59ff18561 100644 --- a/lib/ente_theme_data.dart +++ b/lib/ente_theme_data.dart @@ -31,10 +31,10 @@ extension CustomColorScheme on ColorScheme { // todo: use brightness == Brightness.light for changing color for dark/light theme ButtonStyle get optionalActionButtonStyle => buildElevatedButtonThemeData( - onPrimary: Color(0xFF777777), - primary: Color(0xFFF0F0F0), - elevation: 0) - .style; + onPrimary: Color(0xFF777777), + primary: Color(0xFFF0F0F0), + elevation: 0, + ).style; Color get recoveryKeyBoxColor => brightness == Brightness.light ? Color.fromRGBO(49, 155, 86, 0.2) @@ -65,11 +65,13 @@ extension CustomColorScheme on ColorScheme { ? DatePickerTheme( backgroundColor: Colors.white, itemStyle: TextStyle(color: Colors.black), - cancelStyle: TextStyle(color: Colors.black)) + cancelStyle: TextStyle(color: Colors.black), + ) : DatePickerTheme( backgroundColor: Colors.black, itemStyle: TextStyle(color: Colors.white), - cancelStyle: TextStyle(color: Colors.white)); + cancelStyle: TextStyle(color: Colors.white), + ); Color get stepProgressUnselectedColor => brightness == Brightness.light ? Color.fromRGBO(196, 196, 196, 0.6) @@ -123,8 +125,12 @@ extension CustomColorScheme on ColorScheme { : Color.fromRGBO(100, 100, 100, 1); } -OutlinedButtonThemeData buildOutlinedButtonThemeData( - {Color bgDisabled, Color bgEnabled, Color fgDisabled, Color fgEnabled}) { +OutlinedButtonThemeData buildOutlinedButtonThemeData({ + Color bgDisabled, + Color bgEnabled, + Color fgDisabled, + Color fgEnabled, +}) { return OutlinedButtonThemeData( style: OutlinedButton.styleFrom( shape: RoundedRectangleBorder( @@ -159,27 +165,28 @@ OutlinedButtonThemeData buildOutlinedButtonThemeData( ); } -ElevatedButtonThemeData buildElevatedButtonThemeData( - {@required Color onPrimary, // text button color - @required Color primary, - double elevation = 2 // background color of button - }) { +ElevatedButtonThemeData buildElevatedButtonThemeData({ + @required Color onPrimary, // text button color + @required Color primary, + double elevation = 2, // background color of button +}) { return ElevatedButtonThemeData( - style: ElevatedButton.styleFrom( - elevation: elevation, - onPrimary: onPrimary, - primary: primary, - alignment: Alignment.center, - textStyle: TextStyle( - fontWeight: FontWeight.w600, - fontFamily: 'Inter-SemiBold', - fontSize: 18, + style: ElevatedButton.styleFrom( + elevation: elevation, + onPrimary: onPrimary, + primary: primary, + alignment: Alignment.center, + textStyle: TextStyle( + fontWeight: FontWeight.w600, + fontFamily: 'Inter-SemiBold', + fontSize: 18, + ), + padding: EdgeInsets.symmetric(vertical: 18), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(8)), + ), ), - padding: EdgeInsets.symmetric(vertical: 18), - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(8)), - ), - )); + ); } TextStyle gradientButtonTextTheme() { diff --git a/lib/main.dart b/lib/main.dart index 3d1a00da0..1690c2461 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -58,13 +58,15 @@ Future _runInForeground() async { _logger.info("Starting app in foreground"); await _init(false, via: 'mainMethod'); _scheduleFGSync('appStart in FG'); - runApp(AppLock( - builder: (args) => EnteApp(_runBackgroundTask, _killBGTask), - lockScreen: LockScreen(), - enabled: Configuration.instance.shouldShowLockScreen(), - lightTheme: lightThemeData, - darkTheme: darkThemeData, - )); + runApp( + AppLock( + builder: (args) => EnteApp(_runBackgroundTask, _killBGTask), + lockScreen: LockScreen(), + enabled: Configuration.instance.shouldShowLockScreen(), + lightTheme: lightThemeData, + darkTheme: darkThemeData, + ), + ); }); } @@ -74,10 +76,13 @@ Future _runBackgroundTask(String taskId) async { await _sync('bgTaskActiveProcess'); BackgroundFetch.finish(taskId); } else { - _runWithLogs(() async { - _logger.info("run background task"); - _runInBackground(taskId); - }, prefix: "[bg]"); + _runWithLogs( + () async { + _logger.info("run background task"); + _runInBackground(taskId); + }, + prefix: "[bg]", + ); } } @@ -139,7 +144,8 @@ Future _init(bool isBackground, {String via = ''}) async { if (Platform.isIOS) { PushService.instance.init().then((_) { FirebaseMessaging.onBackgroundMessage( - _firebaseMessagingBackgroundHandler); + _firebaseMessagingBackgroundHandler, + ); }); } FeatureFlagService.instance.init(); @@ -160,22 +166,25 @@ Future _sync(String caller) async { } Future _runWithLogs(Function() function, {String prefix = ""}) async { - await SuperLogging.main(LogConfig( - body: function, - logDirPath: (await getTemporaryDirectory()).path + "/logs", - maxLogFiles: 5, - sentryDsn: kDebugMode ? kSentryDebugDSN : kSentryDSN, - tunnel: kSentryTunnel, - enableInDebugMode: true, - prefix: prefix, - )); + await SuperLogging.main( + LogConfig( + body: function, + logDirPath: (await getTemporaryDirectory()).path + "/logs", + maxLogFiles: 5, + sentryDsn: kDebugMode ? kSentryDebugDSN : kSentryDSN, + tunnel: kSentryTunnel, + enableInDebugMode: true, + prefix: prefix, + ), + ); } Future _scheduleHeartBeat(bool isBackground) async { final prefs = await SharedPreferences.getInstance(); await prefs.setInt( - isBackground ? kLastBGTaskHeartBeatTime : kLastFGTaskHeartBeatTime, - DateTime.now().microsecondsSinceEpoch); + isBackground ? kLastBGTaskHeartBeatTime : kLastFGTaskHeartBeatTime, + DateTime.now().microsecondsSinceEpoch, + ); Future.delayed(kHeartBeatFrequency, () async { _scheduleHeartBeat(isBackground); }); @@ -209,7 +218,9 @@ Future _isRunningInForeground() async { Future _killBGTask([String taskId]) async { await UploadLocksDB.instance.releaseLocksAcquiredByOwnerBefore( - ProcessType.background.toString(), DateTime.now().microsecondsSinceEpoch); + ProcessType.background.toString(), + DateTime.now().microsecondsSinceEpoch, + ); final prefs = await SharedPreferences.getInstance(); prefs.remove(kLastBGTaskHeartBeatTime); if (taskId != null) { @@ -222,22 +233,26 @@ Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { bool isInForeground = AppLifecycleService.instance.isForeground; if (_isProcessRunning) { _logger.info( - "Background push received when app is alive and runningInFS: $isRunningInFG inForeground: $isInForeground"); + "Background push received when app is alive and runningInFS: $isRunningInFG inForeground: $isInForeground", + ); if (PushService.shouldSync(message)) { await _sync('firebaseBgSyncActiveProcess'); } } else { // App is dead - _runWithLogs(() async { - _logger.info("Background push received"); - if (Platform.isIOS) { - _scheduleSuicide(kBGPushTimeout); // To prevent OS from punishing us - } - await _init(true, via: 'firebasePush'); - if (PushService.shouldSync(message)) { - await _sync('firebaseBgSyncNoActiveProcess'); - } - }, prefix: "[fbg]"); + _runWithLogs( + () async { + _logger.info("Background push received"); + if (Platform.isIOS) { + _scheduleSuicide(kBGPushTimeout); // To prevent OS from punishing us + } + await _init(true, via: 'firebasePush'); + if (PushService.shouldSync(message)) { + await _sync('firebaseBgSyncNoActiveProcess'); + } + }, + prefix: "[fbg]", + ); } } diff --git a/lib/models/billing_plan.dart b/lib/models/billing_plan.dart index b0e6aba63..78f7ddfbf 100644 --- a/lib/models/billing_plan.dart +++ b/lib/models/billing_plan.dart @@ -33,7 +33,8 @@ class BillingPlans { return BillingPlans( plans: List.from( - map['plans']?.map((x) => BillingPlan.fromMap(x))), + map['plans']?.map((x) => BillingPlan.fromMap(x)), + ), freePlan: FreePlan.fromMap(map['freePlan']), ); } diff --git a/lib/models/collection.dart b/lib/models/collection.dart index eb39acee1..75c8b07f7 100644 --- a/lib/models/collection.dart +++ b/lib/models/collection.dart @@ -68,22 +68,23 @@ class Collection { } } - Collection copyWith( - {int id, - User owner, - String encryptedKey, - String keyDecryptionNonce, - String name, - String encryptedName, - String nameDecryptionNonce, - CollectionType type, - CollectionAttributes attributes, - List sharees, - List publicURLs, - int updationTime, - bool isDeleted, - String mMdEncodedJson, - int mMdVersion}) { + Collection copyWith({ + int id, + User owner, + String encryptedKey, + String keyDecryptionNonce, + String name, + String encryptedName, + String nameDecryptionNonce, + CollectionType type, + CollectionAttributes attributes, + List sharees, + List publicURLs, + int updationTime, + bool isDeleted, + String mMdEncodedJson, + int mMdVersion, + }) { Collection result = Collection( id ?? this.id, owner ?? this.owner, @@ -131,7 +132,8 @@ class Collection { (map['publicURLs'] == null || map['publicURLs'].length == 0) ? [] : List.from( - map['publicURLs'].map((x) => PublicURL.fromMap(x))); + map['publicURLs'].map((x) => PublicURL.fromMap(x)), + ); return Collection( map['id'], User.fromMap(map['owner']), @@ -338,12 +340,13 @@ class PublicURL { bool enableDownload = true; bool passwordEnabled = false; - PublicURL( - {this.url, - this.deviceLimit, - this.validTill, - this.enableDownload, - this.passwordEnabled}); + PublicURL({ + this.url, + this.deviceLimit, + this.validTill, + this.enableDownload, + this.passwordEnabled, + }); Map toMap() { return { diff --git a/lib/models/duplicate_files.dart b/lib/models/duplicate_files.dart index 743d511fa..d89d3c41e 100644 --- a/lib/models/duplicate_files.dart +++ b/lib/models/duplicate_files.dart @@ -9,7 +9,8 @@ class DuplicateFilesResponse { factory DuplicateFilesResponse.fromMap(Map map) { return DuplicateFilesResponse( List.from( - map['duplicates']?.map((x) => DuplicateItems.fromMap(x))), + map['duplicates']?.map((x) => DuplicateItems.fromMap(x)), + ), ); } diff --git a/lib/models/file.dart b/lib/models/file.dart index d03e2fc06..ccda02d34 100644 --- a/lib/models/file.dart +++ b/lib/models/file.dart @@ -71,11 +71,12 @@ class File { if (file.creationTime == 0) { try { final parsedDateTime = DateTime.parse( - basenameWithoutExtension(file.title) - .replaceAll("IMG_", "") - .replaceAll("VID_", "") - .replaceAll("DCIM_", "") - .replaceAll("_", " ")); + basenameWithoutExtension(file.title) + .replaceAll("IMG_", "") + .replaceAll("VID_", "") + .replaceAll("DCIM_", "") + .replaceAll("_", " "), + ); file.creationTime = parsedDateTime.microsecondsSinceEpoch; } catch (e) { file.creationTime = asset.modifiedDateTime.microsecondsSinceEpoch; diff --git a/lib/models/ignored_file.dart b/lib/models/ignored_file.dart index 17525b6d9..38f66c665 100644 --- a/lib/models/ignored_file.dart +++ b/lib/models/ignored_file.dart @@ -22,7 +22,11 @@ class IgnoredFile { return null; } - return IgnoredFile(trashFile.localID, trashFile.title, - trashFile.deviceFolder, kIgnoreReasonTrash); + return IgnoredFile( + trashFile.localID, + trashFile.title, + trashFile.deviceFolder, + kIgnoreReasonTrash, + ); } } diff --git a/lib/models/magic_metadata.dart b/lib/models/magic_metadata.dart index a7918cf57..28dad62e0 100644 --- a/lib/models/magic_metadata.dart +++ b/lib/models/magic_metadata.dart @@ -74,7 +74,8 @@ class CollectionMagicMetadata { factory CollectionMagicMetadata.fromEncodedJson(String encodedJson) => CollectionMagicMetadata.fromJson(jsonDecode(encodedJson)); - factory CollectionMagicMetadata.fromJson(dynamic json) => CollectionMagicMetadata.fromMap(json); + factory CollectionMagicMetadata.fromJson(dynamic json) => + CollectionMagicMetadata.fromMap(json); Map toJson() { final map = {}; diff --git a/lib/models/subscription.dart b/lib/models/subscription.dart index 76879ec4a..74cbe2aff 100644 --- a/lib/models/subscription.dart +++ b/lib/models/subscription.dart @@ -135,7 +135,8 @@ class Attributes { Attributes({ this.isCancelled, - this.customerID}); + this.customerID, + }); Attributes.fromJson(dynamic json) { isCancelled = json["isCancelled"]; @@ -153,5 +154,4 @@ class Attributes { String toString() { return 'Attributes{isCancelled: $isCancelled, customerID: $customerID}'; } - -} \ No newline at end of file +} diff --git a/lib/models/trash_file.dart b/lib/models/trash_file.dart index 53e059a8f..08dccd8f0 100644 --- a/lib/models/trash_file.dart +++ b/lib/models/trash_file.dart @@ -1,7 +1,6 @@ import 'package:photos/models/file.dart'; class TrashFile extends File { - // time when file was put in the trash for first time int createdAt; diff --git a/lib/models/update_share_url_request.dart b/lib/models/update_share_url_request.dart index e69de29bb..8b1378917 100644 --- a/lib/models/update_share_url_request.dart +++ b/lib/models/update_share_url_request.dart @@ -0,0 +1 @@ + diff --git a/lib/models/user_details.dart b/lib/models/user_details.dart index ec7621a0b..ff6993c72 100644 --- a/lib/models/user_details.dart +++ b/lib/models/user_details.dart @@ -40,10 +40,11 @@ class UserDetails { int getFreeStorage() { return max( - isPartOfFamily() - ? (familyData.storage - familyData.getTotalUsage()) - : (subscription.storage - (usage)), - 0); + isPartOfFamily() + ? (familyData.storage - familyData.getTotalUsage()) + : (subscription.storage - (usage)), + 0, + ); } int getTotalStorage() { @@ -118,7 +119,8 @@ class FamilyData { } assert(map['members'] != null && map['members'].length >= 0); final members = List.from( - map['members'].map((x) => FamilyMember.fromMap(x))); + map['members'].map((x) => FamilyMember.fromMap(x)), + ); return FamilyData( members, map['storage'] as int, diff --git a/lib/services/billing_service.dart b/lib/services/billing_service.dart index 7e5f24b9d..5e34838ac 100644 --- a/lib/services/billing_service.dart +++ b/lib/services/billing_service.dart @@ -11,11 +11,15 @@ import 'package:photos/models/billing_plan.dart'; import 'package:photos/models/subscription.dart'; const kWebPaymentRedirectUrl = "https://payments.ente.io/frameRedirect"; -const kWebPaymentBaseEndpoint = String.fromEnvironment("web-payment", - defaultValue: "https://payments.ente.io"); +const kWebPaymentBaseEndpoint = String.fromEnvironment( + "web-payment", + defaultValue: "https://payments.ente.io", +); -const kFamilyPlanManagementUrl = String.fromEnvironment("web-family", - defaultValue: "https://family.ente.io"); +const kFamilyPlanManagementUrl = String.fromEnvironment( + "web-family", + defaultValue: "https://family.ente.io", +); class BillingService { BillingService._privateConstructor(); @@ -42,9 +46,10 @@ class BillingService { } for (final purchase in purchases) { if (purchase.status == PurchaseStatus.purchased) { - verifySubscription(purchase.productID, - purchase.verificationData.serverVerificationData) - .then((response) { + verifySubscription( + purchase.productID, + purchase.verificationData.serverVerificationData, + ).then((response) { if (response != null) { InAppPurchaseConnection.instance.completePurchase(purchase); } @@ -166,8 +171,9 @@ class BillingService { } } - Future getStripeCustomerPortalUrl( - {String endpoint = kWebPaymentRedirectUrl}) async { + Future getStripeCustomerPortalUrl({ + String endpoint = kWebPaymentRedirectUrl, + }) async { try { final response = await _dio.get( _config.getHttpEndpoint() + "/billing/stripe/customer-portal", diff --git a/lib/services/collections_service.dart b/lib/services/collections_service.dart index 709d3c69c..d3b065505 100644 --- a/lib/services/collections_service.dart +++ b/lib/services/collections_service.dart @@ -192,7 +192,9 @@ class CollectionsService { Future share(int collectionID, String email, String publicKey) async { final encryptedKey = CryptoUtil.sealSync( - getCollectionKey(collectionID), Sodium.base642bin(publicKey)); + getCollectionKey(collectionID), + Sodium.base642bin(publicKey), + ); try { await _dio.post( Configuration.instance.getHttpEndpoint() + "/collections/share", @@ -202,7 +204,8 @@ class CollectionsService { "encryptedKey": Sodium.bin2base64(encryptedKey), }, options: Options( - headers: {"X-Auth-Token": Configuration.instance.getToken()}), + headers: {"X-Auth-Token": Configuration.instance.getToken()}, + ), ); } on DioError catch (e) { if (e.response.statusCode == 402) { @@ -222,7 +225,8 @@ class CollectionsService { "email": email, }, options: Options( - headers: {"X-Auth-Token": Configuration.instance.getToken()}), + headers: {"X-Auth-Token": Configuration.instance.getToken()}, + ), ); _collectionIDToCollections[collectionID] .sharees @@ -253,20 +257,26 @@ class CollectionsService { Uint8List _getDecryptedKey(Collection collection) { final encryptedKey = Sodium.base642bin(collection.encryptedKey); if (collection.owner.id == _config.getUserID()) { - return CryptoUtil.decryptSync(encryptedKey, _config.getKey(), - Sodium.base642bin(collection.keyDecryptionNonce)); + return CryptoUtil.decryptSync( + encryptedKey, + _config.getKey(), + Sodium.base642bin(collection.keyDecryptionNonce), + ); } else { return CryptoUtil.openSealSync( - encryptedKey, - Sodium.base642bin(_config.getKeyAttributes().publicKey), - _config.getSecretKey()); + encryptedKey, + Sodium.base642bin(_config.getKeyAttributes().publicKey), + _config.getSecretKey(), + ); } } Future rename(Collection collection, String newName) async { try { final encryptedName = CryptoUtil.encryptSync( - utf8.encode(newName), getCollectionKey(collection.id)); + utf8.encode(newName), + getCollectionKey(collection.id), + ); await _dio.post( Configuration.instance.getHttpEndpoint() + "/collections/rename", data: { @@ -275,7 +285,8 @@ class CollectionsService { "nameDecryptionNonce": Sodium.bin2base64(encryptedName.nonce) }, options: Options( - headers: {"X-Auth-Token": Configuration.instance.getToken()}), + headers: {"X-Auth-Token": Configuration.instance.getToken()}, + ), ); // trigger sync to fetch the latest name from server sync(); @@ -286,7 +297,9 @@ class CollectionsService { } Future updateMagicMetadata( - Collection collection, Map newMetadataUpdate) async { + Collection collection, + Map newMetadataUpdate, + ) async { final int ownerID = Configuration.instance.getUserID(); try { if (collection.owner.id != ownerID) { @@ -307,7 +320,9 @@ class CollectionsService { final key = getCollectionKey(collection.id); final encryptedMMd = await CryptoUtil.encryptChaCha( - utf8.encode(jsonEncode(jsonToUpdate)), key); + utf8.encode(jsonEncode(jsonToUpdate)), + key, + ); // for required field, the json validator on golang doesn't treat 0 as valid // value. Instead of changing version to ptr, decided to start version with 1. int currentVersion = max(collection.mMdVersion, 1); @@ -325,7 +340,8 @@ class CollectionsService { "/collections/magic-metadata", data: params, options: Options( - headers: {"X-Auth-Token": Configuration.instance.getToken()}), + headers: {"X-Auth-Token": Configuration.instance.getToken()}, + ), ); collection.mMdVersion = currentVersion + 1; _cacheCollectionAttributes(collection); @@ -351,7 +367,8 @@ class CollectionsService { "collectionID": collection.id, }, options: Options( - headers: {"X-Auth-Token": Configuration.instance.getToken()}), + headers: {"X-Auth-Token": Configuration.instance.getToken()}, + ), ); collection.publicURLs?.add(PublicURL.fromMap(response.data["result"])); await _db.insert(List.from([collection])); @@ -369,14 +386,17 @@ class CollectionsService { } Future updateShareUrl( - Collection collection, Map prop) async { + Collection collection, + Map prop, + ) async { prop.putIfAbsent('collectionID', () => collection.id); try { final response = await _dio.put( Configuration.instance.getHttpEndpoint() + "/collections/share-url", data: json.encode(prop), options: Options( - headers: {"X-Auth-Token": Configuration.instance.getToken()}), + headers: {"X-Auth-Token": Configuration.instance.getToken()}, + ), ); // remove existing url information collection.publicURLs?.clear(); @@ -426,7 +446,8 @@ class CollectionsService { "source": AppLifecycleService.instance.isForeground ? "fg" : "bg", }, options: Options( - headers: {"X-Auth-Token": Configuration.instance.getToken()}), + headers: {"X-Auth-Token": Configuration.instance.getToken()}, + ), ); final List collections = []; if (response != null) { @@ -436,13 +457,15 @@ class CollectionsService { if (collectionData['magicMetadata'] != null) { final decryptionKey = _getDecryptedKey(collection); final utfEncodedMmd = await CryptoUtil.decryptChaCha( - Sodium.base642bin(collectionData['magicMetadata']['data']), - decryptionKey, - Sodium.base642bin(collectionData['magicMetadata']['header'])); + Sodium.base642bin(collectionData['magicMetadata']['data']), + decryptionKey, + Sodium.base642bin(collectionData['magicMetadata']['header']), + ); collection.mMdEncodedJson = utf8.decode(utfEncodedMmd); collection.mMdVersion = collectionData['magicMetadata']['version']; collection.magicMetadata = CollectionMagicMetadata.fromEncodedJson( - collection.mMdEncodedJson); + collection.mMdEncodedJson, + ); } collections.add(collection); } @@ -464,20 +487,22 @@ class CollectionsService { final key = CryptoUtil.generateKey(); final encryptedKeyData = CryptoUtil.encryptSync(key, _config.getKey()); final encryptedName = CryptoUtil.encryptSync(utf8.encode(albumName), key); - final collection = await createAndCacheCollection(Collection( - null, - null, - Sodium.bin2base64(encryptedKeyData.encryptedData), - Sodium.bin2base64(encryptedKeyData.nonce), - null, - Sodium.bin2base64(encryptedName.encryptedData), - Sodium.bin2base64(encryptedName.nonce), - CollectionType.album, - CollectionAttributes(), - null, - null, - null, - )); + final collection = await createAndCacheCollection( + Collection( + null, + null, + Sodium.bin2base64(encryptedKeyData.encryptedData), + Sodium.bin2base64(encryptedKeyData.nonce), + null, + Sodium.bin2base64(encryptedName.encryptedData), + Sodium.bin2base64(encryptedName.nonce), + CollectionType.album, + CollectionAttributes(), + null, + null, + null, + ), + ); return collection; } @@ -487,7 +512,8 @@ class CollectionsService { final response = await _dio.get( Configuration.instance.getHttpEndpoint() + "/collections/$collectionID", options: Options( - headers: {"X-Auth-Token": Configuration.instance.getToken()}), + headers: {"X-Auth-Token": Configuration.instance.getToken()}, + ), ); assert(response != null && response.data != null); final collectionData = response.data["collection"]; @@ -495,9 +521,10 @@ class CollectionsService { if (collectionData['magicMetadata'] != null) { final decryptionKey = _getDecryptedKey(collection); final utfEncodedMmd = await CryptoUtil.decryptChaCha( - Sodium.base642bin(collectionData['magicMetadata']['data']), - decryptionKey, - Sodium.base642bin(collectionData['magicMetadata']['header'])); + Sodium.base642bin(collectionData['magicMetadata']['data']), + decryptionKey, + Sodium.base642bin(collectionData['magicMetadata']['header']), + ); collection.mMdEncodedJson = utf8.decode(utfEncodedMmd); collection.mMdVersion = collectionData['magicMetadata']['version']; collection.magicMetadata = @@ -523,38 +550,43 @@ class CollectionsService { final key = CryptoUtil.generateKey(); final encryptedKeyData = CryptoUtil.encryptSync(key, _config.getKey()); final encryptedPath = CryptoUtil.encryptSync(utf8.encode(path), key); - final collection = await createAndCacheCollection(Collection( - null, - null, - Sodium.bin2base64(encryptedKeyData.encryptedData), - Sodium.bin2base64(encryptedKeyData.nonce), - null, - Sodium.bin2base64(encryptedPath.encryptedData), - Sodium.bin2base64(encryptedPath.nonce), - CollectionType.folder, - CollectionAttributes( - encryptedPath: Sodium.bin2base64(encryptedPath.encryptedData), - pathDecryptionNonce: Sodium.bin2base64(encryptedPath.nonce), - version: 1, + final collection = await createAndCacheCollection( + Collection( + null, + null, + Sodium.bin2base64(encryptedKeyData.encryptedData), + Sodium.bin2base64(encryptedKeyData.nonce), + null, + Sodium.bin2base64(encryptedPath.encryptedData), + Sodium.bin2base64(encryptedPath.nonce), + CollectionType.folder, + CollectionAttributes( + encryptedPath: Sodium.bin2base64(encryptedPath.encryptedData), + pathDecryptionNonce: Sodium.bin2base64(encryptedPath.nonce), + version: 1, + ), + null, + null, + null, ), - null, - null, - null, - )); + ); return collection; } Future addToCollection(int collectionID, List files) async { final containsUploadedFile = files.firstWhere( - (element) => element.uploadedFileID != null, - orElse: () => null) != + (element) => element.uploadedFileID != null, + orElse: () => null, + ) != null; if (containsUploadedFile) { final existingFileIDsInCollection = await FilesDB.instance.getUploadedFileIDs(collectionID); - files.removeWhere((element) => - element.uploadedFileID != null && - existingFileIDsInCollection.contains(element.uploadedFileID)); + files.removeWhere( + (element) => + element.uploadedFileID != null && + existingFileIDsInCollection.contains(element.uploadedFileID), + ); } if (files.isEmpty || !containsUploadedFile) { _logger.info("nothing to add to the collection"); @@ -574,9 +606,13 @@ class CollectionsService { if (params["files"] == null) { params["files"] = []; } - params["files"].add(CollectionFileItem( - file.uploadedFileID, file.encryptedKey, file.keyDecryptionNonce) - .toMap()); + params["files"].add( + CollectionFileItem( + file.uploadedFileID, + file.encryptedKey, + file.keyDecryptionNonce, + ).toMap(), + ); } try { @@ -584,7 +620,8 @@ class CollectionsService { Configuration.instance.getHttpEndpoint() + "/collections/add-files", data: params, options: Options( - headers: {"X-Auth-Token": Configuration.instance.getToken()}), + headers: {"X-Auth-Token": Configuration.instance.getToken()}, + ), ); await _filesDB.insertMultiple(files); Bus.instance.fire(CollectionUpdatedEvent(collectionID, files)); @@ -605,16 +642,21 @@ class CollectionsService { final encryptedKeyData = CryptoUtil.encryptSync(key, toCollectionKey); file.encryptedKey = Sodium.bin2base64(encryptedKeyData.encryptedData); file.keyDecryptionNonce = Sodium.bin2base64(encryptedKeyData.nonce); - params["files"].add(CollectionFileItem( - file.uploadedFileID, file.encryptedKey, file.keyDecryptionNonce) - .toMap()); + params["files"].add( + CollectionFileItem( + file.uploadedFileID, + file.encryptedKey, + file.keyDecryptionNonce, + ).toMap(), + ); } try { await _dio.post( Configuration.instance.getHttpEndpoint() + "/collections/restore-files", data: params, options: Options( - headers: {"X-Auth-Token": Configuration.instance.getToken()}), + headers: {"X-Auth-Token": Configuration.instance.getToken()}, + ), ); await _filesDB.insertMultiple(files); await TrashDB.instance @@ -641,7 +683,10 @@ class CollectionsService { } Future move( - int toCollectionID, int fromCollectionID, List files) async { + int toCollectionID, + int fromCollectionID, + List files, + ) async { _validateMoveRequest(toCollectionID, fromCollectionID, files); files.removeWhere((element) => element.uploadedFileID == null); if (files.isEmpty) { @@ -660,9 +705,13 @@ class CollectionsService { CryptoUtil.encryptSync(fileKey, getCollectionKey(toCollectionID)); file.encryptedKey = Sodium.bin2base64(encryptedKeyData.encryptedData); file.keyDecryptionNonce = Sodium.bin2base64(encryptedKeyData.nonce); - params["files"].add(CollectionFileItem( - file.uploadedFileID, file.encryptedKey, file.keyDecryptionNonce) - .toMap()); + params["files"].add( + CollectionFileItem( + file.uploadedFileID, + file.encryptedKey, + file.keyDecryptionNonce, + ).toMap(), + ); } await _dio.post( Configuration.instance.getHttpEndpoint() + "/collections/move-files", @@ -673,20 +722,31 @@ class CollectionsService { // remove files from old collection await _filesDB.removeFromCollection( - fromCollectionID, files.map((e) => e.uploadedFileID).toList()); - Bus.instance.fire(CollectionUpdatedEvent(fromCollectionID, files, - type: EventType.deletedFromRemote)); + fromCollectionID, + files.map((e) => e.uploadedFileID).toList(), + ); + Bus.instance.fire( + CollectionUpdatedEvent( + fromCollectionID, + files, + type: EventType.deletedFromRemote, + ), + ); // insert new files in the toCollection which are not part of the toCollection final existingUploadedIDs = await FilesDB.instance.getUploadedFileIDs(toCollectionID); files.removeWhere( - (element) => existingUploadedIDs.contains(element.uploadedFileID)); + (element) => existingUploadedIDs.contains(element.uploadedFileID), + ); await _filesDB.insertMultiple(files); Bus.instance.fire(CollectionUpdatedEvent(toCollectionID, files)); } void _validateMoveRequest( - int toCollectionID, int fromCollectionID, List files) { + int toCollectionID, + int fromCollectionID, + List files, + ) { if (toCollectionID == fromCollectionID) { throw AssertionError("can't move to same album"); } @@ -754,10 +814,13 @@ class CollectionsService { final key = collection.attributes.version == 1 ? _getDecryptedKey(collection) : _config.getKey(); - return utf8.decode(CryptoUtil.decryptSync( + return utf8.decode( + CryptoUtil.decryptSync( Sodium.base642bin(collection.attributes.encryptedPath), key, - Sodium.base642bin(collection.attributes.pathDecryptionNonce))); + Sodium.base642bin(collection.attributes.pathDecryptionNonce), + ), + ); } bool hasSyncedCollections() { @@ -770,13 +833,17 @@ class CollectionsService { String name; try { final result = CryptoUtil.decryptSync( - Sodium.base642bin(collection.encryptedName), - _getDecryptedKey(collection), - Sodium.base642bin(collection.nameDecryptionNonce)); + Sodium.base642bin(collection.encryptedName), + _getDecryptedKey(collection), + Sodium.base642bin(collection.nameDecryptionNonce), + ); name = utf8.decode(result); } catch (e, s) { _logger.severe( - "failed to decrypt collection name: ${collection.id}", e, s); + "failed to decrypt collection name: ${collection.id}", + e, + s, + ); name = "Unknown Album"; } return collection.copyWith(name: name); @@ -830,7 +897,8 @@ class AddFilesRequest { return AddFilesRequest( map['collectionID'], List.from( - map['files']?.map((x) => CollectionFileItem.fromMap(x))), + map['files']?.map((x) => CollectionFileItem.fromMap(x)), + ), ); } diff --git a/lib/services/deduplication_service.dart b/lib/services/deduplication_service.dart index 4fef9ea82..2dd8d302b 100644 --- a/lib/services/deduplication_service.dart +++ b/lib/services/deduplication_service.dart @@ -52,11 +52,14 @@ class DeduplicationService { } if (missingFileIDs.isNotEmpty) { _logger.severe( - "Missing files", - InvalidStateError("Could not find " + + "Missing files", + InvalidStateError( + "Could not find " + missingFileIDs.length.toString() + " files in local DB: " + - missingFileIDs.toString())); + missingFileIDs.toString(), + ), + ); } return result; } catch (e) { diff --git a/lib/services/favorites_service.dart b/lib/services/favorites_service.dart index a41e44847..0a7c7a8b9 100644 --- a/lib/services/favorites_service.dart +++ b/lib/services/favorites_service.dart @@ -37,7 +37,9 @@ class FavoritesService { return false; } return _filesDB.doesFileExistInCollection( - file.uploadedFileID, collection.id); + file.uploadedFileID, + collection.id, + ); } Future addToFavorites(File file) async { @@ -84,21 +86,22 @@ class FavoritesService { final key = CryptoUtil.generateKey(); final encryptedKeyData = CryptoUtil.encryptSync(key, _config.getKey()); final encryptedName = CryptoUtil.encryptSync(utf8.encode("Favorites"), key); - final collection = - await _collectionsService.createAndCacheCollection(Collection( - null, - null, - Sodium.bin2base64(encryptedKeyData.encryptedData), - Sodium.bin2base64(encryptedKeyData.nonce), - null, - Sodium.bin2base64(encryptedName.encryptedData), - Sodium.bin2base64(encryptedName.nonce), - CollectionType.favorites, - CollectionAttributes(), - null, - null, - null, - )); + final collection = await _collectionsService.createAndCacheCollection( + Collection( + null, + null, + Sodium.bin2base64(encryptedKeyData.encryptedData), + Sodium.bin2base64(encryptedKeyData.nonce), + null, + Sodium.bin2base64(encryptedName.encryptedData), + Sodium.bin2base64(encryptedName.nonce), + CollectionType.favorites, + CollectionAttributes(), + null, + null, + null, + ), + ); _cachedFavoritesCollectionID = collection.id; return collection.id; } diff --git a/lib/services/feature_flag_service.dart b/lib/services/feature_flag_service.dart index 47289cae4..4f7c8a54e 100644 --- a/lib/services/feature_flag_service.dart +++ b/lib/services/feature_flag_service.dart @@ -101,21 +101,23 @@ class FeatureFlagService { class FeatureFlags { static FeatureFlags defaultFlags = FeatureFlags( - disableCFWorker: FFDefault.disableCFWorker, - disableUrlSharing: FFDefault.disableUrlSharing, - enableStripe: FFDefault.enableStripe, - enableMissingLocationMigration: FFDefault.enableMissingLocationMigration); + disableCFWorker: FFDefault.disableCFWorker, + disableUrlSharing: FFDefault.disableUrlSharing, + enableStripe: FFDefault.enableStripe, + enableMissingLocationMigration: FFDefault.enableMissingLocationMigration, + ); final bool disableCFWorker; final bool disableUrlSharing; final bool enableStripe; final bool enableMissingLocationMigration; - FeatureFlags( - {@required this.disableCFWorker, - @required this.disableUrlSharing, - @required this.enableStripe, - @required this.enableMissingLocationMigration}); + FeatureFlags({ + @required this.disableCFWorker, + @required this.disableUrlSharing, + @required this.enableStripe, + @required this.enableMissingLocationMigration, + }); Map toMap() { return { diff --git a/lib/services/file_magic_service.dart b/lib/services/file_magic_service.dart index 2f74e749d..a03fe71fb 100644 --- a/lib/services/file_magic_service.dart +++ b/lib/services/file_magic_service.dart @@ -44,7 +44,9 @@ class FileMagicService { } Future updatePublicMagicMetadata( - List files, Map newMetadataUpdate) async { + List files, + Map newMetadataUpdate, + ) async { final params = {}; params['metadataList'] = []; final int ownerID = Configuration.instance.getUserID(); @@ -52,7 +54,8 @@ class FileMagicService { for (final file in files) { if (file.uploadedFileID == null) { throw AssertionError( - "operation is only supported on backed up files"); + "operation is only supported on backed up files", + ); } else if (file.ownerID != ownerID) { throw AssertionError("cannot modify memories not owned by you"); } @@ -70,15 +73,20 @@ class FileMagicService { final fileKey = decryptFileKey(file); final encryptedMMd = await CryptoUtil.encryptChaCha( - utf8.encode(jsonEncode(jsonToUpdate)), fileKey); - params['metadataList'].add(UpdateMagicMetadataRequest( + utf8.encode(jsonEncode(jsonToUpdate)), + fileKey, + ); + params['metadataList'].add( + UpdateMagicMetadataRequest( id: file.uploadedFileID, magicMetadata: MetadataRequest( version: file.pubMmdVersion, count: jsonToUpdate.length, data: Sodium.bin2base64(encryptedMMd.encryptedData), header: Sodium.bin2base64(encryptedMMd.header), - ))); + ), + ), + ); file.pubMmdVersion = file.pubMmdVersion + 1; } @@ -87,7 +95,8 @@ class FileMagicService { "/files/public-magic-metadata", data: params, options: Options( - headers: {"X-Auth-Token": Configuration.instance.getToken()}), + headers: {"X-Auth-Token": Configuration.instance.getToken()}, + ), ); // update the state of the selected file. Same file in other collection // should be eventually synced after remote sync has completed @@ -105,7 +114,9 @@ class FileMagicService { } Future _updateMagicData( - List files, Map newMetadataUpdate) async { + List files, + Map newMetadataUpdate, + ) async { final params = {}; params['metadataList'] = []; final int ownerID = Configuration.instance.getUserID(); @@ -113,7 +124,8 @@ class FileMagicService { for (final file in files) { if (file.uploadedFileID == null) { throw AssertionError( - "operation is only supported on backed up files"); + "operation is only supported on backed up files", + ); } else if (file.ownerID != ownerID) { throw AssertionError("cannot modify memories not owned by you"); } @@ -131,15 +143,20 @@ class FileMagicService { final fileKey = decryptFileKey(file); final encryptedMMd = await CryptoUtil.encryptChaCha( - utf8.encode(jsonEncode(jsonToUpdate)), fileKey); - params['metadataList'].add(UpdateMagicMetadataRequest( + utf8.encode(jsonEncode(jsonToUpdate)), + fileKey, + ); + params['metadataList'].add( + UpdateMagicMetadataRequest( id: file.uploadedFileID, magicMetadata: MetadataRequest( version: file.mMdVersion, count: jsonToUpdate.length, data: Sodium.bin2base64(encryptedMMd.encryptedData), header: Sodium.bin2base64(encryptedMMd.header), - ))); + ), + ), + ); file.mMdVersion = file.mMdVersion + 1; } @@ -147,7 +164,8 @@ class FileMagicService { Configuration.instance.getHttpEndpoint() + "/files/magic-metadata", data: params, options: Options( - headers: {"X-Auth-Token": Configuration.instance.getToken()}), + headers: {"X-Auth-Token": Configuration.instance.getToken()}, + ), ); // update the state of the selected file. Same file in other collection // should be eventually synced after remote sync has completed @@ -173,10 +191,11 @@ class UpdateMagicMetadataRequest { factory UpdateMagicMetadataRequest.fromJson(dynamic json) { return UpdateMagicMetadataRequest( - id: json['id'], - magicMetadata: json['magicMetadata'] != null - ? MetadataRequest.fromJson(json['magicMetadata']) - : null); + id: json['id'], + magicMetadata: json['magicMetadata'] != null + ? MetadataRequest.fromJson(json['magicMetadata']) + : null, + ); } Map toJson() { diff --git a/lib/services/file_migration_service.dart b/lib/services/file_migration_service.dart index 0851f3085..6725bffee 100644 --- a/lib/services/file_migration_service.dart +++ b/lib/services/file_migration_service.dart @@ -81,13 +81,15 @@ class FileMigrationService { final eTime = DateTime.now().microsecondsSinceEpoch; final d = Duration(microseconds: eTime - sTime); _logger.info( - 'filesWithMissingLocation migration completed in ${d.inSeconds.toString()} seconds'); + 'filesWithMissingLocation migration completed in ${d.inSeconds.toString()} seconds', + ); } await _markLocationMigrationAsCompleted(); } Future _checkAndMarkFilesForReUpload( - List localIDsToProcess) async { + List localIDsToProcess, + ) async { _logger.info("files to process ${localIDsToProcess.length}"); var localIDsWithLocation = []; for (var localID in localIDsToProcess) { @@ -101,7 +103,8 @@ class FileMigrationService { if ((latLng.longitude ?? 0.0) != 0.0 || (latLng.longitude ?? 0.0) != 0.0) { _logger.finest( - 'found lat/long ${latLng.longitude}/${latLng.longitude} for ${assetEntity.title} ${assetEntity.relativePath} with id : $localID'); + 'found lat/long ${latLng.longitude}/${latLng.longitude} for ${assetEntity.title} ${assetEntity.relativePath} with id : $localID', + ); hasLocation = true; } } catch (e, s) { @@ -127,7 +130,8 @@ class FileMigrationService { final eTime = DateTime.now().microsecondsSinceEpoch; final d = Duration(microseconds: eTime - sTime); _logger.info( - 'importing completed, total files count ${fileLocalIDs.length} and took ${d.inSeconds.toString()} seconds'); + 'importing completed, total files count ${fileLocalIDs.length} and took ${d.inSeconds.toString()} seconds', + ); _prefs.setBool(isLocalImportDone, true); } } diff --git a/lib/services/ignored_files_service.dart b/lib/services/ignored_files_service.dart index 47f6df609..df8b28faa 100644 --- a/lib/services/ignored_files_service.dart +++ b/lib/services/ignored_files_service.dart @@ -25,10 +25,12 @@ class IgnoredFilesService { Future cacheAndInsert(List ignoredFiles) async { final existingIDs = await ignoredIDs; - existingIDs.addAll(ignoredFiles - .map((e) => _idForIgnoredFile(e)) - .where((id) => id != null) - .toSet()); + existingIDs.addAll( + ignoredFiles + .map((e) => _idForIgnoredFile(e)) + .where((id) => id != null) + .toSet(), + ); return _db.insertMultiple(ignoredFiles); } @@ -56,7 +58,10 @@ class IgnoredFilesService { String _idForIgnoredFile(IgnoredFile ignoredFile) { return _getIgnoreID( - ignoredFile.localID, ignoredFile.deviceFolder, ignoredFile.title); + ignoredFile.localID, + ignoredFile.deviceFolder, + ignoredFile.title, + ); } // _computeIgnoreID will return null if don't have sufficient information diff --git a/lib/services/local_sync_service.dart b/lib/services/local_sync_service.dart index 53ea703ec..9c017dceb 100644 --- a/lib/services/local_sync_service.dart +++ b/lib/services/local_sync_service.dart @@ -55,8 +55,10 @@ class LocalSyncService { if (Platform.isAndroid && AppLifecycleService.instance.isForeground) { final permissionState = await PhotoManager.requestPermissionExtend(); if (permissionState != PermissionState.authorized) { - _logger.severe("sync requested with invalid permission", - permissionState.toString()); + _logger.severe( + "sync requested with invalid permission", + permissionState.toString(), + ); return; } } @@ -67,7 +69,8 @@ class LocalSyncService { _existingSync = Completer(); final existingLocalFileIDs = await _db.getExistingLocalFileIDs(); _logger.info( - existingLocalFileIDs.length.toString() + " localIDs were discovered"); + existingLocalFileIDs.length.toString() + " localIDs were discovered", + ); final editedFileIDs = getEditedFileIDs().toSet(); final downloadedFileIDs = getDownloadedFileIDs().toSet(); final syncStartTime = DateTime.now().microsecondsSinceEpoch; @@ -127,11 +130,13 @@ class LocalSyncService { final localAssets = await getAllLocalAssets(); final eTime = DateTime.now().microsecondsSinceEpoch; final d = Duration(microseconds: eTime - sTime); - _logger.info("Loading from the beginning returned " + - localAssets.length.toString() + - " assets and took " + - d.inMilliseconds.toString() + - "ms"); + _logger.info( + "Loading from the beginning returned " + + localAssets.length.toString() + + " assets and took " + + d.inMilliseconds.toString() + + "ms", + ); final existingIDs = await _db.getExistingLocalFileIDs(); final invalidIDs = getInvalidFileIDs().toSet(); final unsyncedFiles = @@ -139,7 +144,8 @@ class LocalSyncService { if (unsyncedFiles.isNotEmpty) { await _db.insertMultiple(unsyncedFiles); _logger.info( - "Inserted " + unsyncedFiles.length.toString() + " unsynced files."); + "Inserted " + unsyncedFiles.length.toString() + " unsynced files.", + ); _updatePathsToBackup(unsyncedFiles); Bus.instance.fire(LocalPhotosUpdatedEvent(unsyncedFiles)); return true; @@ -218,10 +224,12 @@ class LocalSyncService { Set editedFileIDs, Set downloadedFileIDs, ) async { - _logger.info("Loading photos from " + - DateTime.fromMicrosecondsSinceEpoch(fromTime).toString() + - " to " + - DateTime.fromMicrosecondsSinceEpoch(toTime).toString()); + _logger.info( + "Loading photos from " + + DateTime.fromMicrosecondsSinceEpoch(fromTime).toString() + + " to " + + DateTime.fromMicrosecondsSinceEpoch(toTime).toString(), + ); final files = await getDeviceFiles(fromTime, toTime, _computer); if (files.isNotEmpty) { _logger.info("Fetched " + files.length.toString() + " files."); @@ -233,7 +241,8 @@ class LocalSyncService { .removeWhere((file) => downloadedFileIDs.contains(file.localID)); if (updatedFiles.isNotEmpty) { _logger.info( - updatedFiles.length.toString() + " local files were updated."); + updatedFiles.length.toString() + " local files were updated.", + ); } for (final file in updatedFiles) { await _db.updateUploadedFile( diff --git a/lib/services/memories_service.dart b/lib/services/memories_service.dart index 01d57b8a7..0179029bb 100644 --- a/lib/services/memories_service.dart +++ b/lib/services/memories_service.dart @@ -30,7 +30,8 @@ class MemoriesService extends ChangeNotifier { // Intention of delay is to give more CPU cycles to other tasks Future.delayed(const Duration(seconds: 5), () { _memoriesDB.clearMemoriesSeenBeforeTime( - DateTime.now().microsecondsSinceEpoch - (7 * kMicroSecondsInDay)); + DateTime.now().microsecondsSinceEpoch - (7 * kMicroSecondsInDay), + ); }); } @@ -53,10 +54,13 @@ class MemoriesService extends ChangeNotifier { Future> _fetchMemories() async { _logger.info("Fetching memories"); final presentTime = DateTime.now(); - final present = presentTime.subtract(Duration( + final present = presentTime.subtract( + Duration( hours: presentTime.hour, minutes: presentTime.minute, - seconds: presentTime.second)); + seconds: presentTime.second, + ), + ); final List> durations = []; for (var yearAgo = 1; yearAgo <= yearsBefore; yearAgo++) { final date = _getDate(present, yearAgo); @@ -94,7 +98,9 @@ class MemoriesService extends ChangeNotifier { Future markMemoryAsSeen(Memory memory) async { memory.markSeen(); await _memoriesDB.markMemoryAsSeen( - memory, DateTime.now().microsecondsSinceEpoch); + memory, + DateTime.now().microsecondsSinceEpoch, + ); notifyListeners(); } } diff --git a/lib/services/notification_service.dart b/lib/services/notification_service.dart index 7d8ea2d35..e3b27806c 100644 --- a/lib/services/notification_service.dart +++ b/lib/services/notification_service.dart @@ -20,8 +20,10 @@ class NotificationService { InitializationSettings( android: initializationSettingsAndroid, ); - await _flutterLocalNotificationsPlugin.initialize(initializationSettings, - onSelectNotification: selectNotification); + await _flutterLocalNotificationsPlugin.initialize( + initializationSettings, + onSelectNotification: selectNotification, + ); } Future selectNotification(String payload) async {} @@ -42,6 +44,10 @@ class NotificationService { const NotificationDetails platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics); await _flutterLocalNotificationsPlugin.show( - 0, title, message, platformChannelSpecifics); + 0, + title, + message, + platformChannelSpecifics, + ); } } diff --git a/lib/services/push_service.dart b/lib/services/push_service.dart index 5c645cc7d..fa6a10e9e 100644 --- a/lib/services/push_service.dart +++ b/lib/services/push_service.dart @@ -61,7 +61,9 @@ class PushService { await _setPushTokenOnServer(fcmToken, apnsToken); await _prefs.setString(kFCMPushToken, fcmToken); await _prefs.setInt( - kLastFCMTokenUpdationTime, DateTime.now().microsecondsSinceEpoch); + kLastFCMTokenUpdationTime, + DateTime.now().microsecondsSinceEpoch, + ); _logger.info("Push token updated on server"); } catch (e) { _logger.severe("Could not set push token", e, StackTrace.current); @@ -88,7 +90,8 @@ class PushService { _logger.info("Message data: ${message.data}"); if (message.notification != null) { _logger.info( - "Message also contained a notification: ${message.notification}"); + "Message also contained a notification: ${message.notification}", + ); } if (shouldSync(message)) { SyncService.instance.sync(); diff --git a/lib/services/remote_sync_service.dart b/lib/services/remote_sync_service.dart index c3efb6757..4a7509be6 100644 --- a/lib/services/remote_sync_service.dart +++ b/lib/services/remote_sync_service.dart @@ -147,7 +147,9 @@ class RemoteSyncService { } for (final c in updatedCollections) { await _syncCollectionDiff( - c.id, _collectionsService.getCollectionSyncTime(c.id)); + c.id, + _collectionsService.getCollectionSyncTime(c.id), + ); await _collectionsService.setCollectionSyncTime(c.id, c.updationTime); } } @@ -156,8 +158,10 @@ class RemoteSyncService { _logger.info('re-sync collections sinceTime: $sinceTime'); final collections = _collectionsService.getActiveCollections(); for (final c in collections) { - await _syncCollectionDiff(c.id, - min(_collectionsService.getCollectionSyncTime(c.id), sinceTime)); + await _syncCollectionDiff( + c.id, + min(_collectionsService.getCollectionSyncTime(c.id), sinceTime), + ); await _collectionsService.setCollectionSyncTime(c.id, c.updationTime); } } @@ -170,17 +174,28 @@ class RemoteSyncService { final deletedFiles = (await FilesDB.instance.getFilesFromIDs(fileIDs)).values.toList(); await FilesDB.instance.deleteFilesFromCollection(collectionID, fileIDs); - Bus.instance.fire(CollectionUpdatedEvent(collectionID, deletedFiles, - type: EventType.deletedFromRemote)); - Bus.instance.fire(LocalPhotosUpdatedEvent(deletedFiles, - type: EventType.deletedFromRemote)); + Bus.instance.fire( + CollectionUpdatedEvent( + collectionID, + deletedFiles, + type: EventType.deletedFromRemote, + ), + ); + Bus.instance.fire( + LocalPhotosUpdatedEvent( + deletedFiles, + type: EventType.deletedFromRemote, + ), + ); } if (diff.updatedFiles.isNotEmpty) { await _storeDiff(diff.updatedFiles, collectionID); - _logger.info("Updated " + - diff.updatedFiles.length.toString() + - " files in collection " + - collectionID.toString()); + _logger.info( + "Updated " + + diff.updatedFiles.length.toString() + + " files in collection " + + collectionID.toString(), + ); Bus.instance.fire(LocalPhotosUpdatedEvent(diff.updatedFiles)); Bus.instance .fire(CollectionUpdatedEvent(collectionID, diff.updatedFiles)); @@ -188,11 +203,15 @@ class RemoteSyncService { if (diff.latestUpdatedAtTime > 0) { await _collectionsService.setCollectionSyncTime( - collectionID, diff.latestUpdatedAtTime); + collectionID, + diff.latestUpdatedAtTime, + ); } if (diff.hasMore) { - return await _syncCollectionDiff(collectionID, - _collectionsService.getCollectionSyncTime(collectionID)); + return await _syncCollectionDiff( + collectionID, + _collectionsService.getCollectionSyncTime(collectionID), + ); } } @@ -213,11 +232,15 @@ class RemoteSyncService { if (filesToBeUploaded.isNotEmpty) { final int prevCount = filesToBeUploaded.length; final ignoredIDs = await IgnoredFilesService.instance.ignoredIDs; - filesToBeUploaded.removeWhere((file) => - IgnoredFilesService.instance.shouldSkipUpload(ignoredIDs, file)); + filesToBeUploaded.removeWhere( + (file) => + IgnoredFilesService.instance.shouldSkipUpload(ignoredIDs, file), + ); if (prevCount != filesToBeUploaded.length) { - _logger.info((prevCount - filesToBeUploaded.length).toString() + - " files were ignored for upload"); + _logger.info( + (prevCount - filesToBeUploaded.length).toString() + + " files were ignored for upload", + ); } } if (filesToBeUploaded.isEmpty) { @@ -227,7 +250,8 @@ class RemoteSyncService { } _sortByTimeAndType(filesToBeUploaded); _logger.info( - filesToBeUploaded.length.toString() + " new files to be uploaded."); + filesToBeUploaded.length.toString() + " new files to be uploaded.", + ); return filesToBeUploaded; } @@ -320,13 +344,21 @@ class RemoteSyncService { _completedUploads < 0 || toBeUploadedInThisSession < 0) { _logger.info( - "Incorrect sync status", - InvalidSyncStatusError("Tried to report $_completedUploads as " - "uploaded out of $toBeUploadedInThisSession")); + "Incorrect sync status", + InvalidSyncStatusError( + "Tried to report $_completedUploads as " + "uploaded out of $toBeUploadedInThisSession", + ), + ); return; } - Bus.instance.fire(SyncStatusUpdate(SyncStatus.in_progress, - completed: _completedUploads, total: toBeUploadedInThisSession)); + Bus.instance.fire( + SyncStatusUpdate( + SyncStatus.in_progress, + completed: _completedUploads, + total: toBeUploadedInThisSession, + ), + ); } Future _storeDiff(List diff, int collectionID) async { @@ -362,17 +394,21 @@ class RemoteSyncService { // case when localID for a file changes and the file is uploaded again in // the same collection final fileWithLocalID = existingFiles.firstWhere( - (e) => - file.localID != null && - e.localID != null && - e.localID == file.localID, - orElse: () => existingFiles.firstWhere((e) => e.localID != null, - orElse: () => null)); + (e) => + file.localID != null && + e.localID != null && + e.localID == file.localID, + orElse: () => existingFiles.firstWhere( + (e) => e.localID != null, + orElse: () => null, + ), + ); if (fileWithLocalID != null) { // File should ideally have the same localID if (file.localID != null && file.localID != fileWithLocalID.localID) { _logger.severe( - "unexpected mismatch in localIDs remote: ${file.toString()} and existing: ${fileWithLocalID.toString()}"); + "unexpected mismatch in localIDs remote: ${file.toString()} and existing: ${fileWithLocalID.toString()}", + ); } file.localID = fileWithLocalID.localID; } else { @@ -384,8 +420,10 @@ class RemoteSyncService { file.generatedID = existingFiles[0].generatedID; if (file.modificationTime != existingFiles[0].modificationTime) { // File was updated since the app was uninstalled - _logger.info("Updated since last installation: " + - file.uploadedFileID.toString()); + _logger.info( + "Updated since last installation: " + + file.uploadedFileID.toString(), + ); file.modificationTime = existingFiles[0].modificationTime; file.updationTime = null; updated++; diff --git a/lib/services/sync_service.dart b/lib/services/sync_service.dart index 7d8dfb04a..a726d34b9 100644 --- a/lib/services/sync_service.dart +++ b/lib/services/sync_service.dart @@ -91,18 +91,28 @@ class SyncService { } on WiFiUnavailableError { _logger.warning("Not uploading over mobile data"); Bus.instance.fire( - SyncStatusUpdate(SyncStatus.paused, reason: "waiting for WiFi...")); + SyncStatusUpdate(SyncStatus.paused, reason: "waiting for WiFi..."), + ); } on SyncStopRequestedError { _syncStopRequested = false; Bus.instance.fire( - SyncStatusUpdate(SyncStatus.completed_backup, wasStopped: true)); + SyncStatusUpdate(SyncStatus.completed_backup, wasStopped: true), + ); } on NoActiveSubscriptionError { - Bus.instance.fire(SyncStatusUpdate(SyncStatus.error, - error: NoActiveSubscriptionError())); + Bus.instance.fire( + SyncStatusUpdate( + SyncStatus.error, + error: NoActiveSubscriptionError(), + ), + ); } on StorageLimitExceededError { _showStorageLimitExceededNotification(); - Bus.instance.fire(SyncStatusUpdate(SyncStatus.error, - error: StorageLimitExceededError())); + Bus.instance.fire( + SyncStatusUpdate( + SyncStatus.error, + error: StorageLimitExceededError(), + ), + ); } on UnauthorizedError { _logger.info("Logging user out"); Bus.instance.fire(TriggerLogoutEvent()); @@ -112,8 +122,12 @@ class SyncService { e.type == DioErrorType.sendTimeout || e.type == DioErrorType.receiveTimeout || e.type == DioErrorType.other) { - Bus.instance.fire(SyncStatusUpdate(SyncStatus.paused, - reason: "waiting for network...")); + Bus.instance.fire( + SyncStatusUpdate( + SyncStatus.paused, + reason: "waiting for network...", + ), + ); _logger.severe("unable to connect", e, StackTrace.current); return false; } @@ -155,15 +169,21 @@ class SyncService { } void onFoldersSet(Set paths) { - _uploader.removeFromQueueWhere((file) { - return !paths.contains(file.deviceFolder); - }, UserCancelledUploadError()); + _uploader.removeFromQueueWhere( + (file) { + return !paths.contains(file.deviceFolder); + }, + UserCancelledUploadError(), + ); } void onVideoBackupPaused() { - _uploader.removeFromQueueWhere((file) { - return file.fileType == FileType.video; - }, UserCancelledUploadError()); + _uploader.removeFromQueueWhere( + (file) { + return file.fileType == FileType.video; + }, + UserCancelledUploadError(), + ); } Future deleteFilesOnServer(List fileIDs) async { @@ -224,7 +244,9 @@ class SyncService { if ((now - lastNotificationShownTime) > kMicroSecondsInDay) { await _prefs.setInt(kLastStorageLimitExceededNotificationPushTime, now); NotificationService.instance.showNotification( - "storage limit exceeded", "sorry, we had to pause your backups"); + "storage limit exceeded", + "sorry, we had to pause your backups", + ); } } } diff --git a/lib/services/trash_sync_service.dart b/lib/services/trash_sync_service.dart index 091d7a1b6..24664223f 100644 --- a/lib/services/trash_sync_service.dart +++ b/lib/services/trash_sync_service.dart @@ -113,7 +113,8 @@ class TrashSyncService { } Future> _trashFiles( - Map requestData) async { + Map requestData, + ) async { return _dio.post( Configuration.instance.getHttpEndpoint() + "/files/trash", options: Options( diff --git a/lib/services/update_service.dart b/lib/services/update_service.dart index 5d2186e8c..dfdd69dc0 100644 --- a/lib/services/update_service.dart +++ b/lib/services/update_service.dart @@ -69,7 +69,9 @@ class UpdateService { hasBeen3DaysSinceLastNotification && _latestVersion.shouldNotify) { NotificationService.instance.showNotification( - "update available", "click to install our best version yet"); + "update available", + "click to install our best version yet", + ); await _prefs.setInt(kUpdateAvailableShownTimeKey, now); } else { _logger.info("Debouncing notification"); diff --git a/lib/services/user_service.dart b/lib/services/user_service.dart index 781561ac6..47b44c6ec 100644 --- a/lib/services/user_service.dart +++ b/lib/services/user_service.dart @@ -59,9 +59,11 @@ class UserService { Navigator.of(context).push( MaterialPageRoute( builder: (BuildContext context) { - return OTTVerificationPage(email, - isChangeEmail: isChangeEmail, - isCreateAccountScreen: isCreateAccountScreen); + return OTTVerificationPage( + email, + isChangeEmail: isChangeEmail, + isCreateAccountScreen: isCreateAccountScreen, + ); }, ), ); @@ -143,15 +145,17 @@ class UserService { Future terminateSession(String token) async { try { - await _dio.delete(_config.getHttpEndpoint() + "/users/session", - options: Options( - headers: { - "X-Auth-Token": _config.getToken(), - }, - ), - queryParameters: { - "token": token, - }); + await _dio.delete( + _config.getHttpEndpoint() + "/users/session", + options: Options( + headers: { + "X-Auth-Token": _config.getToken(), + }, + ), + queryParameters: { + "token": token, + }, + ); } on DioError catch (e) { _logger.info(e); rethrow; @@ -160,12 +164,14 @@ class UserService { Future leaveFamilyPlan() async { try { - await _dio.delete(_config.getHttpEndpoint() + "/family/leave", - options: Options( - headers: { - "X-Auth-Token": _config.getToken(), - }, - )); + await _dio.delete( + _config.getHttpEndpoint() + "/family/leave", + options: Options( + headers: { + "X-Auth-Token": _config.getToken(), + }, + ), + ); } on DioError catch (e) { _logger.warning('failed to leave family plan', e); rethrow; @@ -176,13 +182,14 @@ class UserService { final dialog = createProgressDialog(context, "Logging out..."); await dialog.show(); try { - final response = - await _dio.post(_config.getHttpEndpoint() + "/users/logout", - options: Options( - headers: { - "X-Auth-Token": _config.getToken(), - }, - )); + final response = await _dio.post( + _config.getHttpEndpoint() + "/users/logout", + options: Options( + headers: { + "X-Auth-Token": _config.getToken(), + }, + ), + ); if (response != null && response.statusCode == 200) { await Configuration.instance.logout(); await dialog.hide(); @@ -240,11 +247,17 @@ class UserService { await dialog.hide(); if (e.response != null && e.response.statusCode == 410) { await showErrorDialog( - context, "Oops", "Your verification code has expired"); + context, + "Oops", + "Your verification code has expired", + ); Navigator.of(context).pop(); } else { - showErrorDialog(context, "Incorrect code", - "Sorry, the code you've entered is incorrect"); + showErrorDialog( + context, + "Incorrect code", + "Sorry, the code you've entered is incorrect", + ); } } catch (e) { await dialog.hide(); @@ -287,8 +300,11 @@ class UserService { if (e.response != null && e.response.statusCode == 403) { showErrorDialog(context, "Oops", "This email is already in use"); } else { - showErrorDialog(context, "Incorrect code", - "Authentication failed, please try again"); + showErrorDialog( + context, + "Incorrect code", + "Authentication failed, please try again", + ); } } catch (e) { await dialog.hide(); @@ -371,7 +387,10 @@ class UserService { } Future verifyTwoFactor( - BuildContext context, String sessionID, String code) async { + BuildContext context, + String sessionID, + String code, + ) async { final dialog = createProgressDialog(context, "Authenticating..."); await dialog.show(); try { @@ -409,14 +428,20 @@ class UserService { (route) => route.isFirst, ); } else { - showErrorDialog(context, "Incorrect code", - "Authentication failed, please try again"); + showErrorDialog( + context, + "Incorrect code", + "Authentication failed, please try again", + ); } } catch (e) { await dialog.hide(); _logger.severe(e); showErrorDialog( - context, "Oops", "Authentication failed, please try again"); + context, + "Oops", + "Authentication failed, please try again", + ); } } @@ -435,9 +460,10 @@ class UserService { MaterialPageRoute( builder: (BuildContext context) { return TwoFactorRecoveryPage( - sessionID, - response.data["encryptedSecret"], - response.data["secretDecryptionNonce"]); + sessionID, + response.data["encryptedSecret"], + response.data["secretDecryptionNonce"], + ); }, ), (route) => route.isFirst, @@ -457,12 +483,18 @@ class UserService { ); } else { showErrorDialog( - context, "Oops", "Something went wrong, please try again"); + context, + "Oops", + "Something went wrong, please try again", + ); } } catch (e) { _logger.severe(e); showErrorDialog( - context, "Oops", "Something went wrong, please try again"); + context, + "Oops", + "Something went wrong, please try again", + ); } finally { await dialog.hide(); } @@ -479,14 +511,20 @@ class UserService { await dialog.show(); String secret; try { - secret = Sodium.bin2base64(await CryptoUtil.decrypt( + secret = Sodium.bin2base64( + await CryptoUtil.decrypt( Sodium.base642bin(encryptedSecret), Sodium.hex2bin(recoveryKey.trim()), - Sodium.base642bin(secretDecryptionNonce))); + Sodium.base642bin(secretDecryptionNonce), + ), + ); } catch (e) { await dialog.hide(); - showErrorDialog(context, "Incorrect recovery key", - "The recovery key you entered is incorrect"); + showErrorDialog( + context, + "Incorrect recovery key", + "The recovery key you entered is incorrect", + ); return; } try { @@ -523,12 +561,18 @@ class UserService { ); } else { showErrorDialog( - context, "Oops", "Something went wrong, please try again"); + context, + "Oops", + "Something went wrong, please try again", + ); } } catch (e) { _logger.severe(e); showErrorDialog( - context, "Oops", "Something went wrong, please try again"); + context, + "Oops", + "Something went wrong, please try again", + ); } finally { await dialog.hide(); } @@ -548,9 +592,12 @@ class UserService { ); await dialog.hide(); routeToPage( - context, - TwoFactorSetupPage( - response.data["secretCode"], response.data["qrCode"])); + context, + TwoFactorSetupPage( + response.data["secretCode"], + response.data["qrCode"], + ), + ); } catch (e, s) { await dialog.hide(); _logger.severe(e, s); @@ -559,7 +606,10 @@ class UserService { } Future enableTwoFactor( - BuildContext context, String secret, String code) async { + BuildContext context, + String secret, + String code, + ) async { Uint8List recoveryKey; try { recoveryKey = await getOrCreateRecoveryKey(context); @@ -596,13 +646,19 @@ class UserService { _logger.severe(e, s); if (e is DioError) { if (e.response != null && e.response.statusCode == 401) { - showErrorDialog(context, "Incorrect code", - "Please verify the code you have entered"); + showErrorDialog( + context, + "Incorrect code", + "Please verify the code you have entered", + ); return false; } } - showErrorDialog(context, "Something went wrong", - "Please contact support if the problem persists"); + showErrorDialog( + context, + "Something went wrong", + "Please contact support if the problem persists", + ); } return false; } @@ -626,8 +682,11 @@ class UserService { } catch (e, s) { await dialog.hide(); _logger.severe(e, s); - showErrorDialog(context, "Something went wrong", - "Please contact support if the problem persists"); + showErrorDialog( + context, + "Something went wrong", + "Please contact support if the problem persists", + ); } } @@ -716,7 +775,8 @@ class UserService { await Configuration.instance .setEncryptedToken(response.data["encryptedToken"]); await Configuration.instance.setKeyAttributes( - KeyAttributes.fromMap(response.data["keyAttributes"])); + KeyAttributes.fromMap(response.data["keyAttributes"]), + ); } else { await Configuration.instance.setToken(response.data["token"]); } diff --git a/lib/ui/app_lock.dart b/lib/ui/app_lock.dart index 74f1c63ad..73b236681 100644 --- a/lib/ui/app_lock.dart +++ b/lib/ui/app_lock.dart @@ -106,11 +106,13 @@ class _AppLockState extends State with WidgetsBindingObserver { switch (settings.name) { case '/lock-screen': return PageRouteBuilder( - pageBuilder: (_, __, ___) => this._lockScreen); + pageBuilder: (_, __, ___) => this._lockScreen, + ); case '/unlocked': return PageRouteBuilder( - pageBuilder: (_, __, ___) => - this.widget.builder(settings.arguments)); + pageBuilder: (_, __, ___) => + this.widget.builder(settings.arguments), + ); } return PageRouteBuilder(pageBuilder: (_, __, ___) => this._lockScreen); }, diff --git a/lib/ui/app_update_dialog.dart b/lib/ui/app_update_dialog.dart index 30b16db13..e68492028 100644 --- a/lib/ui/app_update_dialog.dart +++ b/lib/ui/app_update_dialog.dart @@ -19,10 +19,12 @@ class _AppUpdateDialogState extends State { Widget build(BuildContext context) { final List changelog = []; for (final log in widget.latestVersionInfo.changelog) { - changelog.add(Padding( - padding: const EdgeInsets.fromLTRB(8, 4, 0, 4), - child: Text("- " + log, style: Theme.of(context).textTheme.caption), - )); + changelog.add( + Padding( + padding: const EdgeInsets.fromLTRB(8, 4, 0, 4), + child: Text("- " + log, style: Theme.of(context).textTheme.caption), + ), + ); } final content = Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -36,10 +38,12 @@ class _AppUpdateDialogState extends State { ), ), Padding(padding: EdgeInsets.all(8)), - Text("Changelog", - style: TextStyle( - fontSize: 18, - )), + Text( + "Changelog", + style: TextStyle( + fontSize: 18, + ), + ), Padding(padding: EdgeInsets.all(4)), Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -79,9 +83,9 @@ class _AppUpdateDialogState extends State { return WillPopScope( onWillPop: () async => !shouldForceUpdate, child: AlertDialog( - title: Text(shouldForceUpdate - ? "Critical update available" - : "Update available"), + title: Text( + shouldForceUpdate ? "Critical update available" : "Update available", + ), content: content, ), ); @@ -134,12 +138,15 @@ class _ApkDownloaderDialogState extends State { Future _downloadApk() async { try { - await Network.instance.getDio().download(widget.versionInfo.url, _saveUrl, - onReceiveProgress: (count, _) { - setState(() { - _downloadProgress = count / widget.versionInfo.size; - }); - }); + await Network.instance.getDio().download( + widget.versionInfo.url, + _saveUrl, + onReceiveProgress: (count, _) { + setState(() { + _downloadProgress = count / widget.versionInfo.size; + }); + }, + ); Navigator.of(context, rootNavigator: true).pop('dialog'); OpenFile.open(_saveUrl); } catch (e) { diff --git a/lib/ui/archive_page.dart b/lib/ui/archive_page.dart index 284cd2528..996e8a9e9 100644 --- a/lib/ui/archive_page.dart +++ b/lib/ui/archive_page.dart @@ -16,26 +16,32 @@ class ArchivePage extends StatelessWidget { final GalleryType overlayType; final _selectedFiles = SelectedFiles(); - ArchivePage( - {this.tagPrefix = "archived_page", - this.appBarType = GalleryType.archive, - this.overlayType = GalleryType.archive, - Key key}) - : super(key: key); + ArchivePage({ + this.tagPrefix = "archived_page", + this.appBarType = GalleryType.archive, + this.overlayType = GalleryType.archive, + Key key, + }) : super(key: key); @override Widget build(Object context) { final gallery = Gallery( asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) { - return FilesDB.instance.getAllUploadedFiles(creationStartTime, - creationEndTime, Configuration.instance.getUserID(), - visibility: kVisibilityArchive, limit: limit, asc: asc); + return FilesDB.instance.getAllUploadedFiles( + creationStartTime, + creationEndTime, + Configuration.instance.getUserID(), + visibility: kVisibilityArchive, + limit: limit, + asc: asc, + ); }, reloadEvent: Bus.instance.on().where( (event) => event.updatedFiles.firstWhere( - (element) => element.uploadedFileID != null, - orElse: () => null) != + (element) => element.uploadedFileID != null, + orElse: () => null, + ) != null, ), removalEventTypes: const {EventType.unarchived}, @@ -43,8 +49,9 @@ class ArchivePage extends StatelessWidget { Bus.instance.on().where( (event) => event.updatedFiles.firstWhere( - (element) => element.uploadedFileID != null, - orElse: () => null) != + (element) => element.uploadedFileID != null, + orElse: () => null, + ) != null, ), ], diff --git a/lib/ui/backup_folder_selection_page.dart b/lib/ui/backup_folder_selection_page.dart index b0e552169..1caa8e027 100644 --- a/lib/ui/backup_folder_selection_page.dart +++ b/lib/ui/backup_folder_selection_page.dart @@ -133,21 +133,28 @@ class _BackupFolderSelectionPageState extends State { .compareTo(second.deviceFolder.toLowerCase()); }); setState(() {}); - }), + }, + ), Expanded(child: _getFolders()), Hero( tag: "select_folders", child: Container( width: double.infinity, - decoration: BoxDecoration(boxShadow: [ - BoxShadow( + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( color: Theme.of(context).backgroundColor, blurRadius: 24, offset: Offset(0, -8), - spreadRadius: 4) - ]), + spreadRadius: 4, + ) + ], + ), padding: EdgeInsets.only( - left: 20, right: 20, bottom: Platform.isIOS ? 60 : 32), + left: 20, + right: 20, + bottom: Platform.isIOS ? 60 : 32, + ), child: OutlinedButton( child: Text(widget.buttonText), onPressed: _selectedFolders.isEmpty @@ -226,24 +233,26 @@ class _BackupFolderSelectionPageState extends State { padding: const EdgeInsets.only(bottom: 1, right: 1), child: Container( decoration: BoxDecoration( - border: Border.all( - color: Theme.of(context).colorScheme.boxUnSelectColor, - ), - borderRadius: BorderRadius.all( - Radius.circular(12), - ), - // color: isSelected - // ? Theme.of(context).colorScheme.boxSelectColor - // : Theme.of(context).colorScheme.boxUnSelectColor, - gradient: isSelected - ? LinearGradient(colors: const [ - Color(0xFF00DD4D), - Color(0xFF43BA6C) - ]) //same for both themes - : LinearGradient(colors: [ + border: Border.all( + color: Theme.of(context).colorScheme.boxUnSelectColor, + ), + borderRadius: BorderRadius.all( + Radius.circular(12), + ), + // color: isSelected + // ? Theme.of(context).colorScheme.boxSelectColor + // : Theme.of(context).colorScheme.boxUnSelectColor, + gradient: isSelected + ? LinearGradient( + colors: const [Color(0xFF00DD4D), Color(0xFF43BA6C)], + ) //same for both themes + : LinearGradient( + colors: [ Theme.of(context).colorScheme.boxUnSelectColor, Theme.of(context).colorScheme.boxUnSelectColor - ])), + ], + ), + ), padding: EdgeInsets.fromLTRB(8, 4, 4, 4), child: InkWell( child: Row( @@ -343,21 +352,25 @@ class _BackupFolderSelectionPageState extends State { return ClipRRect( borderRadius: BorderRadius.circular(8), child: SizedBox( - child: Stack(alignment: AlignmentDirectional.bottomEnd, children: [ - ThumbnailWidget( - file, - shouldShowSyncStatus: false, - key: Key("backup_selection_widget" + file.tag()), - ), - Padding( + child: Stack( + alignment: AlignmentDirectional.bottomEnd, + children: [ + ThumbnailWidget( + file, + shouldShowSyncStatus: false, + key: Key("backup_selection_widget" + file.tag()), + ), + Padding( padding: const EdgeInsets.all(9), child: isSelected ? Icon( Icons.local_police, color: Colors.white, ) - : null), - ]), + : null, + ), + ], + ), height: 88, width: 88, ), diff --git a/lib/ui/billing_questions_widget.dart b/lib/ui/billing_questions_widget.dart index 816007667..4cc454b88 100644 --- a/lib/ui/billing_questions_widget.dart +++ b/lib/ui/billing_questions_widget.dart @@ -26,22 +26,26 @@ class BillingQuestionsWidget extends StatelessWidget { builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasData) { final faqs = []; - faqs.add(Padding( - padding: const EdgeInsets.all(24), - child: Text( - "FAQs", - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, + faqs.add( + Padding( + padding: const EdgeInsets.all(24), + child: Text( + "FAQs", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), ), ), - )); + ); for (final faq in snapshot.data) { faqs.add(FaqWidget(faq: faq)); } - faqs.add(Padding( - padding: EdgeInsets.all(16), - )); + faqs.add( + Padding( + padding: EdgeInsets.all(16), + ), + ); return SingleChildScrollView( child: Column( children: faqs, diff --git a/lib/ui/change_email_dialog.dart b/lib/ui/change_email_dialog.dart index 7c2a3d876..f1d95f6d0 100644 --- a/lib/ui/change_email_dialog.dart +++ b/lib/ui/change_email_dialog.dart @@ -64,8 +64,11 @@ class _ChangeEmailDialogState extends State { ), onPressed: () { if (!isValidEmail(_email)) { - showErrorDialog(context, "Invalid email address", - "Please enter a valid email address."); + showErrorDialog( + context, + "Invalid email address", + "Please enter a valid email address.", + ); return; } UserService.instance.getOtt(context, _email, isChangeEmail: true); diff --git a/lib/ui/collection_page.dart b/lib/ui/collection_page.dart index d997627b6..eb9427e5a 100644 --- a/lib/ui/collection_page.dart +++ b/lib/ui/collection_page.dart @@ -17,12 +17,13 @@ class CollectionPage extends StatelessWidget { final GalleryType overlayType; final _selectedFiles = SelectedFiles(); - CollectionPage(this.c, - {this.tagPrefix = "collection", - this.appBarType = GalleryType.owned_collection, - this.overlayType = GalleryType.owned_collection, - Key key}) - : super(key: key); + CollectionPage( + this.c, { + this.tagPrefix = "collection", + this.appBarType = GalleryType.owned_collection, + this.overlayType = GalleryType.owned_collection, + Key key, + }) : super(key: key); @override Widget build(Object context) { @@ -30,8 +31,12 @@ class CollectionPage extends StatelessWidget { final gallery = Gallery( asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) { return FilesDB.instance.getFilesInCollection( - c.collection.id, creationStartTime, creationEndTime, - limit: limit, asc: asc); + c.collection.id, + creationStartTime, + creationEndTime, + limit: limit, + asc: asc, + ); }, reloadEvent: Bus.instance .on() diff --git a/lib/ui/collections_gallery_widget.dart b/lib/ui/collections_gallery_widget.dart index e3d462e92..cb439719a 100644 --- a/lib/ui/collections_gallery_widget.dart +++ b/lib/ui/collections_gallery_widget.dart @@ -100,8 +100,10 @@ class _CollectionsGalleryWidgetState extends State for (final file in latestLocalFiles) { folders.add(DeviceFolder(file.deviceFolder, file.deviceFolder, file)); } - folders.sort((first, second) => - second.thumbnail.creationTime.compareTo(first.thumbnail.creationTime)); + folders.sort( + (first, second) => + second.thumbnail.creationTime.compareTo(first.thumbnail.creationTime), + ); final List collectionsWithThumbnail = []; final latestCollectionFiles = @@ -136,8 +138,8 @@ class _CollectionsGalleryWidgetState extends State .textTheme .subtitle1 .copyWith( - color: - Theme.of(context).textTheme.subtitle1.color.withOpacity(0.5)); + color: Theme.of(context).textTheme.subtitle1.color.withOpacity(0.5), + ); Size size = MediaQuery.of(context).size; int albumsCountInOneRow = max(size.width ~/ 220.0, 2); final double sideOfThumbnail = (size.width / 2) - @@ -155,8 +157,8 @@ class _CollectionsGalleryWidgetState extends State ? Padding( padding: const EdgeInsets.all(22), child: nothingToSeeHere( - textColor: - Theme.of(context).colorScheme.defaultTextColor), + textColor: Theme.of(context).colorScheme.defaultTextColor, + ), ) : Padding( padding: const EdgeInsets.symmetric(horizontal: 8), @@ -168,7 +170,8 @@ class _CollectionsGalleryWidgetState extends State ? nothingToSeeHere( textColor: Theme.of(context) .colorScheme - .defaultTextColor) + .defaultTextColor, + ) : ListView.builder( shrinkWrap: true, scrollDirection: Axis.horizontal, @@ -203,21 +206,25 @@ class _CollectionsGalleryWidgetState extends State // to disable GridView's scrolling itemBuilder: (context, index) { return _buildCollection( - context, items.collections, index); + context, + items.collections, + index, + ); }, itemCount: items.collections.length + 1, // To include the + button gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: albumsCountInOneRow, - mainAxisSpacing: 12, - crossAxisSpacing: crossAxisSpacingOfGrid, - childAspectRatio: sideOfThumbnail / - (sideOfThumbnail + - 24)), //24 is height of album title + crossAxisCount: albumsCountInOneRow, + mainAxisSpacing: 12, + crossAxisSpacing: crossAxisSpacingOfGrid, + childAspectRatio: + sideOfThumbnail / (sideOfThumbnail + 24), + ), //24 is height of album title ), ) : nothingToSeeHere( - textColor: Theme.of(context).colorScheme.defaultTextColor), + textColor: Theme.of(context).colorScheme.defaultTextColor, + ), const SizedBox(height: 10), const Divider(), const Padding(padding: EdgeInsets.all(8)), @@ -258,31 +265,38 @@ class _CollectionsGalleryWidgetState extends State builder: (context, snapshot) { if (snapshot.hasData && snapshot.data > 0) { return RichText( - text: TextSpan( - style: trashAndHiddenTextStyle, - children: [ + text: TextSpan( + style: trashAndHiddenTextStyle, + children: [ TextSpan( - text: "Trash", - style: Theme.of(context) - .textTheme - .subtitle1), + text: "Trash", + style: Theme.of(context) + .textTheme + .subtitle1, + ), TextSpan(text: " \u2022 "), TextSpan( - text: snapshot.data.toString()), + text: snapshot.data.toString(), + ), //need to query in db and bring this value - ])); + ], + ), + ); } else { return RichText( - text: TextSpan( - style: trashAndHiddenTextStyle, - children: [ + text: TextSpan( + style: trashAndHiddenTextStyle, + children: [ TextSpan( - text: "Trash", - style: Theme.of(context) - .textTheme - .subtitle1), + text: "Trash", + style: Theme.of(context) + .textTheme + .subtitle1, + ), //need to query in db and bring this value - ])); + ], + ), + ); } }, ), @@ -333,38 +347,46 @@ class _CollectionsGalleryWidgetState extends State ), Padding(padding: EdgeInsets.all(6)), FutureBuilder( - future: FilesDB.instance - .fileCountWithVisibility( - kVisibilityArchive, - Configuration.instance.getUserID()), + future: + FilesDB.instance.fileCountWithVisibility( + kVisibilityArchive, + Configuration.instance.getUserID(), + ), builder: (context, snapshot) { if (snapshot.hasData && snapshot.data > 0) { return RichText( - text: TextSpan( - style: trashAndHiddenTextStyle, - children: [ + text: TextSpan( + style: trashAndHiddenTextStyle, + children: [ TextSpan( - text: "Hidden", - style: Theme.of(context) - .textTheme - .subtitle1), + text: "Hidden", + style: Theme.of(context) + .textTheme + .subtitle1, + ), TextSpan(text: " \u2022 "), TextSpan( - text: snapshot.data.toString()), + text: snapshot.data.toString(), + ), //need to query in db and bring this value - ])); + ], + ), + ); } else { return RichText( - text: TextSpan( - style: trashAndHiddenTextStyle, - children: [ + text: TextSpan( + style: trashAndHiddenTextStyle, + children: [ TextSpan( - text: "Hidden", - style: Theme.of(context) - .textTheme - .subtitle1), + text: "Hidden", + style: Theme.of(context) + .textTheme + .subtitle1, + ), //need to query in db and bring this value - ])); + ], + ), + ); } }, ), @@ -408,10 +430,13 @@ class _CollectionsGalleryWidgetState extends State case AlbumSortKey.lastUpdated: text = "Last updated"; } - return Text(text, - style: Theme.of(context).textTheme.subtitle1.copyWith( + return Text( + text, + style: Theme.of(context).textTheme.subtitle1.copyWith( fontSize: 14, - color: Theme.of(context).iconTheme.color.withOpacity(0.7))); + color: Theme.of(context).iconTheme.color.withOpacity(0.7), + ), + ); } return Padding( @@ -460,8 +485,11 @@ class _CollectionsGalleryWidgetState extends State ); } - Widget _buildCollection(BuildContext context, - List collections, int index) { + Widget _buildCollection( + BuildContext context, + List collections, + int index, + ) { if (index < collections.length) { final c = collections[index]; return CollectionItem(c); @@ -473,10 +501,11 @@ class _CollectionsGalleryWidgetState extends State color: Theme.of(context).backgroundColor, boxShadow: [ BoxShadow( - blurRadius: 2, - spreadRadius: 0, - offset: Offset(0, 0), - color: Theme.of(context).iconTheme.color.withOpacity(0.3)) + blurRadius: 2, + spreadRadius: 0, + offset: Offset(0, 0), + color: Theme.of(context).iconTheme.color.withOpacity(0.3), + ) ], borderRadius: BorderRadius.circular(4), ), @@ -486,9 +515,11 @@ class _CollectionsGalleryWidgetState extends State ), ), onTap: () async { - await showToast(context, - "long press to select photos and click + to create an album", - toastLength: Toast.LENGTH_LONG); + await showToast( + context, + "long press to select photos and click + to create an album", + toastLength: Toast.LENGTH_LONG, + ); Bus.instance .fire(TabChangedEvent(0, TabChangedEventSource.collections_page)); }, @@ -566,9 +597,11 @@ class DeviceFolderIcon extends StatelessWidget { ThumbnailWidget( folder.thumbnail, shouldShowSyncStatus: false, - key: Key("device_folder:" + - folder.path + - folder.thumbnail.tag()), + key: Key( + "device_folder:" + + folder.path + + folder.thumbnail.tag(), + ), ), isBackedUp ? Container() : kUnsyncedIconOverlay, ], @@ -623,17 +656,19 @@ class CollectionItem extends StatelessWidget { ClipRRect( borderRadius: BorderRadius.circular(4), child: SizedBox( - child: Hero( - tag: "collection" + c.thumbnail.tag(), - child: ThumbnailWidget( - c.thumbnail, - shouldShowArchiveStatus: c.collection.isArchived(), - key: Key( - "collection" + c.thumbnail.tag(), - ), - )), - height: sideOfThumbnail, - width: sideOfThumbnail), + child: Hero( + tag: "collection" + c.thumbnail.tag(), + child: ThumbnailWidget( + c.thumbnail, + shouldShowArchiveStatus: c.collection.isArchived(), + key: Key( + "collection" + c.thumbnail.tag(), + ), + ), + ), + height: sideOfThumbnail, + width: sideOfThumbnail, + ), ), SizedBox(height: 4), Row( @@ -651,15 +686,17 @@ class CollectionItem extends StatelessWidget { builder: (context, snapshot) { if (snapshot.hasData && snapshot.data > 0) { return RichText( - text: TextSpan( - style: albumTitleTextStyle.copyWith( - color: - albumTitleTextStyle.color.withOpacity(0.5)), - children: [ + text: TextSpan( + style: albumTitleTextStyle.copyWith( + color: albumTitleTextStyle.color.withOpacity(0.5), + ), + children: [ TextSpan(text: " \u2022 "), TextSpan(text: snapshot.data.toString()), //need to query in db and bring this value - ])); + ], + ), + ); } else { return Container(); } diff --git a/lib/ui/common/bottomShadow.dart b/lib/ui/common/bottomShadow.dart index 42af573b4..dafe4503c 100644 --- a/lib/ui/common/bottomShadow.dart +++ b/lib/ui/common/bottomShadow.dart @@ -14,13 +14,13 @@ class BottomShadowWidget extends StatelessWidget { color: Colors.transparent, boxShadow: [ BoxShadow( - color: shadowColor == null - ? Theme.of(context).backgroundColor - : shadowColor, - spreadRadius: 42, - blurRadius: 42, - offset: Offset(0, offsetDy) // changes position of shadow - ), + color: shadowColor == null + ? Theme.of(context).backgroundColor + : shadowColor, + spreadRadius: 42, + blurRadius: 42, + offset: Offset(0, offsetDy), // changes position of shadow + ), ], ), ); diff --git a/lib/ui/common/dynamicFAB.dart b/lib/ui/common/dynamicFAB.dart index 6575a7942..74e4c5dd9 100644 --- a/lib/ui/common/dynamicFAB.dart +++ b/lib/ui/common/dynamicFAB.dart @@ -9,13 +9,13 @@ class DynamicFAB extends StatelessWidget { final String buttonText; final Function onPressedFunction; - DynamicFAB( - {Key key, - this.isKeypadOpen, - this.buttonText, - this.isFormValid, - this.onPressedFunction}) - : super(key: key); + DynamicFAB({ + Key key, + this.isKeypadOpen, + this.buttonText, + this.isFormValid, + this.onPressedFunction, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -36,24 +36,24 @@ class DynamicFAB extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.end, children: [ FloatingActionButton( - heroTag: 'FAB', - backgroundColor: - Theme.of(context).colorScheme.dynamicFABBackgroundColor, - foregroundColor: - Theme.of(context).colorScheme.dynamicFABTextColor, - child: Transform.rotate( - angle: isFormValid ? 0 : math.pi / 2, - child: Icon( - Icons.chevron_right, - size: 36, - ), - ), - onPressed: isFormValid - ? onPressedFunction - : () { - FocusScope.of(context).unfocus(); - } //keypad down here + heroTag: 'FAB', + backgroundColor: + Theme.of(context).colorScheme.dynamicFABBackgroundColor, + foregroundColor: + Theme.of(context).colorScheme.dynamicFABTextColor, + child: Transform.rotate( + angle: isFormValid ? 0 : math.pi / 2, + child: Icon( + Icons.chevron_right, + size: 36, ), + ), + onPressed: isFormValid + ? onPressedFunction + : () { + FocusScope.of(context).unfocus(); + }, //keypad down here + ), ], ), ); diff --git a/lib/ui/common/onlyOuterShadow.dart b/lib/ui/common/onlyOuterShadow.dart index fea9b32db..c4ed4adb8 100644 --- a/lib/ui/common/onlyOuterShadow.dart +++ b/lib/ui/common/onlyOuterShadow.dart @@ -10,20 +10,23 @@ class onlyOuterShadow extends BoxShadow { double spreadRadius = 0.0, this.blurStyle = BlurStyle.normal, }) : super( - color: color, - offset: offset, - blurRadius: blurRadius, - spreadRadius: spreadRadius); + color: color, + offset: offset, + blurRadius: blurRadius, + spreadRadius: spreadRadius, + ); @override Paint toPaint() { final Paint result = Paint() ..color = color ..maskFilter = MaskFilter.blur(this.blurStyle, blurSigma); - assert(() { - if (debugDisableShadows) result.maskFilter = null; - return true; - }()); + assert( + () { + if (debugDisableShadows) result.maskFilter = null; + return true; + }(), + ); return result; } } diff --git a/lib/ui/common/report_bug_popup.dart b/lib/ui/common/report_bug_popup.dart index cf8c3199a..be5f1c9d2 100644 --- a/lib/ui/common/report_bug_popup.dart +++ b/lib/ui/common/report_bug_popup.dart @@ -19,8 +19,12 @@ PopupMenuButton reportBugPopupMenu(BuildContext context) { }, onSelected: (value) async { if (value == 1) { - await sendLogs(context, "Contact support", "support@ente.io", - postShare: () {}); + await sendLogs( + context, + "Contact support", + "support@ente.io", + postShare: () {}, + ); } }, ); diff --git a/lib/ui/create_collection_page.dart b/lib/ui/create_collection_page.dart index 94b78807f..cfd487153 100644 --- a/lib/ui/create_collection_page.dart +++ b/lib/ui/create_collection_page.dart @@ -43,9 +43,12 @@ class CreateCollectionPage extends StatefulWidget { final List sharedFiles; final CollectionActionType actionType; - const CreateCollectionPage(this.selectedFiles, this.sharedFiles, - {Key key, this.actionType = CollectionActionType.addFiles}) - : super(key: key); + const CreateCollectionPage( + this.selectedFiles, + this.sharedFiles, { + Key key, + this.actionType = CollectionActionType.addFiles, + }) : super(key: key); @override _CreateCollectionPageState createState() => _CreateCollectionPageState(); @@ -78,7 +81,11 @@ class _CreateCollectionPageState extends State { Expanded( child: Padding( padding: const EdgeInsets.only( - top: 30, bottom: 12, left: 40, right: 40), + top: 30, + bottom: 12, + left: 40, + right: 40, + ), child: GradientButton( child: Row( mainAxisAlignment: MainAxisAlignment.center, @@ -182,10 +189,11 @@ class _CreateCollectionPageState extends State { onTap: () async { if (await _runCollectionAction(item.collection.id)) { showShortToast( - context, - widget.actionType == CollectionActionType.addFiles - ? "Added successfully to " + item.collection.name - : "Moved successfully to " + item.collection.name); + context, + widget.actionType == CollectionActionType.addFiles + ? "Added successfully to " + item.collection.name + : "Moved successfully to " + item.collection.name, + ); _navigateToCollection(item.collection); } }, @@ -243,10 +251,14 @@ class _CreateCollectionPageState extends State { if (await _runCollectionAction(collection.id)) { if (widget.actionType == CollectionActionType.restoreFiles) { showShortToast( - context, 'Restored files to album ' + _albumName); + context, + 'Restored files to album ' + _albumName, + ); } else { showShortToast( - context, "Album '" + _albumName + "' created."); + context, + "Album '" + _albumName + "' created.", + ); } _navigateToCollection(collection); } @@ -267,12 +279,14 @@ class _CreateCollectionPageState extends State { void _navigateToCollection(Collection collection) { Navigator.pop(context); Navigator.push( - context, - PageTransition( - type: PageTransitionType.bottomToTop, - child: CollectionPage( - CollectionWithThumbnail(collection, null), - ))); + context, + PageTransition( + type: PageTransitionType.bottomToTop, + child: CollectionPage( + CollectionWithThumbnail(collection, null), + ), + ), + ); } Future _runCollectionAction(int collectionID) async { @@ -292,8 +306,11 @@ class _CreateCollectionPageState extends State { await dialog.show(); try { int fromCollectionID = widget.selectedFiles.files?.first?.collectionID; - await CollectionsService.instance.move(toCollectionID, fromCollectionID, - widget.selectedFiles.files?.toList()); + await CollectionsService.instance.move( + toCollectionID, + fromCollectionID, + widget.selectedFiles.files?.toList(), + ); RemoteSyncService.instance.sync(silently: true); widget.selectedFiles?.clearAll(); await dialog.hide(); @@ -339,8 +356,12 @@ class _CreateCollectionPageState extends State { final List files = []; final List filesPendingUpload = []; if (widget.sharedFiles != null) { - filesPendingUpload.addAll(await convertIncomingSharedMediaToFile( - widget.sharedFiles, collectionID)); + filesPendingUpload.addAll( + await convertIncomingSharedMediaToFile( + widget.sharedFiles, + collectionID, + ), + ); } else { final List filesPendingUpload = []; for (final file in widget.selectedFiles.files) { diff --git a/lib/ui/deduplicate_page.dart b/lib/ui/deduplicate_page.dart index fa5658158..bcd6181c0 100644 --- a/lib/ui/deduplicate_page.dart +++ b/lib/ui/deduplicate_page.dart @@ -126,15 +126,17 @@ class _DeduplicatePageState extends State { return Padding( padding: EdgeInsets.only(top: 32), child: nothingToSeeHere( - textColor: - Theme.of(context).colorScheme.defaultTextColor), + textColor: Theme.of(context).colorScheme.defaultTextColor, + ), ); } } return Padding( padding: const EdgeInsets.only(top: 10, bottom: 10), - child: _getGridView(_duplicates[index - kHeaderRowCount], - index - kHeaderRowCount), + child: _getGridView( + _duplicates[index - kHeaderRowCount], + index - kHeaderRowCount, + ), ); }, itemCount: _duplicates.length + kHeaderRowCount, @@ -153,10 +155,11 @@ class _DeduplicatePageState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - "Following files were clubbed based on their sizes" + - ((_shouldClubByCaptureTime ? " and capture times." : ".") + - ", please review and delete the items you believe are duplicates."), - style: Theme.of(context).textTheme.subtitle2), + "Following files were clubbed based on their sizes" + + ((_shouldClubByCaptureTime ? " and capture times." : ".") + + ", please review and delete the items you believe are duplicates."), + style: Theme.of(context).textTheme.subtitle2, + ), Padding( padding: EdgeInsets.all(12), ), @@ -210,8 +213,9 @@ class _DeduplicatePageState extends State { return Text( text, style: Theme.of(context).textTheme.subtitle1.copyWith( - fontSize: 14, - color: Theme.of(context).iconTheme.color.withOpacity(0.7)), + fontSize: 14, + color: Theme.of(context).iconTheme.color.withOpacity(0.7), + ), ); } @@ -377,19 +381,21 @@ class _DeduplicatePageState extends State { ) : null, ), - child: Stack(children: [ - Hero( - tag: "deduplicate_" + file.tag(), - child: ThumbnailWidget( - file, - diskLoadDeferDuration: kThumbnailDiskLoadDeferDuration, - serverLoadDeferDuration: kThumbnailServerLoadDeferDuration, - shouldShowLivePhotoOverlay: true, - key: Key("deduplicate_" + file.tag()), + child: Stack( + children: [ + Hero( + tag: "deduplicate_" + file.tag(), + child: ThumbnailWidget( + file, + diskLoadDeferDuration: kThumbnailDiskLoadDeferDuration, + serverLoadDeferDuration: kThumbnailServerLoadDeferDuration, + shouldShowLivePhotoOverlay: true, + key: Key("deduplicate_" + file.tag()), + ), ), - ), - _selectedFiles.contains(file) ? kDeleteIconOverlay : Container(), - ]), + _selectedFiles.contains(file) ? kDeleteIconOverlay : Container(), + ], + ), ), ); } diff --git a/lib/ui/detail_page.dart b/lib/ui/detail_page.dart index 0cf4e4a08..26cafcf68 100644 --- a/lib/ui/detail_page.dart +++ b/lib/ui/detail_page.dart @@ -91,13 +91,15 @@ class _DetailPageState extends State { @override Widget build(BuildContext context) { - _logger.info("Opening " + - _files[_selectedIndex].toString() + - ". " + - (_selectedIndex + 1).toString() + - " / " + - _files.length.toString() + - " files ."); + _logger.info( + "Opening " + + _files[_selectedIndex].toString() + + ". " + + (_selectedIndex + 1).toString() + + " / " + + _files.length.toString() + + " files .", + ); _appBarKey = GlobalKey(); _bottomBarKey = GlobalKey(); return Scaffold( @@ -198,10 +200,11 @@ class _DetailPageState extends State { } if (_selectedIndex == 0 && !_hasLoadedTillStart) { final result = await widget.config.asyncLoader( - _files[_selectedIndex].creationTime + 1, - DateTime.now().microsecondsSinceEpoch, - limit: kLoadLimit, - asc: true); + _files[_selectedIndex].creationTime + 1, + DateTime.now().microsecondsSinceEpoch, + limit: kLoadLimit, + asc: true, + ); setState(() { // Returned result could be a subtype of File // ignore: unnecessary_cast @@ -218,8 +221,10 @@ class _DetailPageState extends State { } if (_selectedIndex == _files.length - 1 && !_hasLoadedTillEnd) { final result = await widget.config.asyncLoader( - kGalleryLoadStartTime, _files[_selectedIndex].creationTime - 1, - limit: kLoadLimit); + kGalleryLoadStartTime, + _files[_selectedIndex].creationTime - 1, + limit: kLoadLimit, + ); setState(() { if (!result.hasMore) { _hasLoadedTillEnd = true; @@ -248,13 +253,17 @@ class _DetailPageState extends State { if (_selectedIndex == totalFiles - 1) { // Deleted the last file await _pageController.previousPage( - duration: Duration(milliseconds: 200), curve: Curves.easeInOut); + duration: Duration(milliseconds: 200), + curve: Curves.easeInOut, + ); setState(() { _files.remove(file); }); } else { await _pageController.nextPage( - duration: Duration(milliseconds: 200), curve: Curves.easeInOut); + duration: Duration(milliseconds: 200), + curve: Curves.easeInOut, + ); setState(() { _selectedIndex--; _files.remove(file); @@ -265,10 +274,16 @@ class _DetailPageState extends State { Future _onEditFileRequested(File file) async { if (file.uploadedFileID != null && file.ownerID != Configuration.instance.getUserID()) { - _logger.severe("Attempt to edit unowned file", UnauthorizedEditError(), - StackTrace.current); - showErrorDialog(context, "Sorry", - "We don't support editing photos and albums that you don't own yet"); + _logger.severe( + "Attempt to edit unowned file", + UnauthorizedEditError(), + StackTrace.current, + ); + showErrorDialog( + context, + "Sorry", + "We don't support editing photos and albums that you don't own yet", + ); return; } final dialog = createProgressDialog(context, "Please wait..."); diff --git a/lib/ui/device_folder_page.dart b/lib/ui/device_folder_page.dart index 78cfbc29f..f3c26c128 100644 --- a/lib/ui/device_folder_page.dart +++ b/lib/ui/device_folder_page.dart @@ -24,8 +24,12 @@ class DeviceFolderPage extends StatelessWidget { final gallery = Gallery( asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) { return FilesDB.instance.getFilesInPath( - folder.path, creationStartTime, creationEndTime, - limit: limit, asc: asc); + folder.path, + creationStartTime, + creationEndTime, + limit: limit, + asc: asc, + ); }, reloadEvent: Bus.instance.on(), removalEventTypes: const { @@ -96,10 +100,11 @@ class _BackupConfigurationHeaderWidgetState : Text( "Backup disabled", style: TextStyle( - color: Theme.of(context) - .colorScheme - .defaultTextColor - .withOpacity(0.7)), + color: Theme.of(context) + .colorScheme + .defaultTextColor + .withOpacity(0.7), + ), ), Switch( value: isBackedUp, diff --git a/lib/ui/editor/filtered_image.dart b/lib/ui/editor/filtered_image.dart index 867e8fb21..9e24a61e9 100644 --- a/lib/ui/editor/filtered_image.dart +++ b/lib/ui/editor/filtered_image.dart @@ -18,19 +18,23 @@ class FilteredImage extends StatelessWidget { @override Widget build(BuildContext context) { return ColorFiltered( - colorFilter: - ColorFilter.matrix(ColorFilterGenerator.brightnessAdjustMatrix( - value: brightness ?? 1, - )), + colorFilter: ColorFilter.matrix( + ColorFilterGenerator.brightnessAdjustMatrix( + value: brightness ?? 1, + ), + ), child: ColorFiltered( - colorFilter: - ColorFilter.matrix(ColorFilterGenerator.saturationAdjustMatrix( - value: saturation ?? 1, - )), + colorFilter: ColorFilter.matrix( + ColorFilterGenerator.saturationAdjustMatrix( + value: saturation ?? 1, + ), + ), child: ColorFiltered( - colorFilter: ColorFilter.matrix(ColorFilterGenerator.hueAdjustMatrix( - value: hue ?? 0, - )), + colorFilter: ColorFilter.matrix( + ColorFilterGenerator.hueAdjustMatrix( + value: hue ?? 0, + ), + ), child: child, ), ), diff --git a/lib/ui/email_entry_page.dart b/lib/ui/email_entry_page.dart index 0ee480ac0..d7bb870f5 100644 --- a/lib/ui/email_entry_page.dart +++ b/lib/ui/email_entry_page.dart @@ -88,15 +88,16 @@ class _EmailEntryPageState extends State { }, ), title: Material( - type: MaterialType.transparency, - child: StepProgressIndicator( - totalSteps: 4, - currentStep: 1, - selectedColor: Theme.of(context).buttonColor, - roundedEdges: Radius.circular(10), - unselectedColor: - Theme.of(context).colorScheme.stepProgressUnselectedColor, - )), + type: MaterialType.transparency, + child: StepProgressIndicator( + totalSteps: 4, + currentStep: 1, + selectedColor: Theme.of(context).buttonColor, + roundedEdges: Radius.circular(10), + unselectedColor: + Theme.of(context).colorScheme.stepProgressUnselectedColor, + ), + ), ); return Scaffold( appBar: appBar, @@ -136,8 +137,10 @@ class _EmailEntryPageState extends State { Padding( padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 20), - child: Text('Create new account', - style: Theme.of(context).textTheme.headline4), + child: Text( + 'Create new account', + style: Theme.of(context).textTheme.headline4, + ), ), Padding( padding: const EdgeInsets.fromLTRB(20, 0, 20, 0), @@ -151,8 +154,9 @@ class _EmailEntryPageState extends State { contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 14), border: UnderlineInputBorder( - borderSide: BorderSide.none, - borderRadius: BorderRadius.circular(6)), + borderSide: BorderSide.none, + borderRadius: BorderRadius.circular(6), + ), suffixIcon: _emailIsValid ? Icon( Icons.check, @@ -221,8 +225,9 @@ class _EmailEntryPageState extends State { ) : null, border: UnderlineInputBorder( - borderSide: BorderSide.none, - borderRadius: BorderRadius.circular(6)), + borderSide: BorderSide.none, + borderRadius: BorderRadius.circular(6), + ), ), focusNode: _password1FocusNode, onChanged: (password) { @@ -284,8 +289,9 @@ class _EmailEntryPageState extends State { ) : null, border: UnderlineInputBorder( - borderSide: BorderSide.none, - borderRadius: BorderRadius.circular(6)), + borderSide: BorderSide.none, + borderRadius: BorderRadius.circular(6), + ), ), focusNode: _password2FocusNode, onChanged: (cnfPassword) { @@ -348,13 +354,14 @@ class _EmailEntryPageState extends State { child: Row( children: [ Checkbox( - value: _hasAgreedToTOS, - side: CheckboxTheme.of(context).side, - onChanged: (value) { - setState(() { - _hasAgreedToTOS = value; - }); - }), + value: _hasAgreedToTOS, + side: CheckboxTheme.of(context).side, + onChanged: (value) { + setState(() { + _hasAgreedToTOS = value; + }); + }, + ), Expanded( child: RichText( text: TextSpan( @@ -390,7 +397,9 @@ class _EmailEntryPageState extends State { MaterialPageRoute( builder: (BuildContext context) { return WebPage( - "Privacy", "https://ente.io/privacy"); + "Privacy", + "https://ente.io/privacy", + ); }, ), ); @@ -448,7 +457,9 @@ class _EmailEntryPageState extends State { MaterialPageRoute( builder: (BuildContext context) { return WebPage( - "encryption", "https://ente.io/architecture"); + "encryption", + "https://ente.io/architecture", + ); }, ), ); @@ -526,12 +537,14 @@ class PricingWidget extends StatelessWidget { children: planWidgets, ), ), - Text("We offer a free trial of " + - convertBytesToReadableFormat(freePlan.storage) + - " for " + - freePlan.duration.toString() + - " " + - freePlan.period), + Text( + "We offer a free trial of " + + convertBytesToReadableFormat(freePlan.storage) + + " for " + + freePlan.duration.toString() + + " " + + freePlan.period, + ), GestureDetector( child: Row( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/ui/expansion_card.dart b/lib/ui/expansion_card.dart index 01e149343..020cb093f 100644 --- a/lib/ui/expansion_card.dart +++ b/lib/ui/expansion_card.dart @@ -178,21 +178,22 @@ class _ExpansionTileState extends State mainAxisSize: MainAxisSize.min, children: [ ListTileTheme.merge( - iconColor: _iconColor.value, - textColor: _headerColor.value, - child: Container( - margin: widget.margin, - child: ListTile( - onTap: _handleTap, - leading: widget.leading, - title: widget.title, - trailing: widget.trailing ?? - RotationTransition( - turns: _iconTurns, - child: const Icon(Icons.expand_more), - ), - ), - )), + iconColor: _iconColor.value, + textColor: _headerColor.value, + child: Container( + margin: widget.margin, + child: ListTile( + onTap: _handleTap, + leading: widget.leading, + title: widget.title, + trailing: widget.trailing ?? + RotationTransition( + turns: _iconTurns, + child: const Icon(Icons.expand_more), + ), + ), + ), + ), ClipRect( child: Align( heightFactor: _heightFactor.value, diff --git a/lib/ui/extents_page_view.dart b/lib/ui/extents_page_view.dart index e97163599..58141966c 100644 --- a/lib/ui/extents_page_view.dart +++ b/lib/ui/extents_page_view.dart @@ -368,14 +368,28 @@ class _PageViewState extends State { description .add(EnumProperty('scrollDirection', widget.scrollDirection)); description.add( - FlagProperty('reverse', value: widget.reverse, ifTrue: 'reversed')); - description.add(DiagnosticsProperty( - 'controller', widget.controller, - showName: false)); - description.add(DiagnosticsProperty( - 'physics', widget.physics, - showName: false)); - description.add(FlagProperty('pageSnapping', - value: widget.pageSnapping, ifFalse: 'snapping disabled')); + FlagProperty('reverse', value: widget.reverse, ifTrue: 'reversed'), + ); + description.add( + DiagnosticsProperty( + 'controller', + widget.controller, + showName: false, + ), + ); + description.add( + DiagnosticsProperty( + 'physics', + widget.physics, + showName: false, + ), + ); + description.add( + FlagProperty( + 'pageSnapping', + value: widget.pageSnapping, + ifFalse: 'snapping disabled', + ), + ); } } diff --git a/lib/ui/fading_app_bar.dart b/lib/ui/fading_app_bar.dart index a76eb56bc..bbe8e052b 100644 --- a/lib/ui/fading_app_bar.dart +++ b/lib/ui/fading_app_bar.dart @@ -99,87 +99,89 @@ class FadingAppBarState extends State { if (widget.file.ownerID == null || widget.file.ownerID == widget.userID) { actions.add(_getFavoriteButton()); } - actions.add(PopupMenuButton( - itemBuilder: (context) { - final List items = []; - if (widget.file.isRemoteFile()) { - items.add( - PopupMenuItem( - value: 1, - child: Row( - children: [ - Icon( - Platform.isAndroid - ? Icons.download - : CupertinoIcons.cloud_download, - color: Theme.of(context).iconTheme.color, - ), - Padding( - padding: EdgeInsets.all(8), - ), - Text("Download"), - ], - ), - ), - ); - } - // options for files owned by the user - if (widget.file.ownerID == null || - widget.file.ownerID == widget.userID) { - if (widget.file.uploadedFileID != null) { + actions.add( + PopupMenuButton( + itemBuilder: (context) { + final List items = []; + if (widget.file.isRemoteFile()) { items.add( PopupMenuItem( - value: 2, + value: 1, child: Row( children: [ Icon( Platform.isAndroid - ? Icons.access_time_rounded - : CupertinoIcons.time, + ? Icons.download + : CupertinoIcons.cloud_download, color: Theme.of(context).iconTheme.color, ), Padding( padding: EdgeInsets.all(8), ), - Text("Edit time"), + Text("Download"), ], ), ), ); } + // options for files owned by the user + if (widget.file.ownerID == null || + widget.file.ownerID == widget.userID) { + if (widget.file.uploadedFileID != null) { + items.add( + PopupMenuItem( + value: 2, + child: Row( + children: [ + Icon( + Platform.isAndroid + ? Icons.access_time_rounded + : CupertinoIcons.time, + color: Theme.of(context).iconTheme.color, + ), + Padding( + padding: EdgeInsets.all(8), + ), + Text("Edit time"), + ], + ), + ), + ); + } - items.add( - PopupMenuItem( - value: 3, - child: Row( - children: [ - Icon( - Platform.isAndroid - ? Icons.delete_outline - : CupertinoIcons.delete, - color: Theme.of(context).iconTheme.color, - ), - Padding( - padding: EdgeInsets.all(8), - ), - Text("Delete"), - ], + items.add( + PopupMenuItem( + value: 3, + child: Row( + children: [ + Icon( + Platform.isAndroid + ? Icons.delete_outline + : CupertinoIcons.delete, + color: Theme.of(context).iconTheme.color, + ), + Padding( + padding: EdgeInsets.all(8), + ), + Text("Delete"), + ], + ), ), - ), - ); - } - return items; - }, - onSelected: (value) { - if (value == 1) { - _download(widget.file); - } else if (value == 2) { - _showDateTimePicker(widget.file); - } else if (value == 3) { - _showDeleteSheet(widget.file); - } - }, - )); + ); + } + return items; + }, + onSelected: (value) { + if (value == 1) { + _download(widget.file); + } else if (value == 2) { + _showDateTimePicker(widget.file); + } else if (value == 3) { + _showDeleteSheet(widget.file); + } + }, + ), + ); return AppBar( iconTheme: IconThemeData(color: Colors.white), //same for both themes actions: shouldShowActions ? actions : [], @@ -267,8 +269,11 @@ class FadingAppBarState extends State { theme: Theme.of(context).colorScheme.dateTimePickertheme, ); if (dateWithTimeResult != null) { - if (await editTime(context, List.of([widget.file]), - dateWithTimeResult.microsecondsSinceEpoch)) { + if (await editTime( + context, + List.of([widget.file]), + dateWithTimeResult.microsecondsSinceEpoch, + )) { widget.file.creationTime = dateWithTimeResult.microsecondsSinceEpoch; setState(() {}); } @@ -278,48 +283,56 @@ class FadingAppBarState extends State { void _showDeleteSheet(File file) { final List actions = []; if (file.uploadedFileID == null || file.localID == null) { - actions.add(CupertinoActionSheetAction( - child: Text("Everywhere"), - isDestructiveAction: true, - onPressed: () async { - await deleteFilesFromEverywhere(context, [file]); - Navigator.of(context, rootNavigator: true).pop(); - widget.onFileDeleted(file); - }, - )); + actions.add( + CupertinoActionSheetAction( + child: Text("Everywhere"), + isDestructiveAction: true, + onPressed: () async { + await deleteFilesFromEverywhere(context, [file]); + Navigator.of(context, rootNavigator: true).pop(); + widget.onFileDeleted(file); + }, + ), + ); } else { // uploaded file which is present locally too - actions.add(CupertinoActionSheetAction( - child: Text("Device"), - isDestructiveAction: true, - onPressed: () async { - await deleteFilesOnDeviceOnly(context, [file]); - showToast(context, "File deleted from device"); - Navigator.of(context, rootNavigator: true).pop(); - // TODO: Fix behavior when inside a device folder - }, - )); + actions.add( + CupertinoActionSheetAction( + child: Text("Device"), + isDestructiveAction: true, + onPressed: () async { + await deleteFilesOnDeviceOnly(context, [file]); + showToast(context, "File deleted from device"); + Navigator.of(context, rootNavigator: true).pop(); + // TODO: Fix behavior when inside a device folder + }, + ), + ); - actions.add(CupertinoActionSheetAction( - child: Text("ente"), - isDestructiveAction: true, - onPressed: () async { - await deleteFilesFromRemoteOnly(context, [file]); - showShortToast(context, "Moved to trash"); - Navigator.of(context, rootNavigator: true).pop(); - // TODO: Fix behavior when inside a collection - }, - )); + actions.add( + CupertinoActionSheetAction( + child: Text("ente"), + isDestructiveAction: true, + onPressed: () async { + await deleteFilesFromRemoteOnly(context, [file]); + showShortToast(context, "Moved to trash"); + Navigator.of(context, rootNavigator: true).pop(); + // TODO: Fix behavior when inside a collection + }, + ), + ); - actions.add(CupertinoActionSheetAction( - child: Text("Everywhere"), - isDestructiveAction: true, - onPressed: () async { - await deleteFilesFromEverywhere(context, [file]); - Navigator.of(context, rootNavigator: true).pop(); - widget.onFileDeleted(file); - }, - )); + actions.add( + CupertinoActionSheetAction( + child: Text("Everywhere"), + isDestructiveAction: true, + onPressed: () async { + await deleteFilesFromEverywhere(context, [file]); + Navigator.of(context, rootNavigator: true).pop(); + widget.onFileDeleted(file); + }, + ), + ); } final action = CupertinoActionSheet( title: Text("Delete file?"), diff --git a/lib/ui/fading_bottom_bar.dart b/lib/ui/fading_bottom_bar.dart index adf45201e..018684fa2 100644 --- a/lib/ui/fading_bottom_bar.dart +++ b/lib/ui/fading_bottom_bar.dart @@ -192,14 +192,16 @@ class FadingBottomBarState extends State { final selectedFiles = SelectedFiles(); selectedFiles.toggleSelection(widget.file); Navigator.push( - context, - PageTransition( - type: PageTransitionType.bottomToTop, - child: CreateCollectionPage( - selectedFiles, - null, - actionType: CollectionActionType.restoreFiles, - ))); + context, + PageTransition( + type: PageTransitionType.bottomToTop, + child: CreateCollectionPage( + selectedFiles, + null, + actionType: CollectionActionType.restoreFiles, + ), + ), + ); }, ), ), diff --git a/lib/ui/file_info_dialog.dart b/lib/ui/file_info_dialog.dart index 51b6ce1e2..891db08a2 100644 --- a/lib/ui/file_info_dialog.dart +++ b/lib/ui/file_info_dialog.dart @@ -134,7 +134,8 @@ class _FileInfoWidgetState extends State { Padding(padding: EdgeInsets.all(4)), Text( getFormattedTime( - DateTime.fromMicrosecondsSinceEpoch(file.updationTime)), + DateTime.fromMicrosecondsSinceEpoch(file.updationTime), + ), style: TextStyle(color: infoColor), ), ], @@ -385,8 +386,10 @@ class _FileInfoWidgetState extends State { children: [ Icon(Icons.center_focus_strong_outlined, color: infoColor), Padding(padding: EdgeInsets.all(4)), - Text(focalLength.toString() + " mm", - style: TextStyle(color: infoColor)), + Text( + focalLength.toString() + " mm", + style: TextStyle(color: infoColor), + ), ], ), Padding(padding: EdgeInsets.all(6)), diff --git a/lib/ui/free_space_page.dart b/lib/ui/free_space_page.dart index 254ca433b..f70d59266 100644 --- a/lib/ui/free_space_page.dart +++ b/lib/ui/free_space_page.dart @@ -30,8 +30,9 @@ class _FreeSpacePageState extends State { } Widget _getBody() { - Logger("FreeSpacePage").info("Number of uploaded files: " + - widget.status.localIDs.length.toString()); + Logger("FreeSpacePage").info( + "Number of uploaded files: " + widget.status.localIDs.length.toString(), + ); Logger("FreeSpacePage") .info("Space consumed: " + widget.status.size.toString()); return _getWidget(widget.status); diff --git a/lib/ui/gallery.dart b/lib/ui/gallery.dart index 9573eae6b..d4faf70c3 100644 --- a/lib/ui/gallery.dart +++ b/lib/ui/gallery.dart @@ -79,11 +79,13 @@ class _GalleryState extends State { } if (widget.forceReloadEvents != null) { for (final event in widget.forceReloadEvents) { - _forceReloadEventSubscriptions.add(event.listen((event) async { - _logger.info("Force reload triggered"); - final result = await _loadFiles(); - _setFilesAndReload(result.files); - })); + _forceReloadEventSubscriptions.add( + event.listen((event) async { + _logger.info("Force reload triggered"); + final result = await _loadFiles(); + _setFilesAndReload(result.files); + }), + ); } } if (widget.initialFiles != null) { @@ -111,15 +113,19 @@ class _GalleryState extends State { try { final startTime = DateTime.now().microsecondsSinceEpoch; final result = await widget.asyncLoader( - kGalleryLoadStartTime, DateTime.now().microsecondsSinceEpoch, - limit: limit); + kGalleryLoadStartTime, + DateTime.now().microsecondsSinceEpoch, + limit: limit, + ); final endTime = DateTime.now().microsecondsSinceEpoch; final duration = Duration(microseconds: endTime - startTime); - _logger.info("Time taken to load " + - result.files.length.toString() + - " files :" + - duration.inMilliseconds.toString() + - "ms"); + _logger.info( + "Time taken to load " + + result.files.length.toString() + + " files :" + + duration.inMilliseconds.toString() + + "ms", + ); return result; } catch (e, s) { _logger.severe("failed to load files", e, s); @@ -178,10 +184,13 @@ class _GalleryState extends State { if (widget.header != null) { children.add(widget.header); } - children.add(Expanded( - child: nothingToSeeHere( - textColor: Theme.of(context).colorScheme.defaultTextColor), - )); + children.add( + Expanded( + child: nothingToSeeHere( + textColor: Theme.of(context).colorScheme.defaultTextColor, + ), + ), + ); if (widget.footer != null) { children.add(widget.footer); } @@ -215,8 +224,11 @@ class _GalleryState extends State { return gallery; }, labelTextBuilder: (int index) { - return getMonthAndYear(DateTime.fromMicrosecondsSinceEpoch( - _collatedFiles[index][0].creationTime)); + return getMonthAndYear( + DateTime.fromMicrosecondsSinceEpoch( + _collatedFiles[index][0].creationTime, + ), + ); }, thumbBackgroundColor: Theme.of(context).colorScheme.galleryThumbBackgroundColor, @@ -234,7 +246,9 @@ class _GalleryState extends State { for (int index = 0; index < files.length; index++) { if (index > 0 && !_areFromSameDay( - files[index - 1].creationTime, files[index].creationTime)) { + files[index - 1].creationTime, + files[index].creationTime, + )) { final List collatedDailyFiles = []; collatedDailyFiles.addAll(dailyFiles); collatedFiles.add(collatedDailyFiles); diff --git a/lib/ui/gallery_app_bar_widget.dart b/lib/ui/gallery_app_bar_widget.dart index af0345e0f..415740246 100644 --- a/lib/ui/gallery_app_bar_widget.dart +++ b/lib/ui/gallery_app_bar_widget.dart @@ -135,56 +135,59 @@ class _GalleryAppBarWidgetState extends State { ); } if (widget.type == GalleryType.owned_collection) { - actions.add(PopupMenuButton( - itemBuilder: (context) { - final List items = []; - if (widget.collection.type == CollectionType.album) { + actions.add( + PopupMenuButton( + itemBuilder: (context) { + final List items = []; + if (widget.collection.type == CollectionType.album) { + items.add( + PopupMenuItem( + value: 1, + child: Row( + children: const [ + Icon(Icons.edit), + Padding( + padding: EdgeInsets.all(8), + ), + Text("Rename"), + ], + ), + ), + ); + } + bool isArchived = widget.collection.isArchived(); items.add( PopupMenuItem( - value: 1, + value: 2, child: Row( - children: const [ - Icon(Icons.edit), + children: [ + Icon(isArchived ? Icons.visibility : Icons.visibility_off), Padding( padding: EdgeInsets.all(8), ), - Text("Rename"), + Text(isArchived ? "Unhide" : "Hide"), ], ), ), ); - } - bool isArchived = widget.collection.isArchived(); - items.add( - PopupMenuItem( - value: 2, - child: Row( - children: [ - Icon(isArchived ? Icons.visibility : Icons.visibility_off), - Padding( - padding: EdgeInsets.all(8), - ), - Text(isArchived ? "Unhide" : "Hide"), - ], - ), - ), - ); - return items; - }, - onSelected: (value) async { - if (value == 1) { - await _renameAlbum(context); - } - if (value == 2) { - await changeCollectionVisibility( + return items; + }, + onSelected: (value) async { + if (value == 1) { + await _renameAlbum(context); + } + if (value == 2) { + await changeCollectionVisibility( context, widget.collection, widget.collection.isArchived() ? kVisibilityVisible - : kVisibilityArchive); - } - }, - )); + : kVisibilityArchive, + ); + } + }, + ), + ); } return actions; } @@ -200,7 +203,8 @@ class _GalleryAppBarWidgetState extends State { await CollectionsService.instance.getOrCreateForPath(widget.path); } else { throw Exception( - "Cannot create a collection of type" + widget.type.toString()); + "Cannot create a collection of type" + widget.type.toString(), + ); } } else { final sharees = diff --git a/lib/ui/gallery_overlay_widget.dart b/lib/ui/gallery_overlay_widget.dart index d37f1cab2..da47154a1 100644 --- a/lib/ui/gallery_overlay_widget.dart +++ b/lib/ui/gallery_overlay_widget.dart @@ -27,9 +27,13 @@ class GalleryOverlayWidget extends StatefulWidget { final SelectedFiles selectedFiles; final String path; final Collection collection; - const GalleryOverlayWidget(this.type, this.selectedFiles, - {this.path, this.collection, Key key}) - : super(key: key); + const GalleryOverlayWidget( + this.type, + this.selectedFiles, { + this.path, + this.collection, + Key key, + }) : super(key: key); @override State createState() => _GalleryOverlayWidgetState(); @@ -216,25 +220,29 @@ class _OverlayWidgetState extends State { Future _createAlbum() async { Navigator.push( - context, - PageTransition( - type: PageTransitionType.bottomToTop, - child: CreateCollectionPage( - widget.selectedFiles, - null, - ))); + context, + PageTransition( + type: PageTransitionType.bottomToTop, + child: CreateCollectionPage( + widget.selectedFiles, + null, + ), + ), + ); } Future _moveFiles() async { Navigator.push( - context, - PageTransition( - type: PageTransitionType.bottomToTop, - child: CreateCollectionPage( - widget.selectedFiles, - null, - actionType: CollectionActionType.moveFiles, - ))); + context, + PageTransition( + type: PageTransitionType.bottomToTop, + child: CreateCollectionPage( + widget.selectedFiles, + null, + actionType: CollectionActionType.moveFiles, + ), + ), + ); } List _getActions(BuildContext context) { @@ -276,9 +284,11 @@ class _OverlayWidgetState extends State { message: "Move", child: IconButton( color: Theme.of(context).colorScheme.iconColor, - icon: Icon(Platform.isAndroid - ? Icons.arrow_forward - : CupertinoIcons.arrow_right), + icon: Icon( + Platform.isAndroid + ? Icons.arrow_forward + : CupertinoIcons.arrow_right, + ), onPressed: () { _moveFiles(); }, @@ -352,44 +362,52 @@ class _OverlayWidgetState extends State { if (widget.type == GalleryType.homepage || widget.type == GalleryType.archive) { bool showArchive = widget.type == GalleryType.homepage; - actions.add(Tooltip( - message: showArchive ? "Hide" : "Unhide", - child: IconButton( - color: Theme.of(context).colorScheme.iconColor, - icon: Icon( - showArchive ? Icons.visibility_off : Icons.visibility, + actions.add( + Tooltip( + message: showArchive ? "Hide" : "Unhide", + child: IconButton( + color: Theme.of(context).colorScheme.iconColor, + icon: Icon( + showArchive ? Icons.visibility_off : Icons.visibility, + ), + onPressed: () { + _handleVisibilityChangeRequest( + context, + showArchive ? kVisibilityArchive : kVisibilityVisible, + ); + }, ), - onPressed: () { - _handleVisibilityChangeRequest( - context, showArchive ? kVisibilityArchive : kVisibilityVisible); - }, ), - )); + ); } return actions; } void _addTrashAction(List actions) { - actions.add(Tooltip( - message: "Restore", - child: IconButton( - color: Theme.of(context).colorScheme.iconColor, - icon: Icon( - Icons.restore, - ), - onPressed: () { - Navigator.push( + actions.add( + Tooltip( + message: "Restore", + child: IconButton( + color: Theme.of(context).colorScheme.iconColor, + icon: Icon( + Icons.restore, + ), + onPressed: () { + Navigator.push( context, PageTransition( - type: PageTransitionType.bottomToTop, - child: CreateCollectionPage( - widget.selectedFiles, - null, - actionType: CollectionActionType.restoreFiles, - ))); - }, + type: PageTransitionType.bottomToTop, + child: CreateCollectionPage( + widget.selectedFiles, + null, + actionType: CollectionActionType.restoreFiles, + ), + ), + ); + }, + ), ), - )); + ); actions.add( Tooltip( message: "Delete permanently", @@ -400,7 +418,9 @@ class _OverlayWidgetState extends State { ), onPressed: () async { if (await deleteFromTrash( - context, widget.selectedFiles.files.toList())) { + context, + widget.selectedFiles.files.toList(), + )) { _clearSelectedFiles(); } }, @@ -410,10 +430,15 @@ class _OverlayWidgetState extends State { } Future _handleVisibilityChangeRequest( - BuildContext context, int newVisibility) async { + BuildContext context, + int newVisibility, + ) async { try { await changeVisibility( - context, widget.selectedFiles.files.toList(), newVisibility); + context, + widget.selectedFiles.files.toList(), + newVisibility, + ); } catch (e, s) { _logger.severe("failed to update file visibility", e, s); await showGenericErrorDialog(context); @@ -423,8 +448,11 @@ class _OverlayWidgetState extends State { } void _shareSelected(BuildContext context) { - share(context, widget.selectedFiles.files.toList(), - shareButtonKey: shareButtonKey); + share( + context, + widget.selectedFiles.files.toList(), + shareButtonKey: shareButtonKey, + ); } void _showDeleteSheet(BuildContext context) { @@ -440,56 +468,74 @@ class _OverlayWidgetState extends State { } final actions = []; if (containsUploadedFile && containsLocalFile) { - actions.add(CupertinoActionSheetAction( - child: Text("Device"), - isDestructiveAction: true, - onPressed: () async { - Navigator.of(context, rootNavigator: true).pop(); - await deleteFilesOnDeviceOnly( - context, widget.selectedFiles.files.toList()); - _clearSelectedFiles(); - showToast(context, "Files deleted from device"); - }, - )); - actions.add(CupertinoActionSheetAction( - child: Text("ente"), - isDestructiveAction: true, - onPressed: () async { - Navigator.of(context, rootNavigator: true).pop(); - await deleteFilesFromRemoteOnly( - context, widget.selectedFiles.files.toList()); - _clearSelectedFiles(); - showShortToast(context, "Moved to trash"); - }, - )); - actions.add(CupertinoActionSheetAction( - child: Text("Everywhere"), - isDestructiveAction: true, - onPressed: () async { - Navigator.of(context, rootNavigator: true).pop(); - await deleteFilesFromEverywhere( - context, widget.selectedFiles.files.toList()); - _clearSelectedFiles(); - }, - )); + actions.add( + CupertinoActionSheetAction( + child: Text("Device"), + isDestructiveAction: true, + onPressed: () async { + Navigator.of(context, rootNavigator: true).pop(); + await deleteFilesOnDeviceOnly( + context, + widget.selectedFiles.files.toList(), + ); + _clearSelectedFiles(); + showToast(context, "Files deleted from device"); + }, + ), + ); + actions.add( + CupertinoActionSheetAction( + child: Text("ente"), + isDestructiveAction: true, + onPressed: () async { + Navigator.of(context, rootNavigator: true).pop(); + await deleteFilesFromRemoteOnly( + context, + widget.selectedFiles.files.toList(), + ); + _clearSelectedFiles(); + showShortToast(context, "Moved to trash"); + }, + ), + ); + actions.add( + CupertinoActionSheetAction( + child: Text("Everywhere"), + isDestructiveAction: true, + onPressed: () async { + Navigator.of(context, rootNavigator: true).pop(); + await deleteFilesFromEverywhere( + context, + widget.selectedFiles.files.toList(), + ); + _clearSelectedFiles(); + }, + ), + ); } else { - actions.add(CupertinoActionSheetAction( - child: Text("Delete"), - isDestructiveAction: true, - onPressed: () async { - Navigator.of(context, rootNavigator: true).pop(); - await deleteFilesFromEverywhere( - context, widget.selectedFiles.files.toList()); - _clearSelectedFiles(); - }, - )); + actions.add( + CupertinoActionSheetAction( + child: Text("Delete"), + isDestructiveAction: true, + onPressed: () async { + Navigator.of(context, rootNavigator: true).pop(); + await deleteFilesFromEverywhere( + context, + widget.selectedFiles.files.toList(), + ); + _clearSelectedFiles(); + }, + ), + ); } final action = CupertinoActionSheet( - title: Text("Delete " + - count.toString() + - " file" + - (count == 1 ? "" : "s") + - (containsUploadedFile && containsLocalFile ? " from" : "?")), + title: Text( + "Delete " + + count.toString() + + " file" + + (count == 1 ? "" : "s") + + (containsUploadedFile && containsLocalFile ? " from" : "?"), + ), actions: actions, cancelButton: CupertinoActionSheetAction( child: Text("Cancel"), @@ -508,13 +554,15 @@ class _OverlayWidgetState extends State { void _showRemoveFromCollectionSheet(BuildContext context) { final count = widget.selectedFiles.files.length; final action = CupertinoActionSheet( - title: Text("Remove " + - count.toString() + - " file" + - (count == 1 ? "" : "s") + - " from " + - widget.collection.name + - "?"), + title: Text( + "Remove " + + count.toString() + + " file" + + (count == 1 ? "" : "s") + + " from " + + widget.collection.name + + "?", + ), actions: [ CupertinoActionSheetAction( child: Text("Remove"), @@ -525,7 +573,9 @@ class _OverlayWidgetState extends State { await dialog.show(); try { await CollectionsService.instance.removeFromCollection( - widget.collection.id, widget.selectedFiles.files.toList()); + widget.collection.id, + widget.selectedFiles.files.toList(), + ); await dialog.hide(); widget.selectedFiles.clearAll(); } catch (e, s) { diff --git a/lib/ui/grant_permissions_widget.dart b/lib/ui/grant_permissions_widget.dart index 17768b53e..45270c32d 100644 --- a/lib/ui/grant_permissions_widget.dart +++ b/lib/ui/grant_permissions_widget.dart @@ -47,28 +47,34 @@ class GrantPermissionsWidget extends StatelessWidget { Padding( padding: const EdgeInsets.symmetric(horizontal: 40), child: RichText( - text: TextSpan( + text: TextSpan( + style: Theme.of(context) + .textTheme + .headline5 + .copyWith(fontWeight: FontWeight.w700), + children: [ + TextSpan(text: 'ente '), + TextSpan( + text: "needs permission to ", style: Theme.of(context) .textTheme .headline5 - .copyWith(fontWeight: FontWeight.w700), - children: [ - TextSpan(text: 'ente '), - TextSpan( - text: "needs permission to ", - style: Theme.of(context) - .textTheme - .headline5 - .copyWith(fontWeight: FontWeight.w400)), + .copyWith(fontWeight: FontWeight.w400), + ), TextSpan(text: 'preserve your photos') - ])), + ], + ), + ), ), ], ), Container( width: double.infinity, padding: EdgeInsets.only( - left: 20, right: 20, bottom: Platform.isIOS ? 84 : 60), + left: 20, + right: 20, + bottom: Platform.isIOS ? 84 : 60, + ), child: OutlinedButton( child: Text("Grant permission"), onPressed: () async { @@ -80,7 +86,8 @@ class GrantPermissionsWidget extends StatelessWidget { AlertDialog alert = AlertDialog( title: Text("Please grant permissions"), content: Text( - "ente can encrypt and preserve files only if you grant access to them"), + "ente can encrypt and preserve files only if you grant access to them", + ), actions: [ TextButton( child: Text( @@ -89,8 +96,9 @@ class GrantPermissionsWidget extends StatelessWidget { .textTheme .subtitle1 .copyWith( - fontSize: 14, - fontWeight: FontWeight.w700), + fontSize: 14, + fontWeight: FontWeight.w700, + ), ), onPressed: () { Navigator.of(context, rootNavigator: true) diff --git a/lib/ui/home_widget.dart b/lib/ui/home_widget.dart index c9a969a98..d38540bd0 100644 --- a/lib/ui/home_widget.dart +++ b/lib/ui/home_widget.dart @@ -183,7 +183,8 @@ class _HomeWidgetState extends State { context: context, builder: (BuildContext context) { return AppUpdateDialog( - UpdateService.instance.getLatestVersionInfo()); + UpdateService.instance.getLatestVersionInfo(), + ); }, barrierColor: Colors.black.withOpacity(0.85), ); @@ -209,14 +210,17 @@ class _HomeWidgetState extends State { } void _initMediaShareSubscription() { - _intentDataStreamSubscription = ReceiveSharingIntent.getMediaStream() - .listen((List value) { - setState(() { - _sharedFiles = value; - }); - }, onError: (err) { - _logger.severe("getIntentDataStream error: $err"); - }); + _intentDataStreamSubscription = + ReceiveSharingIntent.getMediaStream().listen( + (List value) { + setState(() { + _sharedFiles = value; + }); + }, + onError: (err) { + _logger.severe("getIntentDataStream error: $err"); + }, + ); // For sharing images coming from outside the app while the app is closed ReceiveSharingIntent.getInitialMedia().then((List value) { setState(() { @@ -283,10 +287,12 @@ class _HomeWidgetState extends State { _settingsPage, ], onPageChanged: (page) { - Bus.instance.fire(TabChangedEvent( - page, - TabChangedEventSource.page_view, - )); + Bus.instance.fire( + TabChangedEvent( + page, + TabChangedEventSource.page_view, + ), + ); }, physics: NeverScrollableScrollPhysics(), controller: _pageController, @@ -330,12 +336,15 @@ class _HomeWidgetState extends State { } // Attach a listener to the stream - linkStream.listen((String link) { - _logger.info("Link received: " + link); - _getCredentials(context, link); - }, onError: (err) { - _logger.severe(err); - }); + linkStream.listen( + (String link) { + _logger.info("Link received: " + link); + _getCredentials(context, link); + }, + onError: (err) { + _logger.severe(err); + }, + ); return false; } @@ -362,31 +371,43 @@ class _HomeWidgetState extends State { CollectionsService.instance.getArchivedCollections(); FileLoadResult result; if (importantPaths.isNotEmpty) { - result = await FilesDB.instance.getImportantFiles(creationStartTime, - creationEndTime, ownerID, importantPaths.toList(), - limit: limit, - asc: asc, - ignoredCollectionIDs: archivedCollectionIds); + result = await FilesDB.instance.getImportantFiles( + creationStartTime, + creationEndTime, + ownerID, + importantPaths.toList(), + limit: limit, + asc: asc, + ignoredCollectionIDs: archivedCollectionIds, + ); } else { if (LocalSyncService.instance.hasGrantedLimitedPermissions()) { result = await FilesDB.instance.getAllLocalAndUploadedFiles( - creationStartTime, creationEndTime, ownerID, - limit: limit, - asc: asc, - ignoredCollectionIDs: archivedCollectionIds); + creationStartTime, + creationEndTime, + ownerID, + limit: limit, + asc: asc, + ignoredCollectionIDs: archivedCollectionIds, + ); } else { result = await FilesDB.instance.getAllUploadedFiles( - creationStartTime, creationEndTime, ownerID, - limit: limit, - asc: asc, - ignoredCollectionIDs: archivedCollectionIds); + creationStartTime, + creationEndTime, + ownerID, + limit: limit, + asc: asc, + ignoredCollectionIDs: archivedCollectionIds, + ); } } // hide ignored files from home page UI final ignoredIDs = await IgnoredFilesService.instance.ignoredIDs; - result.files.removeWhere((f) => - f.uploadedFileID == null && - IgnoredFilesService.instance.shouldSkipUpload(ignoredIDs, f)); + result.files.removeWhere( + (f) => + f.uploadedFileID == null && + IgnoredFilesService.instance.shouldSkipUpload(ignoredIDs, f), + ); return result; }, reloadEvent: Bus.instance.on(), @@ -426,11 +447,13 @@ class _HomeWidgetState extends State { height: 206, ), ), - Text('No photos are being backed up right now', - style: Theme.of(context) - .textTheme - .caption - .copyWith(fontFamily: 'Inter-Medium', fontSize: 16)), + Text( + 'No photos are being backed up right now', + style: Theme.of(context) + .textTheme + .caption + .copyWith(fontFamily: 'Inter-Medium', fontSize: 16), + ), Center( child: Hero( tag: "select_folders", @@ -560,10 +583,12 @@ class _HomeBottomNavigationBarState extends State { } void _onTabChange(int index) { - Bus.instance.fire(TabChangedEvent( - index, - TabChangedEventSource.tab_bar, - )); + Bus.instance.fire( + TabChangedEvent( + index, + TabChangedEventSource.tab_bar, + ), + ); } @override @@ -580,111 +605,112 @@ class _HomeBottomNavigationBarState extends State { child: IgnorePointer( ignoring: filesAreSelected, child: ListView( - physics: const NeverScrollableScrollPhysics(), - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ClipRRect( - borderRadius: BorderRadius.circular(36), - child: Container( - alignment: Alignment.bottomCenter, - height: 52, - width: 240, - child: ClipRect( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20), - child: GNav( - curve: Curves.easeOutExpo, - backgroundColor: Theme.of(context) - .colorScheme - .gNavBackgroundColor, - mainAxisAlignment: MainAxisAlignment.center, - rippleColor: Colors.white.withOpacity(0.1), - activeColor: Theme.of(context) - .colorScheme - .gNavBarActiveColor, - iconSize: 24, - padding: EdgeInsets.fromLTRB(16, 8, 16, 8), - duration: Duration(milliseconds: 200), - gap: 0, - tabBorderRadius: 24, - tabBackgroundColor: Theme.of(context) - .colorScheme - .gNavBarActiveColor, - haptic: false, - tabs: [ - GButton( - margin: EdgeInsets.fromLTRB(6, 6, 0, 6), - icon: Icons.home, - iconColor: Theme.of(context) - .colorScheme - .gNavIconColor, - iconActiveColor: Theme.of(context) - .colorScheme - .gNavActiveIconColor, - text: '', - onPressed: () { - _onTabChange( - 0); // To take care of occasional missing events - }, - ), - GButton( - margin: EdgeInsets.fromLTRB(0, 6, 0, 6), - icon: Icons.photo_library, - iconColor: Theme.of(context) - .colorScheme - .gNavIconColor, - iconActiveColor: Theme.of(context) - .colorScheme - .gNavActiveIconColor, - text: '', - onPressed: () { - _onTabChange( - 1); // To take care of occasional missing events - }, - ), - GButton( - margin: EdgeInsets.fromLTRB(0, 6, 0, 6), - icon: Icons.folder_shared, - iconColor: Theme.of(context) - .colorScheme - .gNavIconColor, - iconActiveColor: Theme.of(context) - .colorScheme - .gNavActiveIconColor, - text: '', - onPressed: () { - _onTabChange( - 2); // To take care of occasional missing events - }, - ), - GButton( - margin: EdgeInsets.fromLTRB(0, 6, 6, 6), - icon: Icons.person, - iconColor: Theme.of(context) - .colorScheme - .gNavIconColor, - iconActiveColor: Theme.of(context) - .colorScheme - .gNavActiveIconColor, - text: '', - onPressed: () { - _onTabChange( - 3); // To take care of occasional missing events - }, - ) - ], - selectedIndex: currentTabIndex, - onTabChange: _onTabChange, - ), + physics: const NeverScrollableScrollPhysics(), + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(36), + child: Container( + alignment: Alignment.bottomCenter, + height: 52, + width: 240, + child: ClipRect( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20), + child: GNav( + curve: Curves.easeOutExpo, + backgroundColor: Theme.of(context) + .colorScheme + .gNavBackgroundColor, + mainAxisAlignment: MainAxisAlignment.center, + rippleColor: Colors.white.withOpacity(0.1), + activeColor: Theme.of(context) + .colorScheme + .gNavBarActiveColor, + iconSize: 24, + padding: EdgeInsets.fromLTRB(16, 8, 16, 8), + duration: Duration(milliseconds: 200), + gap: 0, + tabBorderRadius: 24, + tabBackgroundColor: Theme.of(context) + .colorScheme + .gNavBarActiveColor, + haptic: false, + tabs: [ + GButton( + margin: EdgeInsets.fromLTRB(6, 6, 0, 6), + icon: Icons.home, + iconColor: + Theme.of(context).colorScheme.gNavIconColor, + iconActiveColor: Theme.of(context) + .colorScheme + .gNavActiveIconColor, + text: '', + onPressed: () { + _onTabChange( + 0, + ); // To take care of occasional missing events + }, + ), + GButton( + margin: EdgeInsets.fromLTRB(0, 6, 0, 6), + icon: Icons.photo_library, + iconColor: + Theme.of(context).colorScheme.gNavIconColor, + iconActiveColor: Theme.of(context) + .colorScheme + .gNavActiveIconColor, + text: '', + onPressed: () { + _onTabChange( + 1, + ); // To take care of occasional missing events + }, + ), + GButton( + margin: EdgeInsets.fromLTRB(0, 6, 0, 6), + icon: Icons.folder_shared, + iconColor: + Theme.of(context).colorScheme.gNavIconColor, + iconActiveColor: Theme.of(context) + .colorScheme + .gNavActiveIconColor, + text: '', + onPressed: () { + _onTabChange( + 2, + ); // To take care of occasional missing events + }, + ), + GButton( + margin: EdgeInsets.fromLTRB(0, 6, 6, 6), + icon: Icons.person, + iconColor: + Theme.of(context).colorScheme.gNavIconColor, + iconActiveColor: Theme.of(context) + .colorScheme + .gNavActiveIconColor, + text: '', + onPressed: () { + _onTabChange( + 3, + ); // To take care of occasional missing events + }, + ) + ], + selectedIndex: currentTabIndex, + onTabChange: _onTabChange, ), ), ), ), - ], - ), - ]), + ), + ], + ), + ], + ), ), ), ); diff --git a/lib/ui/huge_listview/draggable_scrollbar.dart b/lib/ui/huge_listview/draggable_scrollbar.dart index ead959daf..0c87d94b5 100644 --- a/lib/ui/huge_listview/draggable_scrollbar.dart +++ b/lib/ui/huge_listview/draggable_scrollbar.dart @@ -62,9 +62,10 @@ class DraggableScrollbarState extends State if (widget.initialScrollIndex > 0 && widget.totalCount > 1) { WidgetsBinding.instance?.addPostFrameCallback((_) { - setState(() => thumbOffset = - (widget.initialScrollIndex / widget.totalCount) * - (thumbMax - thumbMin)); + setState( + () => thumbOffset = (widget.initialScrollIndex / widget.totalCount) * + (thumbMax - thumbMin), + ); }); } @@ -121,7 +122,6 @@ class DraggableScrollbarState extends State } else { return buildThumb(); } - } Widget buildThumb() => Container( @@ -191,25 +191,33 @@ class DraggableScrollbarState extends State void keyHandler(RawKeyEvent value) { if (value.runtimeType == RawKeyDownEvent) { if (value.logicalKey == LogicalKeyboardKey.arrowDown) { - onDragUpdate(DragUpdateDetails( - globalPosition: Offset.zero, - delta: Offset(0, 2), - )); + onDragUpdate( + DragUpdateDetails( + globalPosition: Offset.zero, + delta: Offset(0, 2), + ), + ); } else if (value.logicalKey == LogicalKeyboardKey.arrowUp) { - onDragUpdate(DragUpdateDetails( - globalPosition: Offset.zero, - delta: Offset(0, -2), - )); + onDragUpdate( + DragUpdateDetails( + globalPosition: Offset.zero, + delta: Offset(0, -2), + ), + ); } else if (value.logicalKey == LogicalKeyboardKey.pageDown) { - onDragUpdate(DragUpdateDetails( - globalPosition: Offset.zero, - delta: Offset(0, 25), - )); + onDragUpdate( + DragUpdateDetails( + globalPosition: Offset.zero, + delta: Offset(0, 25), + ), + ); } else if (value.logicalKey == LogicalKeyboardKey.pageUp) { - onDragUpdate(DragUpdateDetails( - globalPosition: Offset.zero, - delta: Offset(0, -25), - )); + onDragUpdate( + DragUpdateDetails( + globalPosition: Offset.zero, + delta: Offset(0, -25), + ), + ); } } } diff --git a/lib/ui/huge_listview/huge_listview.dart b/lib/ui/huge_listview/huge_listview.dart index 46359ff92..d4d9e968a 100644 --- a/lib/ui/huge_listview/huge_listview.dart +++ b/lib/ui/huge_listview/huge_listview.dart @@ -5,9 +5,13 @@ import 'package:photos/ui/huge_listview/draggable_scrollbar.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; typedef HugeListViewItemBuilder = Widget Function( - BuildContext context, int index); + BuildContext context, + int index, +); typedef HugeListViewErrorBuilder = Widget Function( - BuildContext context, dynamic error); + BuildContext context, + dynamic error, +); class HugeListView extends StatefulWidget { /// A [ScrollablePositionedList] controller for jumping or scrolling to an item. @@ -61,11 +65,11 @@ class HugeListView extends StatefulWidget { this.emptyResultBuilder, this.errorBuilder, this.firstShown, - this.thumbBackgroundColor = Colors.red,// Colors.white, + this.thumbBackgroundColor = Colors.red, // Colors.white, this.thumbDrawColor = Colors.yellow, //Colors.grey, this.thumbHeight = 48.0, this.isDraggableScrollbarEnabled = true, - }) : super(key: key); + }) : super(key: key); @override HugeListViewState createState() => HugeListViewState(); diff --git a/lib/ui/huge_listview/lazy_loading_gallery.dart b/lib/ui/huge_listview/lazy_loading_gallery.dart index 629e9e35d..59a5cae6c 100644 --- a/lib/ui/huge_listview/lazy_loading_gallery.dart +++ b/lib/ui/huge_listview/lazy_loading_gallery.dart @@ -101,8 +101,9 @@ class _LazyLoadingGalleryState extends State { final dayStartTime = DateTime(galleryDate.year, galleryDate.month, galleryDate.day); final result = await widget.asyncLoader( - dayStartTime.microsecondsSinceEpoch, - dayStartTime.microsecondsSinceEpoch + kMicroSecondsInDay - 1); + dayStartTime.microsecondsSinceEpoch, + dayStartTime.microsecondsSinceEpoch + kMicroSecondsInDay - 1, + ); if (mounted) { setState(() { _files = result.files; @@ -152,7 +153,10 @@ class _LazyLoadingGalleryState extends State { child: Column( children: [ getDayWidget( - context, _files[0].creationTime, widget.smallerTodayFont), + context, + _files[0].creationTime, + widget.smallerTodayFont, + ), _shouldRender ? _getGallery() : PlaceHolderWidget(_files.length), ], ), @@ -162,14 +166,17 @@ class _LazyLoadingGalleryState extends State { Widget _getGallery() { List childGalleries = []; for (int index = 0; index < _files.length; index += kSubGalleryItemLimit) { - childGalleries.add(LazyLoadingGridView( - widget.tag, - _files.sublist(index, min(index + kSubGalleryItemLimit, _files.length)), - widget.asyncLoader, - widget.selectedFiles, - index == 0, - _files.length > kRecycleLimit, - )); + childGalleries.add( + LazyLoadingGridView( + widget.tag, + _files.sublist( + index, min(index + kSubGalleryItemLimit, _files.length)), + widget.asyncLoader, + widget.selectedFiles, + index == 0, + _files.length > kRecycleLimit, + ), + ); } return Column( @@ -314,9 +321,11 @@ class _LazyLoadingGridViewState extends State { tag: widget.tag + file.tag(), child: ColorFiltered( colorFilter: ColorFilter.mode( - Colors.black.withOpacity( - widget.selectedFiles.files.contains(file) ? 0.4 : 0), - BlendMode.darken), + Colors.black.withOpacity( + widget.selectedFiles.files.contains(file) ? 0.4 : 0, + ), + BlendMode.darken, + ), child: ThumbnailWidget( file, diskLoadDeferDuration: kThumbnailDiskLoadDeferDuration, @@ -350,12 +359,14 @@ class _LazyLoadingGridViewState extends State { } void _routeToDetailPage(File file, BuildContext context) { - final page = DetailPage(DetailPageConfiguration( - List.unmodifiable(widget.files), - widget.asyncLoader, - widget.files.indexOf(file), - widget.tag, - )); + final page = DetailPage( + DetailPageConfiguration( + List.unmodifiable(widget.files), + widget.asyncLoader, + widget.files.indexOf(file), + widget.tag, + ), + ); routeToPage(context, page); } } diff --git a/lib/ui/huge_listview/scroll_bar_thumb.dart b/lib/ui/huge_listview/scroll_bar_thumb.dart index 345bae80f..121e0f571 100644 --- a/lib/ui/huge_listview/scroll_bar_thumb.dart +++ b/lib/ui/huge_listview/scroll_bar_thumb.dart @@ -62,8 +62,8 @@ class ScrollBarThumb extends StatelessWidget { child: Material( elevation: 4.0, child: Container( - constraints: - BoxConstraints.tight(Size(height * 0.6, height))), + constraints: BoxConstraints.tight(Size(height * 0.6, height)), + ), color: backgroundColor, borderRadius: BorderRadius.only( topLeft: Radius.circular(height), @@ -100,20 +100,28 @@ class _ArrowCustomPainter extends CustomPainter { final baseY = size.height / 2; canvas.drawPath( - trianglePath(Offset(baseX - 2.0, baseY - 2.0), width, height, true), - paint); + trianglePath(Offset(baseX - 2.0, baseY - 2.0), width, height, true), + paint, + ); canvas.drawPath( - trianglePath(Offset(baseX - 2.0, baseY + 2.0), width, height, false), - paint); + trianglePath(Offset(baseX - 2.0, baseY + 2.0), width, height, false), + paint, + ); } static Path trianglePath( - Offset offset, double width, double height, bool isUp) { + Offset offset, + double width, + double height, + bool isUp, + ) { return Path() ..moveTo(offset.dx, offset.dy) ..lineTo(offset.dx + width, offset.dy) - ..lineTo(offset.dx + (width / 2), - isUp ? offset.dy - height : offset.dy + height) + ..lineTo( + offset.dx + (width / 2), + isUp ? offset.dy - height : offset.dy + height, + ) ..close(); } } diff --git a/lib/ui/image_editor_page.dart b/lib/ui/image_editor_page.dart index fcc1ae2f0..bb69bbb4e 100644 --- a/lib/ui/image_editor_page.dart +++ b/lib/ui/image_editor_page.dart @@ -308,7 +308,8 @@ class _ImageEditorPageState extends State { option.addOption(ClipOption.fromRect(rect)); option.addOption( - FlipOption(horizontal: flipHorizontal, vertical: flipVertical)); + FlipOption(horizontal: flipHorizontal, vertical: flipVertical), + ); if (action.hasRotateAngle) { option.addOption(RotateOption(radian.toInt())); } @@ -363,8 +364,9 @@ class _ImageEditorPageState extends State { _logger.info("Saved edits to file " + newFile.toString()); final existingFiles = widget.detailPageConfig.files; final files = (await widget.detailPageConfig.asyncLoader( - existingFiles[existingFiles.length - 1].creationTime, - existingFiles[0].creationTime)) + existingFiles[existingFiles.length - 1].creationTime, + existingFiles[0].creationTime, + )) .files; replacePage( context, diff --git a/lib/ui/landing_page_widget.dart b/lib/ui/landing_page_widget.dart index adb746601..0e3abd989 100644 --- a/lib/ui/landing_page_widget.dart +++ b/lib/ui/landing_page_widget.dart @@ -55,9 +55,11 @@ class _LandingPageWidgetState extends State { Theme.of(context).colorScheme.dotsIndicatorActiveColor, color: Theme.of(context).colorScheme.dotsIndicatorInactiveColor, activeShape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(3)), + borderRadius: BorderRadius.circular(3), + ), shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(3)), + borderRadius: BorderRadius.circular(3), + ), size: Size(100, 5), activeSize: Size(100, 5), spacing: EdgeInsets.all(3), diff --git a/lib/ui/loading_photos_widget.dart b/lib/ui/loading_photos_widget.dart index 9217340a0..5952db7cf 100644 --- a/lib/ui/loading_photos_widget.dart +++ b/lib/ui/loading_photos_widget.dart @@ -45,11 +45,12 @@ class _LoadingPhotosWidgetState extends State { // Do nothing, let HomeWidget refresh } else { routeToPage( - context, - BackupFolderSelectionPage( - shouldSelectAll: true, - buttonText: "Start backup", - )); + context, + BackupFolderSelectionPage( + shouldSelectAll: true, + buttonText: "Start backup", + ), + ); } } }); @@ -134,23 +135,25 @@ class _LoadingPhotosWidgetState extends State { ), SizedBox( height: 175, - child: Stack(children: [ - PageView.builder( - scrollDirection: Axis.vertical, - controller: _pageController, - itemBuilder: (context, index) { - return _getMessage(_messages[index]); - }, - itemCount: _messages.length, - physics: NeverScrollableScrollPhysics(), - ), - Positioned( - bottom: 0, - left: 0, - right: 0, - child: BottomShadowWidget(), - ) - ]), + child: Stack( + children: [ + PageView.builder( + scrollDirection: Axis.vertical, + controller: _pageController, + itemBuilder: (context, index) { + return _getMessage(_messages[index]); + }, + itemCount: _messages.length, + physics: NeverScrollableScrollPhysics(), + ), + Positioned( + bottom: 0, + left: 0, + right: 0, + child: BottomShadowWidget(), + ) + ], + ), ), ], ), diff --git a/lib/ui/location_search_widget.dart b/lib/ui/location_search_widget.dart index aca3a616d..2ed6a0327 100644 --- a/lib/ui/location_search_widget.dart +++ b/lib/ui/location_search_widget.dart @@ -48,7 +48,8 @@ class _LocationSearchWidgetState extends State { "query": pattern, }, options: Options( - headers: {"X-Auth-Token": Configuration.instance.getToken()}), + headers: {"X-Auth-Token": Configuration.instance.getToken()}, + ), ) .then((response) { if (_searchString == pattern) { @@ -63,21 +64,23 @@ class _LocationSearchWidgetState extends State { }, onSuggestionSelected: (suggestion) { Navigator.pop(context); - Navigator.of(context).push(MaterialPageRoute( + Navigator.of(context).push( + MaterialPageRoute( builder: (context) => LocationSearchResultsPage( - ViewPort( - Location( - suggestion['geometry']['viewport']['northeast'] - ['lat'], - suggestion['geometry']['viewport']['northeast'] - ['lng']), - Location( - suggestion['geometry']['viewport']['southwest'] - ['lat'], - suggestion['geometry']['viewport']['southwest'] - ['lng'])), - suggestion['name'], - ))); + ViewPort( + Location( + suggestion['geometry']['viewport']['northeast']['lat'], + suggestion['geometry']['viewport']['northeast']['lng'], + ), + Location( + suggestion['geometry']['viewport']['southwest']['lat'], + suggestion['geometry']['viewport']['southwest']['lng'], + ), + ), + suggestion['name'], + ), + ), + ); }, ); } @@ -95,25 +98,27 @@ class LocationSearchResultWidget extends StatelessWidget { return Container( padding: new EdgeInsets.symmetric(vertical: 6.0, horizontal: 6.0), margin: EdgeInsets.symmetric(vertical: 6.0), - child: Column(children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Icon( - Icons.location_on, - ), - Padding(padding: EdgeInsets.only(left: 20.0)), - Flexible( - child: Container( - child: Text( - name, - overflow: TextOverflow.clip, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Icon( + Icons.location_on, + ), + Padding(padding: EdgeInsets.only(left: 20.0)), + Flexible( + child: Container( + child: Text( + name, + overflow: TextOverflow.clip, + ), ), ), - ), - ], - ), - ]), + ], + ), + ], + ), ); } } diff --git a/lib/ui/lock_screen.dart b/lib/ui/lock_screen.dart index b872618bc..e19a43cd3 100644 --- a/lib/ui/lock_screen.dart +++ b/lib/ui/lock_screen.dart @@ -26,35 +26,37 @@ class _LockScreenState extends State { return Scaffold( body: Center( child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Stack( - alignment: Alignment.center, - children: [ - Image.asset(MediaQuery.of(context).platformBrightness == - Brightness.light + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Stack( + alignment: Alignment.center, + children: [ + Image.asset( + MediaQuery.of(context).platformBrightness == Brightness.light ? 'assets/loading_photos_light.png' - : 'assets/loading_photos_dark.png'), - SizedBox( - width: 172, - child: GradientButton( - child: Text( - 'Unlock', - style: gradientButtonTextTheme(), - ), - linearGradientColors: const [ - Color(0xFF2CD267), - Color(0xFF1DB954), - ], - onTap: () async { - _showLockScreen(); - }, + : 'assets/loading_photos_dark.png', + ), + SizedBox( + width: 172, + child: GradientButton( + child: Text( + 'Unlock', + style: gradientButtonTextTheme(), ), + linearGradientColors: const [ + Color(0xFF2CD267), + Color(0xFF1DB954), + ], + onTap: () async { + _showLockScreen(); + }, ), - ], - ), - ]), + ), + ], + ), + ], + ), ), ); } @@ -63,7 +65,8 @@ class _LockScreenState extends State { _logger.info("Showing lockscreen"); try { final result = await requestAuthentication( - "Please authenticate to view your memories"); + "Please authenticate to view your memories", + ); if (result) { AppLock.of(context).didUnlock(); } diff --git a/lib/ui/login_page.dart b/lib/ui/login_page.dart index 8557b5e7e..55edf9af1 100644 --- a/lib/ui/login_page.dart +++ b/lib/ui/login_page.dart @@ -75,8 +75,10 @@ class _LoginPageState extends State { Padding( padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 20), - child: Text('Welcome back!', - style: Theme.of(context).textTheme.headline4), + child: Text( + 'Welcome back!', + style: Theme.of(context).textTheme.headline4, + ), ), Padding( padding: const EdgeInsets.fromLTRB(20, 24, 20, 0), @@ -89,8 +91,9 @@ class _LoginPageState extends State { contentPadding: EdgeInsets.symmetric(horizontal: 15, vertical: 15), border: UnderlineInputBorder( - borderSide: BorderSide.none, - borderRadius: BorderRadius.circular(6)), + borderSide: BorderSide.none, + borderRadius: BorderRadius.circular(6), + ), suffixIcon: _emailIsValid ? Icon( Icons.check, @@ -141,7 +144,8 @@ class _LoginPageState extends State { .copyWith(fontSize: 12), children: [ TextSpan( - text: "By clicking log in, I agree to the "), + text: "By clicking log in, I agree to the ", + ), TextSpan( text: "terms of service", style: TextStyle( @@ -153,7 +157,9 @@ class _LoginPageState extends State { MaterialPageRoute( builder: (BuildContext context) { return WebPage( - "terms", "https://ente.io/terms"); + "terms", + "https://ente.io/terms", + ); }, ), ); @@ -170,8 +176,10 @@ class _LoginPageState extends State { Navigator.of(context).push( MaterialPageRoute( builder: (BuildContext context) { - return WebPage("privacy", - "https://ente.io/privacy"); + return WebPage( + "privacy", + "https://ente.io/privacy", + ); }, ), ); diff --git a/lib/ui/manage_links_widget.dart b/lib/ui/manage_links_widget.dart index bda42e26c..d46fae193 100644 --- a/lib/ui/manage_links_widget.dart +++ b/lib/ui/manage_links_widget.dart @@ -137,12 +137,15 @@ class _ManageSharedLinkWidgetState extends State { inputResult == 'ok' && _textFieldController.text.trim().isNotEmpty) { var propToUpdate = await _getEncryptedPassword( - _textFieldController.text); + _textFieldController.text, + ); await _updateUrlSettings(context, propToUpdate); } } else { await _updateUrlSettings( - context, {'disablePassword': true}); + context, + {'disablePassword': true}, + ); } setState(() {}); }, @@ -166,25 +169,31 @@ class _ManageSharedLinkWidgetState extends State { onChanged: (value) async { if (!value) { final choice = await showChoiceDialog( - context, - 'Disable downloads', - 'Are you sure that you want to disable the download button for files?', - firstAction: 'No', - secondAction: 'Yes', - firstActionColor: - Theme.of(context).colorScheme.greenText, - secondActionColor: Theme.of(context) - .colorScheme - .inverseBackgroundColor); + context, + 'Disable downloads', + 'Are you sure that you want to disable the download button for files?', + firstAction: 'No', + secondAction: 'Yes', + firstActionColor: + Theme.of(context).colorScheme.greenText, + secondActionColor: Theme.of(context) + .colorScheme + .inverseBackgroundColor, + ); if (choice != DialogUserChoice.secondChoice) { return; } } await _updateUrlSettings( - context, {'enableDownload': value}); + context, + {'enableDownload': value}, + ); if (!value) { - showErrorDialog(context, "Please note", - "Viewers can still take screenshots or save a copy of your photos using external tools"); + showErrorDialog( + context, + "Please note", + "Viewers can still take screenshots or save a copy of your photos using external tools", + ); } setState(() {}); }, @@ -262,7 +271,9 @@ class _ManageSharedLinkWidgetState extends State { } if (newValidTill >= 0) { await _updateUrlSettings( - context, {'validTill': newValidTill}); + context, + {'validTill': newValidTill}, + ); setState(() {}); } Navigator.of(context).pop(''); @@ -333,10 +344,11 @@ class _ManageSharedLinkWidgetState extends State { Future _displayLinkPasswordInput(BuildContext context) async { _textFieldController.clear(); return showDialog( - context: context, - builder: (context) { - bool _passwordVisible = false; - return StatefulBuilder(builder: (context, setState) { + context: context, + builder: (context) { + bool _passwordVisible = false; + return StatefulBuilder( + builder: (context, setState) { return AlertDialog( title: Text('Enter password'), content: TextFormField( @@ -369,8 +381,10 @@ class _ManageSharedLinkWidgetState extends State { ), actions: [ TextButton( - child: Text('Cancel', - style: Theme.of(context).textTheme.subtitle2), + child: Text( + 'Cancel', + style: Theme.of(context).textTheme.subtitle2, + ), onPressed: () { Navigator.pop(context, 'cancel'); }, @@ -387,18 +401,26 @@ class _ManageSharedLinkWidgetState extends State { ), ], ); - }); - }); + }, + ); + }, + ); } Future> _getEncryptedPassword(String pass) async { - assert(Sodium.cryptoPwhashAlgArgon2id13 == Sodium.cryptoPwhashAlgDefault, - "mismatch in expected default pw hashing algo"); + assert( + Sodium.cryptoPwhashAlgArgon2id13 == Sodium.cryptoPwhashAlgDefault, + "mismatch in expected default pw hashing algo", + ); int memLimit = Sodium.cryptoPwhashMemlimitInteractive; int opsLimit = Sodium.cryptoPwhashOpslimitInteractive; final kekSalt = CryptoUtil.getSaltToDeriveKey(); final result = await CryptoUtil.deriveKey( - utf8.encode(pass), kekSalt, memLimit, opsLimit); + utf8.encode(pass), + kekSalt, + memLimit, + opsLimit, + ); return { 'passHash': Sodium.bin2base64(result), 'nonce': Sodium.bin2base64(kekSalt), @@ -408,7 +430,9 @@ class _ManageSharedLinkWidgetState extends State { } Future _updateUrlSettings( - BuildContext context, Map prop) async { + BuildContext context, + Map prop, + ) async { final dialog = createProgressDialog(context, "Please wait..."); await dialog.show(); try { @@ -451,7 +475,8 @@ class _ManageSharedLinkWidgetState extends State { List options = []; for (int i = 50; i > 0; i--) { options.add( - Text(i.toString(), style: Theme.of(context).textTheme.subtitle1)); + Text(i.toString(), style: Theme.of(context).textTheme.subtitle1), + ); } return showCupertinoModalPopup( context: context, @@ -493,7 +518,8 @@ class _ManageSharedLinkWidgetState extends State { onPressed: () async { await _updateUrlSettings(context, { 'deviceLimit': int.tryParse( - options[_selectedDeviceLimitIndex].data), + options[_selectedDeviceLimitIndex].data, + ), }); setState(() {}); Navigator.of(context).pop(''); diff --git a/lib/ui/memories_widget.dart b/lib/ui/memories_widget.dart index 61292e901..4e1555b65 100644 --- a/lib/ui/memories_widget.dart +++ b/lib/ui/memories_widget.dart @@ -95,7 +95,9 @@ class _MemoryWidgetState extends State { return GestureDetector( onTap: () async { await routeToPage( - context, FullScreenMemory(title, widget.memories, index)); + context, + FullScreenMemory(title, widget.memories, index), + ); setState(() {}); }, child: SizedBox( @@ -261,9 +263,12 @@ class _FullScreenMemoryState extends State { ), Text( getFormattedDate( - DateTime.fromMicrosecondsSinceEpoch(file.creationTime)), + DateTime.fromMicrosecondsSinceEpoch(file.creationTime), + ), style: Theme.of(context).textTheme.subtitle1.copyWith( - fontSize: 14, color: Colors.white), //same for both themes + fontSize: 14, + color: Colors.white, + ), //same for both themes ), ], ), @@ -271,16 +276,17 @@ class _FullScreenMemoryState extends State { ), flexibleSpace: Container( decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Colors.black.withOpacity(0.6), - Colors.black.withOpacity(0.5), - Colors.transparent, - ], - stops: const [0, 0.6, 1], - )), + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.black.withOpacity(0.6), + Colors.black.withOpacity(0.5), + Colors.transparent, + ], + stops: const [0, 0.6, 1], + ), + ), ), backgroundColor: Color(0x00000000), elevation: 0, @@ -288,12 +294,15 @@ class _FullScreenMemoryState extends State { extendBodyBehindAppBar: true, body: Container( color: Colors.black, - child: Stack(alignment: Alignment.bottomCenter, children: [ - _buildSwiper(), - bottomGradient(), - _buildTitleText(), - _buildBottomIcons(), - ]), + child: Stack( + alignment: Alignment.bottomCenter, + children: [ + _buildSwiper(), + bottomGradient(), + _buildTitleText(), + _buildBottomIcons(), + ], + ), ), ); } @@ -307,11 +316,13 @@ class _FullScreenMemoryState extends State { child: AnimatedOpacity( opacity: _opacity, duration: Duration(milliseconds: 500), - child: Text(widget.title, - style: Theme.of(context) - .textTheme - .headline4 - .copyWith(color: Colors.white)), + child: Text( + widget.title, + style: Theme.of(context) + .textTheme + .headline4 + .copyWith(color: Colors.white), + ), ), ), ); @@ -320,17 +331,18 @@ class _FullScreenMemoryState extends State { Widget _buildBottomIcons() { final file = widget.memories[_index].file; return Container( - alignment: Alignment.bottomRight, - padding: EdgeInsets.fromLTRB(0, 0, 26, 20), - child: IconButton( - icon: Icon( - Icons.adaptive.share, - color: Colors.white, - ), //same for both themes - onPressed: () { - share(context, [file]); - }, - )); + alignment: Alignment.bottomRight, + padding: EdgeInsets.fromLTRB(0, 0, 26, 20), + child: IconButton( + icon: Icon( + Icons.adaptive.share, + color: Colors.white, + ), //same for both themes + onPressed: () { + share(context, [file]); + }, + ), + ); } Widget bottomGradient() { @@ -338,15 +350,16 @@ class _FullScreenMemoryState extends State { height: 124, width: double.infinity, decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.bottomCenter, - end: Alignment.topCenter, - colors: [ - Colors.black.withOpacity(0.5), //same for both themes - Colors.transparent, - ], - stops: const [0, 0.8], - )), + gradient: LinearGradient( + begin: Alignment.bottomCenter, + end: Alignment.topCenter, + colors: [ + Colors.black.withOpacity(0.5), //same for both themes + Colors.transparent, + ], + stops: const [0, 0.8], + ), + ), ); } diff --git a/lib/ui/nav_bar.dart b/lib/ui/nav_bar.dart index 951c1b997..65a434f70 100644 --- a/lib/ui/nav_bar.dart +++ b/lib/ui/nav_bar.dart @@ -77,65 +77,65 @@ class _GNavState extends State { selectedIndex = widget.selectedIndex; return Container( - color: widget.backgroundColor ?? Colors.transparent, - // padding: EdgeInsets.all(12), - // alignment: Alignment.center, - child: Row( - mainAxisAlignment: widget.mainAxisAlignment, - children: widget.tabs - .map((t) => GButton( - key: t.key, - border: t.border ?? widget.tabBorder, - activeBorder: t.activeBorder ?? widget.tabActiveBorder, - borderRadius: - t.borderRadius ?? widget.tabBorderRadius != null - ? BorderRadius.all( - Radius.circular(widget.tabBorderRadius)) - : const BorderRadius.all(Radius.circular(100.0)), - debug: widget.debug ?? false, - margin: t.margin ?? widget.tabMargin, - active: selectedIndex == widget.tabs.indexOf(t), - gap: t.gap ?? widget.gap, - iconActiveColor: t.iconActiveColor ?? widget.activeColor, - iconColor: t.iconColor ?? widget.color, - iconSize: t.iconSize ?? widget.iconSize, - textColor: t.textColor ?? widget.activeColor, - rippleColor: t.rippleColor ?? - widget.rippleColor ?? - Colors.transparent, - hoverColor: t.hoverColor ?? - widget.hoverColor ?? - Colors.transparent, - padding: t.padding ?? widget.padding, - icon: t.icon, - haptic: widget.haptic ?? true, - leading: t.leading, - curve: widget.curve ?? Curves.easeInCubic, - backgroundGradient: - t.backgroundGradient ?? widget.tabBackgroundGradient, - backgroundColor: t.backgroundColor ?? - widget.tabBackgroundColor ?? - Colors.transparent, - duration: - widget.duration ?? const Duration(milliseconds: 500), - onPressed: () { - if (!clickable) return; - setState(() { - selectedIndex = widget.tabs.indexOf(t); - clickable = false; - }); - widget.onTabChange(selectedIndex); + color: widget.backgroundColor ?? Colors.transparent, + // padding: EdgeInsets.all(12), + // alignment: Alignment.center, + child: Row( + mainAxisAlignment: widget.mainAxisAlignment, + children: widget.tabs + .map( + (t) => GButton( + key: t.key, + border: t.border ?? widget.tabBorder, + activeBorder: t.activeBorder ?? widget.tabActiveBorder, + borderRadius: t.borderRadius ?? widget.tabBorderRadius != null + ? BorderRadius.all( + Radius.circular(widget.tabBorderRadius), + ) + : const BorderRadius.all(Radius.circular(100.0)), + debug: widget.debug ?? false, + margin: t.margin ?? widget.tabMargin, + active: selectedIndex == widget.tabs.indexOf(t), + gap: t.gap ?? widget.gap, + iconActiveColor: t.iconActiveColor ?? widget.activeColor, + iconColor: t.iconColor ?? widget.color, + iconSize: t.iconSize ?? widget.iconSize, + textColor: t.textColor ?? widget.activeColor, + rippleColor: + t.rippleColor ?? widget.rippleColor ?? Colors.transparent, + hoverColor: + t.hoverColor ?? widget.hoverColor ?? Colors.transparent, + padding: t.padding ?? widget.padding, + icon: t.icon, + haptic: widget.haptic ?? true, + leading: t.leading, + curve: widget.curve ?? Curves.easeInCubic, + backgroundGradient: + t.backgroundGradient ?? widget.tabBackgroundGradient, + backgroundColor: t.backgroundColor ?? + widget.tabBackgroundColor ?? + Colors.transparent, + duration: widget.duration ?? const Duration(milliseconds: 500), + onPressed: () { + if (!clickable) return; + setState(() { + selectedIndex = widget.tabs.indexOf(t); + clickable = false; + }); + widget.onTabChange(selectedIndex); - Future.delayed( - widget.duration ?? - const Duration(milliseconds: 500), () { - setState(() { - clickable = true; - }); - }); - }, - )) - .toList())); + Future.delayed( + widget.duration ?? const Duration(milliseconds: 500), () { + setState(() { + clickable = true; + }); + }); + }, + ), + ) + .toList(), + ), + ); } } @@ -237,31 +237,31 @@ class _GButtonState extends State { } class Button extends StatefulWidget { - const Button( - {Key key, - this.icon, - this.iconSize, - this.leading, - this.iconActiveColor, - this.iconColor, - this.text, - this.gap = 0, - this.color, - this.rippleColor, - this.hoverColor, - this.onPressed, - this.duration, - this.curve, - this.padding = const EdgeInsets.all(25), - this.margin = const EdgeInsets.all(0), - this.active = false, - this.debug, - this.gradient, - this.borderRadius = const BorderRadius.all(Radius.circular(100.0)), - this.border, - this.activeBorder, - this.shadow}) - : super(key: key); + const Button({ + Key key, + this.icon, + this.iconSize, + this.leading, + this.iconActiveColor, + this.iconColor, + this.text, + this.gap = 0, + this.color, + this.rippleColor, + this.hoverColor, + this.onPressed, + this.duration, + this.curve, + this.padding = const EdgeInsets.all(25), + this.margin = const EdgeInsets.all(0), + this.active = false, + this.debug, + this.gradient, + this.borderRadius = const BorderRadius.all(Radius.circular(100.0)), + this.border, + this.activeBorder, + this.shadow, + }) : super(key: key); final IconData icon; final double iconSize; @@ -317,7 +317,8 @@ class _ButtonState extends State