mirror of
https://github.com/immich-app/immich
synced 2025-10-17 18:19:27 +00:00
Quick date picker
This commit is contained in:
parent
7b7d91a5e1
commit
374ca7d356
3 changed files with 119 additions and 37 deletions
|
|
@ -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/location_picker.dart';
|
||||||
import 'package:immich_mobile/widgets/search/search_filter/media_type_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/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_chip.dart';
|
||||||
import 'package:immich_mobile/widgets/search/search_filter/search_filter_utils.dart';
|
import 'package:immich_mobile/widgets/search/search_filter/search_filter_utils.dart';
|
||||||
|
|
||||||
|
|
@ -242,31 +243,7 @@ class DriftSearchPage extends HookConsumerWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
showDatePicker() async {
|
datePicked(DateTimeRange<DateTime>? date) {
|
||||||
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,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (date == null) {
|
if (date == null) {
|
||||||
filter.value = filter.value.copyWith(date: SearchDateFilter());
|
filter.value = filter.value.copyWith(date: SearchDateFilter());
|
||||||
|
|
||||||
|
|
@ -304,6 +281,55 @@ class DriftSearchPage extends HookConsumerWidget {
|
||||||
search();
|
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
|
// MEDIA PICKER
|
||||||
showMediaTypePicker() {
|
showMediaTypePicker() {
|
||||||
handleOnSelected(AssetType assetType) {
|
handleOnSelected(AssetType assetType) {
|
||||||
|
|
@ -561,7 +587,7 @@ class DriftSearchPage extends HookConsumerWidget {
|
||||||
),
|
),
|
||||||
SearchFilterChip(
|
SearchFilterChip(
|
||||||
icon: Icons.date_range_outlined,
|
icon: Icons.date_range_outlined,
|
||||||
onTap: showDatePicker,
|
onTap: showQuickDatePicker,
|
||||||
label: 'search_filter_date'.t(context: context),
|
label: 'search_filter_date'.t(context: context),
|
||||||
currentFilter: dateRangeCurrentFilterWidget.value,
|
currentFilter: dateRangeCurrentFilterWidget.value,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ class FilterBottomSheetScaffold extends StatelessWidget {
|
||||||
const FilterBottomSheetScaffold({
|
const FilterBottomSheetScaffold({
|
||||||
super.key,
|
super.key,
|
||||||
required this.child,
|
required this.child,
|
||||||
required this.onSearch,
|
this.onSearch,
|
||||||
required this.onClear,
|
required this.onClear,
|
||||||
required this.title,
|
required this.title,
|
||||||
this.expanded,
|
this.expanded,
|
||||||
|
|
@ -15,7 +15,7 @@ class FilterBottomSheetScaffold extends StatelessWidget {
|
||||||
final bool? expanded;
|
final bool? expanded;
|
||||||
final String title;
|
final String title;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
final Function() onSearch;
|
final Function()? onSearch;
|
||||||
final Function() onClear;
|
final Function() onClear;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -48,15 +48,16 @@ class FilterBottomSheetScaffold extends StatelessWidget {
|
||||||
},
|
},
|
||||||
child: const Text('clear').tr(),
|
child: const Text('clear').tr(),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
if (onSearch != null) const SizedBox(width: 8),
|
||||||
ElevatedButton(
|
if (onSearch != null)
|
||||||
key: const Key('search_filter_apply'),
|
ElevatedButton(
|
||||||
onPressed: () {
|
key: const Key('search_filter_apply'),
|
||||||
onSearch();
|
onPressed: () {
|
||||||
context.pop();
|
onSearch!();
|
||||||
},
|
context.pop();
|
||||||
child: const Text('search_filter_apply').tr(),
|
},
|
||||||
),
|
child: const Text('search_filter_apply').tr(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue