mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
feat(mobile): drift search page (#19811)
* feat(mobile): drift search page * migrate to drift page --------- Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
parent
2046dcc5b4
commit
8491fe459d
17 changed files with 1305 additions and 109 deletions
|
|
@ -15,6 +15,7 @@ class TimelineArgs {
|
|||
final double spacing;
|
||||
final int columnCount;
|
||||
final bool showStorageIndicator;
|
||||
final GroupAssetsBy? groupBy;
|
||||
|
||||
const TimelineArgs({
|
||||
required this.maxWidth,
|
||||
|
|
@ -22,6 +23,7 @@ class TimelineArgs {
|
|||
this.spacing = kTimelineSpacing,
|
||||
this.columnCount = kTimelineColumnCount,
|
||||
this.showStorageIndicator = false,
|
||||
this.groupBy,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -30,7 +32,8 @@ class TimelineArgs {
|
|||
maxWidth == other.maxWidth &&
|
||||
maxHeight == other.maxHeight &&
|
||||
columnCount == other.columnCount &&
|
||||
showStorageIndicator == other.showStorageIndicator;
|
||||
showStorageIndicator == other.showStorageIndicator &&
|
||||
groupBy == other.groupBy;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -39,7 +42,8 @@ class TimelineArgs {
|
|||
maxHeight.hashCode ^
|
||||
spacing.hashCode ^
|
||||
columnCount.hashCode ^
|
||||
showStorageIndicator.hashCode;
|
||||
showStorageIndicator.hashCode ^
|
||||
groupBy.hashCode;
|
||||
}
|
||||
|
||||
class TimelineState {
|
||||
|
|
@ -97,8 +101,9 @@ final timelineSegmentProvider = StreamProvider.autoDispose<List<Segment>>(
|
|||
final availableTileWidth = args.maxWidth - (spacing * (columnCount - 1));
|
||||
final tileExtent = math.max(0, availableTileWidth) / columnCount;
|
||||
|
||||
final groupBy = GroupAssetsBy
|
||||
.values[ref.watch(settingsProvider).get(Setting.groupAssetsBy)];
|
||||
final groupBy = args.groupBy ??
|
||||
GroupAssetsBy
|
||||
.values[ref.watch(settingsProvider).get(Setting.groupAssetsBy)];
|
||||
|
||||
final timelineService = ref.watch(timelineServiceProvider);
|
||||
yield* timelineService.watchBuckets().map((buckets) {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/rendering.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/setting.model.dart';
|
||||
import 'package:immich_mobile/domain/models/timeline.model.dart';
|
||||
import 'package:immich_mobile/domain/utils/event_stream.dart';
|
||||
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
|
|
@ -27,8 +28,13 @@ class Timeline extends StatelessWidget {
|
|||
this.topSliverWidget,
|
||||
this.topSliverWidgetHeight,
|
||||
this.showStorageIndicator = false,
|
||||
this.appBar,
|
||||
this.appBar = const ImmichSliverAppBar(
|
||||
floating: true,
|
||||
pinned: false,
|
||||
snap: false,
|
||||
),
|
||||
this.bottomSheet = const GeneralBottomSheet(),
|
||||
this.groupBy,
|
||||
});
|
||||
|
||||
final Widget? topSliverWidget;
|
||||
|
|
@ -36,6 +42,8 @@ class Timeline extends StatelessWidget {
|
|||
final bool showStorageIndicator;
|
||||
final Widget? appBar;
|
||||
final Widget? bottomSheet;
|
||||
final GroupAssetsBy? groupBy;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
|
@ -50,6 +58,7 @@ class Timeline extends StatelessWidget {
|
|||
settingsProvider.select((s) => s.get(Setting.tilesPerRow)),
|
||||
),
|
||||
showStorageIndicator: showStorageIndicator,
|
||||
groupBy: groupBy,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
@ -112,13 +121,17 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
|||
return asyncSegments.widgetWhen(
|
||||
onData: (segments) {
|
||||
final childCount = (segments.lastOrNull?.lastIndex ?? -1) + 1;
|
||||
final statusBarHeight = context.padding.top;
|
||||
final double appBarExpandedHeight =
|
||||
widget.appBar != null && widget.appBar is MesmerizingSliverAppBar
|
||||
? 200
|
||||
: 0;
|
||||
final totalAppBarHeight = statusBarHeight + kToolbarHeight;
|
||||
final topPadding = context.padding.top +
|
||||
(widget.appBar == null ? 0 : kToolbarHeight) +
|
||||
10;
|
||||
|
||||
const scrubberBottomPadding = 100.0;
|
||||
final bottomPadding = context.padding.bottom +
|
||||
(widget.appBar == null ? 0 : scrubberBottomPadding);
|
||||
|
||||
return PrimaryScrollController(
|
||||
controller: _scrollController,
|
||||
|
|
@ -127,8 +140,8 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
|||
Scrubber(
|
||||
layoutSegments: segments,
|
||||
timelineHeight: maxHeight,
|
||||
topPadding: totalAppBarHeight + 10,
|
||||
bottomPadding: context.padding.bottom + scrubberBottomPadding,
|
||||
topPadding: topPadding,
|
||||
bottomPadding: bottomPadding,
|
||||
monthSegmentSnappingOffset:
|
||||
widget.topSliverWidgetHeight ?? 0 + appBarExpandedHeight,
|
||||
child: CustomScrollView(
|
||||
|
|
@ -137,13 +150,8 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
|||
slivers: [
|
||||
if (isSelectionMode)
|
||||
const SelectionSliverAppBar()
|
||||
else
|
||||
widget.appBar ??
|
||||
const ImmichSliverAppBar(
|
||||
floating: true,
|
||||
pinned: false,
|
||||
snap: false,
|
||||
),
|
||||
else if (widget.appBar != null)
|
||||
widget.appBar!,
|
||||
if (widget.topSliverWidget != null) widget.topSliverWidget!,
|
||||
_SliverSegmentedList(
|
||||
segments: segments,
|
||||
|
|
@ -188,21 +196,22 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
|||
child: _MultiSelectStatusButton(),
|
||||
),
|
||||
),
|
||||
Consumer(
|
||||
builder: (_, consumerRef, child) {
|
||||
final isMultiSelectEnabled = consumerRef.watch(
|
||||
multiSelectProvider.select(
|
||||
(s) => s.isEnabled,
|
||||
),
|
||||
);
|
||||
if (widget.bottomSheet != null)
|
||||
Consumer(
|
||||
builder: (_, consumerRef, child) {
|
||||
final isMultiSelectEnabled = consumerRef.watch(
|
||||
multiSelectProvider.select(
|
||||
(s) => s.isEnabled,
|
||||
),
|
||||
);
|
||||
|
||||
if (isMultiSelectEnabled) {
|
||||
return child!;
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
child: widget.bottomSheet,
|
||||
),
|
||||
if (isMultiSelectEnabled) {
|
||||
return child!;
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
child: widget.bottomSheet,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue