Browse Source

feat(mobile): auto close memories on scrolling beyond first / last memory (#3476)

* feat(mobile): Close on scroll beyond first / last memory

* fix(mobile): close memory only on the last asset
shalong-tanwen 2 years ago
parent
commit
e0a3e5a200
1 changed files with 47 additions and 3 deletions
  1. 47 3
      mobile/lib/modules/memories/views/memory_page.dart

+ 47 - 3
mobile/lib/modules/memories/views/memory_page.dart

@@ -64,6 +64,11 @@ class MemoryPage extends HookConsumerWidget {
         return;
       }
 
+      // Context might be removed due to popping out of Memory Lane during Scroll handling
+      if (!context.mounted) {
+        return;
+      }
+
       late Asset asset;
       if (index < currentMemory.value.assets.length) {
         // Uses the next asset in this current memory
@@ -160,18 +165,51 @@ class MemoryPage extends HookConsumerWidget {
      */
     return NotificationListener<ScrollNotification>(
       onNotification: (ScrollNotification notification) {
+        // Calculate OverScroll manually using the number of pixels away from maxScrollExtent
+        // maxScrollExtend contains the sum of horizontal pixels of all assets for depth = 1
+        // or sum of vertical pixels of all memories for depth = 0
+        if (notification is ScrollUpdateNotification) {
+          final offset = notification.metrics.pixels;
+          final isLastMemory =
+              (memories.indexOf(currentMemory.value) + 1) >= memories.length;
+          if (isLastMemory) {
+            // Vertical scroll handling only at the last asset.
+            // Tapping on the last asset instead of swiping will trigger the scroll
+            // implicitly which will trigger the below handling and thereby closes the
+            // memory lane as well
+            if (notification.depth == 0) {
+              final isLastAsset = (currentAssetPage.value + 1) ==
+                  currentMemory.value.assets.length;
+              if (isLastAsset &&
+                  (offset > notification.metrics.maxScrollExtent + 150)) {
+                AutoRouter.of(context).pop();
+                return true;
+              }
+            }
+            // Horizontal scroll handling
+            if (notification.depth == 1 &&
+                (offset > notification.metrics.maxScrollExtent + 100)) {
+              AutoRouter.of(context).pop();
+              return true;
+            }
+          }
+        }
+
         if (notification.depth == 0) {
-          var currentPageNumber = memoryPageController.page!.toInt();
-          currentMemory.value = memories[currentPageNumber];
           if (notification is ScrollStartNotification) {
             assetProgress.value = "";
-          } else if (notification is ScrollEndNotification) {
+            return true;
+          }
+          var currentPageNumber = memoryPageController.page!.toInt();
+          currentMemory.value = memories[currentPageNumber];
+          if (notification is ScrollEndNotification) {
             HapticFeedback.mediumImpact();
             if (currentPageNumber != previousMemoryIndex.value) {
               currentAssetPage.value = 0;
               previousMemoryIndex.value = currentPageNumber;
             }
             updateProgressText();
+            return true;
           }
         }
         return false;
@@ -180,6 +218,9 @@ class MemoryPage extends HookConsumerWidget {
         backgroundColor: bgColor,
         body: SafeArea(
           child: PageView.builder(
+            physics: const BouncingScrollPhysics(
+              parent: AlwaysScrollableScrollPhysics(),
+            ),
             scrollDirection: Axis.vertical,
             controller: memoryPageController,
             itemCount: memories.length,
@@ -189,6 +230,9 @@ class MemoryPage extends HookConsumerWidget {
                 children: [
                   Expanded(
                     child: PageView.builder(
+                      physics: const BouncingScrollPhysics(
+                        parent: AlwaysScrollableScrollPhysics(),
+                      ),
                       controller: memoryAssetPageController,
                       onPageChanged: onAssetChanged,
                       scrollDirection: Axis.horizontal,