UX: indicate incomplete search in offline mode

This commit is contained in:
Pieter Vander Vennet 2025-08-01 00:42:15 +02:00
parent 76dbf50db1
commit b6366412ea
13 changed files with 69 additions and 5 deletions

View file

@ -6,6 +6,8 @@ export default class CombinedSearcher implements GeocodingProvider {
public readonly name = "CombinedSearcher"
private _providers: ReadonlyArray<GeocodingProvider>
private _providersWithSuggest: ReadonlyArray<GeocodingProvider>
public readonly needsInternet
/**
* Merges the various providers together; ignores errors.
@ -15,6 +17,7 @@ export default class CombinedSearcher implements GeocodingProvider {
constructor(...providers: ReadonlyArray<GeocodingProvider>) {
this._providers = Utils.NoNull(providers)
this._providersWithSuggest = this._providers.filter((pr) => pr.suggest !== undefined)
this.needsInternet = this._providers.some(p => p.needsInternet)
}
/**

View file

@ -8,6 +8,8 @@ import CoordinateParser from "coordinate-parser"
*/
export default class CoordinateSearch implements GeocodingProvider {
public readonly name = "CoordinateSearch"
public readonly needsInternet = false
private static readonly latLonRegexes: ReadonlyArray<RegExp> = [
/^ *(-?[0-9]+\.[0-9]+)[ ,;/\\]+(-?[0-9]+\.[0-9]+)/,
/^ *(-?[0-9]+,[0-9]+)[ ;/\\]+(-?[0-9]+,[0-9]+)/,

View file

@ -49,6 +49,7 @@ export interface GeocodingOptions {
export default interface GeocodingProvider {
readonly name: string
readonly needsInternet: boolean
/**
* Performs search.

View file

@ -21,6 +21,8 @@ export default class LocalElementSearch implements GeocodingProvider {
private readonly _state: ThemeViewState
private readonly _limit: number
public readonly name = "LocalElementSearch"
public readonly needsInternet = false
constructor(state: ThemeViewState, limit: number) {
this._state = state
this._limit = limit

View file

@ -10,6 +10,7 @@ export class NominatimGeocoding implements GeocodingProvider {
private readonly _host
private readonly limit: number
public readonly name = "Nominatim"
public readonly needsInternet = true
constructor(limit: number = 3, host: string = Constants.nominatimEndpoint) {
this.limit = limit

View file

@ -3,6 +3,8 @@ import GeocodingProvider, { GeocodeResult, GeocodingOptions } from "./GeocodingP
import { decode as pluscode_decode } from "pluscodes"
export default class OpenLocationCodeSearch implements GeocodingProvider {
public readonly needsInternet = false
/**
* A regex describing all plus-codes
*/

View file

@ -7,6 +7,7 @@ import OsmObjectDownloader from "../Osm/OsmObjectDownloader"
export default class OpenStreetMapIdSearch implements GeocodingProvider {
private static readonly regex =
/((https?:\/\/)?(www.)?(osm|openstreetmap).org\/)?(n|node|w|way|r|relation)[/ ]?([0-9]+)/
public readonly needsInternet = true
public readonly name = "OpenStreetMapId"
private static readonly types: Readonly<Record<string, "node" | "way" | "relation">> = {
n: "node",

View file

@ -5,7 +5,7 @@ import GeocodingProvider, {
GeocodingOptions,
GeocodingUtils,
ReverseGeocodingProvider,
ReverseGeocodingResult,
ReverseGeocodingResult
} from "./GeocodingProvider"
import { Utils } from "../../Utils"
import { Feature, FeatureCollection } from "geojson"
@ -15,6 +15,7 @@ import { Store, Stores } from "../UIEventSource"
export default class PhotonSearch implements GeocodingProvider, ReverseGeocodingProvider {
private readonly _endpoint: string
public readonly needsInternet = true
public readonly name = "photon"
private supportedLanguages = ["en", "de", "fr"]
private static readonly types = {
@ -23,17 +24,14 @@ export default class PhotonSearch implements GeocodingProvider, ReverseGeocoding
N: "node",
}
private readonly ignoreBounds: boolean
private readonly suggestionLimit: number = 5
private readonly searchLimit: number = 1
constructor(
ignoreBounds: boolean = false,
suggestionLimit: number = 5,
searchLimit: number = 1,
endpoint?: string
) {
this.ignoreBounds = ignoreBounds
this.suggestionLimit = suggestionLimit
this.searchLimit = searchLimit
this._endpoint = endpoint ?? Constants.photonEndpoint ?? "https://photon.komoot.io/"

View file

@ -20,6 +20,7 @@ import { BBox } from "../BBox"
import { QueryParameters } from "../Web/QueryParameters"
import { Utils } from "../../Utils"
import { NominatimGeocoding } from "../Search/NominatimGeocoding"
import { IsOnline } from "../Web/IsOnline"
export default class SearchState {
public readonly feedback: UIEventSource<Translation> = new UIEventSource<Translation>(undefined)
@ -62,7 +63,9 @@ export default class SearchState {
if (search.length === 0) {
return undefined
}
return this.locationSearchers.map((ls) => ({
return this.locationSearchers
.filter(ls => !ls.needsInternet || IsOnline.isOnline.data)
.map((ls) => ({
source: ls,
results: ls.suggest(search, { bbox: bounds.data }),
}))