feat: memories in new timeline (#19720)

* feat: memories sliver

* memories lane

* display and show memory

* fix: get correct memories

* naming

* pr feedback

* use equalsValue for visibility

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
Alex 2025-07-04 13:49:15 -05:00 committed by GitHub
parent 181efb9010
commit 4a2cf28882
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 958 additions and 74 deletions

View file

@ -26,6 +26,8 @@ class Scrubber extends ConsumerStatefulWidget {
final double bottomPadding;
final double? monthSegmentSnappingOffset;
Scrubber({
super.key,
Key? scrollThumbKey,
@ -33,6 +35,7 @@ class Scrubber extends ConsumerStatefulWidget {
required this.timelineHeight,
this.topPadding = 0,
this.bottomPadding = 0,
this.monthSegmentSnappingOffset,
required this.child,
}) : assert(child.scrollDirection == Axis.vertical);
@ -296,7 +299,10 @@ class ScrubberState extends ConsumerState<Scrubber>
final viewportHeight = _scrollController.position.viewportDimension;
final targetScrollOffset = layoutSegment.startOffset;
final centeredOffset = targetScrollOffset - (viewportHeight / 4) + 100;
final centeredOffset = targetScrollOffset -
(viewportHeight / 4) +
100 +
(widget.monthSegmentSnappingOffset ?? 0.0);
_scrollController.jumpTo(centeredOffset.clamp(0.0, maxScrollExtent));
}

View file

@ -20,7 +20,10 @@ import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
import 'package:immich_mobile/widgets/common/immich_sliver_app_bar.dart';
class Timeline extends StatelessWidget {
const Timeline({super.key});
const Timeline({super.key, this.topSliverWidget, this.topSliverWidgetHeight});
final Widget? topSliverWidget;
final double? topSliverWidgetHeight;
@override
Widget build(BuildContext context) {
@ -38,7 +41,10 @@ class Timeline extends StatelessWidget {
),
),
],
child: const _SliverTimeline(),
child: _SliverTimeline(
topSliverWidget: topSliverWidget,
topSliverWidgetHeight: topSliverWidgetHeight,
),
),
),
);
@ -46,7 +52,10 @@ class Timeline extends StatelessWidget {
}
class _SliverTimeline extends ConsumerStatefulWidget {
const _SliverTimeline();
const _SliverTimeline({this.topSliverWidget, this.topSliverWidgetHeight});
final Widget? topSliverWidget;
final double? topSliverWidgetHeight;
@override
ConsumerState createState() => _SliverTimelineState();
@ -91,6 +100,7 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
timelineHeight: maxHeight,
topPadding: totalAppBarHeight + 10,
bottomPadding: context.padding.bottom + scrubberBottomPadding,
monthSegmentSnappingOffset: widget.topSliverWidgetHeight,
child: CustomScrollView(
primary: true,
cacheExtent: maxHeight * 2,
@ -100,6 +110,7 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
pinned: false,
snap: false,
),
if (widget.topSliverWidget != null) widget.topSliverWidget!,
_SliverSegmentedList(
segments: segments,
delegate: SliverChildBuilderDelegate(