added location tag search logic

This commit is contained in:
Abhinav 2023-05-30 13:38:53 +05:30
parent 3a78700760
commit 1040f1986f
5 changed files with 57 additions and 54 deletions

View file

@ -6,13 +6,7 @@ import {
getAutoCompleteSuggestions,
getDefaultOptions,
} from 'services/searchService';
import {
Bbox,
DateValue,
Search,
SearchOption,
SuggestionType,
} from 'types/search';
import { DateValue, Search, SearchOption, SuggestionType } from 'types/search';
import { ValueContainerWithIcon } from './valueContainerWithIcon';
import { SelectStyles } from '../../../../styles/search';
import AsyncSelect from 'react-select/async';
@ -25,6 +19,7 @@ import { SearchInputWrapper } from '../styledComponents';
import MenuWithPeople from './MenuWithPeople';
import { Person, Thing, WordGroup } from 'types/machineLearning';
import { t } from 'i18next';
import { LocationTagData } from 'services/entityService';
interface Iprops {
isOpen: boolean;
@ -88,7 +83,7 @@ export default function SearchInput(props: Iprops) {
break;
case SuggestionType.LOCATION:
search = {
location: selectedOption.value as Bbox,
location: selectedOption.value as LocationTagData,
};
props.setIsOpen(true);
break;

View file

@ -118,8 +118,9 @@ import GalleryEmptyState from 'components/GalleryEmptyState';
import AuthenticateUserModal from 'components/AuthenticateUserModal';
import useMemoSingleThreaded from 'hooks/useMemoSingleThreaded';
import { IsArchived } from 'utils/magicMetadata';
import { isSameDayAnyYear, isInsideBox } from 'utils/search';
import { isSameDayAnyYear, isInsideLocationTag } from 'utils/search';
import { getSessionExpiredMessage } from 'utils/ui';
import { syncEntities } from 'services/entityService';
export const DeadCenter = styled('div')`
flex: 1;
@ -428,7 +429,7 @@ export default function Gallery() {
}
if (
search?.location &&
!isInsideBox(
!isInsideLocationTag(
{
latitude: item.metadata.latitude,
longitude: item.metadata.longitude,
@ -553,6 +554,7 @@ export default function Gallery() {
await syncFiles(normalCollections, setFiles);
await syncHiddenFiles(hiddenCollections, setHiddenFiles);
await syncTrash(collections, setTrashedFiles);
await syncEntities();
} catch (e) {
switch (e.message) {
case ServerErrorCodes.SESSION_EXPIRED:

View file

@ -8,20 +8,28 @@ import { Collection } from 'types/collection';
import { EnteFile } from 'types/file';
import { logError } from 'utils/sentry';
import {
Bbox,
DateValue,
LocationSearchResponse,
Search,
SearchOption,
Suggestion,
SuggestionType,
} from 'types/search';
import ObjectService from './machineLearning/objectService';
import { getFormattedDate, isInsideBox, isSameDayAnyYear } from 'utils/search';
import {
getFormattedDate,
isInsideLocationTag,
isSameDayAnyYear,
} from 'utils/search';
import { Person, Thing } from 'types/machineLearning';
import { getUniqueFiles } from 'utils/file';
import { User } from 'types/user';
import { getData, LS_KEYS } from 'utils/storage/localStorage';
import {
EntityType,
LocationTag,
LocationTagData,
getLatestEntities,
} from './entityService';
const DIGITS = new Set(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']);
@ -46,6 +54,7 @@ export const getAutoCompleteSuggestions =
...getCollectionSuggestion(searchPhrase, collections),
getFileNameSuggestion(searchPhrase, files),
getFileCaptionSuggestion(searchPhrase, files),
...(await getLocationTagSuggestions(searchPhrase)),
...(await getThingSuggestion(searchPhrase)),
];
@ -214,16 +223,15 @@ function getFileCaptionSuggestion(
};
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async function getLocationSuggestions(searchPhrase: string) {
const locationResults = await searchLocation(searchPhrase);
async function getLocationTagSuggestions(searchPhrase: string) {
const searchResults = await searchLocationTag(searchPhrase);
return locationResults.map(
(searchResult) =>
return searchResults.map(
(locationTag) =>
({
type: SuggestionType.LOCATION,
value: searchResult.bbox,
label: searchResult.place,
value: locationTag.data,
label: locationTag.data.name,
} as Suggestion)
);
}
@ -298,12 +306,14 @@ function parseHumanDate(humanDate: string): DateValue[] {
return [];
}
async function searchLocation(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
searchPhrase: string
): Promise<LocationSearchResponse[]> {
logError(Error(), 'attempting to use unimplemented search API');
return [];
async function searchLocationTag(searchPhrase: string): Promise<LocationTag[]> {
const locationTags = await getLatestEntities<LocationTagData>(
EntityType.LOCATION_TAG
);
const matchedLocationTags = locationTags.filter((locationTag) =>
locationTag.data.name.toLowerCase().includes(searchPhrase)
);
return matchedLocationTags;
}
async function searchThing(searchPhrase: string) {
@ -327,7 +337,7 @@ function isSearchedFile(user: User, file: EnteFile, search: Search) {
);
}
if (search?.location) {
return isInsideBox(
return isInsideLocationTag(
{
latitude: file.metadata.latitude,
longitude: file.metadata.longitude,
@ -361,7 +371,7 @@ function convertSuggestionToSearchQuery(option: Suggestion): Search {
case SuggestionType.LOCATION:
return {
location: option.value as Bbox,
location: option.value as LocationTagData,
};
case SuggestionType.COLLECTION:

View file

@ -1,17 +1,11 @@
import { Person, Thing, WordGroup } from 'types/machineLearning';
import { IndexStatus } from 'types/machineLearning/ui';
import { EnteFile } from 'types/file';
export type Bbox = [number, number, number, number];
export interface LocationSearchResponse {
place: string;
bbox: Bbox;
}
import { LocationTagData } from 'services/entityService';
export enum SuggestionType {
DATE = 'DATE',
LOCATION = 'LOCATION',
LOCATION = 'LOCATION_TAG',
COLLECTION = 'COLLECTION',
FILE_NAME = 'FILE_NAME',
PERSON = 'PERSON',
@ -31,19 +25,19 @@ export interface Suggestion {
type: SuggestionType;
label: string;
value:
| Bbox
| DateValue
| number[]
| Person
| IndexStatus
| Thing
| WordGroup;
| WordGroup
| LocationTagData;
hide?: boolean;
}
export type Search = {
date?: DateValue;
location?: Bbox;
location?: LocationTagData;
collection?: number;
files?: number[];
person?: Person;

View file

@ -1,20 +1,7 @@
import { Bbox, DateValue } from 'types/search';
import { LocationTagData } from 'services/entityService';
import { DateValue } from 'types/search';
import { Location } from 'types/upload';
export function isInsideBox({ latitude, longitude }: Location, bbox: Bbox) {
if (latitude === null && longitude === null) {
return false;
}
if (
longitude >= bbox[0] &&
latitude >= bbox[1] &&
longitude <= bbox[2] &&
latitude <= bbox[3]
) {
return true;
}
}
export const isSameDayAnyYear =
(baseDate: DateValue) => (compareDate: Date) => {
let same = true;
@ -41,3 +28,18 @@ export function getFormattedDate(date: DateValue) {
new Date(date.year ?? 1, date.month ?? 1, date.date ?? 1)
);
}
export function isInsideLocationTag(
location: Location,
locationTag: LocationTagData
) {
const { centerPoint, aSquare, bSquare } = locationTag;
const { latitude, longitude } = location;
const x = Math.abs(centerPoint.latitude - latitude);
const y = Math.abs(centerPoint.longitude - longitude);
if ((x * x) / aSquare + (y * y) / bSquare <= 1) {
return true;
} else {
return false;
}
}