Procházet zdrojové kódy

Load collection thumbnails lazily, if there are over 100 of them

vishnukvmd před 2 roky
rodič
revize
b075a51e2a

+ 58 - 5
lib/ui/collections/collection_item_widget.dart

@@ -8,14 +8,17 @@ import 'package:photos/ui/viewer/file/no_thumbnail_widget.dart';
 import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
 import 'package:photos/ui/viewer/gallery/collection_page.dart';
 import 'package:photos/utils/navigation_util.dart';
+import 'package:visibility_detector/visibility_detector.dart';
 
 class CollectionItem extends StatelessWidget {
   final CollectionWithThumbnail c;
   final double sideOfThumbnail;
+  final bool shouldRender;
 
   CollectionItem(
     this.c,
     this.sideOfThumbnail, {
+    this.shouldRender = false,
     Key? key,
   }) : super(key: Key(c.collection.id.toString()));
 
@@ -39,11 +42,10 @@ class CollectionItem extends StatelessWidget {
                   child: Hero(
                     tag: heroTag,
                     child: c.thumbnail != null
-                        ? ThumbnailWidget(
-                            c.thumbnail,
-                            shouldShowArchiveStatus: c.collection.isArchived(),
-                            showFavForAlbumOnly: true,
-                            key: Key(heroTag),
+                        ? CollectionItemThumbnailWidget(
+                            c: c,
+                            heroTag: heroTag,
+                            shouldRender: shouldRender,
                           )
                         : const NoThumbnailWidget(),
                   ),
@@ -98,3 +100,54 @@ class CollectionItem extends StatelessWidget {
     );
   }
 }
+
+class CollectionItemThumbnailWidget extends StatefulWidget {
+  const CollectionItemThumbnailWidget({
+    Key? key,
+    required this.c,
+    required this.heroTag,
+    this.shouldRender = false,
+  }) : super(key: key);
+
+  final CollectionWithThumbnail c;
+  final String heroTag;
+  final bool shouldRender;
+
+  @override
+  State<CollectionItemThumbnailWidget> createState() =>
+      _CollectionItemThumbnailWidgetState();
+}
+
+class _CollectionItemThumbnailWidgetState
+    extends State<CollectionItemThumbnailWidget> {
+  bool _shouldRender = false;
+
+  @override
+  void initState() {
+    super.initState();
+    _shouldRender = widget.shouldRender;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return VisibilityDetector(
+      key: Key("collection_item" + widget.c.thumbnail!.tag),
+      onVisibilityChanged: (visibility) {
+        final shouldRender = visibility.visibleFraction > 0;
+        if (mounted && shouldRender && !_shouldRender) {
+          setState(() {
+            _shouldRender = shouldRender;
+          });
+        }
+      },
+      child: _shouldRender
+          ? ThumbnailWidget(
+              widget.c.thumbnail,
+              shouldShowArchiveStatus: widget.c.collection.isArchived(),
+              showFavForAlbumOnly: true,
+              key: Key(widget.heroTag),
+            )
+          : const NoThumbnailWidget(),
+    );
+  }
+}

+ 6 - 1
lib/ui/collections/remote_collections_grid_view_widget.dart

@@ -14,6 +14,7 @@ class RemoteCollectionsGridViewWidget extends StatelessWidget {
   static const maxThumbnailWidth = 224.0;
   static const fixedGapBetweenAlbum = 8.0;
   static const minGapForHorizontalPadding = 8.0;
+  static const collectionItemsToPreload = 100;
 
   final List<CollectionWithThumbnail>? collections;
 
@@ -45,7 +46,11 @@ class RemoteCollectionsGridViewWidget extends StatelessWidget {
         // to disable GridView's scrolling
         itemBuilder: (context, index) {
           if (index < collections!.length) {
-            return CollectionItem(collections![index], sideOfThumbnail);
+            return CollectionItem(
+              collections![index],
+              sideOfThumbnail,
+              shouldRender: index < collectionItemsToPreload,
+            );
           } else {
             return const CreateNewAlbumWidget();
           }