Merge pull request #431 from ente-io/month-search

Month search
This commit is contained in:
Vishnu Mohandas 2022-08-17 19:50:21 +05:30 committed by GitHub
commit f7d4ded925
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 241 additions and 3 deletions

16
lib/data/months.dart Normal file
View 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),
];

View 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);
}

View file

@ -4,6 +4,7 @@ import 'package:photos/core/configuration.dart';
import 'package:photos/core/event_bus.dart';
import 'package:photos/core/network.dart';
import 'package:photos/data/holidays.dart';
import 'package:photos/data/months.dart';
import 'package:photos/db/files_db.dart';
import 'package:photos/events/local_photos_updated_event.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/location_api_response.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/services/collections_service.dart';
import 'package:photos/utils/date_time_util.dart';
@ -168,13 +170,13 @@ class SearchService {
Future<List<HolidaySearchResult>> getHolidaySearchResults(
String query,
) async {
final List<HolidaySearchResult> holidaySearchResult = [];
final List<HolidaySearchResult> holidaySearchResults = [];
final nonCaseSensitiveRegexForQuery = RegExp(query, caseSensitive: false);
for (var holiday in allHolidays) {
if (holiday.name.contains(nonCaseSensitiveRegexForQuery)) {
holidaySearchResult.add(
holidaySearchResults.add(
HolidaySearchResult(
holiday.name,
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) {
@ -200,6 +224,19 @@ class SearchService {
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) {
return location != null &&
location.latitude != null &&

View 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,
)
],
),
);
}
}

View file

@ -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),
);
},
);
}
}

View file

@ -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/holiday_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/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/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/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';
class SearchSuggestionsWidget extends StatelessWidget {
@ -67,6 +69,8 @@ class SearchSuggestionsWidget extends StatelessWidget {
return YearSearchResultWidget(result);
} else if (result is HolidaySearchResult) {
return HolidaySearchResultWidget(result);
} else if (result is MonthSearchResult) {
return MonthSearchResultWidget(result);
} else {
Logger('SearchSuggestionsWidget')
.info("Invalid/Unsupported value");

View file

@ -160,6 +160,9 @@ class _SearchWidgetState extends State<SearchWidget> {
await _searchService.getLocationSearchResults(query);
allResults.addAll(locationResults);
final monthResults = await _searchService.getMonthSearchResults(query);
allResults.addAll(monthResults);
return allResults;
}