Quick date picker

This commit is contained in:
exelix11 2025-10-04 11:16:56 +00:00 committed by Brandon Wees
parent 7b7d91a5e1
commit 374ca7d356
3 changed files with 119 additions and 37 deletions

View file

@ -26,6 +26,7 @@ import 'package:immich_mobile/widgets/search/search_filter/filter_bottom_sheet_s
import 'package:immich_mobile/widgets/search/search_filter/location_picker.dart';
import 'package:immich_mobile/widgets/search/search_filter/media_type_picker.dart';
import 'package:immich_mobile/widgets/search/search_filter/people_picker.dart';
import 'package:immich_mobile/widgets/search/search_filter/quick_date_picker.dart';
import 'package:immich_mobile/widgets/search/search_filter/search_filter_chip.dart';
import 'package:immich_mobile/widgets/search/search_filter/search_filter_utils.dart';
@ -242,31 +243,7 @@ class DriftSearchPage extends HookConsumerWidget {
);
}
showDatePicker() async {
final firstDate = DateTime(1900);
final lastDate = DateTime.now();
final date = await showDateRangePicker(
context: context,
firstDate: firstDate,
lastDate: lastDate,
currentDate: DateTime.now(),
initialDateRange: DateTimeRange(
start: filter.value.date.takenAfter ?? lastDate,
end: filter.value.date.takenBefore ?? lastDate,
),
helpText: 'search_filter_date_title'.t(context: context),
cancelText: 'cancel'.t(context: context),
confirmText: 'select'.t(context: context),
saveText: 'save'.t(context: context),
errorFormatText: 'invalid_date_format'.t(context: context),
errorInvalidText: 'invalid_date'.t(context: context),
fieldStartHintText: 'start_date'.t(context: context),
fieldEndHintText: 'end_date'.t(context: context),
initialEntryMode: DatePickerEntryMode.calendar,
keyboardType: TextInputType.text,
);
datePicked(DateTimeRange<DateTime>? date) {
if (date == null) {
filter.value = filter.value.copyWith(date: SearchDateFilter());
@ -304,6 +281,55 @@ class DriftSearchPage extends HookConsumerWidget {
search();
}
showDatePicker() async {
final firstDate = DateTime(1900);
final lastDate = DateTime.now();
final date = await showDateRangePicker(
context: context,
firstDate: firstDate,
lastDate: lastDate,
currentDate: DateTime.now(),
initialDateRange: DateTimeRange(
start: filter.value.date.takenAfter ?? lastDate,
end: filter.value.date.takenBefore ?? lastDate,
),
helpText: 'search_filter_date_title'.t(context: context),
cancelText: 'cancel'.t(context: context),
confirmText: 'select'.t(context: context),
saveText: 'save'.t(context: context),
errorFormatText: 'invalid_date_format'.t(context: context),
errorInvalidText: 'invalid_date'.t(context: context),
fieldStartHintText: 'start_date'.t(context: context),
fieldEndHintText: 'end_date'.t(context: context),
initialEntryMode: DatePickerEntryMode.calendar,
keyboardType: TextInputType.text,
);
datePicked(date);
}
showQuickDatePicker() {
showFilterBottomSheet(
context: context,
child: FilterBottomSheetScaffold(
title: "Pick date range",
expanded: true,
onClear: () => datePicked(null),
child: QuickDatePicker(
onRequestPicker: () {
context.pop();
showDatePicker();
},
onSelect: (date) {
context.pop();
datePicked(date);
},
),
),
);
}
// MEDIA PICKER
showMediaTypePicker() {
handleOnSelected(AssetType assetType) {
@ -561,7 +587,7 @@ class DriftSearchPage extends HookConsumerWidget {
),
SearchFilterChip(
icon: Icons.date_range_outlined,
onTap: showDatePicker,
onTap: showQuickDatePicker,
label: 'search_filter_date'.t(context: context),
currentFilter: dateRangeCurrentFilterWidget.value,
),

View file

@ -6,7 +6,7 @@ class FilterBottomSheetScaffold extends StatelessWidget {
const FilterBottomSheetScaffold({
super.key,
required this.child,
required this.onSearch,
this.onSearch,
required this.onClear,
required this.title,
this.expanded,
@ -15,7 +15,7 @@ class FilterBottomSheetScaffold extends StatelessWidget {
final bool? expanded;
final String title;
final Widget child;
final Function() onSearch;
final Function()? onSearch;
final Function() onClear;
@override
@ -48,11 +48,12 @@ class FilterBottomSheetScaffold extends StatelessWidget {
},
child: const Text('clear').tr(),
),
const SizedBox(width: 8),
if (onSearch != null) const SizedBox(width: 8),
if (onSearch != null)
ElevatedButton(
key: const Key('search_filter_apply'),
onPressed: () {
onSearch();
onSearch!();
context.pop();
},
child: const Text('search_filter_apply').tr(),

View file

@ -0,0 +1,55 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
class QuickDatePicker extends HookWidget {
const QuickDatePicker({super.key, required this.onSelect, required this.onRequestPicker});
final Function() onRequestPicker;
final Function(DateTimeRange<DateTime> range) onSelect;
ListTile _monthListTile(String text, int monthsFromNow) {
return ListTile(
title: Text(text),
onTap: () {
final now = DateTime.now();
final from = DateTime(now.year, now.month - monthsFromNow, now.day);
onSelect(DateTimeRange(start: from, end: now));
},
);
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemBuilder: (context, index) {
if (index == 0) {
return ListTile(
title: const Text("Exact date"),
onTap: () {
onRequestPicker();
},
);
} else if (index == 1) {
return _monthListTile("Last month", 1);
} else if (index == 2) {
return _monthListTile("Last 3 months", 3);
} else if (index == 3) {
return _monthListTile("Last 9 months", 9);
} else {
final now = DateTime.now();
final years = index - 3;
final year = now.year - years;
return ListTile(
title: Text("In $year"),
onTap: () {
final from = DateTime(year, 1, 1);
final to = DateTime(year, 12, 31, 23, 59, 59);
onSelect(DateTimeRange(start: from, end: to));
},
);
}
},
itemCount: 50,
);
}
}