Merge pull request #419 from ente-io/search_improvements
Search improvements
This commit is contained in:
commit
f4d1c780f2
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue