diff --git a/mobile/lib/modules/memories/views/memory_page.dart b/mobile/lib/modules/memories/views/memory_page.dart index ee8833ff18..8c6776d715 100644 --- a/mobile/lib/modules/memories/views/memory_page.dart +++ b/mobile/lib/modules/memories/views/memory_page.dart @@ -22,6 +22,7 @@ class MemoryPage extends HookConsumerWidget { final memoryPageController = usePageController(initialPage: memoryIndex); final memoryAssetPageController = usePageController(); final currentMemory = useState(memories[memoryIndex]); + final previousMemoryIndex = useState(memoryIndex); final currentAssetPage = useState(0); final assetProgress = useState( "${currentAssetPage.value + 1}|${currentMemory.value.assets.length}", @@ -48,21 +49,13 @@ class MemoryPage extends HookConsumerWidget { "${currentAssetPage.value + 1}|${currentMemory.value.assets.length}"; } - onMemoryChanged(int otherIndex) { - HapticFeedback.mediumImpact(); - currentMemory.value = memories[otherIndex]; - currentAssetPage.value = 0; - updateProgressText(); - } - onAssetChanged(int otherIndex) { HapticFeedback.selectionClick(); - currentAssetPage.value = otherIndex; updateProgressText(); } - buildBottomInfo() { + buildBottomInfo(Memory memory) { return Padding( padding: const EdgeInsets.all(16.0), child: Row( @@ -71,7 +64,7 @@ class MemoryPage extends HookConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - currentMemory.value.title, + memory.title, style: TextStyle( color: Colors.grey[400], fontSize: 11.0, @@ -80,7 +73,7 @@ class MemoryPage extends HookConsumerWidget { ), Text( DateFormat.yMMMMd().format( - currentMemory.value.assets[0].fileCreatedAt, + memory.assets[0].fileCreatedAt, ), style: const TextStyle( color: Colors.white, @@ -95,44 +88,66 @@ class MemoryPage extends HookConsumerWidget { ); } - return Scaffold( - backgroundColor: bgColor, - body: SafeArea( - child: PageView.builder( - scrollDirection: Axis.vertical, - controller: memoryPageController, - onPageChanged: onMemoryChanged, - itemCount: memories.length, - itemBuilder: (context, mIndex) { - // Build horizontal page - return Column( - children: [ - Expanded( - child: PageView.builder( - controller: memoryAssetPageController, - onPageChanged: onAssetChanged, - scrollDirection: Axis.horizontal, - itemCount: memories[mIndex].assets.length, - itemBuilder: (context, index) { - final asset = memories[mIndex].assets[index]; - return Container( - color: Colors.black, - child: MemoryCard( - asset: asset, - onTap: () => toNextAsset(index), - onClose: () => AutoRouter.of(context).pop(), - rightCornerText: assetProgress.value, - title: memories[mIndex].title, - showTitle: index == 0, - ), - ); - }, + /* Notification listener is used instead of OnPageChanged callback since OnPageChanged is called + * when the page in the **center** of the viewer changes. We want to reset currentAssetPage only when the final + * page during the end of scroll is different than the current page + */ + return NotificationListener( + onNotification: (ScrollNotification notification) { + if (notification.depth == 0) { + var currentPageNumber = memoryPageController.page!.toInt(); + currentMemory.value = memories[currentPageNumber]; + if (notification is ScrollStartNotification) { + assetProgress.value = ""; + } else if (notification is ScrollEndNotification) { + HapticFeedback.mediumImpact(); + if (currentPageNumber != previousMemoryIndex.value) { + currentAssetPage.value = 0; + previousMemoryIndex.value = currentPageNumber; + } + updateProgressText(); + } + } + return false; + }, + child: Scaffold( + backgroundColor: bgColor, + body: SafeArea( + child: PageView.builder( + scrollDirection: Axis.vertical, + controller: memoryPageController, + itemCount: memories.length, + itemBuilder: (context, mIndex) { + // Build horizontal page + return Column( + children: [ + Expanded( + child: PageView.builder( + controller: memoryAssetPageController, + onPageChanged: onAssetChanged, + scrollDirection: Axis.horizontal, + itemCount: memories[mIndex].assets.length, + itemBuilder: (context, index) { + final asset = memories[mIndex].assets[index]; + return Container( + color: Colors.black, + child: MemoryCard( + asset: asset, + onTap: () => toNextAsset(index), + onClose: () => AutoRouter.of(context).pop(), + rightCornerText: assetProgress.value, + title: memories[mIndex].title, + showTitle: index == 0, + ), + ); + }, + ), ), - ), - buildBottomInfo(), - ], - ); - }, + buildBottomInfo(memories[mIndex]), + ], + ); + }, + ), ), ), ); diff --git a/mobile/lib/shared/ui/immich_image.dart b/mobile/lib/shared/ui/immich_image.dart index bcc7a3d46b..fcc51490ba 100644 --- a/mobile/lib/shared/ui/immich_image.dart +++ b/mobile/lib/shared/ui/immich_image.dart @@ -108,9 +108,12 @@ class ImmichImage extends StatelessWidget { ); } return Transform.scale( - scale: 0.2, - child: CircularProgressIndicator.adaptive( - value: downloadProgress.progress, + scale: 2, + child: Center( + child: CircularProgressIndicator.adaptive( + strokeWidth: 1, + value: downloadProgress.progress, + ), ), ); },