diff --git a/InitUiElements.ts b/InitUiElements.ts index fb55863..36b62b5 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -10,14 +10,12 @@ import StrayClickHandler from "./Logic/Actors/StrayClickHandler"; import SimpleAddUI from "./UI/BigComponents/SimpleAddUI"; import CenterMessageBox from "./UI/CenterMessageBox"; import {AllKnownLayouts} from "./Customizations/AllKnownLayouts"; -import {TagUtils} from "./Logic/Tags"; import UserBadge from "./UI/BigComponents/UserBadge"; import SearchAndGo from "./UI/BigComponents/SearchAndGo"; import FullScreenMessageBox from "./UI/FullScreenMessageBoxHandler"; import GeoLocationHandler from "./Logic/Actors/GeoLocationHandler"; import {LocalStorageSource} from "./Logic/Web/LocalStorageSource"; import {Utils} from "./Utils"; -import FeatureInfoBox from "./UI/Popup/FeatureInfoBox"; import Svg from "./Svg"; import Link from "./UI/Base/Link"; import * as personal from "./assets/themes/personalLayout/personalLayout.json" @@ -121,49 +119,6 @@ export class InitUiElements { } - /** - * Show the questions and information for the selected element - * This is given to the div which renders fullscreen on mobile devices - */ - State.state.selectedElement.addCallback((feature) => { - - if (feature === undefined) { - State.state.fullScreenMessage.setData(undefined); - } - if (feature?.properties === undefined) { - return; - } - const data = feature.properties; - // Which is the applicable set? - for (const layer of layoutToUse.layers) { - if (typeof layer === "string") { - continue; - } - const applicable = layer.overpassTags.matches(TagUtils.proprtiesToKV(data)); - if (!applicable) { - continue; - } - - if ((layer.title ?? null) === null && layer.tagRenderings.length === 0) { - continue; - } - - // This layer is the layer that gives the questions - const featureBox = new FeatureInfoBox( - State.state.allElements.getEventSourceById(data.id), - layer - ); - - State.state.fullScreenMessage.setData({ - content: featureBox, - hashText: feature.properties.id.replace("/", "_"), - titleText: featureBox.title - }); - break; - } - } - ); - new HistoryHandling(Hash.hash, State.state.fullScreenMessage); InitUiElements.OnlyIf(State.state.featureSwitchUserbadge, () => { @@ -256,7 +211,8 @@ export class InitUiElements { private static InitWelcomeMessage() { - const fullOptions = new FullWelcomePaneWithTabs(); + const isOpened = new UIEventSource(true); + const fullOptions = new FullWelcomePaneWithTabs(() => isOpened.setData(false)); const help = Svg.help_svg().SetClass("open-welcome-button"); const close = Svg.close_svg().SetClass("close-welcome-button"); @@ -285,27 +241,12 @@ export class InitUiElements { } }) - - const fullOptions2 = new FullWelcomePaneWithTabs(); - if (Hash.hash.data === undefined) { - State.state.fullScreenMessage.setData({content: fullOptions2, hashText: "welcome"}) - - } - - Svg.help_svg() - .SetClass("open-welcome-button") - .SetClass("shadow") - .onClick(() => { - State.state.fullScreenMessage.setData({content: fullOptions2, hashText: "welcome"}) - }).AttachTo("help-button-mobile"); - - } private static InitLayerSelection() { InitUiElements.OnlyIf(State.state.featureSwitchLayers, () => { - const layerControlPanel = new LayerControlPanel() + const layerControlPanel = new LayerControlPanel(() => State.state.layerControlIsOpened.setData(false)) .SetStyle("display:block;padding:0.75em;border-radius:1em;"); const closeButton = Svg.close_svg().SetClass("layer-selection-toggle").SetStyle(" background: var(--subtle-detail-color);") const checkbox = new CheckBox( @@ -324,20 +265,9 @@ export class InitUiElements { State.state.locationControl .addCallback(() => { // Close the layer selection when the map is moved - // checkbox.isEnabled.setData(false); + checkbox.isEnabled.setData(false); }); - const fullScreen = new LayerControlPanel(); - checkbox.isEnabled.addCallback(isEnabled => { - if (isEnabled) { - State.state.fullScreenMessage.setData({content: fullScreen, hashText: "layer-select"}); - } - }) - State.state.fullScreenMessage.addCallback(latest => { - if (latest === undefined) { - checkbox.isEnabled.setData(false); - } - }) }); } @@ -404,7 +334,7 @@ export class InitUiElements { source.features.addCallbackAndRun((featuresFreshness: { feature: any, freshness: Date }[]) => { - if(featuresFreshness === undefined){ + if (featuresFreshness === undefined) { return; } let features = featuresFreshness.map(ff => ff.feature); @@ -451,7 +381,9 @@ export class InitUiElements { State.state.leafletMap, State.state.fullScreenMessage, () => { - return new SimpleAddUI(); + return new SimpleAddUI( + () => State.state.LastClickLocation.setData(undefined) + ); } ); }); diff --git a/Logic/Actors/StrayClickHandler.ts b/Logic/Actors/StrayClickHandler.ts index bc18513..16939d4 100644 --- a/Logic/Actors/StrayClickHandler.ts +++ b/Logic/Actors/StrayClickHandler.ts @@ -32,11 +32,16 @@ export default class StrayClickHandler { }) lastClickLocation.addCallback(function (lastClick) { - selectedElement.setData(undefined); - + if (self._lastMarker !== undefined) { leafletMap.data?.removeLayer(self._lastMarker); } + + if(lastClick === undefined){ + return; + } + + selectedElement.setData(undefined); self._lastMarker = L.marker([lastClick.lat, lastClick.lon], { icon: L.icon({ iconUrl: Img.AsData(Svg.add), @@ -51,7 +56,6 @@ export default class StrayClickHandler { self._lastMarker.bindPopup(popup); self._lastMarker.on("click", () => { - fullscreenMessage.setData({content: self._uiToShow(), hashText: "new"}); uiElement.Update(); }); }); diff --git a/UI/Base/ScrollableFullScreen.ts b/UI/Base/ScrollableFullScreen.ts index 3d827b0..77d1597 100644 --- a/UI/Base/ScrollableFullScreen.ts +++ b/UI/Base/ScrollableFullScreen.ts @@ -11,22 +11,23 @@ export default class ScrollableFullScreen extends UIElement { private _component: Combine; - constructor(title: UIElement, content: UIElement) { + constructor(title: UIElement, content: UIElement, onClose: (() => void)) { super(); const returnToTheMap = Svg.back_svg().onClick(() => { - State.state.fullScreenMessage.setData(undefined); - State.state.selectedElement.setData(undefined); - }).SetClass("only-on-mobile") + onClose(); + }).SetClass("sm:hidden") .SetClass("featureinfobox-back-to-the-map") title.SetStyle("width: 100%; display: block;") - const ornament = new Combine([new Ornament().SetStyle("height:5em;")]).SetClass("only-on-mobile") + const ornament = new Combine([new Ornament().SetStyle("height:5em;")]) + .SetClass("block sm:hidden") this._component = new Combine([ - new Combine([returnToTheMap, title]).SetClass("featureinfobox-titlebar"), - new Combine(["",content,"", ornament]).SetClass("featureinfobox-content"), - // We add an ornament which takes around 5em. This is in order to make sure the Web UI doesn't hide + new Combine([returnToTheMap, title]) + .SetClass("text-xl break-words"), + new Combine([content, ornament]) + ]) - this.SetClass("featureinfobox"); + this.SetClass("fixed h-screen w-screen fixed sm:relative"); } diff --git a/UI/BigComponents/FullWelcomePaneWithTabs.ts b/UI/BigComponents/FullWelcomePaneWithTabs.ts index d6e8985..5d69e34 100644 --- a/UI/BigComponents/FullWelcomePaneWithTabs.ts +++ b/UI/BigComponents/FullWelcomePaneWithTabs.ts @@ -15,8 +15,7 @@ import {TabbedComponent} from "../Base/TabbedComponent"; import {UIEventSource} from "../../Logic/UIEventSource"; import LayoutConfig from "../../Customizations/JSON/LayoutConfig"; import UserDetails from "../../Logic/Osm/OsmConnection"; -import {FixedUiElement} from "../Base/FixedUiElement"; -import CombinedInputElement from "../Input/CombinedInputElement"; +import ScrollableFullScreen from "../Base/ScrollableFullScreen"; export default class FullWelcomePaneWithTabs extends UIElement { private readonly _layoutToUse: UIEventSource; @@ -24,7 +23,7 @@ export default class FullWelcomePaneWithTabs extends UIElement { private readonly _component: UIElement; - constructor() { + constructor(onClose: () => void) { super(State.state.layoutToUse); this._layoutToUse = State.state.layoutToUse; this._userDetails = State.state.osmConnection.userDetails; @@ -71,14 +70,13 @@ export default class FullWelcomePaneWithTabs extends UIElement { const tabbedPart = new TabbedComponent(tabs, State.state.welcomeMessageOpenedTab) .ListenTo(this._userDetails); - const backButton = new Combine([ - new Combine([Translations.t.general.returnToTheMap.Clone().SetClass("to-the-map")]) - .SetClass("to-the-map-inner") - - ]).SetClass("only-on-mobile") - .onClick(() => State.state.fullScreenMessage.setData(undefined)); + - this._component = new Combine([tabbedPart, backButton]).SetStyle("width:100%;"); + this._component = new ScrollableFullScreen( + layoutToUse.title, + tabbedPart, + onClose + ) } InnerRender(): string { diff --git a/UI/BigComponents/LayerControlPanel.ts b/UI/BigComponents/LayerControlPanel.ts index 76f7ac4..31eca8c 100644 --- a/UI/BigComponents/LayerControlPanel.ts +++ b/UI/BigComponents/LayerControlPanel.ts @@ -11,7 +11,7 @@ export default class LayerControlPanel extends UIElement { private readonly _panel: UIElement; - constructor() { + constructor(onClose: () => void) { super(); let layerControlPanel: UIElement = new FixedUiElement(""); if (State.state.layoutToUse.data.enableBackgroundLayerSelection) { @@ -31,7 +31,9 @@ export default class LayerControlPanel extends UIElement { const title =Translations.t.general.layerSelection.title.SetClass("featureinfobox-title") - this._panel = new ScrollableFullScreen(title, layerControlPanel); + this._panel = new ScrollableFullScreen(title, layerControlPanel, () => { + onClose + }); } InnerRender(): string { diff --git a/UI/BigComponents/SimpleAddUI.ts b/UI/BigComponents/SimpleAddUI.ts index cecafdb..cd8898d 100644 --- a/UI/BigComponents/SimpleAddUI.ts +++ b/UI/BigComponents/SimpleAddUI.ts @@ -37,7 +37,7 @@ export default class SimpleAddUI extends UIElement { private readonly goToInboxButton: UIElement = new SubtleButton(Svg.envelope_ui(), Translations.t.general.goToInbox, {url: "https://www.openstreetmap.org/messages/inbox", newTab: false}); - constructor() { + constructor(onClose: () => void) { super(State.state.locationControl.map(loc => loc.zoom)); const self = this; this.ListenTo(Locale.language); @@ -61,17 +61,17 @@ export default class SimpleAddUI extends UIElement { this.openLayerControl = new SubtleButton(Svg.layers_ui(), Translations.t.general.add.openLayerControl ).onClick(() => { - State.state.fullScreenMessage.setData(undefined); State.state.layerControlIsOpened.setData(true); }) + + this._component = new ScrollableFullScreen( + Translations.t.general.add.title, + this.CreateContent(), + onClose + ); } InnerRender(): string { - - this._component = new ScrollableFullScreen( - Translations.t.general.add.title, - this.CreateContent() - ) return this._component.Render(); } diff --git a/UI/CustomGenerator/AllLayersPanel.ts b/UI/CustomGenerator/AllLayersPanel.ts index dcf0c63..6f8ce2d 100644 --- a/UI/CustomGenerator/AllLayersPanel.ts +++ b/UI/CustomGenerator/AllLayersPanel.ts @@ -68,7 +68,7 @@ export default class AllLayersPanel extends UIElement { const layer = config.layers[i]; if (typeof layer !== "string") { try { - const iconTagRendering = new TagRenderingConfig(layer.icon, undefined, "icon") + const iconTagRendering = new TagRenderingConfig(layer["icon"], undefined, "icon") const icon = iconTagRendering.GetRenderValue({"id": "node/-1"}).txt; return `` } catch (e) { diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts index b0b59d1..b14bb77 100644 --- a/UI/Popup/FeatureInfoBox.ts +++ b/UI/Popup/FeatureInfoBox.ts @@ -16,7 +16,8 @@ export default class FeatureInfoBox extends UIElement { constructor( tags: UIEventSource, - layerConfig: LayerConfig + layerConfig: LayerConfig, + onClose: () => {} ) { super(); if (layerConfig === undefined) { @@ -60,7 +61,7 @@ export default class FeatureInfoBox extends UIElement { new Combine([title, titleIcons]).SetClass("featureinfobox-titlebar-title") ]) - this._component = new ScrollableFullScreen(titleBar, content) + this._component = new ScrollableFullScreen(titleBar, content, onClose) } InnerRender(): string { diff --git a/UI/ShowDataLayer.ts b/UI/ShowDataLayer.ts index 181ac28..56f1e84 100644 --- a/UI/ShowDataLayer.ts +++ b/UI/ShowDataLayer.ts @@ -126,7 +126,7 @@ export default class ShowDataLayer { const tags = State.state.allElements.getEventSourceFor(feature); - const uiElement: LazyElement = new LazyElement(() => new FeatureInfoBox(tags, layer), + const uiElement: LazyElement = new LazyElement(() => new FeatureInfoBox(tags, layer, () => popup.closePopup()), "
Rendering
"); popup.setContent(uiElement.Render()); popup.on('remove', () => { diff --git a/css/mobile.css b/css/mobile.css index f2986b7..1bdfef6 100644 --- a/css/mobile.css +++ b/css/mobile.css @@ -20,17 +20,6 @@ Contains tweaks for small screens display: none !important; } - #messagesbox { - display: none; - background-color: var(--background-color); - color: var(--foreground-color); - } - - #help-button-mobile{ - display: unset; - pointer-events: all; - } - #help-button-mobile div { box-shadow: 0 0 10px #0006; margin-bottom: 10px; @@ -39,12 +28,6 @@ Contains tweaks for small screens #geolocate-button { display: block; } - - .leaflet-popup { - /* On mobile, the popups are shown as a full-screen element */ - display: none; - visibility: hidden; - } #centermessage { top: 30%; diff --git a/css/tagrendering.css b/css/tagrendering.css index eb3290b..0f8f327 100644 --- a/css/tagrendering.css +++ b/css/tagrendering.css @@ -4,11 +4,6 @@ flex-direction: column; } -.featureinfobox-title { - font-size: xx-large; - word-break: break-word; -} - .featureinfobox-icons img { max-height: 1.5em; width: 1.5em; @@ -63,15 +58,6 @@ } -.featureinfobox-content { - display: block; - max-height: 75vh; - overflow-y: auto; - padding-top: 1em; - width:100%; - overflow-x: hidden; -} - @media only screen and (max-width: 600px), only screen and (max-height: 600px) { .featureinfobox-content { display: block; diff --git a/index.css b/index.css index 486bdbd..a5e151b 100644 --- a/index.css +++ b/index.css @@ -82,9 +82,7 @@ a { } -#help-button-mobile { - display: none; -} + #layer-selection { position: absolute;