mirror of
https://github.com/ente-io/ente.git
synced 2025-08-14 02:07:33 +00:00
wip
This commit is contained in:
@@ -22,8 +22,7 @@ import type {
|
|||||||
Searchable,
|
Searchable,
|
||||||
SearchableData,
|
SearchableData,
|
||||||
SearchDateComponents,
|
SearchDateComponents,
|
||||||
SearchQuery,
|
SearchSuggestion,
|
||||||
Suggestion,
|
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,7 +87,7 @@ export class SearchWorker {
|
|||||||
/**
|
/**
|
||||||
* Return {@link EnteFile}s that satisfy the given {@link suggestion}.
|
* Return {@link EnteFile}s that satisfy the given {@link suggestion}.
|
||||||
*/
|
*/
|
||||||
filterSearchableFiles(suggestion: SearchQuery) {
|
filterSearchableFiles(suggestion: SearchSuggestion) {
|
||||||
return this.searchableData.files.filter((f) =>
|
return this.searchableData.files.filter((f) =>
|
||||||
isMatchingFile(f, suggestion),
|
isMatchingFile(f, suggestion),
|
||||||
);
|
);
|
||||||
@@ -108,7 +107,7 @@ const suggestionsForString = (
|
|||||||
{ locale, holidays, labelledFileTypes }: LocalizedSearchData,
|
{ locale, holidays, labelledFileTypes }: LocalizedSearchData,
|
||||||
locationTags: Searchable<LocationTag>[],
|
locationTags: Searchable<LocationTag>[],
|
||||||
cities: Searchable<City>[],
|
cities: Searchable<City>[],
|
||||||
): Suggestion[] =>
|
): SearchSuggestion[] =>
|
||||||
[
|
[
|
||||||
// <-- caption suggestions will be inserted here by our caller.
|
// <-- caption suggestions will be inserted here by our caller.
|
||||||
fileTypeSuggestions(s, labelledFileTypes),
|
fileTypeSuggestions(s, labelledFileTypes),
|
||||||
@@ -119,7 +118,10 @@ const suggestionsForString = (
|
|||||||
fileCaptionSuggestion(s, searchString, files),
|
fileCaptionSuggestion(s, searchString, files),
|
||||||
].flat();
|
].flat();
|
||||||
|
|
||||||
const collectionSuggestions = (s: string, collections: Collection[]) =>
|
const collectionSuggestions = (
|
||||||
|
s: string,
|
||||||
|
collections: Collection[],
|
||||||
|
): SearchSuggestion[] =>
|
||||||
collections
|
collections
|
||||||
.filter(({ name }) => name.toLowerCase().includes(s))
|
.filter(({ name }) => name.toLowerCase().includes(s))
|
||||||
.map(({ id, name }) => ({
|
.map(({ id, name }) => ({
|
||||||
@@ -131,7 +133,7 @@ const collectionSuggestions = (s: string, collections: Collection[]) =>
|
|||||||
const fileTypeSuggestions = (
|
const fileTypeSuggestions = (
|
||||||
s: string,
|
s: string,
|
||||||
labelledFileTypes: Searchable<LabelledFileType>[],
|
labelledFileTypes: Searchable<LabelledFileType>[],
|
||||||
) =>
|
): SearchSuggestion[] =>
|
||||||
labelledFileTypes
|
labelledFileTypes
|
||||||
.filter(({ lowercasedName }) => lowercasedName.startsWith(s))
|
.filter(({ lowercasedName }) => lowercasedName.startsWith(s))
|
||||||
.map(({ fileType, label }) => ({ type: "fileType", fileType, label }));
|
.map(({ fileType, label }) => ({ type: "fileType", fileType, label }));
|
||||||
@@ -140,7 +142,7 @@ const fileNameSuggestion = (
|
|||||||
s: string,
|
s: string,
|
||||||
searchString: string,
|
searchString: string,
|
||||||
files: EnteFile[],
|
files: EnteFile[],
|
||||||
) => {
|
): SearchSuggestion[] => {
|
||||||
// Convert the search string to a number. This allows searching a file by
|
// Convert the search string to a number. This allows searching a file by
|
||||||
// its exact (integral) ID.
|
// its exact (integral) ID.
|
||||||
const sn = Number(s) || undefined;
|
const sn = Number(s) || undefined;
|
||||||
@@ -153,7 +155,7 @@ const fileNameSuggestion = (
|
|||||||
.map((f) => f.id);
|
.map((f) => f.id);
|
||||||
|
|
||||||
return fileIDs.length
|
return fileIDs.length
|
||||||
? { type: "fileName", fileIDs, label: searchString }
|
? [{ type: "fileName", fileIDs, label: searchString }]
|
||||||
: [];
|
: [];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -161,7 +163,7 @@ const fileCaptionSuggestion = (
|
|||||||
s: string,
|
s: string,
|
||||||
searchString: string,
|
searchString: string,
|
||||||
files: EnteFile[],
|
files: EnteFile[],
|
||||||
) => {
|
): SearchSuggestion[] => {
|
||||||
const fileIDs = files
|
const fileIDs = files
|
||||||
.filter((file) =>
|
.filter((file) =>
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
@@ -170,7 +172,7 @@ const fileCaptionSuggestion = (
|
|||||||
.map((f) => f.id);
|
.map((f) => f.id);
|
||||||
|
|
||||||
return fileIDs.length
|
return fileIDs.length
|
||||||
? { type: "fileCaption", fileIDs, label: searchString }
|
? [{ type: "fileCaption", fileIDs, label: searchString }]
|
||||||
: [];
|
: [];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -178,7 +180,7 @@ const dateSuggestions = (
|
|||||||
s: string,
|
s: string,
|
||||||
locale: string,
|
locale: string,
|
||||||
holidays: Searchable<DateSearchResult>[],
|
holidays: Searchable<DateSearchResult>[],
|
||||||
) =>
|
): SearchSuggestion[] =>
|
||||||
parseDateComponents(s, locale, holidays).map(({ components, label }) => ({
|
parseDateComponents(s, locale, holidays).map(({ components, label }) => ({
|
||||||
type: "date",
|
type: "date",
|
||||||
dateComponents: components,
|
dateComponents: components,
|
||||||
@@ -291,7 +293,7 @@ const locationSuggestions = (
|
|||||||
s: string,
|
s: string,
|
||||||
locationTags: Searchable<LocationTag>[],
|
locationTags: Searchable<LocationTag>[],
|
||||||
cities: Searchable<City>[],
|
cities: Searchable<City>[],
|
||||||
) => {
|
): SearchSuggestion[] => {
|
||||||
const matchingLocationTags = locationTags.filter(searchableIncludes(s));
|
const matchingLocationTags = locationTags.filter(searchableIncludes(s));
|
||||||
|
|
||||||
const matchingLocationTagLNames = new Set(
|
const matchingLocationTagLNames = new Set(
|
||||||
@@ -305,65 +307,68 @@ const locationSuggestions = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
matchingLocationTags.map((locationTag) => ({
|
matchingLocationTags.map(
|
||||||
type: "location",
|
(locationTag): SearchSuggestion => ({
|
||||||
locationTag,
|
type: "location",
|
||||||
label: locationTag.name,
|
locationTag,
|
||||||
})),
|
label: locationTag.name,
|
||||||
matchingCities.map((city) => ({
|
}),
|
||||||
type: "city",
|
),
|
||||||
city,
|
matchingCities.map(
|
||||||
label: city.name,
|
(city): SearchSuggestion => ({
|
||||||
})),
|
type: "city",
|
||||||
|
city,
|
||||||
|
label: city.name,
|
||||||
|
}),
|
||||||
|
),
|
||||||
].flat();
|
].flat();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if file satisfies the given {@link query}.
|
* Return true if file satisfies the given {@link query}.
|
||||||
*/
|
*/
|
||||||
const isMatchingFile = (file: EnteFile, query: SearchQuery) => {
|
const isMatchingFile = (file: EnteFile, suggestion: SearchSuggestion) => {
|
||||||
if (query.collection) {
|
switch (suggestion.type) {
|
||||||
return query.collection === file.collectionID;
|
case "collection":
|
||||||
|
return suggestion.collectionID === file.collectionID;
|
||||||
|
|
||||||
|
case "fileType":
|
||||||
|
return suggestion.fileType === file.metadata.fileType;
|
||||||
|
|
||||||
|
case "fileName":
|
||||||
|
return suggestion.fileIDs.includes(file.id);
|
||||||
|
|
||||||
|
case "fileCaption":
|
||||||
|
return suggestion.fileIDs.includes(file.id);
|
||||||
|
|
||||||
|
case "date":
|
||||||
|
return isDateComponentsMatch(
|
||||||
|
suggestion.dateComponents,
|
||||||
|
fileCreationPhotoDate(file, getPublicMagicMetadataSync(file)),
|
||||||
|
);
|
||||||
|
|
||||||
|
case "location": {
|
||||||
|
const location = fileLocation(file);
|
||||||
|
if (!location) return false;
|
||||||
|
|
||||||
|
return isInsideLocationTag(location, suggestion.locationTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
case "city": {
|
||||||
|
const location = fileLocation(file);
|
||||||
|
if (!location) return false;
|
||||||
|
|
||||||
|
return isInsideCity(location, suggestion.city);
|
||||||
|
}
|
||||||
|
|
||||||
|
case "clip":
|
||||||
|
return suggestion.clipScoreForFileID.has(file.id);
|
||||||
|
|
||||||
|
case "cgroup":
|
||||||
|
// return query.person.files.includes(file.id);
|
||||||
|
// TODO-Cluster implement me
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.date) {
|
|
||||||
return isDateComponentsMatch(
|
|
||||||
query.date,
|
|
||||||
fileCreationPhotoDate(file, getPublicMagicMetadataSync(file)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query.location) {
|
|
||||||
const location = fileLocation(file);
|
|
||||||
if (!location) return false;
|
|
||||||
|
|
||||||
return isInsideLocationTag(location, query.location);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query.city) {
|
|
||||||
const location = fileLocation(file);
|
|
||||||
if (!location) return false;
|
|
||||||
|
|
||||||
return isInsideCity(location, query.city);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query.files) {
|
|
||||||
return query.files.includes(file.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query.person) {
|
|
||||||
return query.person.files.includes(file.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof query.fileType !== "undefined") {
|
|
||||||
return query.fileType === file.metadata.fileType;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof query.clip !== "undefined") {
|
|
||||||
return query.clip.has(file.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const isDateComponentsMatch = (
|
const isDateComponentsMatch = (
|
||||||
|
Reference in New Issue
Block a user