From 29b0b2871bcf89bc94998b5b7c44d5596fa4b821 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Fri, 6 Jan 2023 03:30:18 +0100 Subject: [PATCH] Add awareness of 'api/capabilities', see #880 --- Logic/Osm/OsmConnection.ts | 45 +++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/Logic/Osm/OsmConnection.ts b/Logic/Osm/OsmConnection.ts index 6e294d2bc..fe2aa2e83 100644 --- a/Logic/Osm/OsmConnection.ts +++ b/Logic/Osm/OsmConnection.ts @@ -28,6 +28,8 @@ export default class UserDetails { } } +export type OsmServiceState = "online" | "readonly" | "offline" | "unknown" | "unreachable" + export class OsmConnection { public static readonly oauth_configs = { osm: { @@ -46,6 +48,13 @@ export class OsmConnection { public auth public userDetails: UIEventSource public isLoggedIn: Store + public gpxServiceIsOnline: UIEventSource = new UIEventSource( + "unknown" + ) + public apiIsOnline: UIEventSource = new UIEventSource( + "unknown" + ) + public loadingStatus = new UIEventSource<"not-attempted" | "loading" | "error" | "logged-in">( "not-attempted" ) @@ -94,7 +103,13 @@ export class OsmConnection { ud.totalMessages = 42 } const self = this - this.isLoggedIn = this.userDetails.map((user) => user.loggedIn) + this.UpdateCapabilities() + this.isLoggedIn = this.userDetails.map( + (user) => + user.loggedIn && + (self.apiIsOnline.data === "unknown" || self.apiIsOnline.data === "online"), + [this.apiIsOnline] + ) this.isLoggedIn.addCallback((isLoggedIn) => { if (self.userDetails.data.loggedIn == false && isLoggedIn == true) { // We have an inconsistency: the userdetails say we _didn't_ log in, but this actor says we do @@ -160,11 +175,17 @@ export class OsmConnection { this.loadingStatus.setData("not-attempted") } + /** + * The backend host, without path or trailing '/' + * + * new OsmConnection().Backend() // => "https://www.openstreetmap.org" + */ public Backend(): string { return this._oauth_config.url } public AttemptLogin() { + this.UpdateCapabilities() this.loadingStatus.setData("loading") if (this.fakeUser) { this.loadingStatus.setData("logged-in") @@ -504,4 +525,26 @@ export class OsmConnection { } }) } + + private UpdateCapabilities(): void { + const self = this + this.FetchCapabilities().then(({ api, gpx }) => { + self.apiIsOnline.setData(api) + self.gpxServiceIsOnline.setData(gpx) + }) + } + + private async FetchCapabilities(): Promise<{ api: OsmServiceState; gpx: OsmServiceState }> { + const result = await Utils.downloadAdvanced(this.Backend() + "/api/0.6/capabilities") + if (result["content"] === undefined) { + console.log("Something went wrong:", result) + return { api: "unreachable", gpx: "unreachable" } + } + const xmlRaw = result["content"] + const parsed = new DOMParser().parseFromString(xmlRaw, "text/xml") + const statusEl = parsed.getElementsByTagName("status")[0] + const api = statusEl.getAttribute("api") + const gpx = statusEl.getAttribute("gpx") + return { api, gpx } + } }