Files
TREK/client/src/utils/placeSource.ts
T
Maurice e12ae950df feat(places): send a search to Google, once or always
Since 4.3.0 the TREK index and OpenStreetMap answer every search first and
Google is only asked when they find nothing, so a list with the wrong place
on it never reached Google, whatever key the instance had, and the provider
choice only decided who fills the empty case.

Two ways to change that, both only where Google holds the key slot. Under a
result list that did not come from Google, one quiet line sends the same
query to Google Places alone (`provider: 'google'` on the search contract,
the MCP search tool takes it too). And beside the key, an admin switch
"Search with Google only" hands every search and every suggestion to Google
and asks nothing of the index or OpenStreetMap; off by default, read by the
search after the keyed provider so an install without a key, or one on Amap
or OpenStreetMap, is untouched. The panel says so beside the switch.

Both shells share the one rule for when the line is offered (placeSource),
and the wiki names both switches.
2026-09-21 22:14:44 +02:00

66 lines
2.6 KiB
TypeScript

/**
* Which index a place came from, as a short mark beside it.
*
* A result list can be two indexes interleaved, so the source belongs on the
* row rather than above the list: with the TREK index and OpenStreetMap
* answering together, "one of these came from somewhere" is not an answer
* anyone can use.
*
* Here rather than beside one screen because both the desktop form and the
* mobile sheet show the same lists, and a mark that says TREK on one and
* nothing on the other is worse than either alone.
*/
import type { TranslationFn } from '../types'
/**
* Proper nouns, so they are not translated. A source without a name people
* already know would need a string in 23 languages to say less than nothing.
*/
export const SOURCE_LABELS: Record<string, string> = {
'trek-places': 'TREK',
openstreetmap: 'OpenStreetMap',
nominatim: 'OpenStreetMap',
google: 'Google',
}
/**
* The one name that changes with the reader: 高德地图 to the people it exists
* for, Amap to everyone else. Hence a locale string rather than a fourth noun.
*/
const SOURCE_KEYS: Record<string, string> = {
amap: 'places.source.amap',
}
/**
* The label for one row.
*
* A place carries its own source when the index that produced it says so, which
* is what makes an interleaved list readable. Everything else falls back to what
* answered the call: Google never marks its places, and a merged list marks only
* the index side, so an unmarked row in one is OpenStreetMap by elimination.
*/
/**
* Whether a result list can be sent to Google instead.
*
* The index and OpenStreetMap answer first, and Google is only asked when they
* find nothing, so a list that has the wrong place on it never reaches Google
* on its own. The link that sends it there is offered when the instance has a
* Google key and this list did not already come from Google: a list Google
* produced, alone or as the empty-case fallback, has nowhere further to go, and
* the offline cache is not a search at all.
*/
export function offersGoogleRetry(listSource: string, hasMapsKey: boolean): boolean {
if (!hasMapsKey || !listSource) return false
return !listSource.split('+').includes('google') && listSource !== 'offline-cache'
}
export function sourceLabelFor(place: unknown, listSource: string, t: TranslationFn): string | null {
const own = (place as { source?: unknown } | null)?.source
const source = typeof own === 'string' && own
? own
: listSource.includes('openstreetmap') ? 'openstreetmap' : listSource
if (SOURCE_KEYS[source]) return t(SOURCE_KEYS[source])
return SOURCE_LABELS[source] ?? null
}