commit
f7d4ded925
16
lib/data/months.dart
Normal file
16
lib/data/months.dart
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import 'package:photos/models/search/month_search_result.dart';
|
||||||
|
|
||||||
|
List<MonthData> allMonths = [
|
||||||
|
MonthData('January', 1),
|
||||||
|
MonthData('February', 2),
|
||||||
|
MonthData('March', 3),
|
||||||
|
MonthData('April', 4),
|
||||||
|
MonthData('May', 5),
|
||||||
|
MonthData('June', 6),
|
||||||
|
MonthData('July', 7),
|
||||||
|
MonthData('August', 8),
|
||||||
|
MonthData('September', 9),
|
||||||
|
MonthData('October', 10),
|
||||||
|
MonthData('November', 11),
|
||||||
|
MonthData('December', 12),
|
||||||
|
];
|
14
lib/models/search/month_search_result.dart
Normal file
14
lib/models/search/month_search_result.dart
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import 'package:photos/models/file.dart';
|
||||||
|
import 'package:photos/models/search/search_results.dart';
|
||||||
|
|
||||||
|
class MonthSearchResult extends SearchResult {
|
||||||
|
final String month;
|
||||||
|
final List<File> files;
|
||||||
|
MonthSearchResult(this.month, this.files);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MonthData {
|
||||||
|
final String name;
|
||||||
|
final int monthNumber;
|
||||||
|
MonthData(this.name, this.monthNumber);
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import 'package:photos/core/configuration.dart';
|
||||||
import 'package:photos/core/event_bus.dart';
|
import 'package:photos/core/event_bus.dart';
|
||||||
import 'package:photos/core/network.dart';
|
import 'package:photos/core/network.dart';
|
||||||
import 'package:photos/data/holidays.dart';
|
import 'package:photos/data/holidays.dart';
|
||||||
|
import 'package:photos/data/months.dart';
|
||||||
import 'package:photos/db/files_db.dart';
|
import 'package:photos/db/files_db.dart';
|
||||||
import 'package:photos/events/local_photos_updated_event.dart';
|
import 'package:photos/events/local_photos_updated_event.dart';
|
||||||
import 'package:photos/models/collection.dart';
|
import 'package:photos/models/collection.dart';
|
||||||
|
@ -14,6 +15,7 @@ import 'package:photos/models/search/album_search_result.dart';
|
||||||
import 'package:photos/models/search/holiday_search_result.dart';
|
import 'package:photos/models/search/holiday_search_result.dart';
|
||||||
import 'package:photos/models/search/location_api_response.dart';
|
import 'package:photos/models/search/location_api_response.dart';
|
||||||
import 'package:photos/models/search/location_search_result.dart';
|
import 'package:photos/models/search/location_search_result.dart';
|
||||||
|
import 'package:photos/models/search/month_search_result.dart';
|
||||||
import 'package:photos/models/search/year_search_result.dart';
|
import 'package:photos/models/search/year_search_result.dart';
|
||||||
import 'package:photos/services/collections_service.dart';
|
import 'package:photos/services/collections_service.dart';
|
||||||
import 'package:photos/utils/date_time_util.dart';
|
import 'package:photos/utils/date_time_util.dart';
|
||||||
|
@ -168,13 +170,13 @@ class SearchService {
|
||||||
Future<List<HolidaySearchResult>> getHolidaySearchResults(
|
Future<List<HolidaySearchResult>> getHolidaySearchResults(
|
||||||
String query,
|
String query,
|
||||||
) async {
|
) async {
|
||||||
final List<HolidaySearchResult> holidaySearchResult = [];
|
final List<HolidaySearchResult> holidaySearchResults = [];
|
||||||
|
|
||||||
final nonCaseSensitiveRegexForQuery = RegExp(query, caseSensitive: false);
|
final nonCaseSensitiveRegexForQuery = RegExp(query, caseSensitive: false);
|
||||||
|
|
||||||
for (var holiday in allHolidays) {
|
for (var holiday in allHolidays) {
|
||||||
if (holiday.name.contains(nonCaseSensitiveRegexForQuery)) {
|
if (holiday.name.contains(nonCaseSensitiveRegexForQuery)) {
|
||||||
holidaySearchResult.add(
|
holidaySearchResults.add(
|
||||||
HolidaySearchResult(
|
HolidaySearchResult(
|
||||||
holiday.name,
|
holiday.name,
|
||||||
await FilesDB.instance.getFilesCreatedWithinDurations(
|
await FilesDB.instance.getFilesCreatedWithinDurations(
|
||||||
|
@ -186,7 +188,29 @@ class SearchService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return holidaySearchResult;
|
return holidaySearchResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<MonthSearchResult>> getMonthSearchResults(String query) async {
|
||||||
|
final List<MonthSearchResult> monthSearchResults = [];
|
||||||
|
final nonCaseSensitiveRegexForQuery = RegExp(query, caseSensitive: false);
|
||||||
|
|
||||||
|
for (var month in allMonths) {
|
||||||
|
if (month.name.startsWith(nonCaseSensitiveRegexForQuery)) {
|
||||||
|
monthSearchResults.add(
|
||||||
|
MonthSearchResult(
|
||||||
|
month.name,
|
||||||
|
await FilesDB.instance.getFilesCreatedWithinDurations(
|
||||||
|
_getDurationsOfMonthInEveryYear(month.monthNumber),
|
||||||
|
null,
|
||||||
|
order: 'DESC',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return monthSearchResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<List<int>> _getDurationsOfHolidayInEveryYear(int day, int month) {
|
List<List<int>> _getDurationsOfHolidayInEveryYear(int day, int month) {
|
||||||
|
@ -200,6 +224,19 @@ class SearchService {
|
||||||
return durationsOfHolidayInEveryYear;
|
return durationsOfHolidayInEveryYear;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<List<int>> _getDurationsOfMonthInEveryYear(int month) {
|
||||||
|
final List<List<int>> durationsOfMonthInEveryYear = [];
|
||||||
|
for (var year = 1970; year < currentYear; year++) {
|
||||||
|
durationsOfMonthInEveryYear.add([
|
||||||
|
DateTime.utc(year, month, 1).microsecondsSinceEpoch,
|
||||||
|
month == 12
|
||||||
|
? DateTime.utc(year + 1, 1, 1).microsecondsSinceEpoch
|
||||||
|
: DateTime.utc(year, month + 1, 1).microsecondsSinceEpoch,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return durationsOfMonthInEveryYear;
|
||||||
|
}
|
||||||
|
|
||||||
bool _isValidLocation(Location location) {
|
bool _isValidLocation(Location location) {
|
||||||
return location != null &&
|
return location != null &&
|
||||||
location.latitude != null &&
|
location.latitude != null &&
|
||||||
|
|
75
lib/ui/viewer/search/collections/files_from_month_page.dart
Normal file
75
lib/ui/viewer/search/collections/files_from_month_page.dart
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:photos/core/event_bus.dart';
|
||||||
|
import 'package:photos/events/files_updated_event.dart';
|
||||||
|
import 'package:photos/events/local_photos_updated_event.dart';
|
||||||
|
import 'package:photos/models/file_load_result.dart';
|
||||||
|
import 'package:photos/models/gallery_type.dart';
|
||||||
|
import 'package:photos/models/search/month_search_result.dart';
|
||||||
|
import 'package:photos/models/selected_files.dart';
|
||||||
|
import 'package:photos/ui/viewer/gallery/gallery.dart';
|
||||||
|
import 'package:photos/ui/viewer/gallery/gallery_app_bar_widget.dart';
|
||||||
|
import 'package:photos/ui/viewer/gallery/gallery_overlay_widget.dart';
|
||||||
|
|
||||||
|
class FilesFromMonthPage extends StatelessWidget {
|
||||||
|
final MonthSearchResult monthSearchResult;
|
||||||
|
final String tagPrefix;
|
||||||
|
|
||||||
|
final _selectedFiles = SelectedFiles();
|
||||||
|
static const GalleryType appBarType = GalleryType.searchResults;
|
||||||
|
static const GalleryType overlayType = GalleryType.searchResults;
|
||||||
|
|
||||||
|
FilesFromMonthPage(
|
||||||
|
this.monthSearchResult,
|
||||||
|
this.tagPrefix, {
|
||||||
|
Key key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final gallery = Gallery(
|
||||||
|
asyncLoader: (creationStartTime, creationEndTime, {limit, asc}) {
|
||||||
|
final result = monthSearchResult.files
|
||||||
|
.where(
|
||||||
|
(file) =>
|
||||||
|
file.creationTime >= creationStartTime &&
|
||||||
|
file.creationTime <= creationEndTime,
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
return Future.value(
|
||||||
|
FileLoadResult(
|
||||||
|
result,
|
||||||
|
result.length < monthSearchResult.files.length,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
reloadEvent: Bus.instance.on<LocalPhotosUpdatedEvent>(),
|
||||||
|
removalEventTypes: const {
|
||||||
|
EventType.deletedFromRemote,
|
||||||
|
EventType.deletedFromEverywhere,
|
||||||
|
},
|
||||||
|
tagPrefix: tagPrefix,
|
||||||
|
selectedFiles: _selectedFiles,
|
||||||
|
initialFiles: [monthSearchResult.files[0]],
|
||||||
|
);
|
||||||
|
return Scaffold(
|
||||||
|
appBar: PreferredSize(
|
||||||
|
preferredSize: const Size.fromHeight(50.0),
|
||||||
|
child: GalleryAppBarWidget(
|
||||||
|
appBarType,
|
||||||
|
monthSearchResult.month,
|
||||||
|
_selectedFiles,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Stack(
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
children: [
|
||||||
|
gallery,
|
||||||
|
GalleryOverlayWidget(
|
||||||
|
overlayType,
|
||||||
|
_selectedFiles,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:photos/ente_theme_data.dart';
|
||||||
|
import 'package:photos/models/search/month_search_result.dart';
|
||||||
|
import 'package:photos/ui/viewer/search/collections/files_from_month_page.dart';
|
||||||
|
import 'package:photos/ui/viewer/search/search_result_widgets/search_result_thumbnail_widget.dart';
|
||||||
|
import 'package:photos/utils/navigation_util.dart';
|
||||||
|
|
||||||
|
class MonthSearchResultWidget extends StatelessWidget {
|
||||||
|
static const String _tagPrefix = "month_search";
|
||||||
|
|
||||||
|
final MonthSearchResult monthSearchResult;
|
||||||
|
const MonthSearchResultWidget(this.monthSearchResult, {Key key})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final noOfMemories = monthSearchResult.files.length;
|
||||||
|
final heroTagPrefix = _tagPrefix + monthSearchResult.month;
|
||||||
|
|
||||||
|
return GestureDetector(
|
||||||
|
behavior: HitTestBehavior.opaque,
|
||||||
|
child: Container(
|
||||||
|
color: Theme.of(context).colorScheme.searchResultsColor,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 12),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SearchResultThumbnailWidget(
|
||||||
|
monthSearchResult.files[0],
|
||||||
|
heroTagPrefix,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Date',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Theme.of(context).colorScheme.subTextColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
SizedBox(
|
||||||
|
width: 220,
|
||||||
|
child: Text(
|
||||||
|
monthSearchResult.month,
|
||||||
|
style: const TextStyle(fontSize: 18),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 2),
|
||||||
|
RichText(
|
||||||
|
text: TextSpan(
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.searchResultsCountTextColor,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
TextSpan(text: noOfMemories.toString()),
|
||||||
|
TextSpan(
|
||||||
|
text: noOfMemories != 1 ? ' memories' : ' memory',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Icon(
|
||||||
|
Icons.chevron_right,
|
||||||
|
color: Theme.of(context).colorScheme.subTextColor,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
routeToPage(
|
||||||
|
context,
|
||||||
|
FilesFromMonthPage(monthSearchResult, heroTagPrefix),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,12 +5,14 @@ import 'package:photos/models/search/album_search_result.dart';
|
||||||
import 'package:photos/models/search/file_search_result.dart';
|
import 'package:photos/models/search/file_search_result.dart';
|
||||||
import 'package:photos/models/search/holiday_search_result.dart';
|
import 'package:photos/models/search/holiday_search_result.dart';
|
||||||
import 'package:photos/models/search/location_search_result.dart';
|
import 'package:photos/models/search/location_search_result.dart';
|
||||||
|
import 'package:photos/models/search/month_search_result.dart';
|
||||||
import 'package:photos/models/search/search_results.dart';
|
import 'package:photos/models/search/search_results.dart';
|
||||||
import 'package:photos/models/search/year_search_result.dart';
|
import 'package:photos/models/search/year_search_result.dart';
|
||||||
import 'package:photos/ui/viewer/search/search_result_widgets/collection_result_widget.dart';
|
import 'package:photos/ui/viewer/search/search_result_widgets/collection_result_widget.dart';
|
||||||
import 'package:photos/ui/viewer/search/search_result_widgets/file_result_widget.dart';
|
import 'package:photos/ui/viewer/search/search_result_widgets/file_result_widget.dart';
|
||||||
import 'package:photos/ui/viewer/search/search_result_widgets/holiday_result_widget.dart';
|
import 'package:photos/ui/viewer/search/search_result_widgets/holiday_result_widget.dart';
|
||||||
import 'package:photos/ui/viewer/search/search_result_widgets/location_result_widget.dart';
|
import 'package:photos/ui/viewer/search/search_result_widgets/location_result_widget.dart';
|
||||||
|
import 'package:photos/ui/viewer/search/search_result_widgets/month_result_widget.dart';
|
||||||
import 'package:photos/ui/viewer/search/search_result_widgets/year_result_widget.dart';
|
import 'package:photos/ui/viewer/search/search_result_widgets/year_result_widget.dart';
|
||||||
|
|
||||||
class SearchSuggestionsWidget extends StatelessWidget {
|
class SearchSuggestionsWidget extends StatelessWidget {
|
||||||
|
@ -67,6 +69,8 @@ class SearchSuggestionsWidget extends StatelessWidget {
|
||||||
return YearSearchResultWidget(result);
|
return YearSearchResultWidget(result);
|
||||||
} else if (result is HolidaySearchResult) {
|
} else if (result is HolidaySearchResult) {
|
||||||
return HolidaySearchResultWidget(result);
|
return HolidaySearchResultWidget(result);
|
||||||
|
} else if (result is MonthSearchResult) {
|
||||||
|
return MonthSearchResultWidget(result);
|
||||||
} else {
|
} else {
|
||||||
Logger('SearchSuggestionsWidget')
|
Logger('SearchSuggestionsWidget')
|
||||||
.info("Invalid/Unsupported value");
|
.info("Invalid/Unsupported value");
|
||||||
|
|
|
@ -160,6 +160,9 @@ class _SearchWidgetState extends State<SearchWidget> {
|
||||||
await _searchService.getLocationSearchResults(query);
|
await _searchService.getLocationSearchResults(query);
|
||||||
allResults.addAll(locationResults);
|
allResults.addAll(locationResults);
|
||||||
|
|
||||||
|
final monthResults = await _searchService.getMonthSearchResults(query);
|
||||||
|
allResults.addAll(monthResults);
|
||||||
|
|
||||||
return allResults;
|
return allResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue