Skip to content

Commit 3a52858

Browse files
authored
feat(location): add location-based search functionality (#168)
1 parent ef48808 commit 3a52858

File tree

1 file changed

+31
-3
lines changed

1 file changed

+31
-3
lines changed

apps/web/src/components/gallery/CommandPalette.tsx

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,28 @@ const allTags = photoLoader.getAllTags()
3434
const allCameras = photoLoader.getAllCameras()
3535
const allLenses = photoLoader.getAllLenses()
3636

37+
const getLocationTokens = (
38+
location?: { locationName?: string | null; city?: string | null; country?: string | null } | null,
39+
) => {
40+
if (!location) return []
41+
42+
const tokens = [location.locationName, location.city, location.country]
43+
.map((token) => token?.trim())
44+
.filter((token): token is string => typeof token === 'string' && token.length > 0)
45+
46+
const uniqueTokens: string[] = []
47+
const seen = new Set<string>()
48+
tokens.forEach((token) => {
49+
const normalized = token.toLowerCase()
50+
if (!seen.has(normalized)) {
51+
seen.add(normalized)
52+
uniqueTokens.push(token)
53+
}
54+
})
55+
56+
return uniqueTokens
57+
}
58+
3759
// Fuzzy search utility
3860
const fuzzyMatch = (text: string, query: string): boolean => {
3961
const lowerText = text.toLowerCase()
@@ -62,8 +84,10 @@ const searchPhotos = (photos: ReturnType<typeof photoLoader.getPhotos>, query: s
6284
const matchesCamera =
6385
photo.exif?.Make?.toLowerCase().includes(lowerQuery) || photo.exif?.Model?.toLowerCase().includes(lowerQuery)
6486
const matchesLens = photo.exif?.LensModel?.toLowerCase().includes(lowerQuery)
87+
const locationTokens = getLocationTokens(photo.location)
88+
const matchesLocation = locationTokens.some((token) => token.toLowerCase().includes(lowerQuery))
6589

66-
return matchesTitle || matchesDescription || matchesTags || matchesCamera || matchesLens
90+
return matchesTitle || matchesDescription || matchesTags || matchesCamera || matchesLens || matchesLocation
6791
})
6892
}
6993

@@ -263,11 +287,13 @@ export const CommandPalette = ({ isOpen, onClose }: CommandPaletteProps) => {
263287
if (query.trim()) {
264288
const photos = searchPhotos(photoLoader.getPhotos(), query)
265289
photos.slice(0, 10).forEach((photo) => {
290+
const locationTokens = getLocationTokens(photo.location)
291+
const locationSubtitle = locationTokens.join(', ')
266292
cmds.push({
267293
id: `photo-${photo.id}`,
268294
type: 'photo',
269295
title: photo.title || photo.id,
270-
subtitle: photo.description || `${photo.exif?.Model || 'Photo'}`,
296+
subtitle: photo.description || locationSubtitle || `${photo.exif?.Model || 'Photo'}`,
271297
icon: <img src={photo.thumbnailUrl} alt={photo.title || 'Photo'} className="h-6 w-6 rounded object-cover" />,
272298
action: () => {
273299
const allPhotos = photoLoader.getPhotos()
@@ -278,7 +304,9 @@ export const CommandPalette = ({ isOpen, onClose }: CommandPaletteProps) => {
278304
onClose()
279305
}
280306
},
281-
keywords: [photo.title, photo.description, ...(photo.tags || [])].filter(Boolean) as string[],
307+
keywords: [photo.title, photo.description, ...locationTokens, ...(photo.tags || [])].filter(
308+
Boolean,
309+
) as string[],
282310
})
283311
})
284312
}

0 commit comments

Comments
 (0)