import 'package:nc_photos/account.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; import 'package:nc_photos/entity/file_util.dart' as file_util; import 'package:np_collection/np_collection.dart'; import 'package:to_string/to_string.dart'; part 'search.g.dart'; @toString class SearchCriteria { SearchCriteria(String input, this.filters) : input = input.trim(); SearchCriteria copyWith({ String? input, List? filters, }) => SearchCriteria( input ?? this.input, filters ?? List.of(this.filters), ); @override String toString() => _$toString(); final String input; @Format(r"${$?.toReadableString()}") final List filters; } abstract class SearchFilter { Map toQueryArgument(); bool isSatisfy(File file); } enum SearchFileType { image, video, } @toString class SearchFileTypeFilter implements SearchFilter { const SearchFileTypeFilter(this.type); @override Map toQueryArgument() { if (type == SearchFileType.image) { return {#mimes: file_util.supportedImageFormatMimes}; } else { return {#mimes: file_util.supportedVideoFormatMimes}; } } @override isSatisfy(File file) { switch (type) { case SearchFileType.image: return file_util.isSupportedImageFormat(file); case SearchFileType.video: return file_util.isSupportedVideoFormat(file); } } @override String toString() => _$toString(); final SearchFileType type; } @toString class SearchFavoriteFilter implements SearchFilter { const SearchFavoriteFilter(this.value); @override Map toQueryArgument() { return {#isFavorite: value}; } @override isSatisfy(File file) => (file.isFavorite ?? false) == value; @override String toString() => _$toString(); final bool value; } class SearchRepo { const SearchRepo(this.dataSrc); Future> list(Account account, SearchCriteria criteria) => dataSrc.list(account, criteria); final SearchDataSource dataSrc; } abstract class SearchDataSource { /// List all results from a given search criteria Future> list(Account account, SearchCriteria criteria); }