diff --git a/Models/Constants.ts b/Models/Constants.ts index 8d571a95ab..006a3b2030 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import { Utils } from "../Utils"; export default class Constants { - public static vNumber = "0.5.0-alpha-tailwind"; + public static vNumber = "0.5.0-rc1"; // The user journey states thresholds when a new feature gets unlocked public static userJourney = { diff --git a/UI/Image/DeleteImage.ts b/UI/Image/DeleteImage.ts index 09a5e25546..255620546a 100644 --- a/UI/Image/DeleteImage.ts +++ b/UI/Image/DeleteImage.ts @@ -22,21 +22,20 @@ export default class DeleteImage extends UIElement { this.isDeletedBadge = Translations.t.image.isDeleted; - const style = "display:block;color:white;width:100%;" const deleteButton = Translations.t.image.doDelete.Clone() - .SetStyle(style+"background:#ff8c8c;") + .SetClass("block w-full pl-4 pr-4") + .SetStyle("color:white;background:#ff8c8c; border-top-left-radius:30rem; border-top-right-radius: 30rem;") .onClick(() => { State.state?.changes.addTag(tags.data.id, new Tag(key, "")); }); - const cancelButton = Translations.t.general.cancel; + const cancelButton = Translations.t.general.cancel.SetClass("bg-white pl-4 pr-4").SetStyle( "border-bottom-left-radius:30rem; border-bottom-right-radius: 30rem;"); this.deleteDialog = new CheckBox( new Combine([ deleteButton, cancelButton - - ]).SetStyle("display:flex;flex-direction:column;"), - Svg.delete_icon_ui().SetStyle('width:1.5em;display:block;padding-left: calc(50% - 0.75em);') + ]).SetClass("flex flex-col background-black"), + Svg.delete_icon_svg().SetStyle("width: 2em; height: 2em; display:block;") ) } diff --git a/UI/Image/ImageCarousel.ts b/UI/Image/ImageCarousel.ts index bca28e0326..c3e6302077 100644 --- a/UI/Image/ImageCarousel.ts +++ b/UI/Image/ImageCarousel.ts @@ -21,8 +21,8 @@ export class ImageCarousel extends UIElement{ if(url.key !== undefined){ image = new Combine([ image, - new DeleteImage(url.key, tags) - ]); + new DeleteImage(url.key, tags).SetClass("delete-image-marker absolute top-0 left-0 pl-3") + ]).SetClass("relative"); } image .SetClass("w-full block") @@ -32,7 +32,7 @@ export class ImageCarousel extends UIElement{ }); this.slideshow = new SlideShow(uiElements).HideOnEmpty(true); - this.SetClass("block image-carousel-marker"); + this.SetClass("block w-full"); } /*** diff --git a/UI/Image/SlideShow.ts b/UI/Image/SlideShow.ts index 3168fa601e..e00e3c22d5 100644 --- a/UI/Image/SlideShow.ts +++ b/UI/Image/SlideShow.ts @@ -41,7 +41,7 @@ export class SlideShow extends UIElement { return; } $('.slick-carousel').not('.slick-initialized').slick({ - // autoplay: true, + autoplay: true, arrows: true, dots: true, lazyLoad: 'progressive', diff --git a/UI/ShowDataLayer.ts b/UI/ShowDataLayer.ts index 42ff1b342a..4524d34274 100644 --- a/UI/ShowDataLayer.ts +++ b/UI/ShowDataLayer.ts @@ -23,7 +23,7 @@ export default class ShowDataLayer { layoutToUse: LayoutConfig) { this._leafletMap = leafletMap; const self = this; - let oldGeoLayer: L.Layer = undefined; + const mp = leafletMap.data; this._layerDict = {}; for (const layer of layoutToUse.layers) { @@ -42,6 +42,12 @@ export default class ShowDataLayer { } } + + const knownFeatureIds = new Set(); + const geoLayer = self.CreateGeojsonLayer(); + mp.addLayer(geoLayer); + let cluster = undefined; + function update() { if (features.data === undefined) { return; @@ -49,30 +55,36 @@ export default class ShowDataLayer { if (leafletMap.data === undefined) { return; } - const mp = leafletMap.data; - + const feats = features.data.map(ff => ff.feature); - let geoLayer = self.CreateGeojsonLayer(feats) - if (layoutToUse.clustering.minNeededElements <= features.data.length) { - const cl = window["L"]; // This is a dirty workaround, the clustering plugin binds to the L of the window, not of the namespace or something - const cluster = cl.markerClusterGroup({disableClusteringAtZoom: layoutToUse.clustering.maxZoom}); - cluster.addLayer(geoLayer); - geoLayer = cluster; + for (const feat of feats) { + const key = feat.geometry.type + feat.properties.id + feat.layer; + if (knownFeatureIds.has(key)) { + continue; + } + knownFeatureIds.add(key); + // @ts-ignore + geoLayer.addData(feat); + console.log("Added ", feat) } - - if (oldGeoLayer) { - mp.removeLayer(oldGeoLayer); + if (cluster === undefined) { + if (layoutToUse.clustering.minNeededElements <= features.data.length) { + // Activate clustering if it wasn't already activated + const cl = window["L"]; // This is a dirty workaround, the clustering plugin binds to the L of the window, not of the namespace or something + cluster = cl.markerClusterGroup({disableClusteringAtZoom: layoutToUse.clustering.maxZoom}); + cluster.addLayer(geoLayer); + mp.removeLayer(geoLayer) + mp.addLayer(cluster); + } } - mp.addLayer(geoLayer); - oldGeoLayer = geoLayer; - openSelectedElementFeature(State.state.selectedElement.data); } features.addCallback(() => update()); leafletMap.addCallback(() => update()); - update(); + State.state.selectedElement.addCallbackAndRun(openSelectedElementFeature); + update(); } @@ -122,7 +134,7 @@ export default class ShowDataLayer { const uiElement = new LazyElement(() => FeatureInfoBox.construct(tags, layer, () => { State.state.selectedElement.setData(undefined); - leafletLayer.closePopup(); + leafletLayer.closePopup(); popup.remove(); ScrollableFullScreen.RestoreLeaflet(); }), @@ -156,11 +168,11 @@ export default class ShowDataLayer { } - private CreateGeojsonLayer(features: any[]): L.Layer { + private CreateGeojsonLayer(): L.Layer { const self = this; const data = { type: "FeatureCollection", - features: features + features: [] } return L.geoJSON(data, { style: feature => self.createStyleFor(feature), diff --git a/UI/SubstitutedTranslation.ts b/UI/SubstitutedTranslation.ts index 9191d45a05..9d6aca4321 100644 --- a/UI/SubstitutedTranslation.ts +++ b/UI/SubstitutedTranslation.ts @@ -29,6 +29,7 @@ export class SubstitutedTranslation extends UIElement { self.content = self.CreateContent(); self.Update(); }); + this.SetClass("w-full") } diff --git a/index.css b/index.css index 675a90a7f1..b5619ff976 100644 --- a/index.css +++ b/index.css @@ -122,6 +122,10 @@ a { color: var(--foreground-color) } +.slick-prev:before, .slick-next:before { + /*Slideshow workaround*/ + color:black !important; +} #topleft-tools svg { fill: var(--foreground-color) !important; @@ -159,6 +163,8 @@ a { box-shadow: 0 3px 14px var(--shadow-color) !important; } + + #geolocate-button { position: absolute; bottom: 25px;