Files
TREK/client/src/utils/placesProvider.ts
T

70 lines
2.8 KiB
TypeScript

/**
* Which provider place search will actually use, as far as the client can tell.
*
* This mirrors the server's MapsService.resolvePlacesProvider(): the instance's
* places_provider choice, the keys the server reported for this caller, and the
* same precedence. It exists so a notice can say the truth — "search is running
* on OpenStreetMap", not "you lack a Google key" on an install whose admin
* deliberately picked Amap.
*
* A mirror and not the source of truth on purpose: the server resolves keys per
* request against the database, and only it knows for sure. If the two ever
* disagree, the client shows a slightly wrong hint under a notice and nothing
* else — search itself keeps asking the server.
*/
export type PlacesProviderChoice = 'auto' | 'google' | 'amap' | 'openstreetmap'
export type EffectiveSearchProvider = 'google' | 'amap' | 'openstreetmap'
export interface PlacesProviderState {
/** The admin's places_provider choice; anything unrecognised means 'auto'. */
placesProvider?: string | null
/** Whether a Google key resolves for this caller (operator env, instance, own row). */
hasMapsKey: boolean
hasAmapKey: boolean
}
export function effectivePlacesProvider(state: PlacesProviderState): EffectiveSearchProvider {
const choice: PlacesProviderChoice =
state.placesProvider === 'google' || state.placesProvider === 'amap' || state.placesProvider === 'openstreetmap'
? state.placesProvider
: 'auto'
if (choice === 'openstreetmap') return 'openstreetmap'
if (choice === 'google') return state.hasMapsKey ? 'google' : 'openstreetmap'
if (choice === 'amap') return state.hasAmapKey ? 'amap' : 'openstreetmap'
// auto prefers Google, the incumbent: an existing install must not move to a
// different provider, with a different bill, just because Amap appeared.
if (state.hasMapsKey) return 'google'
if (state.hasAmapKey) return 'amap'
return 'openstreetmap'
}
/**
* Which key the "still on OpenStreetMap" upsell should suggest.
*
* A chosen provider names the key that belongs to it — telling an admin who
* picked Amap to add a Google key is advice they already declined. `auto` with
* no key at all is the only case where both are worth naming.
*
* Null when the admin explicitly chose OpenStreetMap: that is a decision, not a
* gap to fill, and the notices stay quiet rather than nag.
*/
export type KeySuggestion = 'google' | 'amap' | 'any'
export function osmKeySuggestion(placesProvider?: string | null): KeySuggestion | null {
switch (placesProvider) {
case 'google':
return 'google'
case 'amap':
return 'amap'
case 'openstreetmap':
return null
// auto resolving to OSM means neither key is configured (a Google key would
// have won), so both are honest suggestions.
default:
return 'any'
}
}