From 3f8b6e88d3de83c5c2b22ac37c04e047bd429db5 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Fri, 6 Nov 2020 01:58:26 +0100 Subject: [PATCH] Fix deploy --- Customizations/JSON/FromJSON.ts | 2 +- Customizations/JSON/LayerConfig.ts | 3 +- Customizations/JSON/TagRenderingConfig.ts | 2 +- Customizations/Layout.ts | 6 +- InitUiElements.ts | 97 +++++----- Logic/FilteredLayer.ts | 2 +- Logic/PersonalLayersPanel.ts | 6 +- Logic/PersonalLayout.ts | 4 +- Svg.ts | 4 + UI/Base/Link.ts | 5 +- UI/Image/MapillaryImage.ts | 4 +- UI/Image/WikimediaImage.ts | 22 +-- UI/Img.ts | 21 --- UI/Input/MultiInput.ts | 6 +- UI/MoreScreen.ts | 5 +- UI/Popup/EditableTagRendering.ts | 7 +- UI/Popup/FeatureInfoBox.ts | 2 +- UI/Popup/TagRenderingQuestion.ts | 2 +- UI/SearchAndGo.ts | 10 +- UI/ShareScreen.ts | 5 +- UI/SimpleAddUI.ts | 16 +- UI/SpecialVisualizations.ts | 2 +- UI/UserBadge.ts | 4 +- UI/WelcomeMessage.ts | 3 +- UI/i18n/Translation.ts | 103 +++++++++++ UI/i18n/Translations.ts | 130 +------------- assets/home.svg | 3 - assets/josm_logo.svg | 208 ---------------------- assets/star.svg | 10 -- assets/statistics.svg | 7 - assets/svg/mapillary.svg | 1 + createLayouts.ts | 2 +- css/mobile.css | 4 + css/tagrendering.css | 10 ++ css/userbadge.css | 6 - generateIncludedImages.ts | 85 ++++++--- index.css | 129 ++++++++------ index.ts | 2 +- test/Tag.spec.ts | 3 +- 39 files changed, 381 insertions(+), 562 deletions(-) create mode 100644 UI/i18n/Translation.ts delete mode 100644 assets/home.svg delete mode 100644 assets/josm_logo.svg delete mode 100644 assets/star.svg delete mode 100644 assets/statistics.svg create mode 100644 assets/svg/mapillary.svg diff --git a/Customizations/JSON/FromJSON.ts b/Customizations/JSON/FromJSON.ts index aea41ea..9276a22 100644 --- a/Customizations/JSON/FromJSON.ts +++ b/Customizations/JSON/FromJSON.ts @@ -1,8 +1,8 @@ import {AndOrTagConfigJson} from "./TagConfigJson"; import {And, Or, RegexTag, Tag, TagsFilter} from "../../Logic/Tags"; -import {Translation} from "../../UI/i18n/Translations"; import {Utils} from "../../Utils"; +import {Translation} from "../../UI/i18n/Translation"; export class FromJSON { diff --git a/Customizations/JSON/LayerConfig.ts b/Customizations/JSON/LayerConfig.ts index 2297d50..48a19c2 100644 --- a/Customizations/JSON/LayerConfig.ts +++ b/Customizations/JSON/LayerConfig.ts @@ -1,10 +1,11 @@ -import Translations, {Translation} from "../../UI/i18n/Translations"; +import Translations from "../../UI/i18n/Translations"; import TagRenderingConfig from "./TagRenderingConfig"; import {Tag, TagsFilter} from "../../Logic/Tags"; import {LayerConfigJson} from "./LayerConfigJson"; import {FromJSON} from "./FromJSON"; import SharedTagRenderings from "../SharedTagRenderings"; import {TagRenderingConfigJson} from "./TagRenderingConfigJson"; +import {Translation} from "../../UI/i18n/Translation"; export default class LayerConfig { id: string; diff --git a/Customizations/JSON/TagRenderingConfig.ts b/Customizations/JSON/TagRenderingConfig.ts index 4ed01c4..24fdd0b 100644 --- a/Customizations/JSON/TagRenderingConfig.ts +++ b/Customizations/JSON/TagRenderingConfig.ts @@ -1,9 +1,9 @@ -import {Translation} from "../../UI/i18n/Translations"; import {TagsFilter} from "../../Logic/Tags"; import {TagRenderingConfigJson} from "./TagRenderingConfigJson"; import Translations from "../../UI/i18n/Translations"; import {FromJSON} from "./FromJSON"; import ValidatedTextField from "../../UI/Input/ValidatedTextField"; +import {Translation} from "../../UI/i18n/Translation"; /*** * The parsed version of TagRenderingConfigJSON diff --git a/Customizations/Layout.ts b/Customizations/Layout.ts index 95c2bf6..777bbdf 100644 --- a/Customizations/Layout.ts +++ b/Customizations/Layout.ts @@ -2,11 +2,13 @@ import {UIElement} from "../UI/UIElement"; import Translations from "../UI/i18n/Translations"; import Combine from "../UI/Base/Combine"; import State from "../State"; -import {Translation} from "../UI/i18n/Translations"; import LayerConfig from "./JSON/LayerConfig"; import {LayoutConfigJson} from "./JSON/LayoutConfigJson"; import TagRenderingConfig from "./JSON/TagRenderingConfig"; import {FromJSON} from "./JSON/FromJSON"; +import {Translation} from "../UI/i18n/Translation"; +import Svg from "../Svg"; +import {Img} from "../UI/Img"; /** * A layout is a collection of settings of the global view (thus: welcome text, title, selection of layers). @@ -14,7 +16,7 @@ import {FromJSON} from "./JSON/FromJSON"; export class Layout { public id: string; - public icon: string = "./assets/logo.svg"; + public icon: string = Img.AsData(Svg.bug); public title: UIElement; public maintainer: string; public version: string; diff --git a/InitUiElements.ts b/InitUiElements.ts index 18fcc18..be5220d 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -10,7 +10,6 @@ import {FilteredLayer} from "./Logic/FilteredLayer"; import {Basemap} from "./Logic/Leaflet/Basemap"; import State from "./State"; import {WelcomeMessage} from "./UI/WelcomeMessage"; -import {Img} from "./UI/Img"; import {LayerSelection} from "./UI/LayerSelection"; import {VariableUiElement} from "./UI/Base/VariableUIElement"; import {UpdateFromOverpass} from "./Logic/UpdateFromOverpass"; @@ -35,6 +34,8 @@ import BackgroundSelector from "./UI/BackgroundSelector"; import AvailableBaseLayers from "./Logic/AvailableBaseLayers"; import {FeatureInfoBox} from "./UI/Popup/FeatureInfoBox"; import SharedLayers from "./Customizations/SharedLayers"; +import Svg from "./Svg"; +import Link from "./UI/Base/Link"; export class InitUiElements { @@ -197,9 +198,9 @@ export class InitUiElements { if ((window != window.top && !State.state.featureSwitchWelcomeMessage.data) || State.state.featureSwitchIframe.data) { const currentLocation = State.state.locationControl; const url = `${window.location.origin}${window.location.pathname}?z=${currentLocation.data.zoom}&lat=${currentLocation.data.lat}&lon=${currentLocation.data.lon}`; - const content = ``; - new FixedUiElement(content).AttachTo("messagesbox"); - new FixedUiElement(content).AttachTo("help-button-mobile") + const content = new Link(Svg.pop_out_ui().SetClass("iframe-escape"), url, true); + new FixedUiElement(content.Render()).AttachTo("help-button-mobile") + content.AttachTo("messagesbox"); } @@ -269,26 +270,28 @@ export class InitUiElements { const tabs = [ {header: ``, content: welcome}, - {header: ``, content: - Translations.t.general.openStreetMapIntro}, + { + header: Svg.osm_logo_img, + content: Translations.t.general.openStreetMapIntro as UIElement + }, ] if (State.state.featureSwitchShareScreen.data) { - tabs.push({header: ``, content: new ShareScreen()}); + tabs.push({header: Svg.share_img, content: new ShareScreen()}); } if (State.state.featureSwitchMoreQuests.data) { tabs.push({ - header: ``, + header: Svg.add_img, content: new MoreScreen() }); } tabs.push({ - header: ``, + header: Svg.help_img, content: new VariableUiElement(State.state.osmConnection.userDetails.map(userdetails => { if (userdetails.csCount < State.userJourney.mapCompleteHelpUnlock) { return "" @@ -309,14 +312,16 @@ export class InitUiElements { const fullOptions = this.CreateWelcomePane(); - const help = new FixedUiElement(`
help
`); - const close = new FixedUiElement(`
close
`); + const help = Svg.help_ui().SetClass("open-welcome-button"); + const close = Svg.close_ui().SetClass("close-welcome-button"); const checkbox = new CheckBox( new Combine([ - "", close, "", - "", fullOptions.onClick(() => { - }), ""]), - new Combine(["", help, ""]) + close, + fullOptions + .SetClass("welcomeMessage") + .onClick(() => {/*Catch the click*/ + })]), + help , true ).AttachTo("messagesbox"); const openedTime = new Date().getTime(); @@ -331,9 +336,13 @@ export class InitUiElements { const fullOptions2 = this.CreateWelcomePane(); State.state.fullScreenMessage.setData(fullOptions2) - new FixedUiElement(`
help
`).onClick(() => { - State.state.fullScreenMessage.setData(fullOptions2) - }).AttachTo("help-button-mobile"); + + Svg.help_ui() + .SetClass("open-welcome-button") + .SetClass("shadow") + .onClick(() => { + State.state.fullScreenMessage.setData(fullOptions2) + }).AttachTo("help-button-mobile"); } @@ -366,20 +375,18 @@ export class InitUiElements { } layerControlPanel.SetStyle("display:block;padding:1em;border-radius:1em;"); - const closeButton = new Combine([Img.openFilterButton]) - .SetStyle("display:block; width: min-content; background: #e5f5ff;padding:1em; border-radius:1em;"); + const closeButton = Svg.close_ui().SetClass("layer-selection-toggle").SetStyle(" background: #e5f5ff;") const checkbox = new CheckBox( new Combine([ closeButton, layerControlPanel]).SetStyle("display:flex;flex-direction:row;") .SetClass("hidden-on-mobile") , - new Combine([Img.closedFilterButton]) - .SetStyle("display:block;border-radius:50%;background:white;padding:1em;"), + Svg.layers_ui().SetClass("layer-selection-toggle"), State.state.layerControlIsOpened ); - checkbox - .AttachTo("layer-selection"); + + checkbox.AttachTo("layer-selection"); State.state.bm.Location.addCallback(() => { @@ -401,28 +408,27 @@ export class InitUiElements { }); } - - static InitBaseMap(){ - const bm = new Basemap("leafletDiv", State.state.locationControl, new VariableUiElement( + + + static CreateAttribution() { + return new VariableUiElement( State.state.locationControl.map((location) => { - const mapComplete = `Mapcomplete ${State.vNumber}` - const reportBug = ``; - + const mapComplete = new Link(`Mapcomplete ${State.vNumber}`, 'https://github.com/pietervdvn/MapComplete', true); + const reportBug = new Link(Svg.bug_img, "https://github.com/pietervdvn/MapComplete/issues", true); + const layoutId = State.state.layoutToUse.data.id; const osmChaLink = `https://osmcha.org/?filters=%7B%22comment%22%3A%5B%7B%22label%22%3A%22%23${layoutId}%22%2C%22value%22%3A%22%23${layoutId}%22%7D%5D%2C%22date__gte%22%3A%5B%7B%22label%22%3A%222020-07-05%22%2C%22value%22%3A%222020-07-05%22%7D%5D%2C%22editor%22%3A%5B%7B%22label%22%3A%22MapComplete%22%2C%22value%22%3A%22MapComplete%22%7D%5D%7D` - const stats = ``; - let editHere = ""; + const stats = new Link(Svg.statistics_img, osmChaLink, true) + let editHere: (UIElement | string) = ""; if (location !== undefined) { - editHere = - "" + - "edit here" + - "" + const idLink = `https://www.openstreetmap.org/edit?editor=id#map=${location.zoom}/${location.lat}/${location.lon}` + editHere = new Link(Svg.pencil_img, idLink, true); } - let editWithJosm = "" - if(location !== undefined && + let editWithJosm: (UIElement | string) = "" + if (location !== undefined && State.state.osmConnection !== undefined && State.state.bm !== undefined && - State.state.osmConnection.userDetails.data.csCount >= State.userJourney.tagsVisibleAndWikiLinked){ + State.state.osmConnection.userDetails.data.csCount >= State.userJourney.tagsVisibleAndWikiLinked) { const bounds = (State.state.bm as Basemap).map.getBounds(); const top = bounds.getNorth(); const bottom = bounds.getSouth(); @@ -430,21 +436,24 @@ export class InitUiElements { const left = bounds.getWest(); const josmLink = `http://127.0.0.1:8111/load_and_zoom?left=${left}&right=${right}&top=${top}&bottom=${bottom}` - editWithJosm = - `edit here` + editWithJosm = new Link(Svg.josm_logo_img, josmLink, true); } return new Combine([mapComplete, reportBug, " | ", stats, " | ", editHere, editWithJosm]).Render(); }, [State.state.osmConnection.userDetails]) - ) - ); + + ).SetClass("map-attribution") + } + + static InitBaseMap() { + const bm = new Basemap("leafletDiv", State.state.locationControl, this.CreateAttribution()); State.state.bm = bm; State.state.layerUpdater = new UpdateFromOverpass(State.state); State.state.availableBackgroundLayers = new AvailableBaseLayers(State.state).availableEditorLayers; const queryParam = QueryParameters.GetQueryParameter("background", State.state.layoutToUse.data.defaultBackground); - queryParam.addCallbackAndRun((selectedId:string) => { + queryParam.addCallbackAndRun((selectedId: string) => { const available = State.state.availableBackgroundLayers.data; for (const layer of available) { if (layer.id === selectedId) { diff --git a/Logic/FilteredLayer.ts b/Logic/FilteredLayer.ts index 42955a7..bcf71c4 100644 --- a/Logic/FilteredLayer.ts +++ b/Logic/FilteredLayer.ts @@ -53,7 +53,7 @@ export class FilteredLayer { this._showOnPopup = showOnPopup; this._style = (tags) => { - const iconUrl = layerDef.icon?.GetRenderValue(tags)?.txt ?? "./assets/bug.svg"; + const iconUrl = layerDef.icon?.GetRenderValue(tags)?.txt; const iconSize = (layerDef.iconSize?.GetRenderValue(tags)?.txt ?? "40,40,center").split(","); diff --git a/Logic/PersonalLayersPanel.ts b/Logic/PersonalLayersPanel.ts index 429890f..8e7b4f3 100644 --- a/Logic/PersonalLayersPanel.ts +++ b/Logic/PersonalLayersPanel.ts @@ -9,6 +9,8 @@ import {PersonalLayout} from "./PersonalLayout"; import {Layout} from "../Customizations/Layout"; import {SubtleButton} from "../UI/Base/SubtleButton"; import {FixedUiElement} from "../UI/Base/FixedUiElement"; +import {Img} from "../UI/Img"; +import Svg from "../Svg"; export class PersonalLayersPanel extends UIElement { private checkboxes: UIElement[] = []; @@ -50,10 +52,10 @@ export class PersonalLayersPanel extends UIElement { if (typeof layer === "string") { continue; } - let icon = layer.icon ?? "./assets/checkmark.svg"; + let icon = layer.icon ?? Img.AsData(Svg.checkmark); let iconUnset = layer.icon ?? ""; if (layer.icon !== undefined && typeof (layer.icon) !== "string") { - icon = layer.icon.GetContent({"id": "node/-123456"}).txt ?? "./assets/checkmark.svg"; + icon = layer.icon.GetRenderValue({"id": "node/-123456"}).txt ?? Img.AsData(Svg.checkmark) iconUnset = icon; } diff --git a/Logic/PersonalLayout.ts b/Logic/PersonalLayout.ts index 70d057f..2ae11ae 100644 --- a/Logic/PersonalLayout.ts +++ b/Logic/PersonalLayout.ts @@ -1,5 +1,7 @@ import {Layout} from "../Customizations/Layout"; import Translations from "../UI/i18n/Translations"; +import {Img} from "../UI/Img"; +import Svg from "../Svg"; export class PersonalLayout extends Layout { @@ -18,7 +20,7 @@ export class PersonalLayout extends Layout { ); this.maintainer = "MapComplete" this.description = "The personal theme allows to select one or more layers from all the layouts, creating a truly personal editor" - this.icon = "./assets/add.svg" + this.icon = Img.AsData(Svg.add) } } \ No newline at end of file diff --git a/Svg.ts b/Svg.ts index 43470d2..2d941d5 100644 --- a/Svg.ts +++ b/Svg.ts @@ -100,6 +100,10 @@ export default class Svg { public static logout_img = Img.AsImageElement(Svg.logout) public static logout_ui() { return new FixedUiElement(Svg.logout_img);} + public static mapillary = "" + public static mapillary_img = Img.AsImageElement(Svg.mapillary) + public static mapillary_ui() { return new FixedUiElement(Svg.mapillary_img);} + public static or = " image/svg+xml " public static or_img = Img.AsImageElement(Svg.or) public static or_ui() { return new FixedUiElement(Svg.or_img);} diff --git a/UI/Base/Link.ts b/UI/Base/Link.ts index b919b45..dbe164c 100644 --- a/UI/Base/Link.ts +++ b/UI/Base/Link.ts @@ -1,4 +1,5 @@ import {UIElement} from "../UIElement"; +import Translations from "../i18n/Translations"; export default class Link extends UIElement { @@ -6,9 +7,9 @@ export default class Link extends UIElement { private readonly _target: string; private readonly _newTab: string; - constructor(embeddedShow: UIElement, target: string, newTab: boolean = false) { + constructor(embeddedShow: UIElement | string, target: string, newTab: boolean = false) { super(); - this._embeddedShow = embeddedShow; + this._embeddedShow = Translations.W(embeddedShow); this._target = target; this._newTab = ""; if (newTab) { diff --git a/UI/Image/MapillaryImage.ts b/UI/Image/MapillaryImage.ts index 554100c..7971964 100644 --- a/UI/Image/MapillaryImage.ts +++ b/UI/Image/MapillaryImage.ts @@ -5,6 +5,7 @@ import {Imgur} from "../../Logic/Web/Imgur"; import {Mapillary} from "../../Logic/Web/Mapillary"; import {Img} from "../Img"; import {FixedUiElement} from "../Base/FixedUiElement"; +import Svg from "../../Svg"; export class MapillaryImage extends UIElement { @@ -53,8 +54,7 @@ export class MapillaryImage extends UIElement { return "
" + image + "
" + - - new FixedUiElement(Img.mapillaryLogo).SetStyle("height: 1.5em").Render() + + Svg.mapillary_ui().Render() + attribution + "
" + "
"; diff --git a/UI/Image/WikimediaImage.ts b/UI/Image/WikimediaImage.ts index e9ca5f3..f8d4a46 100644 --- a/UI/Image/WikimediaImage.ts +++ b/UI/Image/WikimediaImage.ts @@ -1,6 +1,10 @@ import {UIElement} from "../UIElement"; import {LicenseInfo, Wikimedia} from "../../Logic/Web/Wikimedia"; import {UIEventSource} from "../../Logic/UIEventSource"; +import Svg from "../../Svg"; +import Link from "../Base/Link"; +import {FixedUiElement} from "../Base/FixedUiElement"; +import Combine from "../Base/Combine"; export class WikimediaImage extends UIElement { @@ -8,7 +12,7 @@ export class WikimediaImage extends UIElement { static allLicenseInfos: any = {}; private readonly _imageMeta: UIEventSource; - private readonly _imageLocation : string; + private readonly _imageLocation: string; constructor(source: string) { super(undefined) @@ -33,21 +37,17 @@ export class WikimediaImage extends UIElement { let url = Wikimedia.ImageNameToUrl(this._imageLocation, 500, 400); url = url.replace(/'/g, '%27'); - const wikimediaLink = - "" + - "Wikimedia Commons Logo" + - " "; + const wikimediaLink = new Link(Svg.wikimedia_commons_white_img, + `https://commons.wikimedia.org/wiki/${this._imageLocation}`, true) + .SetStyle("width:2em;height: 2em"); - const attribution = - "" + (this._imageMeta.data.artist ?? "") + "" + " " + (this._imageMeta.data.licenseShortName ?? "") + ""; + const attribution = new FixedUiElement(this._imageMeta.data.artist ?? "").SetClass("attribution-author"); + const license = new FixedUiElement(this._imageMeta.data.licenseShortName ?? "").SetClass("license"); const image = ""; return "
" + image + - "
" + - wikimediaLink + - attribution + - "
" + + new Combine([wikimediaLink, attribution]).SetClass("attribution").Render() + "
"; } diff --git a/UI/Img.ts b/UI/Img.ts index 6b5fe51..b2119ff 100644 --- a/UI/Img.ts +++ b/UI/Img.ts @@ -1,6 +1,3 @@ -import {UIElement} from "./UIElement"; -import {FixedUiElement} from "./Base/FixedUiElement"; - export class Img { static AsData(source:string){ @@ -10,25 +7,7 @@ export class Img { static AsImageElement(source: string): string{ return ``; } - - static AsImage(source: string): UIElement{ - return new FixedUiElement(Img.AsImageElement(source)) - } - static readonly checkmark = ``; static readonly no_checkmark = ``; - - static closedFilterButton: string = ` - - - - ` - - - static openFilterButton: string = ` - - ` - - static mapillaryLogo = "" } diff --git a/UI/Input/MultiInput.ts b/UI/Input/MultiInput.ts index 6385bb4..7f8a14e 100644 --- a/UI/Input/MultiInput.ts +++ b/UI/Input/MultiInput.ts @@ -4,6 +4,8 @@ import {UIElement} from "../UIElement"; import Combine from "../Base/Combine"; import {SubtleButton} from "../Base/SubtleButton"; import {FixedUiElement} from "../Base/FixedUiElement"; +import Svg from "../../Svg"; +import {Img} from "../Img"; export class MultiInput extends InputElement { @@ -28,7 +30,7 @@ export class MultiInput extends InputElement { this.ListenTo(value.map((latest : T[]) => latest.length)); this._options = options ?? {}; - this.addTag = new SubtleButton("./assets/addSmall.svg", addAElement) + this.addTag = new SubtleButton(Img.AsData(Svg.addSmall), addAElement) .SetClass("small-button") .onClick(() => { this.IsSelected.setData(true); @@ -70,7 +72,7 @@ export class MultiInput extends InputElement { this.inputELements.push(input); input.IsSelected.addCallback(() => this.UpdateIsSelected()); - const moveUpBtn = new FixedUiElement("") + const moveUpBtn = new FixedUiElement(Img.AsData(Svg.up)) .onClick(() => { const v = self._value.data[i]; self._value.data[i] = self._value.data[i - 1]; diff --git a/UI/MoreScreen.ts b/UI/MoreScreen.ts index 4f0611e..7d1f797 100644 --- a/UI/MoreScreen.ts +++ b/UI/MoreScreen.ts @@ -8,6 +8,8 @@ import State from "../State"; import {VariableUiElement} from "./Base/VariableUIElement"; import {PersonalLayout} from "../Logic/PersonalLayout"; import {Layout} from "../Customizations/Layout"; +import Svg from "../Svg"; +import {Img} from "./Img"; export class MoreScreen extends UIElement { @@ -77,7 +79,8 @@ export class MoreScreen extends UIElement { if (userDetails.csCount < State.userJourney.themeGeneratorReadOnlyUnlock) { return tr.requestATheme.Render(); } - return new SubtleButton("./assets/pencil.svg", tr.createYourOwnTheme, { + return new SubtleButton( + Img.AsData(Svg.pencil), tr.createYourOwnTheme, { url: "./customGenerator.html", newTab: false }).Render(); diff --git a/UI/Popup/EditableTagRendering.ts b/UI/Popup/EditableTagRendering.ts index bd9f566..b26ade9 100644 --- a/UI/Popup/EditableTagRendering.ts +++ b/UI/Popup/EditableTagRendering.ts @@ -1,12 +1,12 @@ import {UIElement} from "../UIElement"; import {UIEventSource} from "../../Logic/UIEventSource"; import TagRenderingConfig from "../../Customizations/JSON/TagRenderingConfig"; -import {FixedUiElement} from "../Base/FixedUiElement"; import TagRenderingQuestion from "./TagRenderingQuestion"; import Translations from "../i18n/Translations"; import Combine from "../Base/Combine"; import TagRenderingAnswer from "./TagRenderingAnswer"; import State from "../../State"; +import Svg from "../../Svg"; export default class EditableTagRendering extends UIElement { private _tags: UIEventSource; @@ -35,9 +35,8 @@ export default class EditableTagRendering extends UIElement { if (this._configuration.question !== undefined) { // 2.3em total width - this._editButton = new FixedUiElement( - "edit") + this._editButton = + Svg.pencil_ui().SetClass("edit-button") .onClick(() => { self._editMode.setData(true); }); diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts index 7e495f2..c0439c2 100644 --- a/UI/Popup/FeatureInfoBox.ts +++ b/UI/Popup/FeatureInfoBox.ts @@ -42,7 +42,7 @@ export class FeatureInfoBox extends UIElement { new Combine([this._title, this._titleIcons]) .SetClass("featureinfobox-titlebar"), ...this._renderings, - this._questionBox + this._questionBox, ]).Render(); } diff --git a/UI/Popup/TagRenderingQuestion.ts b/UI/Popup/TagRenderingQuestion.ts index 7ebdbd5..10ba6bc 100644 --- a/UI/Popup/TagRenderingQuestion.ts +++ b/UI/Popup/TagRenderingQuestion.ts @@ -5,7 +5,6 @@ import TagRenderingConfig from "../../Customizations/JSON/TagRenderingConfig"; import {InputElement} from "../Input/InputElement"; import {And, Tag, TagsFilter, TagUtils} from "../../Logic/Tags"; import ValidatedTextField from "../Input/ValidatedTextField"; -import {Translation} from "../i18n/Translations"; import {FixedInputElement} from "../Input/FixedInputElement"; import {SubstitutedTranslation} from "../SpecialVisualizations"; import {RadioButton} from "../Input/RadioButton"; @@ -18,6 +17,7 @@ import {Changes} from "../../Logic/Osm/Changes"; import {VariableUiElement} from "../Base/VariableUIElement"; import Translations from "../i18n/Translations"; import {FixedUiElement} from "../Base/FixedUiElement"; +import {Translation} from "../i18n/Translation"; /** * Shows the question element. diff --git a/UI/SearchAndGo.ts b/UI/SearchAndGo.ts index c81c7ff..3db4f88 100644 --- a/UI/SearchAndGo.ts +++ b/UI/SearchAndGo.ts @@ -1,30 +1,28 @@ import Locale from "./i18n/Locale"; import {UIElement} from "./UIElement"; -import Translation from "./i18n/Translation"; import {VariableUiElement} from "./Base/VariableUIElement"; -import {FixedUiElement} from "./Base/FixedUiElement"; import {TextField} from "./Input/TextField"; import {Geocoding} from "../Logic/Osm/Geocoding"; import Translations from "./i18n/Translations"; import State from "../State"; import {UIEventSource} from "../Logic/UIEventSource"; +import Svg from "../Svg"; +import {Translation} from "./i18n/Translation"; export class SearchAndGo extends UIElement { private _placeholder = new UIEventSource(Translations.t.general.search.search) - private _searchField = new TextField({ + private _searchField = new TextField({ placeholder: new VariableUiElement( this._placeholder.map(uiElement => uiElement.InnerRender(), [Locale.language]) ), - fromString: str => str, - toString: str => str, value: new UIEventSource("") } ); private _foundEntries = new UIEventSource([]); - private _goButton = new FixedUiElement("GO"); + private _goButton = Svg.search_ui().SetClass('search-go'); constructor() { super(undefined); diff --git a/UI/ShareScreen.ts b/UI/ShareScreen.ts index 84101d6..a97bb34 100644 --- a/UI/ShareScreen.ts +++ b/UI/ShareScreen.ts @@ -11,9 +11,10 @@ import {Basemap} from "../Logic/Leaflet/Basemap"; import {FilteredLayer} from "../Logic/FilteredLayer"; import {Utils} from "../Utils"; import {UIEventSource} from "../Logic/UIEventSource"; -import Translation from "./i18n/Translation"; import {SubtleButton} from "./Base/SubtleButton"; import {Layout} from "../Customizations/Layout"; +import Svg from "../Svg"; +import {Translation} from "./i18n/Translation"; export class ShareScreen extends UIElement { private readonly _options: UIElement; @@ -186,7 +187,7 @@ export class ShareScreen extends UIElement { return ""; } - return new SubtleButton("./assets/pencil.svg", + return new SubtleButton(Img.AsData(Svg.pencil), new Combine([tr.editThisTheme.SetClass("bold"), "
", tr.editThemeDescription]), {url: `./customGenerator.html#${State.state.layoutDefinition}`, newTab: true}).Render(); diff --git a/UI/SimpleAddUI.ts b/UI/SimpleAddUI.ts index 6984b4f..e02fa36 100644 --- a/UI/SimpleAddUI.ts +++ b/UI/SimpleAddUI.ts @@ -8,6 +8,8 @@ import Locale from "./i18n/Locale"; import State from "../State"; import {UIEventSource} from "../Logic/UIEventSource"; +import {Img} from "./Img"; +import Svg from "../Svg"; /** * Asks to add a feature at the last clicked location, at least if zoom is sufficient @@ -28,7 +30,7 @@ export class SimpleAddUI extends UIElement { private confirmButton: UIElement = undefined; private openLayerControl: UIElement; private cancelButton: UIElement; - private goToInboxButton: UIElement = new SubtleButton("./assets/envelope.svg", + private goToInboxButton: UIElement = new SubtleButton(Img.AsData(Svg.envelope), Translations.t.general.goToInbox, {url:"https://www.openstreetmap.org/messages/inbox", newTab: false}); constructor() { @@ -52,8 +54,7 @@ export class SimpleAddUI extends UIElement { const presets = layer.layerDef.presets; for (const preset of presets) { let icon: string = layer.layerDef.icon.GetRenderValue( - TagUtils.KVtoProperties(preset.tags ?? [])).txt ?? - "./assets/bug.svg"; + TagUtils.KVtoProperties(preset.tags ?? [])).txt const csCount = State.state.osmConnection.userDetails.data.csCount; let tagInfo = ""; @@ -97,14 +98,14 @@ export class SimpleAddUI extends UIElement { } this.cancelButton = new SubtleButton( - "./assets/close.svg", + Img.AsData(Svg.close), Translations.t.general.cancel ).onClick(() => { self._confirmPreset.setData(undefined); }) this.openLayerControl = new SubtleButton( - "./assets/layers.svg", + Img.AsData(Svg.layers), Translations.t.general.add.openLayerControl ).onClick(() => { State.state.layerControlIsOpened.setData(true); @@ -169,9 +170,8 @@ export class SimpleAddUI extends UIElement { } if (userDetails.data.unreadMessages > 0 && userDetails.data.csCount < State.userJourney.addNewPointWithUnreadMessagesUnlock) { - return new Combine([header, "", - Translations.t.general.readYourMessages, - "", + return new Combine([header, + Translations.t.general.readYourMessages.Clone().SetClass("alert"), this.goToInboxButton ]).Render(); diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 6a0948f..75f260f 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -4,11 +4,11 @@ import {UIEventSource} from "../Logic/UIEventSource"; import {VariableUiElement} from "./Base/VariableUIElement"; import LiveQueryHandler from "../Logic/Web/LiveQueryHandler"; import {ImageCarousel} from "./Image/ImageCarousel"; -import {Translation} from "./i18n/Translations"; import Combine from "./Base/Combine"; import {FixedUiElement} from "./Base/FixedUiElement"; import Locale from "../UI/i18n/Locale"; import {ImageUploadFlow} from "./Image/ImageUploadFlow"; +import {Translation} from "./i18n/Translation"; export class SubstitutedTranslation extends UIElement { private readonly tags: UIEventSource; diff --git a/UI/UserBadge.ts b/UI/UserBadge.ts index 78bd196..6338e5a 100644 --- a/UI/UserBadge.ts +++ b/UI/UserBadge.ts @@ -7,10 +7,10 @@ import {UserDetails} from "../Logic/Osm/OsmConnection"; import State from "../State"; import {UIEventSource} from "../Logic/UIEventSource"; import Combine from "./Base/Combine"; -import Locale from "./i18n/Locale"; import Svg from "../Svg"; import Link from "./Base/Link"; import {Img} from "./Img"; +import LanguagePicker from "./LanguagePicker"; /** * Handles and updates the user badge @@ -26,7 +26,7 @@ export class UserBadge extends UIElement { constructor() { super(State.state.osmConnection.userDetails); this._userDetails = State.state.osmConnection.userDetails; - this._languagePicker = (Locale.CreateLanguagePicker(State.state.layoutToUse.data.supportedLanguages) ?? new FixedUiElement("")) + this._languagePicker = (LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.data.supportedLanguages) ?? new FixedUiElement("")) .SetStyle("display:inline-block;width:min-content;"); this._loginButton = Translations.t.general.loginWithOpenStreetMap diff --git a/UI/WelcomeMessage.ts b/UI/WelcomeMessage.ts index 781789f..7079036 100644 --- a/UI/WelcomeMessage.ts +++ b/UI/WelcomeMessage.ts @@ -3,6 +3,7 @@ import Locale from "../UI/i18n/Locale"; import State from "../State"; import Translations from "./i18n/Translations"; import Combine from "./Base/Combine"; +import LanguagePicker from "./LanguagePicker"; export class WelcomeMessage extends UIElement { @@ -17,7 +18,7 @@ export class WelcomeMessage extends UIElement { constructor() { super(State.state.osmConnection.userDetails); this.ListenTo(Locale.language); - this.languagePicker = Locale.CreateLanguagePicker(State.state.layoutToUse.data.supportedLanguages, Translations.t.general.pickLanguage); + this.languagePicker = LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.data.supportedLanguages, Translations.t.general.pickLanguage); const layout = State.state.layoutToUse.data; this.description =Translations.W(layout.welcomeMessage); diff --git a/UI/i18n/Translation.ts b/UI/i18n/Translation.ts new file mode 100644 index 0000000..b84fc40 --- /dev/null +++ b/UI/i18n/Translation.ts @@ -0,0 +1,103 @@ +import {UIElement} from "../UIElement"; +import Combine from "../Base/Combine"; +import Locale from "./Locale"; +import {Utils} from "../../Utils"; + +export class Translation extends UIElement { + + private static forcedLanguage = undefined; + + public Subs(text: any): Translation { + const newTranslations = {}; + for (const lang in this.translations) { + let template: string = this.translations[lang]; + for (const k in text) { + const combined = []; + const parts = template.split("{" + k + "}"); + const el: string | UIElement = text[k]; + if (el === undefined) { + continue; + } + let rtext: string = ""; + if (typeof (el) === "string") { + rtext = el; + } else { + Translation.forcedLanguage = lang; // This is a very dirty hack - it'll bite me one day + rtext = el.InnerRender(); + } + for (let i = 0; i < parts.length - 1; i++) { + combined.push(parts[i]); + combined.push(rtext) + } + combined.push(parts[parts.length - 1]); + template = new Combine(combined).InnerRender(); + } + newTranslations[lang] = template; + } + Translation.forcedLanguage = undefined; + return new Translation(newTranslations); + + } + + + get txt(): string { + if (this.translations["*"]) { + return this.translations["*"]; + } + const txt = this.translations[Translation.forcedLanguage ?? Locale.language.data]; + if (txt !== undefined) { + return txt; + } + const en = this.translations["en"]; + if (en !== undefined) { + return en; + } + for (const i in this.translations) { + return this.translations[i]; // Return a random language + } + console.error("Missing language ", Locale.language.data, "for", this.translations) + return undefined; + } + + + InnerRender(): string { + return this.txt + } + + public readonly translations: object + + constructor(translations: object) { + super(Locale.language) + let count = 0; + for (const translationsKey in translations) { + count++; + } + this.translations = translations + } + + public replace(a: string, b: string) { + if (a.startsWith("{") && a.endsWith("}")) { + a = a.substr(1, a.length - 2); + } + const result = this.Subs({[a]: b}); + return result; + } + + public Clone() { + return new Translation(this.translations) + } + + + FirstSentence() { + + const tr = {}; + for (const lng in this.translations) { + let txt = this.translations[lng]; + txt = txt.replace(/\..*/, ""); + txt = Utils.EllipsesAfter(txt, 255); + tr[lng] = txt; + } + + return new Translation(tr); + } +} \ No newline at end of file diff --git a/UI/i18n/Translations.ts b/UI/i18n/Translations.ts index ff29875..3adc92f 100644 --- a/UI/i18n/Translations.ts +++ b/UI/i18n/Translations.ts @@ -1,110 +1,7 @@ import {UIElement} from "../UIElement"; import {FixedUiElement} from "../Base/FixedUiElement"; -import Combine from "../Base/Combine"; -import Locale from "./Locale"; -import {Utils} from "../../Utils"; -import * as TranslationsJson from "../../assets/translations.json" - -export class Translation extends UIElement { - - private static forcedLanguage = undefined; - - public Subs(text: any): Translation { - const newTranslations = {}; - for (const lang in this.translations) { - let template: string = this.translations[lang]; - for (const k in text) { - const combined = []; - const parts = template.split("{" + k + "}"); - const el: string | UIElement = text[k]; - if (el === undefined) { - continue; - } - let rtext: string = ""; - if (typeof (el) === "string") { - rtext = el; - } else { - Translation.forcedLanguage = lang; // This is a very dirty hack - it'll bite me one day - rtext = el.InnerRender(); - } - for (let i = 0; i < parts.length - 1; i++) { - combined.push(parts[i]); - combined.push(rtext) - } - combined.push(parts[parts.length - 1]); - template = new Combine(combined).InnerRender(); - } - newTranslations[lang] = template; - } - Translation.forcedLanguage = undefined; - return new Translation(newTranslations); - - } - - - - - get txt(): string { - if (this.translations["*"]) { - return this.translations["*"]; - } - const txt = this.translations[Translation.forcedLanguage ?? Locale.language.data]; - if (txt !== undefined) { - return txt; - } - const en = this.translations["en"]; - if (en !== undefined) { - return en; - } - for (const i in this.translations) { - return this.translations[i]; // Return a random language - } - console.error("Missing language ",Locale.language.data,"for",this.translations) - return undefined; - } - - - InnerRender(): string { - return this.txt - } - - public readonly translations: object - - constructor(translations: object) { - super(Locale.language) - let count = 0; - for (const translationsKey in translations) { - count++; - } - this.translations = translations - } - - public replace(a: string, b: string) { - if(a.startsWith("{") && a.endsWith("}")){ - a = a.substr(1, a.length - 2); - } - const result= this.Subs({[a]: b}); - return result; - } - - public Clone() { - return new Translation(this.translations) - } - - - FirstSentence() { - - const tr = {}; - for (const lng in this.translations) { - let txt = this.translations[lng]; - txt = txt.replace(/\..*/, ""); - txt = Utils.EllipsesAfter(txt, 255); - tr[lng] = txt; - } - - return new Translation(tr); - } -} +import AllTranslationAssets from "../../AllTranslationAssets"; +import {Translation} from "./Translation"; export default class Translations { @@ -112,7 +9,7 @@ export default class Translations { throw "Translations is static. If you want to intitialize a new translation, use the singular form" } - static t = TranslationsJson; + static t = AllTranslationAssets.t; private static isTranslation(tr: any): boolean { for (const key in tr) { @@ -123,27 +20,6 @@ export default class Translations { return true; } - private static InitT(): boolean { - const queue = [Translations.t] - while (queue.length > 0) { - const tr = queue.pop(); - const copy = {} - for (const subKey in tr) { - if (Translations.isTranslation(tr[subKey])) { - copy[subKey] = new Translation(tr[subKey]); - } else if(tr[subKey].translations === undefined /**should not be a translation already*/){ - queue.push(tr[subKey]); - } - } - for (const subKey in copy) { - tr[subKey] = copy[subKey] - } - } - return true; - } - - private static isInited = Translations.InitT(); - public static W(s: string | UIElement): UIElement { if (typeof (s) === "string") { diff --git a/assets/home.svg b/assets/home.svg deleted file mode 100644 index b9f31cf..0000000 --- a/assets/home.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/assets/josm_logo.svg b/assets/josm_logo.svg deleted file mode 100644 index 7e8f5f3..0000000 --- a/assets/josm_logo.svg +++ /dev/null @@ -1,208 +0,0 @@ - - - JOSM Logotype 2019 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - JOSM Logotype 2019 - 2019-08-05 - - - Diamond00744 - - - - - Public Domain - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/assets/star.svg b/assets/star.svg deleted file mode 100644 index 33b2a2e..0000000 --- a/assets/star.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - -Created by potrace 1.15, written by Peter Selinger 2001-2017 - - - - - \ No newline at end of file diff --git a/assets/statistics.svg b/assets/statistics.svg deleted file mode 100644 index 4988617..0000000 --- a/assets/statistics.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - Svg Vector Icons : http://www.onlinewebfonts.com/icon - - \ No newline at end of file diff --git a/assets/svg/mapillary.svg b/assets/svg/mapillary.svg new file mode 100644 index 0000000..64f205d --- /dev/null +++ b/assets/svg/mapillary.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/createLayouts.ts b/createLayouts.ts index f933e90..9d6d0de 100644 --- a/createLayouts.ts +++ b/createLayouts.ts @@ -7,8 +7,8 @@ import {Layout} from "./Customizations/Layout"; import {readFileSync, writeFile, writeFileSync} from "fs"; import Locale from "./UI/i18n/Locale"; import svg2img from 'promise-svg2img'; -import {Translation} from "./UI/i18n/Translations"; import Translations from "./UI/i18n/Translations"; +import {Translation} from "./UI/i18n/Translation"; function enc(str: string): string { return encodeURIComponent(str.toLowerCase()); diff --git a/css/mobile.css b/css/mobile.css index 8488c67..f4c5839 100644 --- a/css/mobile.css +++ b/css/mobile.css @@ -8,6 +8,10 @@ Contains tweaks for small screens @media only screen and (max-width: 600px), only screen and (max-height: 600px) { + .leaflet-control-attribution { + display: none; + } + .only-on-mobile { display: unset; } diff --git a/css/tagrendering.css b/css/tagrendering.css index 3cbcda2..7c08861 100644 --- a/css/tagrendering.css +++ b/css/tagrendering.css @@ -108,4 +108,14 @@ input:checked + label .question-option-with-border { font-size: x-large; font-weight: bold; border-radius: 1.5em; +} + +.edit-button img { + width: 1.3em; + height: 1.3em; + padding: 0.5em; + border-radius: 0.65em; + border: solid black 1px; + font-size: medium; + float: right; } \ No newline at end of file diff --git a/css/userbadge.css b/css/userbadge.css index d5ed6f6..81ac712 100644 --- a/css/userbadge.css +++ b/css/userbadge.css @@ -50,12 +50,6 @@ display: block; } -.small-userbadge-icon { - width: 1em; - height: 1em; - fill: black; - border-radius: 0; -} #profile-pic { float: left; diff --git a/generateIncludedImages.ts b/generateIncludedImages.ts index c273f7a..1237403 100644 --- a/generateIncludedImages.ts +++ b/generateIncludedImages.ts @@ -1,28 +1,69 @@ import * as fs from "fs"; +import {Utils} from "./Utils"; -console.log("Generating images") +function genImages() { -const dir = fs.readdirSync("./assets/svg") -console.log(dir) + console.log("Generating images") + const dir = fs.readdirSync("./assets/svg") -let module = "import {Img} from \"./UI/Img\";\nimport {FixedUiElement} from \"./UI/Base/FixedUiElement\";\n\nexport default class Svg {\n\n\n"; -for (const path of dir) { - - if(!path.endsWith(".svg")){ - throw "Non-svg file detected in the svg files: "+path; + let module = "import {Img} from \"./UI/Img\";\nimport {FixedUiElement} from \"./UI/Base/FixedUiElement\";\n\nexport default class Svg {\n\n\n"; + for (const path of dir) { + + if (!path.endsWith(".svg")) { + throw "Non-svg file detected in the svg files: " + path; + } + + const svg = fs.readFileSync("./assets/svg/" + path, "utf-8") + .replace(/\n/g, " ") + .replace(/\r/g, "") + .replace(/\\/g, "\\") + .replace(/"/g, "\\\"") + const name = path.substr(0, path.length - 4) + .replace(/[ -]/g, "_"); + module += ` public static ${name} = "${svg}"\n` + module += ` public static ${name}_img = Img.AsImageElement(Svg.${name})\n` + module += ` public static ${name}_ui() { return new FixedUiElement(Svg.${name}_img);}\n\n` } - - const svg = fs.readFileSync("./assets/svg/"+path, "utf-8") - .replace(/\n/g, " ") - .replace(/\r/g, "") - .replace(/\\/g, "\\") - .replace(/"/g, "\\\"") - const name = path.substr(0, path.length-4) - .replace(/[ -]/g, "_"); - module += ` public static ${name} = "${svg}"\n` - module += ` public static ${name}_img = Img.AsImageElement(Svg.${name})\n` - module += ` public static ${name}_ui() { return new FixedUiElement(Svg.${name}_img);}\n\n` + module += "}\n"; + fs.writeFileSync("Svg.ts", module); + console.log("Done") } -module += "}\n"; -fs.writeFileSync("Svg.ts", module); -console.log("Done") \ No newline at end of file + +function isTranslation(tr: any): boolean { + for (const key in tr) { + if (typeof tr[key] !== "string") { + return false; + } + } + return true; +} + +function transformTranslation(obj: any, depth = 1) { + + if (isTranslation(obj)) { + return `new Translation( ${JSON.stringify(obj)} )` + } + + let values = "" + for (const key in obj) { + values += (Utils.Times((_) => " ", depth)) + key + ": " + transformTranslation(obj[key], depth + 1) + ",\n" + } + return `{${values}}`; + +} + +function genTranslations() { + const translations = JSON.parse(fs.readFileSync("./assets/translations.json", "utf-8")) + const transformed = transformTranslation(translations); + + let module = `import {Translation} from "./UI/i18n/Translation"\n\nexport default class AllTranslationAssets {\n\n`; + module += " public static t = " + transformed; + module += "}" + + fs.writeFileSync("AllTranslationAssets.ts", module); + + +} + +genTranslations() +genImages() \ No newline at end of file diff --git a/index.css b/index.css index 4cb60d9..135578a 100644 --- a/index.css +++ b/index.css @@ -42,6 +42,20 @@ body { background-color: white; border-radius: 1em; cursor: pointer; + box-shadow: 0 0 10px #00000066; +} + +.layer-selection-toggle { + border-top-left-radius: 1em; + border-bottom-left-radius: 1em; + display: flex; + flex-direction: column-reverse; +} + +.layer-selection-toggle img { + display: block; + width: 2em; + padding: 1em; } /**************** GENERIC ****************/ @@ -158,7 +172,7 @@ body { box-sizing: border-box; } -.search-go { +.search-go img { position: relative; float: right; height: 1.2em; @@ -167,7 +181,6 @@ body { padding: 0.4em; margin-left: 0.5em; margin-right: 0; - } @@ -187,69 +200,51 @@ body { position: absolute; z-index: 5000; transition: all 500ms linear; - overflow: hidden; + overflow-x: hidden; pointer-events: none; /* Shadow offset */ padding: 0.5em 10px 0 0.5em; } - -.collapse-button { - position: absolute; - background-color: #e5f5ff; - width: 3.5em; - border-top-left-radius: 2em; - border-bottom-left-radius: 2em; - display: inline-block; - height: 100%; - box-shadow: -10px 0 10px -10px #0006; -} - -.collapse-button .collapse-button-img { - background-color: #e5f5ff; -} - -.open-button { - width: 2em; - border-top-left-radius: 2em; - border-bottom-left-radius: 2em; - margin-bottom: 10px; -} - -.open-button .collapse-button-img { - border-radius: 50%; - box-sizing: border-box; - display: inline-block; - padding: 1em; - background-color: white; - box-shadow: 0 0 10px #0006; -} - -.collapse-button-img { - border-radius: 50%; - box-sizing: border-box; - display: inline-block; - padding: 1em; - background-color: white; - box-shadow: none; - margin: 0; - -} - -.collapse-button-img img { - width: 1.5em; - margin: 0; - padding: 0; -} - -#welcomeMessage { - display: inline-block; - margin-left: 3.5em; - border-radius: 0 2em 2em 0; - max-width: 40em; - width: 45vw; +.welcomeMessage { + display: block; + margin-left: 4em; + max-width: calc(100vw - 5em); + width: 40em; max-height: calc(100vh - 15em); overflow-y: auto; + border-top-right-radius: 1em; + border-bottom-right-radius: 1em; +} + +.close-welcome-button { + position: absolute; + display: inline-block; + height: 100%; + background-color: #e5f5ff; + box-sizing: border-box; + width: 4em; + padding: 1em; + border-top-left-radius: 1em; + border-bottom-left-radius: 1em; +} + +.close-welcome-button img { + width: 2em; +} + +.open-welcome-button { + display: inline-block; + box-sizing: border-box; + background-color: white; + height: 4em; + width: 4em; + padding: 1em; + border-radius: 1em; +} + +.open-welcome-button img { + width: 2em; } #messagesbox { @@ -257,6 +252,9 @@ body { position: relative; padding: 0; pointer-events: all; + box-shadow: 0 0 10px #00000066; + border-radius: 1em; + width: min-content } @@ -309,6 +307,13 @@ body { } +.attribution img { + height: 1.2em !important; + padding-right: 0.5em; + padding-left: 0.2em; + +} + .attribution-author { display: inline-block; } @@ -325,6 +330,14 @@ body { /***************** Info box (box containing features and questions ******************/ + +.map-attribution img { + width: 1em; + height: 1em; + fill: black; + border-radius: 0; +} + .leaflet-popup-content { width: 40em !important; max-height: 80vh; diff --git a/index.ts b/index.ts index da649a1..bc242490 100644 --- a/index.ts +++ b/index.ts @@ -5,7 +5,6 @@ import {InitUiElements} from "./InitUiElements"; import {QueryParameters} from "./Logic/Web/QueryParameters"; import {UIEventSource} from "./Logic/UIEventSource"; import * as $ from "jquery"; -import {FromJSON} from "./Customizations/JSON/FromJSON"; import SharedLayers from "./Customizations/SharedLayers"; let defaultLayout = "bookcases" @@ -16,6 +15,7 @@ if (location.href.startsWith("http://buurtnatuur.be")) { window.location.replace("https://buurtnatuur.be"); } + if (location.href.indexOf("buurtnatuur.be") >= 0) { // Reload the https version. This is important for the 'locate me' button defaultLayout = "buurtnatuur" diff --git a/test/Tag.spec.ts b/test/Tag.spec.ts index 20a12f9..9544c43 100644 --- a/test/Tag.spec.ts +++ b/test/Tag.spec.ts @@ -6,7 +6,7 @@ import T from "./TestHelper"; import {FromJSON} from "../Customizations/JSON/FromJSON"; import {And, Tag} from "../Logic/Tags"; import Locale from "../UI/i18n/Locale"; -import Translations, {Translation} from "../UI/i18n/Translations"; +import Translations from "../UI/i18n/Translations"; import {UIEventSource} from "../Logic/UIEventSource"; import {OH, OpeningHour} from "../Logic/OpeningHours"; import PublicHolidayInput from "../UI/Input/OpeningHours/PublicHolidayInput"; @@ -14,6 +14,7 @@ import TagRenderingConfig from "../Customizations/JSON/TagRenderingConfig"; import EditableTagRendering from "../UI/Popup/EditableTagRendering"; import {SubstitutedTranslation} from "../UI/SpecialVisualizations"; import {Utils} from "../Utils"; +import {Translation} from "../UI/i18n/Translation";