diff --git a/Customizations/Layout.ts b/Customizations/Layout.ts index df6b38d..352df80 100644 --- a/Customizations/Layout.ts +++ b/Customizations/Layout.ts @@ -1,6 +1,9 @@ import {LayerDefinition} from "./LayerDefinition"; import {UIElement} from "../UI/UIElement"; import Translations from "../UI/i18n/Translations"; +import Combine from "../UI/Base/Combine"; +import {FixedUiElement} from "../UI/Base/FixedUiElement"; +import {State} from "../State"; /** * A layout is a collection of settings of the global view (thus: welcome text, title, selection of layers). @@ -66,7 +69,12 @@ export class Layout { startLat: number, startLon: number, welcomeMessage: UIElement | string, - gettingStartedPlzLogin: UIElement | string = Translations.t.general.getStarted, + gettingStartedPlzLogin: UIElement | string = new Combine([ + Translations.t.general.getStartedLogin + .SetClass("soft") + .onClick(() => {State.state.osmConnection.AttemptLogin()}), + Translations.t.general.getStartedNewAccount + ]), welcomeBackMessage: UIElement | string = Translations.t.general.welcomeBack, welcomeTail: UIElement | string = "" ) { diff --git a/Customizations/TagRendering.ts b/Customizations/TagRendering.ts index b7cd764..9fd321a 100644 --- a/Customizations/TagRendering.ts +++ b/Customizations/TagRendering.ts @@ -16,6 +16,7 @@ import {State} from "../State"; import {TagRenderingOptions} from "./TagRenderingOptions"; import Translation from "../UI/i18n/Translation"; import {SubtleButton} from "../UI/Base/SubtleButton"; +import Combine from "../UI/Base/Combine"; export class TagRendering extends UIElement implements TagDependantUIElement { @@ -393,12 +394,14 @@ export class TagRendering extends UIElement implements TagDependantUIElement { if (this.IsQuestioning() && !State.state?.osmConnection?.userDetails?.data?.loggedIn) { const question = - this.ApplyTemplate(this._question).Render(); + this.ApplyTemplate(this._question).SetClass('question-text'); return "
" + - "" + question + "" + - "
" + - "" + this._friendlyLogin.Render() + "" + - "
" + new Combine([ + question, + "
", + this._questionElement.Render(), + "" + this._friendlyLogin.Render() + "", + ]).Render() + ""; } if (this.IsQuestioning() || this._editMode.data) { diff --git a/Logic/Osm/OsmConnection.ts b/Logic/Osm/OsmConnection.ts index 755e678..c4e98b2 100644 --- a/Logic/Osm/OsmConnection.ts +++ b/Logic/Osm/OsmConnection.ts @@ -36,7 +36,7 @@ export class OsmConnection { const iframeMode = window !== window.top; - if ( iframeMode || !singlePage) { + if ( iframeMode || pwaStandAloneMode || !singlePage) { // In standalone mode, we DON'T use single page login, as 'redirecting' opens a new window anyway... // Same for an iframe... this.auth = new osmAuth({ diff --git a/README.md b/README.md index d8d3738..dd9b23a 100644 --- a/README.md +++ b/README.md @@ -40,23 +40,19 @@ MapComplete is set up to lure people into OpenStreetMap and to teach them while A typical user journey would be: -0) Oh, this is a cool map of _my specific interest_! There is a lot of data already... -0a) The user might discover the explanation about OSM in the dedicated tab page -0b) The user might discover the other themes in the other tab -0c) The user might share the map and/or embed it - +0. Oh, this is a cool map of _my specific interest_! There is a lot of data already... + a. The user might discover the explanation about OSM in the dedicated tab page + b. The user might discover the other themes in the other tab + c. The user might share the map and/or embed it 1) The user clicks that big tempting button 'login' in order to answer questions. The user makes an account - a big step. - -2) The user answers a question! Hooray! +2. The user answers a question! Hooray! When at least one question is answered (aka: having one changeset on OSM), adding a new point is unlocked - -3) The user adds a new POI somewhere -3a) Note that _all messages_ must be read before being able to add a point. In other words, sending a message to a misbehaving MapComplete user acts as having a zero-minutes-block. This is added deliberately to avoid new users fucking up too much - -4) At 50 changesets, the custom layout becomes available -5) At 200 changesets, the tags become visible when answering questions and when adding a new point from a preset. This is to give more control to power users and to teach new users the tagging scheme -5) At 250 changesets, the tags get linked to the wiki -6) At 500 changesets, I expect users to be power users and to be comfortable with tagging scheme and such. The custom theme generator is unlocked. +3. The user adds a new POI somewhere + a. Note that _all messages_ must be read before being able to add a point. In other words, sending a message to a misbehaving MapComplete user acts as having a zero-minutes-block. This is added deliberately to avoid new users fucking up too much +4. At 50 changesets, the custom layout becomes available +5. At 200 changesets, the tags become visible when answering questions and when adding a new point from a preset. This is to give more control to power users and to teach new users the tagging scheme +6. At 250 changesets, the tags get linked to the wiki +7. At 500 changesets, I expect contributors to be power users and to be comfortable with tagging scheme and such. The custom theme generator is unlocked. ## License @@ -133,7 +129,7 @@ Geolocation is available on mobile only throught hte device's GPS location (so n TODO: erase cookies of third party websites and API's -# Attributions: +# Attributions Data from OpenStreetMap Images from Wikipedia/Wikimedia diff --git a/State.ts b/State.ts index 036b8c9..b74bffe 100644 --- a/State.ts +++ b/State.ts @@ -24,7 +24,7 @@ export class State { // The singleton of the global state public static state: State; - public static vNumber = "0.0.6"; + public static vNumber = "0.0.6a"; // The user journey states thresholds when a new feature gets unlocked public static userJourney = { diff --git a/UI/ImageUploadFlow.ts b/UI/ImageUploadFlow.ts index e75d82e..d3768d6 100644 --- a/UI/ImageUploadFlow.ts +++ b/UI/ImageUploadFlow.ts @@ -10,6 +10,7 @@ import {VerticalCombine} from "./Base/VerticalCombine"; import {State} from "../State"; import {UIEventSource} from "../Logic/UIEventSource"; import {Imgur} from "../Logic/Web/Imgur"; +import {SubtleButton} from "./Base/SubtleButton"; export class ImageUploadFlow extends UIElement { private _licensePicker: UIElement; @@ -18,7 +19,8 @@ export class ImageUploadFlow extends UIElement { private _didFail: UIEventSource = new UIEventSource(false); private _allDone: UIEventSource = new UIEventSource(false); private _uploadOptions: (license: string) => { title: string; description: string; handleURL: (url: string) => void; allDone: (() => void) }; - + private _connectButton : UIElement; + constructor( preferedLicense: UIEventSource, uploadOptions: ((license: string) => @@ -42,10 +44,13 @@ export class ImageUploadFlow extends UIElement { {value: "CC-BY 4.0", shown: Translations.t.image.ccb} ], preferedLicense - ); + ); const t = Translations.t.image; + this._licensePicker = licensePicker; this._selectedLicence = licensePicker.GetValue(); - + this._connectButton = new Combine([ t.pleaseLogin]) + .onClick(() => State.state.osmConnection.AttemptLogin()) + .SetClass("login-button-friendly"); } @@ -58,7 +63,7 @@ export class ImageUploadFlow extends UIElement { } if (!State.state.osmConnection.userDetails.data.loggedIn) { - return t.pleaseLogin.Render(); + return this._connectButton.Render(); } let currentState: UIElement[] = []; @@ -115,12 +120,6 @@ export class ImageUploadFlow extends UIElement { super.InnerUpdate(htmlElement); const user = State.state.osmConnection.userDetails.data; - htmlElement.onclick = function () { - if (!user.loggedIn) { - State.state.osmConnection.AttemptLogin(); - } - } - this._licensePicker.Update() const form = document.getElementById('fileselector-form-' + this.id) as HTMLFormElement const selector = document.getElementById('fileselector-' + this.id) diff --git a/UI/WelcomeMessage.ts b/UI/WelcomeMessage.ts index 62a5b1b..34d86df 100644 --- a/UI/WelcomeMessage.ts +++ b/UI/WelcomeMessage.ts @@ -46,7 +46,7 @@ export class WelcomeMessage extends UIElement { return "" + this.description.Render() + - "
" + + "

" + loginStatus + this.tail.Render() + "
" + diff --git a/UI/i18n/Translations.ts b/UI/i18n/Translations.ts index 9d1cedc..7dfa25e 100644 --- a/UI/i18n/Translations.ts +++ b/UI/i18n/Translations.ts @@ -619,9 +619,9 @@ export default class Translations { fr: 'Mettre votre {count} photos en ligne' }), pleaseLogin: new T({ - en: 'Please login to add a picure or to answer questions', - nl: 'Gelieve je aan te melden om een foto toe te voegen of vragen te beantwoorden', - fr: 'Merci de vous connecter pour mettre une photo en ligne ou répondre aux questions' + en: 'Please login to add a picure', + nl: 'Gelieve je aan te melden om een foto toe te voegen', + fr: 'Connectez vous pour mettre une photo en ligne' }), willBePublished: new T({ en: 'Your picture will be published: ', @@ -664,12 +664,6 @@ export default class Translations { }, general: { loginWithOpenStreetMap: new T({en: "Login with OpenStreetMap", nl: "Aanmelden met OpenStreetMap", fr:'Se connecter avec OpenStreeMap'}), - getStarted: new T({ - en: "Login with OpenStreetMap or make a free account to get started", - nl: "Meld je aan met je OpenStreetMap-account of maak snel en gratis een account om te beginnen", - fr: "Se connecter avec OpenStreetMap ou créer un compte gratuitement pour commencer", - - }), welcomeBack: new T({ en: "You are logged in, welcome back!", nl: "Je bent aangemeld. Welkom terug!", @@ -677,7 +671,8 @@ export default class Translations { }), loginToStart: new T({ en: "Login to answer this question", - nl: "Meld je aan om deze vraag te beantwoorden" + nl: "Meld je aan om deze vraag te beantwoorden", + fr: "Connectez vous pour répondre à cette question" }), search: { search: new Translation({ @@ -926,7 +921,17 @@ export default class Translations { en: "Open inbox", nl: "Ga naar de berichten", fr: "Ouvrir les messages" - }) + }), + getStartedLogin: new T({ + en: "Login with OpenStreetMap to get started", + nl: "Login met OpenStreetMap om te beginnen", + fr: "Connectez vous avec OpenStreetMap pour commencer" + }), + getStartedNewAccount: new T({ + en: " or create a new account", + nl: " of maak een nieuwe account aan ", + fr: " ou registrez vous" + }), }, favourite: { title: new T({en: "Personal theme"}), diff --git a/index.css b/index.css index 9ad07b0..97eee4f 100644 --- a/index.css +++ b/index.css @@ -78,6 +78,18 @@ form { padding-bottom: 0.15em; } +.soft { + background-color: #e5f5ff; + font-weight: bold; + border-radius: 1em; + padding: 0.3em; + margin: 0.25em; + text-align: center; + padding-top: 0.15em; + padding-bottom: 0.15em; +} + + .subtle { color: #999; }