From e31c87feab3b6a41bc565247e9fff5774981e5e2 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Fri, 6 Jan 2023 03:37:22 +0100 Subject: [PATCH] Use LoginToggle where possible, --- UI/AllThemesGui.ts | 9 ++-- UI/BigComponents/SimpleAddUI.ts | 14 +++--- UI/Image/ImageUploadFlow.ts | 11 ++--- UI/Popup/DeleteWizard.ts | 77 +++++++++++++++------------------ UI/Popup/MoveWizard.ts | 7 +-- UI/Popup/QuestionBox.ts | 43 ++++++++++-------- UI/Popup/SplitRoadWizard.ts | 8 +--- UI/Reviews/ReviewForm.ts | 30 ++++++++----- UI/SpecialVisualizations.ts | 2 +- 9 files changed, 101 insertions(+), 100 deletions(-) diff --git a/UI/AllThemesGui.ts b/UI/AllThemesGui.ts index 06195d6e45..7a4cd705a6 100644 --- a/UI/AllThemesGui.ts +++ b/UI/AllThemesGui.ts @@ -13,6 +13,7 @@ import { SubtleButton } from "./Base/SubtleButton" import { VariableUiElement } from "./Base/VariableUIElement" import Svg from "../Svg" import { ImportViewerLinks } from "./BigComponents/UserInformation" +import {LoginToggle} from "./Popup/LoginButton"; export default class AllThemesGui { setup() { @@ -29,12 +30,10 @@ export default class AllThemesGui { intro, new FeaturedMessage().SetClass("mb-4 block"), new MoreScreen(state, true), - new Toggle( + new LoginToggle( undefined, - new SubtleButton(undefined, Translations.t.index.logIn) - .SetStyle("height:min-content") - .onClick(() => state.osmConnection.AttemptLogin()), - state.osmConnection.isLoggedIn + Translations.t.index.logIn, + state ), new ImportViewerLinks(state.osmConnection), Translations.t.general.aboutMapcomplete diff --git a/UI/BigComponents/SimpleAddUI.ts b/UI/BigComponents/SimpleAddUI.ts index d7d8c05337..8ce8be8d1d 100644 --- a/UI/BigComponents/SimpleAddUI.ts +++ b/UI/BigComponents/SimpleAddUI.ts @@ -1,7 +1,7 @@ /** * Asks to add a feature at the last clicked location, at least if zoom is sufficient */ -import { UIEventSource } from "../../Logic/UIEventSource" +import { Store, UIEventSource } from "../../Logic/UIEventSource" import Svg from "../../Svg" import { SubtleButton } from "../Base/SubtleButton" import Combine from "../Base/Combine" @@ -28,6 +28,7 @@ import Hash from "../../Logic/Web/Hash" import { GlobalFilter } from "../../Logic/State/MapState" import { WayId } from "../../Models/OsmFeature" import { Tag } from "../../Logic/Tags/Tag" +import { LoginToggle } from "../Popup/LoginButton" /* * The SimpleAddUI is a single panel, which can have multiple states: @@ -44,7 +45,7 @@ export interface PresetInfo extends PresetConfig { boundsFactor?: 0.25 | number } -export default class SimpleAddUI extends Toggle { +export default class SimpleAddUI extends LoginToggle { /** * * @param isShown @@ -59,6 +60,7 @@ export default class SimpleAddUI extends Toggle { filterViewIsOpened: UIEventSource, state: { featureSwitchIsTesting: UIEventSource + featureSwitchUserbadge: Store layoutToUse: LayoutConfig osmConnection: OsmConnection changes: Changes @@ -74,10 +76,6 @@ export default class SimpleAddUI extends Toggle { }, takeLocationFrom?: UIEventSource<{ lat: number; lon: number }> ) { - const loginButton = new SubtleButton( - Svg.osm_logo_ui(), - Translations.t.general.add.pleaseLogin.Clone() - ).onClick(() => state.osmConnection.AttemptLogin()) const readYourMessages = new Combine([ Translations.t.general.readYourMessages.Clone().SetClass("alert"), new SubtleButton(Svg.envelope_ui(), Translations.t.general.goToInbox, { @@ -187,8 +185,8 @@ export default class SimpleAddUI extends Toggle { userdetails.unreadMessages == 0 ) ), - loginButton, - state.osmConnection.isLoggedIn + Translations.t.general.add.pleaseLogin, + state ) } diff --git a/UI/Image/ImageUploadFlow.ts b/UI/Image/ImageUploadFlow.ts index 0f7dcc7df6..26759ea858 100644 --- a/UI/Image/ImageUploadFlow.ts +++ b/UI/Image/ImageUploadFlow.ts @@ -16,6 +16,7 @@ import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig" import { OsmConnection } from "../../Logic/Osm/OsmConnection" import { Changes } from "../../Logic/Osm/Changes" import Loading from "../Base/Loading" +import {LoginToggle} from "../Popup/LoginButton"; export class ImageUploadFlow extends Toggle { private static readonly uploadCountsPerId = new Map>() @@ -180,16 +181,12 @@ export class ImageUploadFlow extends Toggle { chosenLicense.SetClass("subtle text-sm"), ]).SetClass("flex flex-col image-upload-flow mt-4 mb-8 text-center") - const pleaseLoginButton = t.pleaseLogin - .Clone() - .onClick(() => state.osmConnection.AttemptLogin()) - .SetClass("login-button-friendly") super( - new Toggle( + new LoginToggle( /*We can show the actual upload button!*/ uploadFlow, - /* User not logged in*/ pleaseLoginButton, - state?.osmConnection?.isLoggedIn + /* User not logged in*/ t.pleaseLogin.Clone(), + state ), undefined /* Nothing as the user badge is disabled*/, state?.featureSwitchUserbadge diff --git a/UI/Popup/DeleteWizard.ts b/UI/Popup/DeleteWizard.ts index ff5950aff0..13e7360875 100644 --- a/UI/Popup/DeleteWizard.ts +++ b/UI/Popup/DeleteWizard.ts @@ -23,6 +23,7 @@ import { SubstitutedTranslation } from "../SubstitutedTranslation" import FeaturePipelineState from "../../Logic/State/FeaturePipelineState" import TagRenderingQuestion from "./TagRenderingQuestion" import { OsmId } from "../../Models/OsmFeature" +import { LoginToggle } from "./LoginButton" export default class DeleteWizard extends Toggle { /** @@ -122,6 +123,40 @@ export default class DeleteWizard extends Toggle { ]).SetClass("flex mt-2 justify-between"), ]).SetClass("question") + const deleteFlow = new Toggle( + new Toggle( + new Toggle( + deleteDialog, + new SubtleButton(Svg.envelope_ui(), t.readMessages), + state.osmConnection.userDetails.map( + (ud) => + ud.csCount > + Constants.userJourney.addNewPointWithUnreadMessagesUnlock || + ud.unreadMessages == 0 + ) + ), + + deleteButton, + confirm + ), + new VariableUiElement( + deleteAbility.canBeDeleted.map((cbd) => + new Combine([ + Svg.delete_not_allowed_svg() + .SetStyle("height: 2rem; width: auto") + .SetClass("mr-2"), + new Combine([ + t.cannotBeDeleted, + cbd.reason.SetClass("subtle"), + t.useSomethingElse.SetClass("subtle"), + ]).SetClass("flex flex-col"), + ]).SetClass("flex m-2 p-2 rounded-lg bg-gray-200 bg-gray-200") + ) + ), + + deleteAbility.canBeDeleted.map((cbd) => allowSoftDeletion || cbd.canBeDeleted !== false) + ) + super( new Toggle( new Combine([ @@ -130,47 +165,7 @@ export default class DeleteWizard extends Toggle { ), t.isDeleted, ]).SetClass("flex m-2 rounded-full"), - new Toggle( - new Toggle( - new Toggle( - new Toggle( - deleteDialog, - new SubtleButton(Svg.envelope_ui(), t.readMessages), - state.osmConnection.userDetails.map( - (ud) => - ud.csCount > - Constants.userJourney - .addNewPointWithUnreadMessagesUnlock || - ud.unreadMessages == 0 - ) - ), - - deleteButton, - confirm - ), - new VariableUiElement( - deleteAbility.canBeDeleted.map((cbd) => - new Combine([ - Svg.delete_not_allowed_svg() - .SetStyle("height: 2rem; width: auto") - .SetClass("mr-2"), - new Combine([ - t.cannotBeDeleted, - cbd.reason.SetClass("subtle"), - t.useSomethingElse.SetClass("subtle"), - ]).SetClass("flex flex-col"), - ]).SetClass("flex m-2 p-2 rounded-lg bg-gray-200 bg-gray-200") - ) - ), - - deleteAbility.canBeDeleted.map( - (cbd) => allowSoftDeletion || cbd.canBeDeleted !== false - ) - ), - - t.loginToDelete.onClick(state.osmConnection.AttemptLogin), - state.osmConnection.isLoggedIn - ), + new LoginToggle(deleteFlow, undefined, state), isDeleted ), undefined, diff --git a/UI/Popup/MoveWizard.ts b/UI/Popup/MoveWizard.ts index 8a11d97b6d..d643b799e1 100644 --- a/UI/Popup/MoveWizard.ts +++ b/UI/Popup/MoveWizard.ts @@ -23,6 +23,7 @@ import SearchAndGo from "../BigComponents/SearchAndGo" import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction" import { And } from "../../Logic/Tags/And" import { Tag } from "../../Logic/Tags/Tag" +import { LoginToggle } from "./LoginButton" interface MoveReason { text: Translation | string @@ -220,7 +221,7 @@ export default class MoveWizard extends Toggle { const dialogClasses = "p-2 md:p-4 m-2 border border-gray-400 rounded-xl flex flex-col" - const moveFlow = new Toggle( + const moveFlow = new LoginToggle( new VariableUiElement( currentStep.map((currentStep) => { switch (currentStep) { @@ -246,8 +247,8 @@ export default class MoveWizard extends Toggle { } }) ), - loginButton, - state.osmConnection.isLoggedIn + undefined, + state ) let id = featureToMove.properties.id const backend = state.osmConnection._oauth_config.url diff --git a/UI/Popup/QuestionBox.ts b/UI/Popup/QuestionBox.ts index 7053a4a681..669f9a4323 100644 --- a/UI/Popup/QuestionBox.ts +++ b/UI/Popup/QuestionBox.ts @@ -7,6 +7,7 @@ import { VariableUiElement } from "../Base/VariableUIElement" import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig" import { Unit } from "../../Models/Unit" import Lazy from "../Base/Lazy" +import { OsmServiceState } from "../../Logic/Osm/OsmConnection" /** * Generates all the questions, one by one @@ -119,30 +120,34 @@ export default class QuestionBox extends VariableUiElement { ) super( - questionsToAsk.map((allQuestions) => { - const els: BaseUIElement[] = [] - if ( - options.showAllQuestionsAtOnce === true || - options.showAllQuestionsAtOnce["data"] - ) { - els.push(...questionsToAsk.data) - } else { - els.push(allQuestions[0]) - } + questionsToAsk.map( + (allQuestions) => { + const apiState: OsmServiceState = state.osmConnection.apiIsOnline.data + if (apiState !== "online" && apiState !== "unknown") { + return undefined + } + const els: BaseUIElement[] = [] + if ( + options.showAllQuestionsAtOnce === true || + options.showAllQuestionsAtOnce["data"] + ) { + els.push(...questionsToAsk.data) + } else { + els.push(allQuestions[0]) + } - if (skippedQuestions.data.length > 0) { - els.push(skippedQuestionsButton) - } + if (skippedQuestions.data.length > 0) { + els.push(skippedQuestionsButton) + } - return new Combine(els).SetClass("block mb-8") - }) + return new Combine(els).SetClass("block mb-8") + }, + [state.osmConnection.apiIsOnline] + ) ) this.skippedQuestions = skippedQuestions this.restingQuestions = questionsToAsk - focus = () => - this.ScrollIntoView({ - onlyIfPartiallyHidden: true, - }) + focus = () => this.ScrollIntoView() } } diff --git a/UI/Popup/SplitRoadWizard.ts b/UI/Popup/SplitRoadWizard.ts index dbdac314ce..036adec1cb 100644 --- a/UI/Popup/SplitRoadWizard.ts +++ b/UI/Popup/SplitRoadWizard.ts @@ -25,6 +25,7 @@ import FilteredLayer from "../../Models/FilteredLayer" import BaseUIElement from "../BaseUIElement" import { VariableUiElement } from "../Base/VariableUIElement" import ScrollableFullScreen from "../Base/ScrollableFullScreen" +import { LoginToggle } from "./LoginButton" export default class SplitRoadWizard extends Combine { // @ts-ignore @@ -82,12 +83,7 @@ export default class SplitRoadWizard extends Combine { ) ) - // Only show the splitButton if logged in, else show login prompt - const loginBtn = t.loginToSplit - .Clone() - .onClick(() => state.osmConnection.AttemptLogin()) - .SetClass("login-button-friendly") - const splitToggle = new Toggle(splitButton, loginBtn, state.osmConnection.isLoggedIn) + const splitToggle = new LoginToggle(splitButton, t.loginToSplit.Clone(), state) // Save button const saveButton = new Button(t.split.Clone(), async () => { diff --git a/UI/Reviews/ReviewForm.ts b/UI/Reviews/ReviewForm.ts index 0a7ccda2ae..101de512fb 100644 --- a/UI/Reviews/ReviewForm.ts +++ b/UI/Reviews/ReviewForm.ts @@ -1,6 +1,6 @@ import { InputElement } from "../Input/InputElement" import { Review } from "../../Logic/Web/Review" -import { UIEventSource } from "../../Logic/UIEventSource" +import { Store, UIEventSource } from "../../Logic/UIEventSource" import { TextField } from "../Input/TextField" import Translations from "../i18n/Translations" import Combine from "../Base/Combine" @@ -11,6 +11,7 @@ import CheckBoxes from "../Input/Checkboxes" import UserDetails, { OsmConnection } from "../../Logic/Osm/OsmConnection" import BaseUIElement from "../BaseUIElement" import Toggle from "../Input/Toggle" +import { LoginToggle } from "../Popup/LoginButton" export default class ReviewForm extends InputElement { IsSelected: UIEventSource = new UIEventSource(false) @@ -20,11 +21,21 @@ export default class ReviewForm extends InputElement { private _saveButton: BaseUIElement private readonly _isAffiliated: BaseUIElement private readonly _postingAs: BaseUIElement - private readonly _osmConnection: OsmConnection + private readonly _state: { + readonly osmConnection: OsmConnection + readonly featureSwitchUserbadge: Store + } - constructor(onSave: (r: Review, doneSaving: () => void) => void, osmConnection: OsmConnection) { + constructor( + onSave: (r: Review, doneSaving: () => void) => void, + state: { + readonly osmConnection: OsmConnection + readonly featureSwitchUserbadge: Store + } + ) { super() - this._osmConnection = osmConnection + this._state = state + const osmConnection = state.osmConnection this._value = new UIEventSource({ made_by_user: new UIEventSource(true), rating: undefined, @@ -112,12 +123,11 @@ export default class ReviewForm extends InputElement { " border: 2px solid var(--subtle-detail-color-contrast)" ) - const connection = this._osmConnection - const login = Translations.t.reviews.plz_login - .Clone() - .onClick(() => connection.AttemptLogin()) - - return new Toggle(form, login, connection.isLoggedIn).ConstructElement() + return new LoginToggle( + form, + Translations.t.reviews.plz_login.Clone(), + this._state + ).ConstructElement() } IsValid(r: Review): boolean { diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 9182383dbe..56ae3cf7c2 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -219,7 +219,7 @@ export default class SpecialVisualizations { ) const form = new ReviewForm( (r, whenDone) => mangrove.AddReview(r, whenDone), - state.osmConnection + state ) return new ReviewElement(mangrove.GetSubjectUri(), mangrove.GetReviews(), form) },