From e0a3e5a20031e05eaba500227a57a3b2a3cbc00e Mon Sep 17 00:00:00 2001 From: shalong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Date: Mon, 31 Jul 2023 18:14:17 +0000 Subject: [PATCH] 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 --- .../modules/memories/views/memory_page.dart | 50 +++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/mobile/lib/modules/memories/views/memory_page.dart b/mobile/lib/modules/memories/views/memory_page.dart index b78bd2d224..a1aae5156a 100644 --- a/mobile/lib/modules/memories/views/memory_page.dart +++ b/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( 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,