浏览代码

temp commit

Neeraj Gupta 2 年之前
父节点
当前提交
588cbbbce1
共有 3 个文件被更改,包括 130 次插入125 次删除
  1. 94 95
      lib/services/collections_service.dart
  2. 34 30
      lib/services/file_magic_service.dart
  3. 2 0
      lib/utils/file_uploader.dart

+ 94 - 95
lib/services/collections_service.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'dart:async';
 import 'dart:convert';
 import 'dart:math';
@@ -47,17 +45,18 @@ class CollectionsService {
 
   final _logger = Logger("CollectionsService");
 
-  CollectionsDB _db;
-  FilesDB _filesDB;
-  Configuration _config;
-  SharedPreferences _prefs;
-  Future<List<File>> _cachedLatestFiles;
+  late CollectionsDB _db;
+  late FilesDB _filesDB;
+  late Configuration _config;
+  late SharedPreferences _prefs;
+
   final _enteDio = Network.instance.enteDio;
   final _localPathToCollectionID = <String, int>{};
   final _collectionIDToCollections = <int, Collection>{};
   final _cachedKeys = <int, Uint8List>{};
   final _cachedUserIdToUser = <int, User>{};
-  Collection cachedDefaultHiddenCollection;
+  Collection? cachedDefaultHiddenCollection;
+  Future<List<File>>? _cachedLatestFiles;
 
   CollectionsService._privateConstructor() {
     _db = CollectionsDB.instance;
@@ -122,7 +121,7 @@ class CollectionsService {
       }
 
       // remove reference for incoming collections when unshared/deleted
-      if (collection.isDeleted && ownerID != collection?.owner?.id) {
+      if (collection.isDeleted && ownerID != collection.owner?.id) {
         await _db.deleteCollection(collection.id);
       } else {
         // keep entry for deletedCollection as collectionKey may be used during
@@ -202,10 +201,10 @@ class CollectionsService {
 
   Future<List<File>> getLatestCollectionFiles() {
     _cachedLatestFiles ??= _filesDB.getLatestCollectionFiles();
-    return _cachedLatestFiles;
+    return _cachedLatestFiles!;
   }
 
-  Future<void> setCollectionSyncTime(int collectionID, int time) async {
+  Future<bool> setCollectionSyncTime(int collectionID, int? time) async {
     final key = _collectionSyncTimeKeyPrefix + collectionID.toString();
     if (time == null) {
       return _prefs.remove(key);
@@ -221,21 +220,21 @@ class CollectionsService {
         .toList();
   }
 
-  User getFileOwner(int userID, int collectionID) {
+  User getFileOwner(int userID, int? collectionID) {
     if (_cachedUserIdToUser.containsKey(userID)) {
-      return _cachedUserIdToUser[userID];
+      return _cachedUserIdToUser[userID]!;
     }
     if (collectionID != null) {
-      final Collection collection = getCollectionByID(collectionID);
+      final Collection? collection = getCollectionByID(collectionID);
       if (collection != null) {
-        if (collection.owner.id == userID) {
-          _cachedUserIdToUser[userID] = collection.owner;
+        if (collection.owner?.id == userID) {
+          _cachedUserIdToUser[userID] = collection.owner!;
         } else {
           final matchingUser = collection.getSharees().firstWhereOrNull(
                 (u) => u.id == userID,
               );
           if (matchingUser != null) {
-            _cachedUserIdToUser[userID] = collection.owner;
+            _cachedUserIdToUser[userID] = collection.owner!;
           }
         }
       }
@@ -262,20 +261,20 @@ class CollectionsService {
       if (includeCollabCollections) {
         usersCollection.removeWhere(
           (c) =>
-              (c.owner.id != userID) &&
+              (c.owner?.id != userID) &&
               (c.getSharees().any((u) => (u.id ?? -1) == userID && u.isViewer)),
         );
       } else {
-        usersCollection.removeWhere((c) => c.owner.id != userID);
+        usersCollection.removeWhere((c) => c.owner?.id != userID);
       }
     }
     final latestCollectionFiles = await getLatestCollectionFiles();
     final Map<int, File> collectionToThumbnailMap = Map.fromEntries(
-      latestCollectionFiles.map((e) => MapEntry(e.collectionID, e)),
+      latestCollectionFiles.map((e) => MapEntry(e.collectionID!, e)),
     );
 
     for (final c in usersCollection) {
-      final File thumbnail = collectionToThumbnailMap[c.id];
+      final File? thumbnail = collectionToThumbnailMap[c.id];
       collectionsWithThumbnail.add(CollectionWithThumbnail(c, thumbnail));
     }
     return collectionsWithThumbnail;
@@ -322,12 +321,12 @@ class CollectionsService {
         sharees.add(User.fromMap(user));
       }
       _collectionIDToCollections[collectionID] =
-          _collectionIDToCollections[collectionID].copyWith(sharees: sharees);
-      unawaited(_db.insert([_collectionIDToCollections[collectionID]]));
+          _collectionIDToCollections[collectionID]!.copyWith(sharees: sharees);
+      unawaited(_db.insert([_collectionIDToCollections[collectionID]!]));
       RemoteSyncService.instance.sync(silently: true).ignore();
       return sharees;
     } on DioError catch (e) {
-      if (e.response.statusCode == 402) {
+      if (e.response?.statusCode == 402) {
         throw SharingNotPermittedForFreeAccountsError();
       }
       rethrow;
@@ -348,15 +347,14 @@ class CollectionsService {
         sharees.add(User.fromMap(user));
       }
       _collectionIDToCollections[collectionID] =
-          _collectionIDToCollections[collectionID].copyWith(sharees: sharees);
-      unawaited(_db.insert([_collectionIDToCollections[collectionID]]));
+          _collectionIDToCollections[collectionID]!.copyWith(sharees: sharees);
+      unawaited(_db.insert([_collectionIDToCollections[collectionID]!]));
       RemoteSyncService.instance.sync(silently: true).ignore();
       return sharees;
     } catch (e) {
       _logger.severe(e);
       rethrow;
     }
-    RemoteSyncService.instance.sync(silently: true).ignore();
   }
 
   Future<void> trashCollection(
@@ -424,7 +422,7 @@ class CollectionsService {
       _cachedKeys[collectionID] =
           _getAndCacheDecryptedKey(collection, source: "getCollectionKey");
     }
-    return _cachedKeys[collectionID];
+    return _cachedKeys[collectionID]!;
   }
 
   Uint8List _getAndCacheDecryptedKey(
@@ -432,7 +430,7 @@ class CollectionsService {
     String source = "",
   }) {
     if (_cachedKeys.containsKey(collection.id)) {
-      return _cachedKeys[collection.id];
+      return _cachedKeys[collection.id]!;
     }
     debugPrint(
       "Compute collection decryption key for ${collection.id} source"
@@ -440,20 +438,20 @@ class CollectionsService {
     );
     final encryptedKey = Sodium.base642bin(collection.encryptedKey);
     Uint8List collectionKey;
-    if (collection.owner.id == _config.getUserID()) {
+    if (collection.owner?.id == _config.getUserID()) {
       if (_config.getKey() == null) {
         throw Exception("key can not be null");
       }
       collectionKey = CryptoUtil.decryptSync(
         encryptedKey,
         _config.getKey(),
-        Sodium.base642bin(collection.keyDecryptionNonce),
+        Sodium.base642bin(collection.keyDecryptionNonce!),
       );
     } else {
       collectionKey = CryptoUtil.openSealSync(
         encryptedKey,
-        Sodium.base642bin(_config.getKeyAttributes().publicKey),
-        _config.getSecretKey(),
+        Sodium.base642bin(_config.getKeyAttributes()!.publicKey),
+        _config.getSecretKey()!,
       );
     }
     if (collectionKey != null) {
@@ -470,15 +468,15 @@ class CollectionsService {
         await updateMagicMetadata(collection, {"subType": 0});
       }
       final encryptedName = CryptoUtil.encryptSync(
-        utf8.encode(newName),
+        utf8.encode(newName) as Uint8List,
         getCollectionKey(collection.id),
       );
       await _enteDio.post(
         "/collections/rename",
         data: {
           "collectionID": collection.id,
-          "encryptedName": Sodium.bin2base64(encryptedName.encryptedData),
-          "nameDecryptionNonce": Sodium.bin2base64(encryptedName.nonce)
+          "encryptedName": Sodium.bin2base64(encryptedName.encryptedData!),
+          "nameDecryptionNonce": Sodium.bin2base64(encryptedName.nonce!)
         },
       );
       // trigger sync to fetch the latest name from server
@@ -505,9 +503,9 @@ class CollectionsService {
     Collection collection,
     Map<String, dynamic> newMetadataUpdate,
   ) async {
-    final int ownerID = Configuration.instance.getUserID();
+    final int ownerID = Configuration.instance.getUserID()!;
     try {
-      if (collection.owner.id != ownerID) {
+      if (collection.owner?.id != ownerID) {
         throw AssertionError("cannot modify albums not owned by you");
       }
       // read the existing magic metadata and apply new updates to existing data
@@ -525,7 +523,7 @@ class CollectionsService {
 
       final key = getCollectionKey(collection.id);
       final encryptedMMd = await CryptoUtil.encryptChaCha(
-        utf8.encode(jsonEncode(jsonToUpdate)),
+        utf8.encode(jsonEncode(jsonToUpdate)) as Uint8List,
         key,
       );
       // for required field, the json validator on golang doesn't treat 0 as valid
@@ -536,8 +534,8 @@ class CollectionsService {
         magicMetadata: MetadataRequest(
           version: currentVersion,
           count: jsonToUpdate.length,
-          data: Sodium.bin2base64(encryptedMMd.encryptedData),
-          header: Sodium.bin2base64(encryptedMMd.header),
+          data: Sodium.bin2base64(encryptedMMd.encryptedData!),
+          header: Sodium.bin2base64(encryptedMMd.header!),
         ),
       );
       await _enteDio.put(
@@ -549,7 +547,7 @@ class CollectionsService {
       // trigger sync to fetch the latest collection state from server
       sync().ignore();
     } on DioError catch (e) {
-      if (e.response != null && e.response.statusCode == 409) {
+      if (e.response != null && e.response?.statusCode == 409) {
         _logger.severe('collection magic data out of sync');
         sync().ignore();
       }
@@ -575,7 +573,7 @@ class CollectionsService {
         CollectionUpdatedEvent(collection.id, <File>[], "shareUrL"),
       );
     } on DioError catch (e) {
-      if (e.response.statusCode == 402) {
+      if (e.response?.statusCode == 402) {
         throw SharingNotPermittedForFreeAccountsError();
       }
       rethrow;
@@ -603,7 +601,7 @@ class CollectionsService {
       Bus.instance
           .fire(CollectionUpdatedEvent(collection.id, <File>[], "updateUrl"));
     } on DioError catch (e) {
-      if (e.response.statusCode == 402) {
+      if (e.response?.statusCode == 402) {
         throw SharingNotPermittedForFreeAccountsError();
       }
       rethrow;
@@ -618,7 +616,7 @@ class CollectionsService {
       await _enteDio.delete(
         "/collections/share-url/" + collection.id.toString(),
       );
-      collection.publicURLs.clear();
+      collection.publicURLs?.clear();
       await _db.insert(List.from([collection]));
       _cacheCollectionAttributes(collection);
       Bus.instance.fire(
@@ -674,23 +672,24 @@ class CollectionsService {
     }
   }
 
-  Collection getCollectionByID(int collectionID) {
+  Collection? getCollectionByID(int collectionID) {
     return _collectionIDToCollections[collectionID];
   }
 
   Future<Collection> createAlbum(String albumName) async {
     final key = CryptoUtil.generateKey();
-    final encryptedKeyData = CryptoUtil.encryptSync(key, _config.getKey());
-    final encryptedName = CryptoUtil.encryptSync(utf8.encode(albumName), key);
+    final encryptedKeyData = CryptoUtil.encryptSync(key, _config.getKey()!);
+    final encryptedName =
+        CryptoUtil.encryptSync(utf8.encode(albumName) as Uint8List, key);
     final collection = await createAndCacheCollection(
       Collection(
         null,
         null,
-        Sodium.bin2base64(encryptedKeyData.encryptedData),
-        Sodium.bin2base64(encryptedKeyData.nonce),
+        Sodium.bin2base64(encryptedKeyData.encryptedData!),
+        Sodium.bin2base64(encryptedKeyData.nonce!),
         null,
-        Sodium.bin2base64(encryptedName.encryptedData),
-        Sodium.bin2base64(encryptedName.nonce),
+        Sodium.bin2base64(encryptedName.encryptedData!),
+        Sodium.bin2base64(encryptedName.nonce!),
         CollectionType.album,
         CollectionAttributes(),
         null,
@@ -739,30 +738,31 @@ class CollectionsService {
 
   Future<Collection> getOrCreateForPath(String path) async {
     if (_localPathToCollectionID.containsKey(path)) {
-      final Collection cachedCollection =
+      final Collection? cachedCollection =
           _collectionIDToCollections[_localPathToCollectionID[path]];
       if (cachedCollection != null &&
           !cachedCollection.isDeleted &&
-          cachedCollection.owner.id == _config.getUserID()) {
+          cachedCollection.owner?.id == _config.getUserID()) {
         return cachedCollection;
       }
     }
     final key = CryptoUtil.generateKey();
-    final encryptedKeyData = CryptoUtil.encryptSync(key, _config.getKey());
-    final encryptedPath = CryptoUtil.encryptSync(utf8.encode(path), key);
+    final encryptedKeyData = CryptoUtil.encryptSync(key, _config.getKey()!);
+    final encryptedPath =
+        CryptoUtil.encryptSync(utf8.encode(path) as Uint8List, key);
     final collection = await createAndCacheCollection(
       Collection(
         null,
         null,
-        Sodium.bin2base64(encryptedKeyData.encryptedData),
-        Sodium.bin2base64(encryptedKeyData.nonce),
+        Sodium.bin2base64(encryptedKeyData.encryptedData!),
+        Sodium.bin2base64(encryptedKeyData.nonce!),
         null,
-        Sodium.bin2base64(encryptedPath.encryptedData),
-        Sodium.bin2base64(encryptedPath.nonce),
+        Sodium.bin2base64(encryptedPath.encryptedData!),
+        Sodium.bin2base64(encryptedPath.nonce!),
         CollectionType.folder,
         CollectionAttributes(
-          encryptedPath: Sodium.bin2base64(encryptedPath.encryptedData),
-          pathDecryptionNonce: Sodium.bin2base64(encryptedPath.nonce),
+          encryptedPath: Sodium.bin2base64(encryptedPath.encryptedData!),
+          pathDecryptionNonce: Sodium.bin2base64(encryptedPath.nonce!),
           version: 1,
         ),
         null,
@@ -774,9 +774,8 @@ class CollectionsService {
   }
 
   Future<void> addToCollection(int collectionID, List<File> files) async {
-    final containsUploadedFile = files.firstWhere(
+    final containsUploadedFile = files.firstWhereOrNull(
           (element) => element.uploadedFileID != null,
-          orElse: () => null,
         ) !=
         null;
     if (containsUploadedFile) {
@@ -805,13 +804,13 @@ class CollectionsService {
         file.collectionID = collectionID;
         final encryptedKeyData =
             CryptoUtil.encryptSync(key, getCollectionKey(collectionID));
-        file.encryptedKey = Sodium.bin2base64(encryptedKeyData.encryptedData);
-        file.keyDecryptionNonce = Sodium.bin2base64(encryptedKeyData.nonce);
+        file.encryptedKey = Sodium.bin2base64(encryptedKeyData.encryptedData!);
+        file.keyDecryptionNonce = Sodium.bin2base64(encryptedKeyData.nonce!);
         params["files"].add(
           CollectionFileItem(
-            file.uploadedFileID,
-            file.encryptedKey,
-            file.keyDecryptionNonce,
+            file.uploadedFileID!,
+            file.encryptedKey!,
+            file.keyDecryptionNonce!,
           ).toMap(),
         );
       }
@@ -831,13 +830,13 @@ class CollectionsService {
 
   Future<File> linkLocalFileToExistingUploadedFileInAnotherCollection(
     int destCollectionID, {
-    @required File localFileToUpload,
-    @required File existingUploadedFile,
+    required File localFileToUpload,
+    required File existingUploadedFile,
   }) async {
     final params = <String, dynamic>{};
     params["collectionID"] = destCollectionID;
     params["files"] = [];
-    final int uploadedFileID = existingUploadedFile.uploadedFileID;
+    final int uploadedFileID = existingUploadedFile.uploadedFileID!;
 
     // encrypt the fileKey with destination collection's key
     final fileKey = decryptFileKey(existingUploadedFile);
@@ -845,15 +844,15 @@ class CollectionsService {
         CryptoUtil.encryptSync(fileKey, getCollectionKey(destCollectionID));
 
     localFileToUpload.encryptedKey =
-        Sodium.bin2base64(encryptedKeyData.encryptedData);
+        Sodium.bin2base64(encryptedKeyData.encryptedData!);
     localFileToUpload.keyDecryptionNonce =
-        Sodium.bin2base64(encryptedKeyData.nonce);
+        Sodium.bin2base64(encryptedKeyData.nonce!);
 
     params["files"].add(
       CollectionFileItem(
         uploadedFileID,
-        localFileToUpload.encryptedKey,
-        localFileToUpload.keyDecryptionNonce,
+        localFileToUpload.encryptedKey!,
+        localFileToUpload.keyDecryptionNonce!,
       ).toMap(),
     );
 
@@ -884,13 +883,13 @@ class CollectionsService {
             null; // So that a new entry is created in the FilesDB
         file.collectionID = toCollectionID;
         final encryptedKeyData = CryptoUtil.encryptSync(key, toCollectionKey);
-        file.encryptedKey = Sodium.bin2base64(encryptedKeyData.encryptedData);
-        file.keyDecryptionNonce = Sodium.bin2base64(encryptedKeyData.nonce);
+        file.encryptedKey = Sodium.bin2base64(encryptedKeyData.encryptedData!);
+        file.keyDecryptionNonce = Sodium.bin2base64(encryptedKeyData.nonce!);
         params["files"].add(
           CollectionFileItem(
-            file.uploadedFileID,
-            file.encryptedKey,
-            file.keyDecryptionNonce,
+            file.uploadedFileID!,
+            file.encryptedKey!,
+            file.keyDecryptionNonce!,
           ).toMap(),
         );
       }
@@ -901,7 +900,7 @@ class CollectionsService {
         );
         await _filesDB.insertMultiple(batch);
         await TrashDB.instance
-            .delete(batch.map((e) => e.uploadedFileID).toList());
+            .delete(batch.map((e) => e.uploadedFileID!).toList());
         Bus.instance.fire(
           CollectionUpdatedEvent(toCollectionID, batch, "restore"),
         );
@@ -911,7 +910,7 @@ class CollectionsService {
         // but not uploaded automatically as it was trashed.
         final localIDs = batch
             .where((e) => e.localID != null)
-            .map((e) => e.localID)
+            .map((e) => e.localID!)
             .toSet()
             .toList();
         if (localIDs.isNotEmpty) {
@@ -950,13 +949,13 @@ class CollectionsService {
         file.collectionID = toCollectionID;
         final encryptedKeyData =
             CryptoUtil.encryptSync(fileKey, getCollectionKey(toCollectionID));
-        file.encryptedKey = Sodium.bin2base64(encryptedKeyData.encryptedData);
-        file.keyDecryptionNonce = Sodium.bin2base64(encryptedKeyData.nonce);
+        file.encryptedKey = Sodium.bin2base64(encryptedKeyData.encryptedData!);
+        file.keyDecryptionNonce = Sodium.bin2base64(encryptedKeyData.nonce!);
         params["files"].add(
           CollectionFileItem(
-            file.uploadedFileID,
-            file.encryptedKey,
-            file.keyDecryptionNonce,
+            file.uploadedFileID!,
+            file.encryptedKey!,
+            file.keyDecryptionNonce!,
           ).toMap(),
         );
       }
@@ -969,7 +968,7 @@ class CollectionsService {
     // remove files from old collection
     await _filesDB.removeFromCollection(
       fromCollectionID,
-      files.map((e) => e.uploadedFileID).toList(),
+      files.map((e) => e.uploadedFileID!).toList(),
     );
     Bus.instance.fire(
       CollectionUpdatedEvent(
@@ -1035,11 +1034,11 @@ class CollectionsService {
   }
 
   Future<Collection> createAndCacheCollection(
-    Collection collection, {
-    CreateRequest createRequest,
+    Collection? collection, {
+    CreateRequest? createRequest,
   }) async {
     final dynamic payload =
-        createRequest != null ? createRequest.toJson() : collection.toMap();
+        createRequest != null ? createRequest.toJson() : collection!.toMap();
     return _enteDio
         .post(
       "/collections",
@@ -1073,7 +1072,7 @@ class CollectionsService {
         _getCollectionWithDecryptedName(collection);
     if (collection.attributes.encryptedPath != null &&
         !collection.isDeleted &&
-        collection.owner.id == _config.getUserID()) {
+        collection.owner?.id == _config.getUserID()) {
       _localPathToCollectionID[decryptCollectionPath(collection)] =
           collection.id;
     }
@@ -1087,9 +1086,9 @@ class CollectionsService {
         : _config.getKey();
     return utf8.decode(
       CryptoUtil.decryptSync(
-        Sodium.base642bin(collection.attributes.encryptedPath),
+        Sodium.base642bin(collection.attributes.encryptedPath!),
         key,
-        Sodium.base642bin(collection.attributes.pathDecryptionNonce),
+        Sodium.base642bin(collection.attributes.pathDecryptionNonce!),
       ),
     );
   }

+ 34 - 30
lib/services/file_magic_service.dart

@@ -1,6 +1,5 @@
-// @dart=2.9
-
 import 'dart:convert';
+import 'dart:typed_data';
 
 import 'package:dio/dio.dart';
 import 'package:flutter_sodium/flutter_sodium.dart';
@@ -22,8 +21,8 @@ import 'package:photos/utils/file_download_util.dart';
 
 class FileMagicService {
   final _logger = Logger("FileMagicService");
-  Dio _enteDio;
-  FilesDB _filesDB;
+  late Dio _enteDio;
+  late FilesDB _filesDB;
 
   FileMagicService._privateConstructor() {
     _filesDB = FilesDB.instance;
@@ -59,12 +58,12 @@ class FileMagicService {
 
   Future<void> updatePublicMagicMetadata(
     List<File> files,
-    Map<String, dynamic> newMetadataUpdate, {
-    Map<int, Map<String, dynamic>> metadataUpdateMap,
+    Map<String, dynamic>? newMetadataUpdate, {
+    Map<int, Map<String, dynamic>>? metadataUpdateMap,
   }) async {
     final params = <String, dynamic>{};
     params['metadataList'] = [];
-    final int ownerID = Configuration.instance.getUserID();
+    final int ownerID = Configuration.instance.getUserID()!;
     try {
       for (final file in files) {
         if (file.uploadedFileID == null) {
@@ -85,8 +84,8 @@ class FileMagicService {
           "can not apply empty updates",
         );
         final Map<String, dynamic> jsonToUpdate =
-            jsonDecode(file.pubMmdEncodedJson);
-        newUpdates.forEach((key, value) {
+            jsonDecode(file.pubMmdEncodedJson ?? '{}');
+        newUpdates!.forEach((key, value) {
           jsonToUpdate[key] = value;
         });
 
@@ -96,17 +95,17 @@ class FileMagicService {
 
         final fileKey = decryptFileKey(file);
         final encryptedMMd = await CryptoUtil.encryptChaCha(
-          utf8.encode(jsonEncode(jsonToUpdate)),
+          utf8.encode(jsonEncode(jsonToUpdate)) as Uint8List,
           fileKey,
         );
         params['metadataList'].add(
           UpdateMagicMetadataRequest(
-            id: file.uploadedFileID,
+            id: file.uploadedFileID!,
             magicMetadata: MetadataRequest(
               version: file.pubMmdVersion,
               count: jsonToUpdate.length,
-              data: Sodium.bin2base64(encryptedMMd.encryptedData),
-              header: Sodium.bin2base64(encryptedMMd.header),
+              data: Sodium.bin2base64(encryptedMMd.encryptedData!),
+              header: Sodium.bin2base64(encryptedMMd.header!),
             ),
           ),
         );
@@ -119,7 +118,7 @@ class FileMagicService {
       await _filesDB.insertMultiple(files);
       RemoteSyncService.instance.sync(silently: true);
     } on DioError catch (e) {
-      if (e.response != null && e.response.statusCode == 409) {
+      if (e.response != null && e.response!.statusCode == 409) {
         RemoteSyncService.instance.sync(silently: true);
       }
       rethrow;
@@ -134,7 +133,7 @@ class FileMagicService {
     Map<String, dynamic> newMetadataUpdate,
   ) async {
     final params = <String, dynamic>{};
-    final int ownerID = Configuration.instance.getUserID();
+    final int ownerID = Configuration.instance.getUserID()!;
     final batchedFiles = files.chunks(batchSize);
     try {
       for (final batch in batchedFiles) {
@@ -151,7 +150,7 @@ class FileMagicService {
           // current update is simple replace. This will be enhanced in the future,
           // as required.
           final Map<String, dynamic> jsonToUpdate =
-              jsonDecode(file.mMdEncodedJson);
+              jsonDecode(file.mMdEncodedJson ?? '{}');
           newMetadataUpdate.forEach((key, value) {
             jsonToUpdate[key] = value;
           });
@@ -162,17 +161,17 @@ class FileMagicService {
 
           final fileKey = decryptFileKey(file);
           final encryptedMMd = await CryptoUtil.encryptChaCha(
-            utf8.encode(jsonEncode(jsonToUpdate)),
+            utf8.encode(jsonEncode(jsonToUpdate)) as Uint8List,
             fileKey,
           );
           params['metadataList'].add(
             UpdateMagicMetadataRequest(
-              id: file.uploadedFileID,
+              id: file.uploadedFileID!,
               magicMetadata: MetadataRequest(
                 version: file.mMdVersion,
                 count: jsonToUpdate.length,
-                data: Sodium.bin2base64(encryptedMMd.encryptedData),
-                header: Sodium.bin2base64(encryptedMMd.header),
+                data: Sodium.bin2base64(encryptedMMd.encryptedData!),
+                header: Sodium.bin2base64(encryptedMMd.header!),
               ),
             ),
           );
@@ -187,7 +186,7 @@ class FileMagicService {
       // should be eventually synced after remote sync has completed
       RemoteSyncService.instance.sync(silently: true);
     } on DioError catch (e) {
-      if (e.response != null && e.response.statusCode == 409) {
+      if (e.response != null && e.response!.statusCode == 409) {
         RemoteSyncService.instance.sync(silently: true);
       }
       rethrow;
@@ -200,9 +199,9 @@ class FileMagicService {
 
 class UpdateMagicMetadataRequest {
   final int id;
-  final MetadataRequest magicMetadata;
+  final MetadataRequest? magicMetadata;
 
-  UpdateMagicMetadataRequest({this.id, this.magicMetadata});
+  UpdateMagicMetadataRequest({required this.id, required this.magicMetadata});
 
   factory UpdateMagicMetadataRequest.fromJson(dynamic json) {
     return UpdateMagicMetadataRequest(
@@ -217,19 +216,24 @@ class UpdateMagicMetadataRequest {
     final map = <String, dynamic>{};
     map['id'] = id;
     if (magicMetadata != null) {
-      map['magicMetadata'] = magicMetadata.toJson();
+      map['magicMetadata'] = magicMetadata!.toJson();
     }
     return map;
   }
 }
 
 class MetadataRequest {
-  int version;
-  int count;
-  String data;
-  String header;
-
-  MetadataRequest({this.version, this.count, this.data, this.header});
+  int? version;
+  int? count;
+  String? data;
+  String? header;
+
+  MetadataRequest({
+    required this.version,
+    required this.count,
+    required this.data,
+    required this.header,
+  });
 
   MetadataRequest.fromJson(dynamic json) {
     version = json['version'];

+ 2 - 0
lib/utils/file_uploader.dart

@@ -56,6 +56,7 @@ class FileUploader {
   // Maintains the count of files in the current upload session.
   // Upload session is the period between the first entry into the _queue and last entry out of the _queue
   int _totalCountInUploadSession = 0;
+
   // _uploadCounter indicates number of uploads which are currently in progress
   int _uploadCounter = 0;
   int _videoUploadCounter = 0;
@@ -68,6 +69,7 @@ class FileUploader {
       _uploadURLFetchInProgress = null;
     });
   }
+
   static FileUploader instance = FileUploader._privateConstructor();
 
   Future<void> init(SharedPreferences preferences, bool isBackground) async {