mirror of
https://github.com/immich-app/immich.git
synced 2025-12-22 17:24:56 +03:00
feat(mobile): Add end page to the end to memories (#6780)
* Adding memory epilogue card * Adds epilogue page to memories * Fixes a next / back issue * color --------- Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
@@ -4,10 +4,11 @@ import 'package:flutter/services.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/modules/memories/models/memory.dart';
|
||||
import 'package:immich_mobile/modules/memories/ui/memory_bottom_info.dart';
|
||||
import 'package:immich_mobile/modules/memories/ui/memory_card.dart';
|
||||
import 'package:immich_mobile/modules/memories/ui/memory_epilogue.dart';
|
||||
import 'package:immich_mobile/shared/models/asset.dart';
|
||||
import 'package:immich_mobile/shared/ui/immich_image.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:openapi/api.dart' as api;
|
||||
|
||||
@RoutePage()
|
||||
@@ -26,7 +27,6 @@ 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}",
|
||||
@@ -129,39 +129,6 @@ class MemoryPage extends HookConsumerWidget {
|
||||
updateProgressText();
|
||||
}
|
||||
|
||||
buildBottomInfo(Memory memory) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
memory.title,
|
||||
style: TextStyle(
|
||||
color: Colors.grey[400],
|
||||
fontSize: 13.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
DateFormat.yMMMMd().format(
|
||||
memory.assets[0].fileCreatedAt,
|
||||
),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 15.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/* 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
|
||||
@@ -172,49 +139,17 @@ class MemoryPage extends HookConsumerWidget {
|
||||
// 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 isEpiloguePage =
|
||||
(memoryPageController.page?.floor() ?? 0) >= memories.length;
|
||||
|
||||
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)) {
|
||||
context.popRoute();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Horizontal scroll handling
|
||||
if (notification.depth == 1 &&
|
||||
(offset > notification.metrics.maxScrollExtent + 100)) {
|
||||
context.popRoute();
|
||||
return true;
|
||||
}
|
||||
if (isEpiloguePage &&
|
||||
(offset > notification.metrics.maxScrollExtent + 150)) {
|
||||
context.popRoute();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (notification.depth == 0) {
|
||||
if (notification is ScrollStartNotification) {
|
||||
assetProgress.value = "";
|
||||
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;
|
||||
},
|
||||
child: Scaffold(
|
||||
@@ -226,8 +161,28 @@ class MemoryPage extends HookConsumerWidget {
|
||||
),
|
||||
scrollDirection: Axis.vertical,
|
||||
controller: memoryPageController,
|
||||
itemCount: memories.length,
|
||||
onPageChanged: (pageNumber) {
|
||||
HapticFeedback.mediumImpact();
|
||||
if (pageNumber < memories.length) {
|
||||
currentMemory.value = memories[pageNumber];
|
||||
}
|
||||
|
||||
currentAssetPage.value = 0;
|
||||
|
||||
updateProgressText();
|
||||
},
|
||||
itemCount: memories.length + 1,
|
||||
itemBuilder: (context, mIndex) {
|
||||
// Build last page
|
||||
if (mIndex == memories.length) {
|
||||
return MemoryEpilogue(
|
||||
onStartOver: () => memoryPageController.animateToPage(
|
||||
0,
|
||||
duration: const Duration(seconds: 1),
|
||||
curve: Curves.easeInOut,
|
||||
),
|
||||
);
|
||||
}
|
||||
// Build horizontal page
|
||||
return Column(
|
||||
children: [
|
||||
@@ -256,7 +211,7 @@ class MemoryPage extends HookConsumerWidget {
|
||||
},
|
||||
),
|
||||
),
|
||||
buildBottomInfo(memories[mIndex]),
|
||||
MemoryBottomInfo(memory: memories[mIndex]),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user