Unsearchable

This commit is contained in:
Manav Rathi
2024-09-18 17:09:38 +05:30
parent 215126f695
commit 7bf37c2800
3 changed files with 25 additions and 65 deletions

View File

@@ -158,14 +158,8 @@ let _localizedSearchData: LocalizedSearchData | undefined;
const localizedSearchData = () =>
(_localizedSearchData ??= {
locale: i18n.language,
holidays: holidays().map((h) => ({
...h,
searchTerms: h.label.toLowerCase().split(" "),
})),
labelledFileTypes: labelledFileTypes().map((t) => ({
...t,
searchTerms: t.label.toLowerCase().split(" "),
})),
holidays: holidays(),
labelledFileTypes: labelledFileTypes(),
});
/**

View File

@@ -62,28 +62,14 @@ export interface LabelledFileType {
label: string;
}
/**
* An annotated version of {@link T} that includes a list of lowercased words
* that it should match.
*
* Precomputing these lowercased values saves us from doing the lowercasing
* during the search itself.
*/
export type Searchable<T> = T & {
/**
* The name or label of T, split into words and lowercased.
*/
searchTerms: string[];
};
/**
* Various bits of static but locale specific data that the search worker needs
* during searching.
*/
export interface LocalizedSearchData {
locale: string;
holidays: Searchable<LabelledSearchDateComponents>[];
labelledFileTypes: Searchable<LabelledFileType>[];
holidays: LabelledSearchDateComponents[];
labelledFileTypes: LabelledFileType[];
}
/**

View File

@@ -21,7 +21,6 @@ import type {
LabelledFileType,
LabelledSearchDateComponents,
LocalizedSearchData,
Searchable,
SearchCollectionsAndFiles,
SearchDateComponents,
SearchSuggestion,
@@ -32,13 +31,13 @@ import type {
* remains responsive.
*/
export class SearchWorker {
private locationTags: Searchable<LocationTag>[] = [];
private cities: Searchable<City>[] = [];
private locationTags: LocationTag[] = [];
private cities: City[] = [];
private collectionsAndFiles: SearchCollectionsAndFiles = {
collections: [],
files: [],
};
private searchablePeople: Searchable<Person>[] = [];
private people: Person[] = [];
/**
* Fetch any state we might need when the actual search happens.
@@ -50,18 +49,8 @@ export class SearchWorker {
return Promise.all([
pullLocationTags(masterKey)
.then(() => savedLocationTags())
.then((ts) => {
this.locationTags = ts.map((t) => ({
...t,
searchTerms: t.name.toLowerCase().split(" "),
}));
}),
fetchCities().then((cs) => {
this.cities = cs.map((c) => ({
...c,
searchTerms: c.name.toLowerCase().split(" "),
}));
}),
.then((ts) => (this.locationTags = ts)),
fetchCities().then((cs) => (this.cities = cs)),
]);
}
@@ -76,12 +65,7 @@ export class SearchWorker {
* Set the people that we should search across.
*/
setPeople(people: Person[]) {
this.searchablePeople = people.map((person) => {
return {
...person,
searchTerms: person.name.toLowerCase().split(" "),
};
});
this.people = people;
}
/**
@@ -92,15 +76,14 @@ export class SearchWorker {
searchString: string,
localizedSearchData: LocalizedSearchData,
) {
// Case insensitive word prefix match, considering underscores also as a
// word separator.
const re = new RegExp("(\\b|_)" + s, "i");
return suggestionsForString(
s,
re,
// Case insensitive word prefix match, considering underscores also
// as a word separator.
new RegExp("(\\b|_)" + s, "i"),
searchString,
this.collectionsAndFiles,
this.searchablePeople,
this.people,
localizedSearchData,
this.locationTags,
this.cities,
@@ -139,12 +122,12 @@ const suggestionsForString = (
re: RegExp,
searchString: string,
{ collections, files }: SearchCollectionsAndFiles,
searchablePeople: Searchable<Person>[],
people: Person[],
{ locale, holidays, labelledFileTypes }: LocalizedSearchData,
locationTags: Searchable<LocationTag>[],
cities: Searchable<City>[],
locationTags: LocationTag[],
cities: City[],
): [SearchSuggestion[], SearchSuggestion[]] => [
[peopleSuggestions(re, searchablePeople)].flat(),
[peopleSuggestions(re, people)].flat(),
// . <-- clip suggestions will be inserted here by our caller.
[
fileTypeSuggestions(re, labelledFileTypes),
@@ -170,7 +153,7 @@ const collectionSuggestions = (
const fileTypeSuggestions = (
re: RegExp,
labelledFileTypes: Searchable<LabelledFileType>[],
labelledFileTypes: LabelledFileType[],
): SearchSuggestion[] =>
labelledFileTypes
.filter(({ label }) => re.test(label))
@@ -213,11 +196,8 @@ const fileCaptionSuggestion = (
: [];
};
const peopleSuggestions = (
re: RegExp,
searchablePeople: Searchable<Person>[],
): SearchSuggestion[] =>
searchablePeople
const peopleSuggestions = (re: RegExp, people: Person[]): SearchSuggestion[] =>
people
.filter((p) => re.test(p.name))
.map((person) => ({ type: "person", person, label: person.name }));
@@ -225,7 +205,7 @@ const dateSuggestions = (
s: string,
re: RegExp,
locale: string,
holidays: Searchable<LabelledSearchDateComponents>[],
holidays: LabelledSearchDateComponents[],
): SearchSuggestion[] =>
parseDateComponents(s, re, locale, holidays).map(
({ components, label }) => ({
@@ -253,7 +233,7 @@ const parseDateComponents = (
s: string,
re: RegExp,
locale: string,
holidays: Searchable<LabelledSearchDateComponents>[],
holidays: LabelledSearchDateComponents[],
): LabelledSearchDateComponents[] =>
[
parseChrono(s, locale),
@@ -335,8 +315,8 @@ const fetchCities = async () => {
const locationSuggestions = (
re: RegExp,
locationTags: Searchable<LocationTag>[],
cities: Searchable<City>[],
locationTags: LocationTag[],
cities: City[],
): SearchSuggestion[] => {
const matchingLocationTags = locationTags.filter((t) => re.test(t.name));