Преглед на файлове

NullSafety: Fix select files & download

Neeraj Gupta преди 2 години
родител
ревизия
bc4e759e01

+ 0 - 3
lib/models/file.dart

@@ -10,12 +10,9 @@ import 'package:photos/models/ente_file.dart';
 import 'package:photos/models/file_type.dart';
 import 'package:photos/models/file_type.dart';
 import 'package:photos/models/location.dart';
 import 'package:photos/models/location.dart';
 import 'package:photos/models/magic_metadata.dart';
 import 'package:photos/models/magic_metadata.dart';
-// ignore: import_of_legacy_library_into_null_safe
 import 'package:photos/services/feature_flag_service.dart';
 import 'package:photos/services/feature_flag_service.dart';
 import 'package:photos/utils/date_time_util.dart';
 import 'package:photos/utils/date_time_util.dart';
-// ignore: import_of_legacy_library_into_null_safe
 import 'package:photos/utils/exif_util.dart';
 import 'package:photos/utils/exif_util.dart';
-// ignore: import_of_legacy_library_into_null_safe
 import 'package:photos/utils/file_uploader_util.dart';
 import 'package:photos/utils/file_uploader_util.dart';
 
 
 class File extends EnteFile {
 class File extends EnteFile {

+ 3 - 4
lib/ui/home/home_gallery_widget.dart

@@ -1,4 +1,3 @@
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/core/event_bus.dart';
@@ -18,13 +17,13 @@ import 'package:photos/ui/viewer/gallery/gallery.dart';
 class HomeGalleryWidget extends StatelessWidget {
 class HomeGalleryWidget extends StatelessWidget {
   final Widget? header;
   final Widget? header;
   final Widget? footer;
   final Widget? footer;
-  final SelectedFiles? selectedFiles;
+  final SelectedFiles selectedFiles;
 
 
   const HomeGalleryWidget({
   const HomeGalleryWidget({
     Key? key,
     Key? key,
     this.header,
     this.header,
     this.footer,
     this.footer,
-    this.selectedFiles,
+    required this.selectedFiles,
   }) : super(key: key);
   }) : super(key: key);
 
 
   @override
   @override
@@ -88,7 +87,7 @@ class HomeGalleryWidget extends StatelessWidget {
     return Stack(
     return Stack(
       children: [
       children: [
         gallery,
         gallery,
-        FileSelectionOverlayBar(GalleryType.homepage, selectedFiles!)
+        FileSelectionOverlayBar(GalleryType.homepage, selectedFiles)
       ],
       ],
     );
     );
     // return gallery;
     // return gallery;

+ 32 - 33
lib/ui/huge_listview/lazy_loading_gallery.dart

@@ -1,5 +1,3 @@
-
-
 import 'dart:async';
 import 'dart:async';
 import 'dart:math';
 import 'dart:math';
 
 
@@ -25,12 +23,12 @@ import 'package:photos/utils/navigation_util.dart';
 import 'package:visibility_detector/visibility_detector.dart';
 import 'package:visibility_detector/visibility_detector.dart';
 
 
 class LazyLoadingGallery extends StatefulWidget {
 class LazyLoadingGallery extends StatefulWidget {
-  final List<File?> files;
+  final List<File> files;
   final int index;
   final int index;
   final Stream<FilesUpdatedEvent>? reloadEvent;
   final Stream<FilesUpdatedEvent>? reloadEvent;
   final Set<EventType> removalEventTypes;
   final Set<EventType> removalEventTypes;
   final GalleryLoader asyncLoader;
   final GalleryLoader asyncLoader;
-  final SelectedFiles? selectedFiles;
+  final SelectedFiles selectedFiles;
   final String tag;
   final String tag;
   final String? logTag;
   final String? logTag;
   final Stream<int> currentIndexStream;
   final Stream<int> currentIndexStream;
@@ -60,7 +58,7 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
 
 
   late Logger _logger;
   late Logger _logger;
 
 
-  List<File?>? _files;
+  late List<File> _files;
   late StreamSubscription<FilesUpdatedEvent> _reloadEventSubscription;
   late StreamSubscription<FilesUpdatedEvent> _reloadEventSubscription;
   late StreamSubscription<int> _currentIndexSubscription;
   late StreamSubscription<int> _currentIndexSubscription;
   bool? _shouldRender;
   bool? _shouldRender;
@@ -71,7 +69,7 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
   @override
   @override
   void initState() {
   void initState() {
     //this is for removing the 'select all from day' icon on unselecting all files with 'cancel'
     //this is for removing the 'select all from day' icon on unselecting all files with 'cancel'
-    widget.selectedFiles!.addListener(_selectedFilesListener);
+    widget.selectedFiles.addListener(_selectedFilesListener);
     super.initState();
     super.initState();
     _init();
     _init();
   }
   }
@@ -96,7 +94,7 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
 
 
   Future _onReload(FilesUpdatedEvent event) async {
   Future _onReload(FilesUpdatedEvent event) async {
     final galleryDate =
     final galleryDate =
-        DateTime.fromMicrosecondsSinceEpoch(_files![0]!.creationTime!);
+        DateTime.fromMicrosecondsSinceEpoch(_files[0].creationTime!);
     final filesUpdatedThisDay = event.updatedFiles.where((file) {
     final filesUpdatedThisDay = event.updatedFiles.where((file) {
       final fileDate = DateTime.fromMicrosecondsSinceEpoch(file.creationTime!);
       final fileDate = DateTime.fromMicrosecondsSinceEpoch(file.creationTime!);
       return fileDate.year == galleryDate.year &&
       return fileDate.year == galleryDate.year &&
@@ -134,16 +132,16 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
             uploadedFileIds.add(file.uploadedFileID);
             uploadedFileIds.add(file.uploadedFileID);
           }
           }
         }
         }
-        final List<File?> files = [];
-        files.addAll(_files!);
+        final List<File> files = [];
+        files.addAll(_files);
         files.removeWhere(
         files.removeWhere(
           (file) =>
           (file) =>
-              generatedFileIDs.contains(file!.generatedID) ||
+              generatedFileIDs.contains(file.generatedID) ||
               uploadedFileIds.contains(file.uploadedFileID),
               uploadedFileIds.contains(file.uploadedFileID),
         );
         );
         if (kDebugMode) {
         if (kDebugMode) {
           _logger.finest(
           _logger.finest(
-            "removed ${_files!.length - files.length} due to ${event.reason}",
+            "removed ${_files.length - files.length} due to ${event.reason}",
           );
           );
         }
         }
         if (mounted) {
         if (mounted) {
@@ -163,7 +161,7 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
   void dispose() {
   void dispose() {
     _reloadEventSubscription.cancel();
     _reloadEventSubscription.cancel();
     _currentIndexSubscription.cancel();
     _currentIndexSubscription.cancel();
-    widget.selectedFiles!.removeListener(_selectedFilesListener);
+    widget.selectedFiles.removeListener(_selectedFilesListener);
     _toggleSelectAllFromDay.dispose();
     _toggleSelectAllFromDay.dispose();
     _showSelectAllButton.dispose();
     _showSelectAllButton.dispose();
     _areAllFromDaySelected.dispose();
     _areAllFromDaySelected.dispose();
@@ -181,7 +179,7 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    if (_files!.isEmpty) {
+    if (_files.isEmpty) {
       return const SizedBox.shrink();
       return const SizedBox.shrink();
     }
     }
     return Column(
     return Column(
@@ -191,7 +189,7 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
           children: [
           children: [
             getDayWidget(
             getDayWidget(
               context,
               context,
-              _files![0]!.creationTime!,
+              _files[0].creationTime!,
               widget.photoGirdSize!,
               widget.photoGirdSize!,
             ),
             ),
             ValueListenableBuilder(
             ValueListenableBuilder(
@@ -235,7 +233,7 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
         _shouldRender!
         _shouldRender!
             ? _getGallery()
             ? _getGallery()
             : PlaceHolderWidget(
             : PlaceHolderWidget(
-                _files!.length,
+                _files.length,
                 widget.photoGirdSize!,
                 widget.photoGirdSize!,
               ),
               ),
       ],
       ],
@@ -247,18 +245,18 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
     final subGalleryItemLimit = widget.photoGirdSize! < photoGridSizeDefault
     final subGalleryItemLimit = widget.photoGirdSize! < photoGridSizeDefault
         ? subGalleryLimitMin
         ? subGalleryLimitMin
         : subGalleryLimitDefault;
         : subGalleryLimitDefault;
-    for (int index = 0; index < _files!.length; index += subGalleryItemLimit) {
+    for (int index = 0; index < _files.length; index += subGalleryItemLimit) {
       childGalleries.add(
       childGalleries.add(
         LazyLoadingGridView(
         LazyLoadingGridView(
           widget.tag,
           widget.tag,
-          _files!.sublist(
+          _files.sublist(
             index,
             index,
-            min(index + subGalleryItemLimit, _files!.length),
+            min(index + subGalleryItemLimit, _files.length),
           ),
           ),
           widget.asyncLoader,
           widget.asyncLoader,
           widget.selectedFiles,
           widget.selectedFiles,
           index == 0,
           index == 0,
-          _files!.length > kRecycleLimit,
+          _files.length > kRecycleLimit,
           _toggleSelectAllFromDay,
           _toggleSelectAllFromDay,
           _areAllFromDaySelected,
           _areAllFromDaySelected,
           widget.photoGirdSize,
           widget.photoGirdSize,
@@ -272,7 +270,7 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
   }
   }
 
 
   void _selectedFilesListener() {
   void _selectedFilesListener() {
-    if (widget.selectedFiles!.files.isEmpty) {
+    if (widget.selectedFiles.files.isEmpty) {
       _showSelectAllButton.value = false;
       _showSelectAllButton.value = false;
     } else {
     } else {
       _showSelectAllButton.value = true;
       _showSelectAllButton.value = true;
@@ -282,9 +280,9 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
 
 
 class LazyLoadingGridView extends StatefulWidget {
 class LazyLoadingGridView extends StatefulWidget {
   final String tag;
   final String tag;
-  final List<File?> filesInDay;
+  final List<File> filesInDay;
   final GalleryLoader asyncLoader;
   final GalleryLoader asyncLoader;
-  final SelectedFiles? selectedFiles;
+  final SelectedFiles selectedFiles;
   final bool shouldRender;
   final bool shouldRender;
   final bool shouldRecycle;
   final bool shouldRecycle;
   final ValueNotifier toggleSelectAllFromDay;
   final ValueNotifier toggleSelectAllFromDay;
@@ -317,7 +315,7 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
   void initState() {
   void initState() {
     _shouldRender = widget.shouldRender;
     _shouldRender = widget.shouldRender;
     _currentUserID = Configuration.instance.getUserID();
     _currentUserID = Configuration.instance.getUserID();
-    widget.selectedFiles!.addListener(_selectedFilesListener);
+    widget.selectedFiles.addListener(_selectedFilesListener);
     _clearSelectionsEvent =
     _clearSelectionsEvent =
         Bus.instance.on<ClearSelectionsEvent>().listen((event) {
         Bus.instance.on<ClearSelectionsEvent>().listen((event) {
       if (mounted) {
       if (mounted) {
@@ -330,7 +328,7 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
 
 
   @override
   @override
   void dispose() {
   void dispose() {
-    widget.selectedFiles!.removeListener(_selectedFilesListener);
+    widget.selectedFiles.removeListener(_selectedFilesListener);
     _clearSelectionsEvent.cancel();
     _clearSelectionsEvent.cancel();
     widget.toggleSelectAllFromDay
     widget.toggleSelectAllFromDay
         .removeListener(_toggleSelectAllFromDayListener);
         .removeListener(_toggleSelectAllFromDayListener);
@@ -396,7 +394,7 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
       physics: const NeverScrollableScrollPhysics(),
       physics: const NeverScrollableScrollPhysics(),
       // to disable GridView's scrolling
       // to disable GridView's scrolling
       itemBuilder: (context, index) {
       itemBuilder: (context, index) {
-        return _buildFile(context, widget.filesInDay[index]!);
+        return _buildFile(context, widget.filesInDay[index]);
       },
       },
       itemCount: widget.filesInDay.length,
       itemCount: widget.filesInDay.length,
       gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
       gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
@@ -409,7 +407,7 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
   }
   }
 
 
   Widget _buildFile(BuildContext context, File file) {
   Widget _buildFile(BuildContext context, File file) {
-    final isFileSelected = widget.selectedFiles!.isFileSelected(file);
+    final isFileSelected = widget.selectedFiles.isFileSelected(file);
     Color selectionColor = Colors.white;
     Color selectionColor = Colors.white;
     if (isFileSelected &&
     if (isFileSelected &&
         file.isUploaded &&
         file.isUploaded &&
@@ -423,7 +421,7 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
     }
     }
     return GestureDetector(
     return GestureDetector(
       onTap: () {
       onTap: () {
-        if (widget.selectedFiles!.files.isNotEmpty) {
+        if (widget.selectedFiles.files.isNotEmpty) {
           _selectFile(file);
           _selectFile(file);
         } else {
         } else {
           _routeToDetailPage(file, context);
           _routeToDetailPage(file, context);
@@ -478,7 +476,7 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
   }
   }
 
 
   void _selectFile(File file) {
   void _selectFile(File file) {
-    widget.selectedFiles!.toggleSelection(file);
+    widget.selectedFiles.toggleSelection(file);
   }
   }
 
 
   void _routeToDetailPage(File file, BuildContext context) {
   void _routeToDetailPage(File file, BuildContext context) {
@@ -494,14 +492,14 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
   }
   }
 
 
   void _selectedFilesListener() {
   void _selectedFilesListener() {
-    if (widget.selectedFiles!.files.containsAll(widget.filesInDay.toSet())) {
+    if (widget.selectedFiles.files.containsAll(widget.filesInDay.toSet())) {
       widget.areAllFilesSelected.value = true;
       widget.areAllFilesSelected.value = true;
     } else {
     } else {
       widget.areAllFilesSelected.value = false;
       widget.areAllFilesSelected.value = false;
     }
     }
     bool shouldRefresh = false;
     bool shouldRefresh = false;
     for (final file in widget.filesInDay) {
     for (final file in widget.filesInDay) {
-      if (widget.selectedFiles!.isPartOfLastSelected(file!)) {
+      if (widget.selectedFiles.isPartOfLastSelected(file)) {
         shouldRefresh = true;
         shouldRefresh = true;
       }
       }
     }
     }
@@ -511,12 +509,13 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
   }
   }
 
 
   void _toggleSelectAllFromDayListener() {
   void _toggleSelectAllFromDayListener() {
-    if (widget.selectedFiles!.files.containsAll(widget.filesInDay.toSet())) {
+    if (widget.selectedFiles.files.containsAll(widget.filesInDay.toSet())) {
       setState(() {
       setState(() {
-        widget.selectedFiles!.unSelectAll(widget.filesInDay.toSet() as Set<File>);
+        widget.selectedFiles
+            .unSelectAll(widget.filesInDay.toSet() as Set<File>);
       });
       });
     } else {
     } else {
-      widget.selectedFiles!.selectAll(widget.filesInDay.toSet() as Set<File>);
+      widget.selectedFiles.selectAll(widget.filesInDay.toSet() as Set<File>);
     }
     }
   }
   }
 }
 }

+ 3 - 4
lib/ui/viewer/gallery/collection_page.dart

@@ -1,11 +1,10 @@
-
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/db/files_db.dart';
 import 'package:photos/db/files_db.dart';
 import 'package:photos/events/collection_updated_event.dart';
 import 'package:photos/events/collection_updated_event.dart';
 import 'package:photos/events/files_updated_event.dart';
 import 'package:photos/events/files_updated_event.dart';
 import 'package:photos/models/collection_items.dart';
 import 'package:photos/models/collection_items.dart';
+import 'package:photos/models/file.dart';
 import 'package:photos/models/file_load_result.dart';
 import 'package:photos/models/file_load_result.dart';
 import 'package:photos/models/gallery_type.dart';
 import 'package:photos/models/gallery_type.dart';
 import 'package:photos/models/selected_files.dart';
 import 'package:photos/models/selected_files.dart';
@@ -56,8 +55,8 @@ class _CollectionPageState extends State<CollectionPage> {
     if (widget.hasVerifiedLock == false && widget.c.collection.isHidden()) {
     if (widget.hasVerifiedLock == false && widget.c.collection.isHidden()) {
       return const EmptyState();
       return const EmptyState();
     }
     }
-    final initialFiles =
-        widget.c.thumbnail != null ? [widget.c.thumbnail] : null;
+    final List<File>? initialFiles =
+        widget.c.thumbnail != null ? [widget.c.thumbnail!] : null;
     final gallery = Gallery(
     final gallery = Gallery(
       asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) async {
       asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) async {
         final FileLoadResult result =
         final FileLoadResult result =

+ 1 - 3
lib/ui/viewer/gallery/device_folder_page.dart

@@ -1,5 +1,3 @@
-
-
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/core/event_bus.dart';
@@ -45,7 +43,7 @@ class DeviceFolderPage extends StatelessWidget {
       header: Configuration.instance.hasConfiguredAccount()
       header: Configuration.instance.hasConfiguredAccount()
           ? BackupConfigurationHeaderWidget(deviceCollection)
           ? BackupConfigurationHeaderWidget(deviceCollection)
           : const SizedBox.shrink(),
           : const SizedBox.shrink(),
-      initialFiles: [deviceCollection.thumbnail],
+      initialFiles: [deviceCollection.thumbnail!],
     );
     );
     return Scaffold(
     return Scaffold(
       appBar: PreferredSize(
       appBar: PreferredSize(

+ 12 - 12
lib/ui/viewer/gallery/gallery.dart

@@ -29,11 +29,11 @@ typedef GalleryLoader = Future<FileLoadResult> Function(
 
 
 class Gallery extends StatefulWidget {
 class Gallery extends StatefulWidget {
   final GalleryLoader asyncLoader;
   final GalleryLoader asyncLoader;
-  final List<File?>? initialFiles;
+  final List<File>? initialFiles;
   final Stream<FilesUpdatedEvent>? reloadEvent;
   final Stream<FilesUpdatedEvent>? reloadEvent;
   final List<Stream<Event>>? forceReloadEvents;
   final List<Stream<Event>>? forceReloadEvents;
   final Set<EventType> removalEventTypes;
   final Set<EventType> removalEventTypes;
-  final SelectedFiles? selectedFiles;
+  final SelectedFiles selectedFiles;
   final String tagPrefix;
   final String tagPrefix;
   final Widget? header;
   final Widget? header;
   final Widget? footer;
   final Widget? footer;
@@ -69,7 +69,7 @@ class _GalleryState extends State<Gallery> {
   final _hugeListViewKey = GlobalKey<HugeListViewState>();
   final _hugeListViewKey = GlobalKey<HugeListViewState>();
 
 
   late Logger _logger;
   late Logger _logger;
-  List<List<File?>> _collatedFiles = [];
+  List<List<File>> _collatedFiles = [];
   bool _hasLoadedFiles = false;
   bool _hasLoadedFiles = false;
   ItemScrollController? _itemScroller;
   ItemScrollController? _itemScroller;
   StreamSubscription<FilesUpdatedEvent>? _reloadEventSubscription;
   StreamSubscription<FilesUpdatedEvent>? _reloadEventSubscription;
@@ -167,7 +167,7 @@ class _GalleryState extends State<Gallery> {
   }
   }
 
 
   // Collates files and returns `true` if it resulted in a gallery reload
   // Collates files and returns `true` if it resulted in a gallery reload
-  bool _onFilesLoaded(List<File?> files) {
+  bool _onFilesLoaded(List<File> files) {
     final updatedCollatedFiles = _collateFiles(files);
     final updatedCollatedFiles = _collateFiles(files);
     if (_collatedFiles.length != updatedCollatedFiles.length ||
     if (_collatedFiles.length != updatedCollatedFiles.length ||
         _collatedFiles.isEmpty) {
         _collatedFiles.isEmpty) {
@@ -260,7 +260,7 @@ class _GalleryState extends State<Gallery> {
       labelTextBuilder: (int index) {
       labelTextBuilder: (int index) {
         return getMonthAndYear(
         return getMonthAndYear(
           DateTime.fromMicrosecondsSinceEpoch(
           DateTime.fromMicrosecondsSinceEpoch(
-            _collatedFiles[index][0]!.creationTime!,
+            _collatedFiles[index][0].creationTime!,
           ),
           ),
         );
         );
       },
       },
@@ -278,16 +278,16 @@ class _GalleryState extends State<Gallery> {
     );
     );
   }
   }
 
 
-  List<List<File?>> _collateFiles(List<File?> files) {
-    final List<File?> dailyFiles = [];
-    final List<List<File?>> collatedFiles = [];
+  List<List<File>> _collateFiles(List<File> files) {
+    final List<File> dailyFiles = [];
+    final List<List<File>> collatedFiles = [];
     for (int index = 0; index < files.length; index++) {
     for (int index = 0; index < files.length; index++) {
       if (index > 0 &&
       if (index > 0 &&
           !areFromSameDay(
           !areFromSameDay(
-            files[index - 1]!.creationTime!,
-            files[index]!.creationTime!,
+            files[index - 1].creationTime!,
+            files[index].creationTime!,
           )) {
           )) {
-        final List<File?> collatedDailyFiles = [];
+        final List<File> collatedDailyFiles = [];
         collatedDailyFiles.addAll(dailyFiles);
         collatedDailyFiles.addAll(dailyFiles);
         collatedFiles.add(collatedDailyFiles);
         collatedFiles.add(collatedDailyFiles);
         dailyFiles.clear();
         dailyFiles.clear();
@@ -298,7 +298,7 @@ class _GalleryState extends State<Gallery> {
       collatedFiles.add(dailyFiles);
       collatedFiles.add(dailyFiles);
     }
     }
     collatedFiles
     collatedFiles
-        .sort((a, b) => b[0]!.creationTime!.compareTo(a[0]!.creationTime!));
+        .sort((a, b) => b[0].creationTime!.compareTo(a[0].creationTime!));
     return collatedFiles;
     return collatedFiles;
   }
   }
 }
 }

+ 1 - 1
lib/utils/file_util.dart

@@ -157,7 +157,7 @@ Future<bool> isFileCached(ente.File file, {bool liveVideo = false}) async {
 }
 }
 
 
 final Map<int, Future<_LivePhoto?>> _livePhotoDownloadsTracker =
 final Map<int, Future<_LivePhoto?>> _livePhotoDownloadsTracker =
-    <int, Future<_LivePhoto>>{};
+    <int, Future<_LivePhoto?>>{};
 
 
 Future<io.File?> _getLivePhotoFromServer(
 Future<io.File?> _getLivePhotoFromServer(
   ente.File file, {
   ente.File file, {