diff --git a/UI/Popup/LoginButton.ts b/UI/Popup/LoginButton.ts index 872e143b4..e5c651fc3 100644 --- a/UI/Popup/LoginButton.ts +++ b/UI/Popup/LoginButton.ts @@ -1,11 +1,13 @@ import { SubtleButton } from "../Base/SubtleButton" import BaseUIElement from "../BaseUIElement" import Svg from "../../Svg" -import { OsmConnection } from "../../Logic/Osm/OsmConnection" -import Toggle from "../Input/Toggle" +import { OsmConnection, OsmServiceState } from "../../Logic/Osm/OsmConnection" import { VariableUiElement } from "../Base/VariableUIElement" import Loading from "../Base/Loading" import Translations from "../i18n/Translations" +import { Store } from "../../Logic/UIEventSource" +import Combine from "../Base/Combine" +import { Translation } from "../i18n/Translation" class LoginButton extends SubtleButton { constructor( @@ -23,30 +25,67 @@ class LoginButton extends SubtleButton { } export class LoginToggle extends VariableUiElement { + /** + * Constructs an element which shows 'el' if the user is logged in + * If not logged in, 'text' is shown on the button which invites to login. + * + * If logging in is not possible for some reason, an appropriate error message is shown + * + * State contains the 'osmConnection' to work with + */ constructor( el: BaseUIElement, text: BaseUIElement | string, state: { - osmConnection: OsmConnection + readonly osmConnection: OsmConnection + readonly featureSwitchUserbadge: Store } ) { const loading = new Loading("Trying to log in...") - const login = new LoginButton(text, state) - super( - state.osmConnection.loadingStatus.map((osmConnectionState) => { - if (osmConnectionState === "loading") { - return loading - } - if (osmConnectionState === "not-attempted") { - return login - } - if (osmConnectionState === "logged-in") { - return el - } + const login = text === undefined ? undefined : new LoginButton(text, state) + const t = Translations.t.general + const offlineModes: Partial> = { + offline: t.loginFailedOfflineMode, + unreachable: t.loginFailedUnreachableMode, + readonly: t.loginFailedReadonlyMode, + } - // Error! - return new LoginButton(Translations.t.general.loginFailed, state, Svg.invalid_svg()) - }) + super( + state.osmConnection.loadingStatus.map( + (osmConnectionState) => { + if (state.featureSwitchUserbadge.data == false) { + // All features to login with are disabled + return undefined + } + + const apiState = state.osmConnection.apiIsOnline.data + const apiTranslation = offlineModes[apiState] + if (apiTranslation !== undefined) { + return new Combine([ + Svg.invalid_svg().SetClass("w-8 h-8 m-2 shrink-0"), + apiTranslation, + ]).SetClass("flex items-center alert max-w-64") + } + + if (osmConnectionState === "loading") { + return loading + } + if (osmConnectionState === "not-attempted") { + return login + } + if (osmConnectionState === "logged-in") { + return el + } + + // Error! + return new LoginButton( + Translations.t.general.loginFailed, + state, + Svg.invalid_svg() + ) + }, + [state.featureSwitchUserbadge, state.osmConnection.apiIsOnline] + ) ) } } diff --git a/css/index-tailwind-output.css b/css/index-tailwind-output.css index f3ae9bd25..94276247c 100644 --- a/css/index-tailwind-output.css +++ b/css/index-tailwind-output.css @@ -1382,6 +1382,10 @@ video { border-bottom-width: 1px; } +.border-b-2 { + border-bottom-width: 2px; +} + .border-dotted { border-style: dotted; } @@ -1561,6 +1565,10 @@ video { padding-right: 0.5rem; } +.pb-8 { + padding-bottom: 2rem; +} + .pl-5 { padding-left: 1.25rem; } diff --git a/langs/en.json b/langs/en.json index a67879fcf..cfe6d0d47 100644 --- a/langs/en.json +++ b/langs/en.json @@ -188,6 +188,9 @@ "loading": "Loading…", "loadingTheme": "Loading {theme}…", "loginFailed": "Logging in into OpenStreetMap failed", + "loginFailedOfflineMode": "OpenStreetMap.org is currently not available due to maintenance. Making edits will be possible soon", + "loginFailedReadonlyMode": "OpenStreetMap.org is currently in readonly mode due to maintenance. Making edits will be possible soon", + "loginFailedUnreachableMode": "OpenStreetMap.org is currently not reachable. Are you connected to the internet or do you block third parties? Try again later", "loginOnlyNeededToEdit": "if you want to edit the map", "loginToStart": "Log in to answer this question", "loginWithOpenStreetMap": "Login with OpenStreetMap", @@ -284,6 +287,7 @@ "uploadGpx": { "choosePermission": "Choose below if your track should be shared:", "confirm": "Confirm upload", + "gpxServiceOffline": "The GPX-service is currently offline - uploading is currently not possible. Try again later.", "intro0": "By uploading your track, OpenStreetMap.org will retain a full copy of the track.", "intro1": "You will be able to download your track again and to load them into OpenStreetMap editing programs", "meta": {