forked from OurHike/OurHike
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearchPoi.ts
More file actions
42 lines (36 loc) · 1.33 KB
/
Copy pathsearchPoi.ts
File metadata and controls
42 lines (36 loc) · 1.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// Local search over what is already on the phone (WIREFRAMES.md Interactions).
//
// There is no network path here, by design rather than by omission. Search
// that needs signal is useless in exactly the place someone needs it, so this
// only ever matches against the exported POIs already downloaded - and the UI
// is required to say so when nothing matches (`7c`), because "not found" and
// "outside what you downloaded" are different answers.
export interface SearchablePoi {
id: string
name: string
type: string
mile: number
}
export interface SearchOptions {
type?: string
}
/** Enough to scan without scrolling past the point of usefulness. */
export const SEARCH_RESULT_LIMIT = 25
export function searchPois(
query: string,
pois: SearchablePoi[],
{ type }: SearchOptions = {},
): SearchablePoi[] {
const needle = query.trim().toLowerCase()
// An empty query means "you haven't asked anything yet", not "show me all
// 4,000 waypoints on the trail".
if (needle === '') return []
const scored = pois
.filter((poi) => type === undefined || poi.type === type)
.map((poi) => ({ poi, at: poi.name.toLowerCase().indexOf(needle) }))
.filter(({ at }) => at !== -1)
return scored
.sort((a, b) => a.at - b.at || a.poi.name.localeCompare(b.poi.name))
.slice(0, SEARCH_RESULT_LIMIT)
.map(({ poi }) => poi)
}