Merge pull request #419 from ente-io/search_improvements

Search improvements
This commit is contained in:
Ashil 2022-08-11 18:04:44 +05:30 committed by GitHub
commit f4d1c780f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 85 additions and 97 deletions

View file

@ -15,8 +15,7 @@ import 'package:photos/services/collections_service.dart';
import 'package:photos/services/user_service.dart';
class SearchService {
List<File> _cachedFiles;
Future<List<File>> _future;
Future<List<File>> _cachedFilesFuture;
final _dio = Network.instance.getDio();
final _config = Configuration.instance;
final _logger = Logger((UserService).toString());
@ -31,26 +30,23 @@ class SearchService {
Future.delayed(const Duration(seconds: 5), () async {
/* In case home screen loads before 5 seconds and user starts search,
future will not be null.So here getAllFiles won't run again in that case. */
if (_future == null) {
if (_cachedFilesFuture == null) {
getAllFiles();
}
});
Bus.instance.on<LocalPhotosUpdatedEvent>().listen((event) {
_cachedFiles = null;
_cachedFilesFuture = null;
getAllFiles();
});
}
Future<List<File>> getAllFiles() async {
if (_cachedFiles != null) {
return _cachedFiles;
if (_cachedFilesFuture != null) {
return _cachedFilesFuture;
}
if (_future != null) {
return _future;
}
_future = _fetchAllFiles();
return _future;
_cachedFilesFuture = FilesDB.instance.getAllFilesFromDB();
return _cachedFilesFuture;
}
Future<List<File>> getFileSearchResults(String query) async {
@ -69,19 +65,19 @@ class SearchService {
}
void clearCache() {
_cachedFiles.clear();
_cachedFilesFuture = null;
}
Future<List<LocationSearchResult>> getLocationSearchResults(
String query,
) async {
final List<LocationSearchResult> locationSearchResults = [];
try {
final List<File> allFiles = await SearchService.instance.getAllFiles();
final List<LocationSearchResult> locationSearchResults = [];
final response = await _dio.get(
_config.getHttpEndpoint() + "/search/location",
queryParameters: {"query": query, "limit": 4},
queryParameters: {"query": query, "limit": 10},
options: Options(
headers: {"X-Auth-Token": _config.getToken()},
),
@ -100,17 +96,19 @@ class SearchService {
filesInLocation.add(file);
}
}
filesInLocation.sort(
(first, second) => second.creationTime.compareTo(first.creationTime),
);
if (filesInLocation.isNotEmpty) {
locationSearchResults.add(
LocationSearchResult(locationData.place, filesInLocation),
);
}
}
return locationSearchResults;
} on DioError catch (e) {
_logger.info(e);
rethrow;
} catch (e) {
_logger.severe(e);
}
return locationSearchResults;
}
// getFilteredCollectionsWithThumbnail removes deleted or archived or
@ -160,9 +158,4 @@ class SearchService {
location.longitude < locationData.bbox[2] &&
location.latitude < locationData.bbox[3];
}
Future<List<File>> _fetchAllFiles() async {
_cachedFiles = await FilesDB.instance.getAllFilesFromDB();
return _cachedFiles;
}
}

View file

@ -8,7 +8,6 @@ class ThumbnailPlaceHolder extends StatelessWidget {
@override
Widget build(BuildContext context) {
debugPrint("building placeHolder for thumbnail");
return Container(
alignment: Alignment.center,
color: Theme.of(context).colorScheme.galleryThumbBackgroundColor,

View file

@ -166,7 +166,7 @@ class _ZoomableLiveImageState extends State<ZoomableLiveImage>
void _showLivePhotoToast() async {
var preferences = await SharedPreferences.getInstance();
int promptTillNow = preferences.getInt(kLivePhotoToastCounterKey) ?? 0;
if (promptTillNow < kMaxLivePhotoToastCount) {
if (promptTillNow < kMaxLivePhotoToastCount && mounted) {
showToast(context, "Press and hold to play video");
preferences.setInt(kLivePhotoToastCounterKey, promptTillNow + 1);
}

View file

@ -11,13 +11,15 @@ import 'package:photos/ui/viewer/gallery/gallery_overlay_widget.dart';
class FilesInLocationPage extends StatelessWidget {
final LocationSearchResult locationSearchResult;
final String tagPrefix;
final _selectedFiles = SelectedFiles();
static const String kTagPrefix = "location_search";
static const GalleryType appBarType = GalleryType.searchResults;
static const GalleryType overlayType = GalleryType.searchResults;
FilesInLocationPage({
FilesInLocationPage(
this.locationSearchResult,
this.tagPrefix, {
Key key,
}) : super(key: key);
@ -57,7 +59,7 @@ class FilesInLocationPage extends StatelessWidget {
null,
),
],
tagPrefix: kTagPrefix,
tagPrefix: tagPrefix,
selectedFiles: _selectedFiles,
initialFiles: [locationSearchResult.files[0]],
footer: const SizedBox(height: 120),

View file

@ -6,12 +6,17 @@ import 'package:photos/ui/viewer/search/collections/files_in_location_page.dart'
import 'package:photos/utils/navigation_util.dart';
class LocationSearchResultWidget extends StatelessWidget {
static const String _tagPrefix = "location_search";
final LocationSearchResult locationSearchResult;
const LocationSearchResultWidget(this.locationSearchResult, {Key key})
: super(key: key);
@override
Widget build(BuildContext context) {
final noOfMemories = locationSearchResult.files.length;
final heroTagPrefix = _tagPrefix + locationSearchResult.location;
return GestureDetector(
behavior: HitTestBehavior.opaque,
child: Container(
@ -53,7 +58,7 @@ class LocationSearchResultWidget extends StatelessWidget {
),
),
Hero(
tag: "location_search" + locationSearchResult.files[0].tag(),
tag: heroTagPrefix + locationSearchResult.files[0].tag(),
child: SizedBox(
height: 50,
width: 50,
@ -67,9 +72,8 @@ class LocationSearchResultWidget extends StatelessWidget {
onTap: () {
routeToPage(
context,
FilesInLocationPage(
locationSearchResult: locationSearchResult,
),
FilesInLocationPage(locationSearchResult, heroTagPrefix),
forceCustomPageRoute: true,
);
},
);

View file

@ -29,15 +29,11 @@ class _SearchIconWidgetState extends State<SearchIconWidget> {
tag: "search_icon",
child: IconButton(
onPressed: () {
setState(
() {
Navigator.push(
context,
TransparentRoute(
builder: (BuildContext context) => const SearchWidget(),
),
);
},
Navigator.push(
context,
TransparentRoute(
builder: (BuildContext context) => const SearchWidget(),
),
);
},
icon: const Icon(Icons.search),
@ -63,65 +59,59 @@ class _SearchWidgetState extends State<SearchWidget> {
child: Column(
children: [
const SizedBox(height: 8),
Row(
children: [
Flexible(
child: Container(
color: Theme.of(context).colorScheme.defaultBackgroundColor,
child: TextFormField(
style: Theme.of(context).textTheme.subtitle1,
decoration: InputDecoration(
hintText: 'Search for albums, locations & files',
filled: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 14,
),
border: UnderlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(8),
),
focusedBorder: const UnderlineInputBorder(
borderSide: BorderSide.none,
),
prefixIcon: Hero(
tag: "search_icon",
child: Icon(
Icons.search,
color: Theme.of(context)
.colorScheme
.iconColor
.withOpacity(0.5),
),
),
suffixIcon: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(
Icons.close,
color: Theme.of(context)
.colorScheme
.iconColor
.withOpacity(0.5),
),
),
),
onChanged: (value) async {
final List<SearchResult> allResults =
await getSearchResultsForQuery(value);
if (mounted) {
setState(() {
results.clear();
results.addAll(allResults);
});
}
},
autofocus: true,
Container(
color: Theme.of(context).colorScheme.defaultBackgroundColor,
child: TextFormField(
style: Theme.of(context).textTheme.subtitle1,
decoration: InputDecoration(
hintText: 'Search for albums, locations & files',
filled: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 14,
),
border: UnderlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(8),
),
focusedBorder: const UnderlineInputBorder(
borderSide: BorderSide.none,
),
prefixIcon: Hero(
tag: "search_icon",
child: Icon(
Icons.search,
color: Theme.of(context)
.colorScheme
.iconColor
.withOpacity(0.5),
),
),
suffixIcon: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(
Icons.close,
color: Theme.of(context)
.colorScheme
.iconColor
.withOpacity(0.5),
),
),
),
],
onChanged: (value) async {
final List<SearchResult> allResults =
await getSearchResultsForQuery(value);
if (mounted) {
setState(() {
results.clear();
results.addAll(allResults);
});
}
},
autofocus: true,
),
),
results.isNotEmpty
? SearchSuggestionsWidget(results)