浏览代码

Prevent entire gallery reloads for selection

Vishnu Mohandas 4 年之前
父节点
当前提交
abebf11f38

+ 4 - 3
lib/models/selected_files.dart

@@ -3,7 +3,7 @@ import 'package:photos/models/file.dart';
 
 class SelectedFiles extends ChangeNotifier {
   final files = Set<File>();
-  File latestSelection;
+  final lastSelections = Set<File>();
 
   void toggleSelection(File file) {
     if (files.contains(file)) {
@@ -11,13 +11,14 @@ class SelectedFiles extends ChangeNotifier {
     } else {
       files.add(file);
     }
-    latestSelection = file;
+    lastSelections.clear();
+     lastSelections.add(file);
     notifyListeners();
   }
 
   void clearAll() {
+    lastSelections.addAll(files);
     files.clear();
-    latestSelection = null;
     notifyListeners();
   }
 }

+ 30 - 28
lib/ui/collection_page.dart

@@ -9,42 +9,44 @@ import 'package:photos/models/selected_files.dart';
 import 'gallery.dart';
 import 'gallery_app_bar_widget.dart';
 
-class CollectionPage extends StatefulWidget {
+class CollectionPage extends StatelessWidget {
   final Collection collection;
   final String tagPrefix;
+  final _selectedFiles = SelectedFiles();
 
-  const CollectionPage(this.collection,
-      {this.tagPrefix = "collection", Key key})
+  CollectionPage(this.collection, {this.tagPrefix = "collection", Key key})
       : super(key: key);
 
-  @override
-  _CollectionPageState createState() => _CollectionPageState();
-}
-
-class _CollectionPageState extends State<CollectionPage> {
-  final _selectedFiles = SelectedFiles();
-
   @override
   Widget build(Object context) {
+    final gallery = Gallery(
+      asyncLoader: (creationStartTime, creationEndTime, {limit}) {
+        return FilesDB.instance.getFilesInCollection(
+            collection.id, creationStartTime, creationEndTime,
+            limit: limit);
+      },
+      reloadEvent: Bus.instance
+          .on<CollectionUpdatedEvent>()
+          .where((event) => event.collectionID == collection.id),
+      tagPrefix: tagPrefix,
+      selectedFiles: _selectedFiles,
+    );
     return Scaffold(
-      appBar: GalleryAppBarWidget(
-        GalleryAppBarType.collection,
-        widget.collection.name,
-        _selectedFiles,
-        collection: widget.collection,
-      ),
-      body: Gallery(
-        asyncLoader: (creationStartTime, creationEndTime, {limit}) {
-          return FilesDB.instance.getFilesInCollection(
-              widget.collection.id, creationStartTime, creationEndTime,
-              limit: limit);
-        },
-        reloadEvent: Bus.instance
-            .on<CollectionUpdatedEvent>()
-            .where((event) => event.collectionID == widget.collection.id),
-        tagPrefix: widget.tagPrefix,
-        selectedFiles: _selectedFiles,
-      ),
+      body: Stack(children: [
+        Padding(
+          padding: const EdgeInsets.only(top: 80),
+          child: gallery,
+        ),
+        Container(
+          height: 80,
+          child: GalleryAppBarWidget(
+            GalleryAppBarType.collection,
+            collection.name,
+            _selectedFiles,
+            collection: collection,
+          ),
+        )
+      ]),
     );
   }
 }

+ 23 - 19
lib/ui/device_folder_page.dart

@@ -9,46 +9,50 @@ import 'package:photos/models/selected_files.dart';
 import 'package:photos/ui/gallery.dart';
 import 'package:photos/ui/gallery_app_bar_widget.dart';
 
-class DeviceFolderPage extends StatefulWidget {
+class DeviceFolderPage extends StatelessWidget {
   final DeviceFolder folder;
-
-  const DeviceFolderPage(this.folder, {Key key}) : super(key: key);
-
-  @override
-  _DeviceFolderPageState createState() => _DeviceFolderPageState();
-}
-
-class _DeviceFolderPageState extends State<DeviceFolderPage> {
   final _selectedFiles = SelectedFiles();
 
+  DeviceFolderPage(this.folder, {Key key}) : super(key: key);
+
   @override
   Widget build(Object context) {
     final gallery = Gallery(
       asyncLoader: (creationStartTime, creationEndTime, {limit}) {
         return FilesDB.instance.getFilesInPath(
-            widget.folder.path, creationStartTime, creationEndTime,
+            folder.path, creationStartTime, creationEndTime,
             limit: limit);
       },
       reloadEvent: Bus.instance.on<LocalPhotosUpdatedEvent>(),
-      tagPrefix: "device_folder:" + widget.folder.path,
+      tagPrefix: "device_folder:" + folder.path,
       selectedFiles: _selectedFiles,
       headerWidget: Configuration.instance.hasConfiguredAccount()
           ? _getHeaderWidget()
           : Container(),
     );
     return Scaffold(
-      appBar: GalleryAppBarWidget(
-        GalleryAppBarType.local_folder,
-        widget.folder.name,
-        _selectedFiles,
-        path: widget.folder.thumbnail.deviceFolder,
+      body: Stack(
+        children: [
+          Padding(
+            padding: const EdgeInsets.only(top: 80),
+            child: gallery,
+          ),
+          Container(
+            height: 80,
+            child: GalleryAppBarWidget(
+              GalleryAppBarType.local_folder,
+              folder.name,
+              _selectedFiles,
+              path: folder.thumbnail.deviceFolder,
+            ),
+          )
+        ],
       ),
-      body: gallery,
     );
   }
 
   Widget _getHeaderWidget() {
-    return BackupConfigurationHeaderWidget(widget.folder.path);
+    return BackupConfigurationHeaderWidget(folder.path);
   }
 }
 
@@ -71,7 +75,7 @@ class _BackupConfigurationHeaderWidgetState
     return Container(
       padding: EdgeInsets.only(left: 12, right: 12),
       margin: EdgeInsets.only(bottom: 12),
-      color: Colors.grey.withOpacity(0.15),
+      color: Color.fromRGBO(10, 40, 40, 0.3),
       child: Row(
         mainAxisAlignment: MainAxisAlignment.spaceBetween,
         children: [

+ 0 - 32
lib/ui/gallery.dart

@@ -7,7 +7,6 @@ import 'package:photos/events/files_updated_event.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/models/selected_files.dart';
 import 'package:photos/ui/common_elements.dart';
-import 'package:photos/ui/gallery_app_bar_widget.dart';
 import 'package:photos/ui/huge_listview/huge_listview.dart';
 import 'package:photos/ui/huge_listview/lazy_loading_gallery.dart';
 import 'package:photos/ui/huge_listview/place_holder_widget.dart';
@@ -49,7 +48,6 @@ class _GalleryState extends State<Gallery> {
   int _index = 0;
   List<List<File>> _collatedFiles = [];
   bool _hasLoadedFiles = false;
-  bool _shouldShowAppBar = false;
   StreamSubscription<FilesUpdatedEvent> _reloadEventSubscription;
 
   @override
@@ -62,23 +60,6 @@ class _GalleryState extends State<Gallery> {
         _loadFiles();
       });
     }
-    if (widget.isHomePageGallery) {
-      widget.selectedFiles.addListener(() {
-        if (widget.selectedFiles.files.isEmpty) {
-          if (_shouldShowAppBar && mounted) {
-            setState(() {
-              _shouldShowAppBar = false;
-            });
-          }
-        } else {
-          if (!_shouldShowAppBar && mounted) {
-            setState(() {
-              _shouldShowAppBar = true;
-            });
-          }
-        }
-      });
-    }
     _loadFiles(limit: kInitialLoadLimit).then((value) => _loadFiles());
     super.initState();
   }
@@ -120,19 +101,6 @@ class _GalleryState extends State<Gallery> {
         margin: const EdgeInsets.only(bottom: 50),
         child: gallery,
       );
-      if (_shouldShowAppBar) {
-        gallery = Stack(children: [
-          gallery,
-          Container(
-            height: 60,
-            child: GalleryAppBarWidget(
-              GalleryAppBarType.homepage,
-              null,
-              widget.selectedFiles,
-            ),
-          ),
-        ]);
-      }
     }
     return gallery;
   }

+ 4 - 6
lib/ui/gallery_app_bar_widget.dart

@@ -26,8 +26,7 @@ enum GalleryAppBarType {
   search_results,
 }
 
-class GalleryAppBarWidget extends StatefulWidget
-    implements PreferredSizeWidget {
+class GalleryAppBarWidget extends StatefulWidget {
   final GalleryAppBarType type;
   final String title;
   final SelectedFiles selectedFiles;
@@ -44,9 +43,6 @@ class GalleryAppBarWidget extends StatefulWidget
 
   @override
   _GalleryAppBarWidgetState createState() => _GalleryAppBarWidgetState();
-
-  @override
-  Size get preferredSize => Size.fromHeight(60.0);
 }
 
 class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
@@ -78,7 +74,9 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
   Widget build(BuildContext context) {
     if (widget.selectedFiles.files.isEmpty) {
       return AppBar(
-        backgroundColor: Color(0x00000000),
+        backgroundColor: widget.type == GalleryAppBarType.homepage
+            ? Color(0x00000000)
+            : null,
         elevation: 0,
         title: widget.type == GalleryAppBarType.homepage
             ? Container()

+ 14 - 2
lib/ui/home_widget.dart

@@ -22,6 +22,7 @@ import 'package:photos/ui/backup_folder_selection_widget.dart';
 import 'package:photos/ui/collections_gallery_widget.dart';
 import 'package:photos/ui/extents_page_view.dart';
 import 'package:photos/ui/gallery.dart';
+import 'package:photos/ui/gallery_app_bar_widget.dart';
 import 'package:photos/ui/grant_permissions_widget.dart';
 import 'package:photos/ui/loading_photos_widget.dart';
 import 'package:photos/ui/memories_widget.dart';
@@ -46,7 +47,7 @@ class _HomeWidgetState extends State<HomeWidget> {
   static const _deviceFolderGalleryWidget = const CollectionsGalleryWidget();
   static const _sharedCollectionGallery = const SharedCollectionGallery();
   static const _headerWidget = HeaderWidget();
-  
+
   final _logger = Logger("HomeWidgetState");
   final _selectedFiles = SelectedFiles();
   final _settingsButton = SettingsButton();
@@ -233,7 +234,7 @@ class _HomeWidgetState extends State<HomeWidget> {
     } else {
       header = _headerWidget;
     }
-    return Gallery(
+    final gallery = Gallery(
       asyncLoader: (creationStartTime, creationEndTime, {limit}) {
         final importantPaths = Configuration.instance.getPathsToBackUp();
         if (importantPaths.isNotEmpty) {
@@ -251,6 +252,17 @@ class _HomeWidgetState extends State<HomeWidget> {
       headerWidget: header,
       isHomePageGallery: true,
     );
+    return Stack(children: [
+      gallery,
+      Container(
+        height: 60,
+        child: GalleryAppBarWidget(
+          GalleryAppBarType.homepage,
+          null,
+          _selectedFiles,
+        ),
+      ),
+    ]);
   }
 
   Widget _buildBottomNavigationBar() {

+ 3 - 2
lib/ui/huge_listview/lazy_loading_gallery.dart

@@ -90,7 +90,7 @@ class _LazyLoadingGalleryState extends State<LazyLoadingGallery> {
           files.addAll(_files);
           files.removeWhere((file) => updateFileIDs.contains(file.generatedID));
           if (files.isNotEmpty && mounted) {
-            // All files on this day were deleted, let gallery trigger the reload
+            // If all files on this day were deleted, ignore and let the gallery reload itself
             setState(() {
               _files = files;
             });
@@ -185,7 +185,7 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
     widget.selectedFiles.addListener(() {
       bool shouldRefresh = false;
       for (final file in widget.files) {
-        if (widget.selectedFiles.latestSelection == file) {
+        if (widget.selectedFiles.lastSelections.contains(file)) {
           shouldRefresh = true;
         }
       }
@@ -231,6 +231,7 @@ class _LazyLoadingGridViewState extends State<LazyLoadingGridView> {
         gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
           crossAxisCount: 4,
         ),
+        padding: EdgeInsets.all(0),
       );
     }
   }

+ 21 - 17
lib/ui/shared_collection_page.dart

@@ -7,40 +7,44 @@ import 'package:photos/models/collection.dart';
 import 'package:photos/ui/gallery.dart';
 import 'package:photos/ui/gallery_app_bar_widget.dart';
 
-class SharedCollectionPage extends StatefulWidget {
+class SharedCollectionPage extends StatelessWidget {
   final Collection collection;
-
-  const SharedCollectionPage(this.collection, {Key key}) : super(key: key);
-
-  @override
-  _SharedCollectionPageState createState() => _SharedCollectionPageState();
-}
-
-class _SharedCollectionPageState extends State<SharedCollectionPage> {
   final _selectedFiles = SelectedFiles();
 
+  SharedCollectionPage(this.collection, {Key key}) : super(key: key);
+
   @override
   Widget build(Object context) {
     var gallery = Gallery(
       asyncLoader: (creationStartTime, creationEndTime, {limit}) {
         return FilesDB.instance.getFilesInCollection(
-            widget.collection.id, creationStartTime, creationEndTime,
+            collection.id, creationStartTime, creationEndTime,
             limit: limit);
       },
       reloadEvent: Bus.instance
           .on<CollectionUpdatedEvent>()
-          .where((event) => event.collectionID == widget.collection.id),
+          .where((event) => event.collectionID == collection.id),
       tagPrefix: "shared_collection",
       selectedFiles: _selectedFiles,
     );
     return Scaffold(
-      appBar: GalleryAppBarWidget(
-        GalleryAppBarType.shared_collection,
-        widget.collection.name,
-        _selectedFiles,
-        collection: widget.collection,
+      body: Stack(
+        children: [
+          Padding(
+            padding: const EdgeInsets.only(top: 80),
+            child: gallery,
+          ),
+          Container(
+            height: 80,
+            child: GalleryAppBarWidget(
+              GalleryAppBarType.shared_collection,
+              collection.name,
+              _selectedFiles,
+              collection: collection,
+            ),
+          )
+        ],
       ),
-      body: gallery,
     );
   }
 }