From c15f3d2036ad01385cc13bf72694675182a3b556 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Tue, 1 Feb 2022 04:14:54 +0100 Subject: [PATCH] Lots of styling tweaks, add filter links between layers --- Logic/State/MapState.ts | 30 ++- Models/ThemeConfig/Json/LayerConfigJson.ts | 2 +- Models/ThemeConfig/Json/LayoutConfigJson.ts | 2 +- Models/ThemeConfig/LayerConfig.ts | 18 +- Models/ThemeConfig/LayoutConfig.ts | 2 +- Models/ThemeConfig/PointRenderingConfig.ts | 4 +- UI/Base/MinimapImplementation.ts | 9 +- UI/Base/ScrollableFullScreen.ts | 4 +- UI/Base/SubtleButton.ts | 2 +- UI/BigComponents/CopyrightPanel.ts | 2 +- UI/BigComponents/FilterView.ts | 15 +- UI/BigComponents/LeftControls.ts | 4 +- UI/Image/ImageUploadFlow.ts | 2 +- UI/Popup/FeatureInfoBox.ts | 2 +- UI/Popup/TagRenderingQuestion.ts | 7 +- UI/SubstitutedTranslation.ts | 2 +- UI/i18n/Translation.ts | 2 +- Utils.ts | 6 + assets/layers/gps_location/gps_location.json | 2 +- .../layers/nature_reserve/nature_reserve.json | 13 +- assets/themes/natuurpunt/natuurpunt.css | 24 ++- assets/themes/natuurpunt/natuurpunt.json | 15 +- css/index-tailwind-output.css | 198 +++++++----------- index.css | 89 +++++--- index.manifest | 1 + langs/layers/nl.json | 6 +- package.json | 9 +- scripts/generateLayouts.ts | 8 + 28 files changed, 263 insertions(+), 217 deletions(-) diff --git a/Logic/State/MapState.ts b/Logic/State/MapState.ts index 48e145d35..34b667546 100644 --- a/Logic/State/MapState.ts +++ b/Logic/State/MapState.ts @@ -17,6 +17,7 @@ import SimpleFeatureSource from "../FeatureSource/Sources/SimpleFeatureSource"; import {LocalStorageSource} from "../Web/LocalStorageSource"; import {GeoOperations} from "../GeoOperations"; import TitleHandler from "../Actors/TitleHandler"; +import {BBox} from "../BBox"; /** * Contains all the leaflet-map related state @@ -73,7 +74,7 @@ export default class MapState extends UserRelatedState { /** - * WHich layers are enabled in the current theme + * Which layers are enabled in the current theme and what filters are applied onto them */ public filteredLayers: UIEventSource = new UIEventSource([], "filteredLayers"); /** @@ -169,11 +170,10 @@ export default class MapState extends UserRelatedState { ]; } console.warn("Locking the bounds to ", layout.lockLocation); - this.leafletMap.addCallbackAndRunD(map => { - // @ts-ignore - map.setMaxBounds(layout.lockLocation); - map.setMinZoom(layout.startZoom); - }) + this.mainMapObject.installBounds( + new BBox(layout.lockLocation), + this.featureSwitchIsTesting.data + ) } } @@ -377,6 +377,24 @@ export default class MapState extends UserRelatedState { flayers.push(flayer); } + + for (const layer of layoutToUse.layers) { + if(layer.filterIsSameAs === undefined){ + continue + } + const toReuse = flayers.find(l => l.layerDef.id === layer.filterIsSameAs) + if(toReuse === undefined){ + throw "Error in layer "+layer.id+": it defines that it should be use the filters of "+layer.filterIsSameAs+", but this layer was not loaded" + } + console.warn("Linking filter and isDisplayed-states of "+layer.id+" and "+layer.filterIsSameAs) + const selfLayer = flayers.findIndex(l => l.layerDef.id === layer.id) + flayers[selfLayer] = { + isDisplayed: toReuse.isDisplayed, + layerDef: layer, + appliedFilters: toReuse.appliedFilters + }; + } + return new UIEventSource(flayers); } diff --git a/Models/ThemeConfig/Json/LayerConfigJson.ts b/Models/ThemeConfig/Json/LayerConfigJson.ts index 1656bf8f5..812944520 100644 --- a/Models/ThemeConfig/Json/LayerConfigJson.ts +++ b/Models/ThemeConfig/Json/LayerConfigJson.ts @@ -237,7 +237,7 @@ export interface LayerConfigJson { /** * All the extra questions for filtering */ - filter?: (FilterConfigJson) [], + filter?: (FilterConfigJson) [] | {sameAs: string}, /** * This block defines under what circumstances the delete dialog is shown for objects of this layer. diff --git a/Models/ThemeConfig/Json/LayoutConfigJson.ts b/Models/ThemeConfig/Json/LayoutConfigJson.ts index 02046fff2..b49fe272f 100644 --- a/Models/ThemeConfig/Json/LayoutConfigJson.ts +++ b/Models/ThemeConfig/Json/LayoutConfigJson.ts @@ -232,7 +232,7 @@ export interface LayoutConfigJson { /** * If set to true, the basemap will not scroll outside of the area visible on initial zoom. - * If set to [[lat0, lon0], [lat1, lon1]], the map will not scroll outside of those bounds. + * If set to [[lon, lat], [lon, lat]], the map will not scroll outside of those bounds. * Off by default, which will enable panning to the entire world */ lockLocation?: boolean | [[number, number], [number, number]] | number[][]; diff --git a/Models/ThemeConfig/LayerConfig.ts b/Models/ThemeConfig/LayerConfig.ts index eea16081b..42c6617f2 100644 --- a/Models/ThemeConfig/LayerConfig.ts +++ b/Models/ThemeConfig/LayerConfig.ts @@ -24,6 +24,7 @@ import Link from "../../UI/Base/Link"; import {Utils} from "../../Utils"; import {TagsFilter} from "../../Logic/Tags/TagsFilter"; import Table from "../../UI/Base/Table"; +import FilterConfigJson from "./Json/FilterConfigJson"; export default class LayerConfig extends WithContextLoader { @@ -58,7 +59,8 @@ export default class LayerConfig extends WithContextLoader { public readonly tagRenderings: TagRenderingConfig[]; public readonly filters: FilterConfig[]; - + public readonly filterIsSameAs: string; + constructor( json: LayerConfigJson, context?: string, @@ -243,9 +245,14 @@ export default class LayerConfig extends WithContextLoader { this.tagRenderings = (Utils.NoNull(json.tagRenderings) ?? []).map((tr, i) => new TagRenderingConfig(tr, this.id + ".tagRenderings[" + i + "]")) - this.filters = (json.filter ?? []).map((option, i) => { - return new FilterConfig(option, `${context}.filter-[${i}]`) - }); + if(json.filter !== undefined && json.filter !== null && json.filter["sameAs"] !== undefined){ + this.filterIsSameAs = json.filter["sameAs"] + this.filters = [] + }else{ + this.filters = (json.filter ?? []).map((option, i) => { + return new FilterConfig(option, `${context}.filter-[${i}]`) + }); + } { const duplicateIds = Utils.Dupiclates(this.filters.map(f => f.id)) @@ -302,8 +309,7 @@ export default class LayerConfig extends WithContextLoader { return undefined } const baseTags = TagUtils.changeAsProperties(this.source.osmTags.asChange({id: "node/-1"})) - return mapRendering.GenerateLeafletStyle(new UIEventSource(baseTags), false, - {noSize: true, includeBadges: false}).html + return mapRendering.GetSimpleIcon(new UIEventSource(baseTags)) } public GenerateDocumentation(usedInThemes: string[], layerIsNeededBy: Map, dependencies: { diff --git a/Models/ThemeConfig/LayoutConfig.ts b/Models/ThemeConfig/LayoutConfig.ts index 70c7218b2..10cff4db6 100644 --- a/Models/ThemeConfig/LayoutConfig.ts +++ b/Models/ThemeConfig/LayoutConfig.ts @@ -66,7 +66,7 @@ export default class LayoutConfig { this.maintainer = json.maintainer; this.credits = json.credits; this.version = json.version; - this.language = Array.from(Object.keys(json.title)); + this.language = json.mustHaveLanguage ?? Array.from(Object.keys(json.title)); { if (typeof json.title === "string") { diff --git a/Models/ThemeConfig/PointRenderingConfig.ts b/Models/ThemeConfig/PointRenderingConfig.ts index 6ef8f5aa7..910351e3e 100644 --- a/Models/ThemeConfig/PointRenderingConfig.ts +++ b/Models/ThemeConfig/PointRenderingConfig.ts @@ -150,8 +150,8 @@ export default class PointRenderingConfig extends WithContextLoader { tags: UIEventSource, clickable: boolean, options?: { - noSize: false | boolean, - includeBadges: true | boolean + noSize?: false | boolean, + includeBadges?: true | boolean } ): { diff --git a/UI/Base/MinimapImplementation.ts b/UI/Base/MinimapImplementation.ts index a9d97e2a0..29c38e6e1 100644 --- a/UI/Base/MinimapImplementation.ts +++ b/UI/Base/MinimapImplementation.ts @@ -53,14 +53,15 @@ export default class MinimapImplementation extends BaseUIElement implements Mini public installBounds(factor: number | BBox, showRange?: boolean) { this.leafletMap.addCallbackD(leaflet => { - let bounds; + let bounds : {getEast(), getNorth(), getWest(), getSouth()}; if (typeof factor === "number") { - bounds = leaflet.getBounds().pad(factor) - leaflet.setMaxBounds(bounds) + const lbounds = leaflet.getBounds().pad(factor) + leaflet.setMaxBounds(lbounds) + bounds = lbounds; } else { // @ts-ignore leaflet.setMaxBounds(factor.toLeaflet()) - bounds = leaflet.getBounds() + bounds = factor } if (showRange) { diff --git a/UI/Base/ScrollableFullScreen.ts b/UI/Base/ScrollableFullScreen.ts index 22539a4d1..96184a6d7 100644 --- a/UI/Base/ScrollableFullScreen.ts +++ b/UI/Base/ScrollableFullScreen.ts @@ -6,6 +6,7 @@ import {UIEventSource} from "../../Logic/UIEventSource"; import Hash from "../../Logic/Web/Hash"; import BaseUIElement from "../BaseUIElement"; import Img from "./Img"; +import Title from "./Title"; /** * @@ -101,7 +102,8 @@ export default class ScrollableFullScreen extends UIElement { Hash.hash.setData(undefined) }) - title.SetClass("block text-l sm:text-xl md:text-2xl w-full font-bold p-0 max-h-20vh overflow-y-auto self-center") + title = new Title(title, 2) + title.SetClass("text-l sm:text-xl md:text-2xl w-full p-0 max-h-20vh overflow-y-auto self-center") return new Combine([ new Combine([ new Combine([returnToTheMap, title]) diff --git a/UI/Base/SubtleButton.ts b/UI/Base/SubtleButton.ts index 5174d70d3..0a2915ccd 100644 --- a/UI/Base/SubtleButton.ts +++ b/UI/Base/SubtleButton.ts @@ -21,7 +21,7 @@ export class SubtleButton extends UIElement { } protected InnerRender(): string | BaseUIElement { - const classes = "block flex p-3 my-2 bg-blue-100 rounded-lg hover:shadow-xl hover:bg-blue-200 link-no-underline"; + const classes = "block flex p-3 my-2 bg-subtle rounded-lg hover:shadow-xl hover:bg-unsubtle transition-colors transition-shadow link-no-underline"; const message = Translations.W(this.message); let img; if ((this.imageUrl ?? "") === "") { diff --git a/UI/BigComponents/CopyrightPanel.ts b/UI/BigComponents/CopyrightPanel.ts index ec1b1cfd0..f9a3bfc5c 100644 --- a/UI/BigComponents/CopyrightPanel.ts +++ b/UI/BigComponents/CopyrightPanel.ts @@ -185,7 +185,7 @@ export default class CopyrightPanel extends Combine { ...iconAttributions ].map(e => e?.SetClass("mt-4"))); this.SetClass("flex flex-col link-underline overflow-hidden") - this.SetStyle("max-width: calc(100vw - 3em); width: 40rem; margin-left: 0.75rem; margin-right: 0.5rem") + this.SetStyle("max-width:100%; width: 40rem; margin-left: 0.75rem; margin-right: 0.5rem") } private static CodeContributors(): BaseUIElement { diff --git a/UI/BigComponents/FilterView.ts b/UI/BigComponents/FilterView.ts index d6275e556..3fcd95ba6 100644 --- a/UI/BigComponents/FilterView.ts +++ b/UI/BigComponents/FilterView.ts @@ -115,17 +115,16 @@ export default class FilterView extends VariableUiElement { ) - const style = - "display:flex;align-items:center;padding:0.5rem 0;"; - const layerIcon = layer.defaultIcon()?.SetClass("w-8 h-8 ml-2 shrink-0") - const layerIconUnchecked = layer.defaultIcon()?.SetClass("opacity-50 w-8 h-8 ml-2") + const toggleClasses = "layer-toggle flex flex-wrap items-center pt-2 pb-1 px-0"; + const layerIcon = layer.defaultIcon()?.SetClass("flex-shrink-0 w-8 h-8 ml-2") + const layerIconUnchecked = layer.defaultIcon()?.SetClass("flex-shrink-0 opacity-50 w-8 h-8 ml-2") const layerChecked = new Combine([icon, layerIcon, styledNameChecked, zoomStatus]) - .SetStyle(style) + .SetClass(toggleClasses) .onClick(() => filteredLayer.isDisplayed.setData(false)); const layerNotChecked = new Combine([iconUnselected, layerIconUnchecked, styledNameUnChecked]) - .SetStyle(style) + .SetClass(toggleClasses) .onClick(() => filteredLayer.isDisplayed.setData(true)); @@ -152,7 +151,7 @@ export default class FilterView extends VariableUiElement { const [ui, actualTags] = FilterView.createFilter(filter) - ui.SetClass("mt-3") + ui.SetClass("mt-1") toShow.push(ui) actualTags.addCallback(tagsToFilterFor => { flayer.appliedFilters.data.set(filter.id, tagsToFilterFor) @@ -165,7 +164,7 @@ export default class FilterView extends VariableUiElement { } return new Combine(toShow) - .SetClass("flex flex-col p-2 ml-0 pl-12 bg-gray-200 pt-0 border-b-2 border-detail mb-4") + .SetClass("flex flex-col p-2 ml-12 pl-1 pt-0 border-b-2 border-detail mb-4") } diff --git a/UI/BigComponents/LeftControls.ts b/UI/BigComponents/LeftControls.ts index 389aa5597..750aff5fc 100644 --- a/UI/BigComponents/LeftControls.ts +++ b/UI/BigComponents/LeftControls.ts @@ -35,9 +35,7 @@ export default class LeftControls extends Combine { return defaultIcon; } const tags = {...feature.properties, button: "yes"} - const elem = currentViewFL.layerDef.mapRendering[0]?.GenerateLeafletStyle(new UIEventSource(tags), false, { - noSize: true - })?.html + const elem = currentViewFL.layerDef.mapRendering[0]?.GetSimpleIcon(new UIEventSource(tags)); if (elem === undefined) { return defaultIcon } diff --git a/UI/Image/ImageUploadFlow.ts b/UI/Image/ImageUploadFlow.ts index 1924dbab7..743b1b2c2 100644 --- a/UI/Image/ImageUploadFlow.ts +++ b/UI/Image/ImageUploadFlow.ts @@ -75,7 +75,7 @@ export class ImageUploadFlow extends Toggle { const label = new Combine([ Svg.camera_plus_ui().SetClass("block w-12 h-12 p-1 text-4xl "), labelContent - ]).SetClass("p-2 border-4 border-black rounded-full font-bold h-full align-middle w-full flex justify-center") + ]).SetClass("p-2 border-4 border-detail rounded-full font-bold h-full align-middle w-full flex justify-center") const fileSelector = new FileSelectorButton(label) fileSelector.GetValue().addCallback(filelist => { diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts index e3a10a3a3..55f1a0b67 100644 --- a/UI/Popup/FeatureInfoBox.ts +++ b/UI/Popup/FeatureInfoBox.ts @@ -62,7 +62,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen { layerConfig: LayerConfig, state: {}): BaseUIElement { const title = new TagRenderingAnswer(tags, layerConfig.title ?? new TagRenderingConfig("POI"), state) - .SetClass("break-words font-bold sm:p-0.5 md:p-1 sm:p-1.5 md:p-2"); + .SetClass("break-words font-bold sm:p-0.5 md:p-1 sm:p-1.5 md:p-2 text-2xl"); const titleIcons = new Combine( layerConfig.titleIcons.map(icon => new TagRenderingAnswer(tags, icon, state, "block w-8 h-8 max-h-8 align-baseline box-content sm:p-0.5 w-10",) diff --git a/UI/Popup/TagRenderingQuestion.ts b/UI/Popup/TagRenderingQuestion.ts index 4ea4d5bbf..13f8d4681 100644 --- a/UI/Popup/TagRenderingQuestion.ts +++ b/UI/Popup/TagRenderingQuestion.ts @@ -111,9 +111,8 @@ export default class TagRenderingQuestion extends Combine { const saveButton = new Combine([ options.saveButtonConstr(inputElement.GetValue()), - new Toggle(Translations.t.general.testing.SetClass("alert"), undefined, state.featureSwitchIsTesting) ]) - + let bottomTags: BaseUIElement; if (options.bottomText !== undefined) { bottomTags = options.bottomText(inputElement.GetValue()) @@ -142,7 +141,9 @@ export default class TagRenderingQuestion extends Combine { inputElement, options.cancelButton, saveButton, - bottomTags]) + bottomTags, + new Toggle(Translations.t.general.testing.SetClass("alert"), undefined, state.featureSwitchIsTesting) + ]) this.SetClass("question disable-links") diff --git a/UI/SubstitutedTranslation.ts b/UI/SubstitutedTranslation.ts index 893e0df6f..59d7ae50b 100644 --- a/UI/SubstitutedTranslation.ts +++ b/UI/SubstitutedTranslation.ts @@ -36,7 +36,7 @@ export class SubstitutedTranslation extends VariableUiElement { super( Locale.language.map(language => { - let txt = translation.textFor(language); + let txt = translation?.textFor(language); if (txt === undefined) { return undefined } diff --git a/UI/i18n/Translation.ts b/UI/i18n/Translation.ts index 283e4cd7f..a068be199 100644 --- a/UI/i18n/Translation.ts +++ b/UI/i18n/Translation.ts @@ -35,7 +35,7 @@ export class Translation extends BaseUIElement { get txt(): string { return this.textFor(Translation.forcedLanguage ?? Locale.language.data) - } + } static ExtractAllTranslationsFrom(object: any, context = ""): { context: string, tr: Translation }[] { const allTranslations: { context: string, tr: Translation }[] = [] diff --git a/Utils.ts b/Utils.ts index 16e7ab7e5..e78e5f80d 100644 --- a/Utils.ts +++ b/Utils.ts @@ -305,6 +305,12 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be if (!source.hasOwnProperty(key)) { continue } + if (key.startsWith("=")) { + const trimmedKey = key.substr(1); + target[trimmedKey] = source[key] + continue + } + if (key.startsWith("+") || key.endsWith("+")) { const trimmedKey = key.replace("+", ""); const sourceV = source[key]; diff --git a/assets/layers/gps_location/gps_location.json b/assets/layers/gps_location/gps_location.json index 5016797eb..292c16fce 100644 --- a/assets/layers/gps_location/gps_location.json +++ b/assets/layers/gps_location/gps_location.json @@ -8,7 +8,7 @@ }, "mapRendering": [ { - "icon": "crosshair:#00f", + "icon": "crosshair:var(--catch-detail-color)", "iconSize": "40,40,center", "location": [ "point", diff --git a/assets/layers/nature_reserve/nature_reserve.json b/assets/layers/nature_reserve/nature_reserve.json index ca6baadd2..e7ddf11c5 100644 --- a/assets/layers/nature_reserve/nature_reserve.json +++ b/assets/layers/nature_reserve/nature_reserve.json @@ -151,8 +151,9 @@ ] }, "then": { - "nl": "Dit gebied wordt beheerd door Natuurpunt" - } + "nl": "Dit gebied wordt beheerd door Natuurpunt" + }, + "icon": "./assets/layers/nature_reserve/Natuurpunt.jpg" }, { "if": { @@ -161,8 +162,9 @@ ] }, "then": { - "nl": "Dit gebied wordt beheerd door {operator}" + "nl": "Dit gebied wordt beheerd door {operator}" }, + "icon": "./assets/layers/nature_reserve/Natuurpunt.jpg", "hideInAnswer": true }, { @@ -172,8 +174,9 @@ ] }, "then": { - "nl": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" - } + "nl": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" + }, + "icon": "./assets/layers/nature_reserve/ANB.jpg" } ], "id": "Operator tag" diff --git a/assets/themes/natuurpunt/natuurpunt.css b/assets/themes/natuurpunt/natuurpunt.css index 9f1a65a2b..e8d57ba9e 100644 --- a/assets/themes/natuurpunt/natuurpunt.css +++ b/assets/themes/natuurpunt/natuurpunt.css @@ -1,9 +1,11 @@ :root { --subtle-detail-color: #007759; --subtle-detail-color-contrast: #ffffff; - --subtle-detail-color-light-contrast: lightgrey; + --subtle-detail-color-light-contrast: white; - --catch-detail-color: #0fff00; + --unsubtle-detail-color: #b34f26; + --unsubtle-detail-color-contrast: #ffffff; + --catch-detail-color: #FE6F32; --catch-detail-color-contrast: #ffffff; --alert-color: #fee4d1; --background-color: white; @@ -31,7 +33,21 @@ body { font-family: 'Open Sans Regular', sans-serif; } -h1 h2 h3 h4 { +.layer-toggle .alert { + background: unset !important; + padding: 0 !important; +} + +.layer-toggle svg path { + fill: var(--foreground-color) !important; +} + +.layer-toggle .alert::before { + content: " - " +} + + +h1, h2, h3, h4 { font-family: 'Amaranth', sans-serif; } @@ -43,4 +59,4 @@ h1 h2 h3 h4 { .tab-non-active svg path { fill: white !important; stroke: white !important; -} +} \ No newline at end of file diff --git a/assets/themes/natuurpunt/natuurpunt.json b/assets/themes/natuurpunt/natuurpunt.json index ecb81ab3a..a5ed7ce15 100644 --- a/assets/themes/natuurpunt/natuurpunt.json +++ b/assets/themes/natuurpunt/natuurpunt.json @@ -30,6 +30,7 @@ "startLat": 51.20875, "startLon": 3.22435, "startZoom": 15, + "lockLocation": [[2.1,50.40],[ 6.4,51.54]], "widenFactor": 2, "socialImage": "", "defaultBackgroundId": "CartoDB.Positron", @@ -64,7 +65,10 @@ "render": "circle:#FE6F32;./assets/themes/natuurpunt/nature_reserve.svg" } } - ] + ], + "=filter": { + "sameAs": "nature_reserve_centerpoints" + } } }, { @@ -183,7 +187,12 @@ "source": { "geoJson": "https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/natuurpunt_cache/natuurpunt_{layer}_{z}_{x}_{y}.geojson", "geoJsonZoomLevel": 12, - "isOsmCache": true + "isOsmCache": true, + "osmTags": { + "+and": [ + "operator~.*[nN]atuurpunt.*" + ] + } }, "mapRendering": [ { @@ -313,7 +322,7 @@ } }, { - "builtin": "gps_location_history", + "builtin": "gps_track", "override": { "name": null } diff --git a/css/index-tailwind-output.css b/css/index-tailwind-output.css index 23a816f5c..71b78ca49 100644 --- a/css/index-tailwind-output.css +++ b/css/index-tailwind-output.css @@ -896,12 +896,12 @@ video { margin-left: 0.5rem; } -.mt-3 { - margin-top: 0.75rem; +.ml-12 { + margin-left: 3rem; } -.ml-0 { - margin-left: 0px; +.mt-3 { + margin-top: 0.75rem; } .mb-10 { @@ -1437,11 +1437,6 @@ video { background-color: rgba(255, 255, 255, var(--tw-bg-opacity)); } -.bg-blue-100 { - --tw-bg-opacity: 1; - background-color: rgba(219, 234, 254, var(--tw-bg-opacity)); -} - .bg-gray-400 { --tw-bg-opacity: 1; background-color: rgba(156, 163, 175, var(--tw-bg-opacity)); @@ -1452,16 +1447,16 @@ video { background-color: rgba(224, 231, 255, var(--tw-bg-opacity)); } -.bg-gray-200 { - --tw-bg-opacity: 1; - background-color: rgba(229, 231, 235, var(--tw-bg-opacity)); -} - .bg-black { --tw-bg-opacity: 1; background-color: rgba(0, 0, 0, var(--tw-bg-opacity)); } +.bg-gray-200 { + --tw-bg-opacity: 1; + background-color: rgba(229, 231, 235, var(--tw-bg-opacity)); +} + .bg-gray-100 { --tw-bg-opacity: 1; background-color: rgba(243, 244, 246, var(--tw-bg-opacity)); @@ -1514,6 +1509,11 @@ video { padding: 2rem; } +.px-0 { + padding-left: 0px; + padding-right: 0px; +} + .pb-12 { padding-bottom: 3rem; } @@ -1546,8 +1546,8 @@ video { padding-right: 0.25rem; } -.pl-12 { - padding-left: 3rem; +.pt-2 { + padding-top: 0.5rem; } .pt-0 { @@ -1590,10 +1590,6 @@ video { padding-left: 1.5rem; } -.pt-2 { - padding-top: 0.5rem; -} - .text-center { text-align: center; } @@ -1783,6 +1779,12 @@ video { transition-duration: 150ms; } +.transition-shadow { + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + .transition-opacity { transition-property: opacity; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); @@ -1805,101 +1807,17 @@ video { z-index: 10001 } -.btn { - display: inline-flex; - justify-content: center; - padding-top: 0.5rem; - padding-bottom: 0.5rem; - padding-left: 1rem; - padding-right: 1rem; - border-width: 1px; - border-color: transparent; - --tw-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); - border-radius: 1.5rem; - --tw-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); - --tw-ring-opacity: 1; - --tw-ring-color: rgba(191, 219, 254, var(--tw-ring-opacity)); -} - -.btn:hover { - --tw-ring-opacity: 1; - --tw-ring-color: rgba(147, 197, 253, var(--tw-ring-opacity)); -} - -.btn { - margin-top: 0.25rem; - margin-right: 0.25rem; - font-size: 0.875rem; - line-height: 1.25rem; - font-weight: 500; - --tw-text-opacity: 1; - color: rgba(255, 255, 255, var(--tw-text-opacity)); - --tw-bg-opacity: 1; - background-color: rgba(37, 99, 235, var(--tw-bg-opacity)); -} - -.btn:hover { - --tw-bg-opacity: 1; - background-color: rgba(29, 78, 216, var(--tw-bg-opacity)); -} - -.btn:focus { - outline: 2px solid transparent; - outline-offset: 2px; - --tw-ring-opacity: 1; - --tw-ring-color: rgba(29, 78, 216, var(--tw-ring-opacity)); -} - -.btn-secondary { - --tw-bg-opacity: 1; - background-color: rgba(75, 85, 99, var(--tw-bg-opacity)); -} - -.btn-secondary:hover { - --tw-bg-opacity: 1; - background-color: rgba(55, 65, 81, var(--tw-bg-opacity)); -} - -.btn-disabled { - --tw-bg-opacity: 1; - background-color: rgba(107, 114, 128, var(--tw-bg-opacity)); -} - -.btn-disabled:hover { - --tw-bg-opacity: 1; - background-color: rgba(107, 114, 128, var(--tw-bg-opacity)); -} - -.btn-disabled { - --tw-text-opacity: 1; - color: rgba(209, 213, 219, var(--tw-text-opacity)); - --tw-ring-opacity: 1; - --tw-ring-color: rgba(229, 231, 235, var(--tw-ring-opacity)); -} - -.btn-disabled:hover { - --tw-ring-opacity: 1; - --tw-ring-color: rgba(229, 231, 235, var(--tw-ring-opacity)); -} - -.btn-disabled:focus { - --tw-ring-opacity: 1; - --tw-ring-color: rgba(229, 231, 235, var(--tw-ring-opacity)); -} - -.btn-disabled { - cursor: default; +.bg-subtle { + background-color: var(--subtle-detail-color); + color: var(--subtle-detail-color-contrast); } :root { - --subtle-detail-color: #e5f5ff; + --subtle-detail-color: #DBEAFE; --subtle-detail-color-contrast: black; --subtle-detail-color-light-contrast: lightgrey; + --unsubtle-detail-color: #BFDBFE; + --unsubtle-detail-color-contrast: black; --catch-detail-color: #3a3aeb; --catch-detail-color-contrast: white; --alert-color: #fee4d1; @@ -1967,16 +1885,45 @@ a { color: var(--foreground-color); } -btn { - margin-top: 0.25rem; - margin-right: 0.25rem; - font-size: 0.875rem; +.btn { + margin-top: 0.5rem; + margin-right: 0.5rem; line-height: 1.25rem; - font-weight: 500; --tw-text-opacity: 1; color: var(--catch-detail-color-contrast); --tw-bg-opacity: 1; background-color: var(--catch-detail-color); + display: inline-flex; + border-radius: 1.5rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + padding-left: 1.25rem; + padding-right: 1.25rem; + font-size: large; + font-weight: bold; + /*-- invisible border: rendered on hover*/ + border: 3px solid var(--unsubtle-detail-color); +} + +.btn:hover { + border: 3px solid var(--catch-detail-color); +} + +.btn-secondary { + background-color: var(--unsubtle-detail-color); +} + +.btn-secondary:hover { + background-color: var(--catch-detail-color); +} + +.btn-disabled { + filter: saturate(0.3); + cursor: default; +} + +.btn-disabled:hover { + border: 3px solid var(--unsubtle-detail-color); } .h-min { @@ -2000,9 +1947,8 @@ btn { } .link-underline a { - -webkit-text-decoration: underline 1px #0078a855; - text-decoration: underline 1px #0078a855; - color: #0078A8; + -webkit-text-decoration: underline 1px var(--foreground-color); + text-decoration: underline 1px var(--foreground-color); } .link-no-underline a { @@ -2083,6 +2029,7 @@ li::marker { } .leaflet-container { + font: unset !important; background-color: var(--background-color) !important; } @@ -2134,6 +2081,7 @@ li::marker { .alert { background-color: var(--alert-color); + color: var(--foreground-color); font-weight: bold; border-radius: 1em; margin: 0.25em; @@ -2326,6 +2274,10 @@ li::marker { /***************** Info box (box containing features and questions ******************/ +input { + color: var(--foreground-color) +} + .leaflet-popup-content { width: 45em !important; margin: 0.25rem !important; @@ -2383,11 +2335,6 @@ li::marker { background-color: #f2f2f2; } -.hover\:bg-blue-200:hover { - --tw-bg-opacity: 1; - background-color: rgba(191, 219, 254, var(--tw-bg-opacity)); -} - .hover\:bg-indigo-200:hover { --tw-bg-opacity: 1; background-color: rgba(199, 210, 254, var(--tw-bg-opacity)); @@ -2407,6 +2354,11 @@ li::marker { box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } +.hover\:bg-unsubtle:hover { + background-color: var(--unsubtle-detail-color); + color: var(--unsubtle-detail-color-contrast); +} + .group:hover .group-hover\:text-blue-800 { --tw-text-opacity: 1; color: rgba(30, 64, 175, var(--tw-text-opacity)); diff --git a/index.css b/index.css index 0502f7f50..0af1a3bd1 100644 --- a/index.css +++ b/index.css @@ -24,38 +24,33 @@ .w-160 { width: 40rem; } + + .bg-subtle { + background-color: var(--subtle-detail-color); + color: var(--subtle-detail-color-contrast); + } + + .bg-unsubtle { + background-color: var(--unsubtle-detail-color); + color: var(--unsubtle-detail-color-contrast); + } + + .bg-catch { + background-color: var(--catch-detail-color); + color: var(--catch-detail-color-contrast); + } } - .btn { - @apply inline-flex justify-center; - @apply py-2 px-4; - @apply border border-transparent shadow-sm; - @apply shadow-sm rounded-3xl; - @apply ring-2 ring-blue-200 hover:ring-blue-300; - @apply mt-1 mr-1; - @apply text-sm font-medium text-white; - @apply bg-blue-600 hover:bg-blue-700; - @apply focus:outline-none focus:ring-blue-700; - } - - .btn-secondary { - @apply bg-gray-600 hover:bg-gray-700; - } - - .btn-disabled { - @apply bg-gray-500 hover:bg-gray-500; - @apply text-gray-300; - @apply ring-gray-200 hover:ring-gray-200 focus:ring-gray-200; - @apply cursor-default; - } } :root { - --subtle-detail-color: #e5f5ff; + --subtle-detail-color: #DBEAFE; --subtle-detail-color-contrast: black; --subtle-detail-color-light-contrast: lightgrey; + --unsubtle-detail-color: #BFDBFE; + --unsubtle-detail-color-contrast: black; --catch-detail-color: #3a3aeb; --catch-detail-color-contrast: white; --alert-color: #fee4d1; @@ -123,16 +118,45 @@ a { color: var(--foreground-color); } -btn { - margin-top: 0.25rem; - margin-right: 0.25rem; - font-size: 0.875rem; +.btn { + margin-top: 0.5rem; + margin-right: 0.5rem; line-height: 1.25rem; - font-weight: 500; --tw-text-opacity: 1; color: var(--catch-detail-color-contrast); --tw-bg-opacity: 1; background-color: var(--catch-detail-color); + display: inline-flex; + border-radius: 1.5rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + padding-left: 1.25rem; + padding-right: 1.25rem; + font-size: large; + font-weight: bold; + /*-- invisible border: rendered on hover*/ + border: 3px solid var(--unsubtle-detail-color); +} + +.btn:hover { + border: 3px solid var(--catch-detail-color); +} + +.btn-secondary { + background-color: var(--unsubtle-detail-color); +} + +.btn-secondary:hover { + background-color: var(--catch-detail-color); +} + +.btn-disabled { + filter: saturate(0.3); + cursor: default; +} + +.btn-disabled:hover { + border: 3px solid var(--unsubtle-detail-color); } .h-min { @@ -153,8 +177,7 @@ btn { } .link-underline a { - text-decoration: underline 1px #0078a855;; - color: #0078A8; + text-decoration: underline 1px var(--foreground-color); } .link-no-underline a { @@ -239,6 +262,7 @@ li::marker { } .leaflet-container { + font: unset !important; background-color: var(--background-color) !important; } @@ -292,6 +316,7 @@ li::marker { .alert { background-color: var(--alert-color); + color: var(--foreground-color); font-weight: bold; border-radius: 1em; margin: 0.25em; @@ -434,6 +459,9 @@ li::marker { /***************** Info box (box containing features and questions ******************/ +input { + color: var(--foreground-color) +} .leaflet-popup-content { width: 45em !important; @@ -489,6 +517,7 @@ li::marker { overflow-y: hidden; } + .zebra-table tr:nth-child(even) { background-color: #f2f2f2; } \ No newline at end of file diff --git a/index.manifest b/index.manifest index e9ccebb12..f6d40e4c5 100644 --- a/index.manifest +++ b/index.manifest @@ -2,6 +2,7 @@ "name": "index", "short_name": "MapComplete", "start_url": "index.html", + "lang": "en", "display": "standalone", "background_color": "#fff", "description": "A thematic map viewer and editor based on OpenStreetMap", diff --git a/langs/layers/nl.json b/langs/layers/nl.json index 8654aec17..0bbf2c414 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -3240,13 +3240,13 @@ "Operator tag": { "mappings": { "0": { - "then": "Dit gebied wordt beheerd door Natuurpunt" + "then": "Dit gebied wordt beheerd door Natuurpunt" }, "1": { - "then": "Dit gebied wordt beheerd door {operator}" + "then": "Dit gebied wordt beheerd door {operator}" }, "2": { - "then": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" + "then": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" } }, "question": "Wie beheert dit gebied?", diff --git a/package.json b/package.json index 3bd8d0567..1ee44cb91 100644 --- a/package.json +++ b/package.json @@ -7,12 +7,9 @@ "homepage": "https://mapcomplete.osm.be", "main": "index.js", "scripts": { - "increase-memory": "export NODE_OPTIONS=--max_old_space_size=8364", - "start": "npm run start:prepare && npm-run-all --parallel start:parallel:*", - "strt": "npm run start:prepare && npm run start:parallel:parcel", - "start:prepare": "ts-node scripts/generateLayerOverview.ts --no-fail && npm run increase-memory", - "start:parallel:parcel": "parcel serve *.html UI/** Logic/** assets/*.json assets/svg/* assets/generated/* assets/layers/*/*.svg assets/layers/*/*.jpg assets/layers/*/*.png assets/layers/*/*.css assets/tagRenderings/*.json assets/themes/*/*.svg assets/themes/*/*.ttf assets/themes/*/*/*.ttf aassets/themes/*/*.otf assets/themes/*/*/*.otf ssets/themes/*/*.css assets/themes/*/*.jpg assets/themes/*/*.png vendor/* vendor/*/*", - "start:parallel:tailwindcli": "tailwindcss -i index.css -o css/index-tailwind-output.css --watch", + "start": "npm run generate:layeroverview && npm run ", + "strt": "export NODE_OPTIONS=--max_old_space_size=8364 && parcel serve *.html UI/** Logic/** assets/*.json assets/svg/* assets/generated/* assets/layers/*/*.svg assets/layers/*/*.jpg assets/layers/*/*.png assets/layers/*/*.css assets/tagRenderings/*.json assets/themes/*/*.svg assets/themes/*/*.ttf assets/themes/*/*/*.ttf aassets/themes/*/*.otf assets/themes/*/*/*.otf ssets/themes/*/*.css assets/themes/*/*.jpg assets/themes/*/*.png vendor/* vendor/*/*", + "watch:css": "tailwindcss -i index.css -o css/index-tailwind-output.css --watch", "generate:css": "tailwindcss -i index.css -o css/index-tailwind-output.css", "test": "ts-node test/TestAll.ts", "init": "npm ci && npm run generate && npm run generate:editor-layer-index && npm run generate:layouts && npm run clean", diff --git a/scripts/generateLayouts.ts b/scripts/generateLayouts.ts index 5b6505d10..268b42ccf 100644 --- a/scripts/generateLayouts.ts +++ b/scripts/generateLayouts.ts @@ -195,8 +195,16 @@ if (!existsSync(generatedDir)) { const blacklist = ["", "test", ".", "..", "manifest", "index", "land", "preferences", "account", "openstreetmap", "custom", "theme"] // @ts-ignore const all: LayoutConfigJson[] = all_known_layouts.themes; +const args = process.argv +const theme = args[2] +if(theme !== undefined){ + console.warn("Only generating layout "+theme) +} for (const i in all) { const layoutConfigJson: LayoutConfigJson = all[i] + if(theme !== undefined && layoutConfigJson.id !== theme){ + continue + } const layout = new LayoutConfig(layoutConfigJson, true, "generating layouts") const layoutName = layout.id if (blacklist.indexOf(layoutName.toLowerCase()) >= 0) {