From 9e4035befcd00193ec89c470ae11ac0930f702a3 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Thu, 3 Sep 2020 19:05:18 +0200 Subject: [PATCH] Port bird-hides to new JSON-format, various improvements --- Customizations/JSON/FromJSON.ts | 3 + Customizations/Layers/Birdhide.ts | 164 ------------ Customizations/Layouts/Natuurpunt.ts | 5 +- Customizations/OnlyShowIf.ts | 3 +- Logic/Tags.ts | 2 +- UI/CustomGenerator/CustomGeneratorPanel.ts | 4 +- UI/CustomGenerator/GenerateEmpty.ts | 2 +- UI/CustomGenerator/TagRenderingPanel.ts | 2 +- UI/Image/ImageCarousel.ts | 3 +- UI/Image/ImageCarouselWithUpload.ts | 1 + UI/Input/SingleTagInput.ts | 2 +- UI/SlideShow.ts | 1 + UI/UserBadge.ts | 2 +- .../{nature => layers/bird_hide}/birdhide.svg | 0 assets/layers/bird_hide/birdhides.json | 251 ++++++++++++++++++ .../bird_hide}/birdshelter.svg | 0 assets/nature/birdshelter.png | Bin 23489 -> 0 bytes css/slideshow.css | 84 ++++++ css/userbadge.css | 89 +++++++ customGenerator.ts | 1 + index.css | 217 ++------------- index.html | 2 + 22 files changed, 460 insertions(+), 378 deletions(-) delete mode 100644 Customizations/Layers/Birdhide.ts rename assets/{nature => layers/bird_hide}/birdhide.svg (100%) create mode 100644 assets/layers/bird_hide/birdhides.json rename assets/{nature => layers/bird_hide}/birdshelter.svg (100%) delete mode 100644 assets/nature/birdshelter.png create mode 100644 css/slideshow.css create mode 100644 css/userbadge.css diff --git a/Customizations/JSON/FromJSON.ts b/Customizations/JSON/FromJSON.ts index 6276902..48aa340 100644 --- a/Customizations/JSON/FromJSON.ts +++ b/Customizations/JSON/FromJSON.ts @@ -15,6 +15,8 @@ import * as drinkingWater from "../../assets/layers/drinking_water/drinking_wate import * as ghostbikes from "../../assets/layers/ghost_bike/ghost_bike.json" import * as viewpoint from "../../assets/layers/viewpoint/viewpoint.json" import * as bike_parking from "../../assets/layers/bike_parking/bike_parking.json" +import * as birdhides from "../../assets/layers/bird_hide/birdhides.json" + import {Utils} from "../../Utils"; export class FromJSON { @@ -29,6 +31,7 @@ export class FromJSON { FromJSON.Layer(ghostbikes), FromJSON.Layer(viewpoint), FromJSON.Layer(bike_parking), + FromJSON.Layer(birdhides), ]; for (const layer of sharedLayersList) { diff --git a/Customizations/Layers/Birdhide.ts b/Customizations/Layers/Birdhide.ts deleted file mode 100644 index fa561ee..0000000 --- a/Customizations/Layers/Birdhide.ts +++ /dev/null @@ -1,164 +0,0 @@ -import {LayerDefinition} from "../LayerDefinition"; -import {And, Or, Tag} from "../../Logic/Tags"; -import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload"; -import {TagRenderingOptions} from "../TagRenderingOptions"; - -export class Birdhide extends LayerDefinition { - - private static readonly birdhide = new Tag("leisure", "bird_hide"); - - - constructor() { - super("birdhide",{ - name: "vogelkijkplaats", - description: "Een plaats om vogels te kijken, zoals een vogelkijkhut of kijkwand", - overpassFilter: Birdhide.birdhide, - elementsToShow: [], - icon: "assets/nature/birdhide.svg", - minzoom: 12, - wayHandling: LayerDefinition.WAYHANDLING_CENTER_AND_WAY, - presets: [ - { - title: "Vogelkijkplaats", - tags: [Birdhide.birdhide] - } - ], - style(): { color: string; icon: any } { - return {color: "", icon: undefined}; - }, - }); - - function rmStart(toRemove: string, title: string): string { - if (title.toLowerCase().indexOf(toRemove.toLowerCase()) == 0) { - return title.substr(toRemove.length).trim(); - } - return title; - - } - - function rmStarts(toRemove: string[], title: string) { - for (const toRm of toRemove) { - title = rmStart(toRm, title); - } - return title; - } - - this.title = new TagRenderingOptions({ - tagsPreprocessor: (tags) => { - if (tags.name) { - const nm = - rmStarts( - ["Vogelkijkhut", "Vogelkijkwand", "Kijkwand", "Kijkhut"], - tags.name); - - tags.name = " '" + nm + "'"; - } else { - tags.name = ""; - } - }, - mappings: [ - { - k: new And([new Tag("shelter", "no"), new Tag("building", "")]), - txt: "Vogelkijkwand{name}" - }, - { - k: new And([new Tag("amenity", "shelter"), new Tag("building", "yes")]), - txt: "Vogelijkhut{name}" - }, - { - k: new Tag("amenity", "shelter"), - txt: "Vogelijkhut{name}" - }, - { - k: new Tag("shelter", "yes"), - txt: "Vogelijkhut{name}" - }, - { - k: new Tag("amenity", "shelter"), - txt: "Vogelijkhut{name}" - }, - { - k: new Tag("building", "yes"), - txt: "Vogelijkhut{name}" - }, - {k: null, txt: "Vogelkijkplaats{name}"} - ] - }); - - - this.style = (properties) => { - let icon = "assets/nature/birdhide.svg"; - if (new Or([new Tag("amenity", "shelter"), new Tag("building", "yes"), new Tag("shelter", "yes")]).matchesProperties(properties)) { - icon = "assets/nature/birdshelter.svg"; - } - - return { - color: "#0000bb", - icon: { - iconUrl: icon, - iconSize: [40,40], - iconAnchor: [20,20] - } - } - } - - - this.elementsToShow = [ - new ImageCarouselWithUploadConstructor(), - - new TagRenderingOptions({ - question: "Is dit een kijkwand of kijkhut?", - mappings: [ - { - k: new And([new Tag("shelter", "no"), new Tag("building", ""), new Tag("amenity", "")]), - txt: "Vogelkijkwand" - }, - { - k: new And([new Tag("amenity", "shelter"), new Tag("building", "yes"), new Tag("shelter", "yes")]), - txt: "Vogelijkhut" - }, - { - k: new Or([new Tag("amenity", "shelter"), new Tag("building", "yes"), new Tag("shelter", "yes")]), - txt: "Vogelijkhut" - }, - - ] - }), - new TagRenderingOptions({ - question: "Is ze rolstoeltoegankelijk?", - mappings: [ - { - k: new Tag("wheelchair", "no"), - txt: "Niet rolstoeltoegankelijk" - }, - { - k: new Tag("wheelchair", "limited"), - txt: "Een rolstoel raakt er, maar het is niet makkelijk" - }, - { - k: new Tag("wheelchair", "yes"), - txt: "Een rolstoel raakt er gemakkelijk" - } - ] - }), - - new TagRenderingOptions({ - question: "Wie beheert deze?", - freeform: { - key: "operator", - template: "Beheer door $$$", - renderTemplate: "Beheer door {operator}", - placeholder: "organisatie" - }, - mappings: [ - {k: new Tag("operator", "Natuurpunt"), txt: "Natuurpunt"}, - {k: new Tag("operator", "Agentschap Natuur en Bos"), txt: "het Agentschap Natuur en Bos (ANB)"}, - - ] - }) - - - ]; - - } -} \ No newline at end of file diff --git a/Customizations/Layouts/Natuurpunt.ts b/Customizations/Layouts/Natuurpunt.ts index df81eb6..1ff287e 100644 --- a/Customizations/Layouts/Natuurpunt.ts +++ b/Customizations/Layouts/Natuurpunt.ts @@ -1,5 +1,4 @@ import {Layout} from "../Layout"; -import {Birdhide} from "../Layers/Birdhide"; import {InformationBoard} from "../Layers/InformationBoard"; import {NatureReserves} from "../Layers/NatureReserves"; @@ -9,7 +8,7 @@ export class Natuurpunt extends Layout{ "natuurpunt", ["nl"], "De natuur in", - [new Birdhide(), new InformationBoard(), new NatureReserves(true), "drinking_water"], + ["birdhides", new InformationBoard(), new NatureReserves(true), "drinking_water"], 12, 51.20875, 3.22435, @@ -17,6 +16,6 @@ export class Natuurpunt extends Layout{ "", "" ); - this.icon = "./assets/nature/birdhide.svg" + this.icon = "./assets/layers/bird_hide/birdhide.svg" } } \ No newline at end of file diff --git a/Customizations/OnlyShowIf.ts b/Customizations/OnlyShowIf.ts index 0552a38..d439f07 100644 --- a/Customizations/OnlyShowIf.ts +++ b/Customizations/OnlyShowIf.ts @@ -103,8 +103,9 @@ class OnlyShowIf extends UIElement implements TagDependantUIElement { return this._embedded.IsQuestioning(); } - Activate(): void { + Activate(): UIElement { this._embedded.Activate(); + return this; } Update(): void { diff --git a/Logic/Tags.ts b/Logic/Tags.ts index 414b92b..dcbccd4 100644 --- a/Logic/Tags.ts +++ b/Logic/Tags.ts @@ -46,7 +46,7 @@ export class RegexTag extends TagsFilter { matches(tags: { k: string; v: string }[]): boolean { for (const tag of tags) { if (RegexTag.doesMatch(tag.k, this.key)){ - return RegexTag.doesMatch(tag.v, this.value); + return RegexTag.doesMatch(tag.v, this.value) != this.invert; } } return false; diff --git a/UI/CustomGenerator/CustomGeneratorPanel.ts b/UI/CustomGenerator/CustomGeneratorPanel.ts index 5df977f..fe83784 100644 --- a/UI/CustomGenerator/CustomGeneratorPanel.ts +++ b/UI/CustomGenerator/CustomGeneratorPanel.ts @@ -22,7 +22,7 @@ export default class CustomGeneratorPanel extends UIElement { private mainPanel: UIElement; private loginButton: UIElement; - private connection: OsmConnection; + private readonly connection: OsmConnection; constructor(connection: OsmConnection, layout: LayoutConfigJson) { super(connection.userDetails); @@ -40,7 +40,7 @@ export default class CustomGeneratorPanel extends UIElement { private InitMainPanel(layout: LayoutConfigJson, userDetails: UserDetails, connection: OsmConnection) { const es = new UIEventSource(layout); const encoded = es.map(config => btoa(JSON.stringify(config))); - encoded.addCallback(encoded => LocalStorageSource.Get("\"last-custom-theme\"")) + encoded.addCallback(encoded => LocalStorageSource.Get("last-custom-theme")) const liveUrl = encoded.map(encoded => `./index.html?userlayout=${es.data.id}#${encoded}`) const iframe = liveUrl.map(url => ``); const currentSetting = new UIEventSource>(undefined) diff --git a/UI/CustomGenerator/GenerateEmpty.ts b/UI/CustomGenerator/GenerateEmpty.ts index f07518e..fc02f44 100644 --- a/UI/CustomGenerator/GenerateEmpty.ts +++ b/UI/CustomGenerator/GenerateEmpty.ts @@ -11,7 +11,7 @@ export class GenerateEmpty { overpassTags: {and: [""]}, title: undefined, description: {}, - tagRenderings: [] + tagRenderings: [], } } diff --git a/UI/CustomGenerator/TagRenderingPanel.ts b/UI/CustomGenerator/TagRenderingPanel.ts index ba14ccb..99ebe7e 100644 --- a/UI/CustomGenerator/TagRenderingPanel.ts +++ b/UI/CustomGenerator/TagRenderingPanel.ts @@ -41,7 +41,7 @@ export default class TagRenderingPanel extends InputElement", options?.title ?? "TagRendering", "", options?.description ?? ""]) diff --git a/UI/Image/ImageCarousel.ts b/UI/Image/ImageCarousel.ts index bda22b2..412a42e 100644 --- a/UI/Image/ImageCarousel.ts +++ b/UI/Image/ImageCarousel.ts @@ -85,7 +85,7 @@ export class ImageCarousel extends TagDependantUIElement { this._deleteButton = new ConfirmDialog(showDeleteButton, - "Afbeelding verwijderen", + "Afbeelding verwijderen", "Afbeelding verwijderen", "Terug", deleteCurrent, @@ -149,6 +149,7 @@ export class ImageCarousel extends TagDependantUIElement { Activate() { super.Activate(); this.searcher.Activate(); + return this; } } \ No newline at end of file diff --git a/UI/Image/ImageCarouselWithUpload.ts b/UI/Image/ImageCarouselWithUpload.ts index c82dc09..2984e77 100644 --- a/UI/Image/ImageCarouselWithUpload.ts +++ b/UI/Image/ImageCarouselWithUpload.ts @@ -53,6 +53,7 @@ class ImageCarouselWithUpload extends TagDependantUIElement { super.Activate(); this._imageElement.Activate(); this._pictureUploader.Activate(); + return this; } Update() { diff --git a/UI/Input/SingleTagInput.ts b/UI/Input/SingleTagInput.ts index d48860d..5e998cd 100644 --- a/UI/Input/SingleTagInput.ts +++ b/UI/Input/SingleTagInput.ts @@ -16,7 +16,7 @@ export default class SingleTagInput extends InputElement { constructor(value: UIEventSource = undefined) { super(undefined); - this._value = value ?? new UIEventSource(undefined); + this._value = value ?? new UIEventSource(""); this.key = TextField.KeyInput(); diff --git a/UI/SlideShow.ts b/UI/SlideShow.ts index c6fc1bf..38ee929 100644 --- a/UI/SlideShow.ts +++ b/UI/SlideShow.ts @@ -86,6 +86,7 @@ export class SlideShow extends UIElement { } this._next.Update(); this._prev.Update(); + return this; } } \ No newline at end of file diff --git a/UI/UserBadge.ts b/UI/UserBadge.ts index b73e267..f7ea5da 100644 --- a/UI/UserBadge.ts +++ b/UI/UserBadge.ts @@ -47,7 +47,7 @@ export class UserBadge extends UIElement { this._homeButton = new VariableUiElement( this._userDetails.map((userinfo) => { if (userinfo.home) { - return "home "; + return "home "; } return ""; }) diff --git a/assets/nature/birdhide.svg b/assets/layers/bird_hide/birdhide.svg similarity index 100% rename from assets/nature/birdhide.svg rename to assets/layers/bird_hide/birdhide.svg diff --git a/assets/layers/bird_hide/birdhides.json b/assets/layers/bird_hide/birdhides.json new file mode 100644 index 0000000..78fc325 --- /dev/null +++ b/assets/layers/bird_hide/birdhides.json @@ -0,0 +1,251 @@ +{ + "id": "birdhides", + "name": { + "nl": "Vogelkijkhutten" + }, + "minzoom": 14, + "overpassTags": { + "and": [ + "leisure=bird_hide" + ] + }, + "title": { + "render": { + "nl": "Vogelkijkplaats" + }, + "mappings": [ + { + "if": { + "and": [ + "name~((V|v)ogel.*).*" + ] + }, + "then": { + "nl": "{name}" + } + }, + { + "if": { + "and": [ + "name~*", + { + "or": [ + "building!~no", + "shelter=yes" + ] + } + ] + }, + "then": { + "nl": "Vogelkijkhut {name}" + } + }, + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "Vogelkijkwand {name}" + } + } + ] + }, + "description": { + "nl": "Een vogelkijkhut" + }, + "tagRenderings": [ + { + "question": { + "nl": "Is dit een kijkwand of kijkhut?" + }, + "mappings": [ + { + "if": { + "and": [ + "shelter=no", + "building=", + "amenity=" + ] + }, + "then": { + "nl": "Vogelkijkwand" + } + }, + { + "if": { + "and": [ + "amenity=shelter", + "building=yes", + "shelter=yes" + ] + }, + "then": { + "nl": "Vogelkijkhut" + } + }, + { + "if": { + "or": [ + "amenity=shelter", + "building=yes", + "shelter=yes" + ] + }, + "then": { + "nl": "Vogelkijkhut" + }, + "hideInAnswer": true + } + ] + }, + { + "question": { + "nl": "Is deze vogelkijkplaats rolstoeltoegankelijk?" + }, + "mappings": [ + { + "if": { + "and": [ + "wheelchair=designated" + ] + }, + "then": { + "nl": "Er zijn speciale voorzieningen voor rolstoelen" + } + }, + { + "if": { + "and": [ + "wheelchair=yes" + ] + }, + "then": { + "nl": "Een rolstoel raakt er vlot" + } + }, + { + "if": { + "and": [ + "wheelchair=limited" + ] + }, + "then": { + "nl": "Je kan er raken met een rolstoel, maar het is niet makkelijk" + } + }, + { + "if": { + "and": [ + "wheelchair=no" + ] + }, + "then": { + "nl": "Niet rolstoeltoegankelijk" + } + } + ] + }, + { + "render": { + "nl": "Beheer door {operator}" + }, + "freeform": { + "key": "operator" + }, + "question": { + "nl": "Wie beheert deze vogelkijkplaats?" + }, + "mappings": [ + { + "if": { + "and": [ + "operator~Natuurpunt" + ] + }, + "then": { + "nl": "Beheer door Natuurpunt" + } + }, + { + "if": { + "and": [ + "operator=Agentschap Natuur en Bos" + ] + }, + "then": { + "nl": "Beheer door het Agentschap Natuur en Bos " + } + } + ] + } + ], + "icon": { + "render": { + "nl": "./assets/layers/bird_hide/birdhide.svg" + }, + "mappings": [ + { + "if": { + "or": [ + "building=yes", + "shelter=yes", + "amenity=shelter" + ] + }, + "then": "./assets/layers/bird_hide/birdshelter.svg" + } + ] + }, + "size": { + "question": {}, + "freeform": { + "addExtraTags": [] + }, + "render": { + "nl": "40,40,center" + }, + "mappings": [] + }, + "color": { + "render": { + "nl": "#94bb28" + }, + }, + "stroke": { + "render": { + "nl": "3" + }, + }, + "presets": [ + { + "tags": [ + "leisure=bird_hide", + "building=yes", + "shelter=yes", + "amenity=shelter" + ], + "title": { + "nl": "Vogelkijkhut" + }, + "description": { + "nl": "Een overdekte hut waarbinnen er warm en droog naar vogels gekeken kan worden" + } + }, + { + "tags": [ + "leisure=bird_hide", + "building=no", + "shelter=no" + ], + "title": { + "nl": "Vogelkijkwand" + }, + "description": { + "nl": "Een vogelkijkwand waarachter men kan staan om vogels te kijken" + } + } + ], + "wayHandling": 2 +} \ No newline at end of file diff --git a/assets/nature/birdshelter.svg b/assets/layers/bird_hide/birdshelter.svg similarity index 100% rename from assets/nature/birdshelter.svg rename to assets/layers/bird_hide/birdshelter.svg diff --git a/assets/nature/birdshelter.png b/assets/nature/birdshelter.png deleted file mode 100644 index d5b23033be2c2a8d6e16c888d18001e893baf8b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23489 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 M&Jq30#{2sJ0jWujGXMYp diff --git a/css/slideshow.css b/css/slideshow.css new file mode 100644 index 0000000..4c96502 --- /dev/null +++ b/css/slideshow.css @@ -0,0 +1,84 @@ + +.image-slideshow { + position: relative; + text-align: center; + max-width: 100%; + margin-top: 1em; + margin-bottom: 1em; +} + +.slides { + overflow: hidden; +} + +.prev-button { + background-color: black; + opacity: 0.3; + width: 4.0em; + + height: 100%; + padding-left: 0.5em; + padding-right: 0.5em; + position: absolute; + top: 50%; + left: 0; + transform: translate(0, -50%); + + z-index: 5060; + + border-radius: 1em; +} + + +.next-button { + background-color: black; + opacity: 0.3; + width: 4.0em; + height: 100%; + padding-left: 0.5em; + padding-right: 0.5em; + position: absolute; + top: 50%; + right: 0; + transform: translate(0, -50%); + border-radius: 1em; + + + z-index: 5060; + +} + +.vspan { + height: calc(50% - 3em); +} + +.prev-button img { + margin-left: -1em; + width: 6em; + text-align: center; +} + +.next-button img { + margin-left: -1em; + width: 6em; + text-align: center; +} + +.slide > span { + max-height: 40vh; +} + +.slide > span img { + height: auto; + width: auto; + max-width: 100%; + max-height: 30vh; + border-radius: 1em; +} + + +.hidden { + /* This is used by the slideshow, to hide non-active slides*/ + display: none !important; + +} diff --git a/css/userbadge.css b/css/userbadge.css new file mode 100644 index 0000000..1e618dd --- /dev/null +++ b/css/userbadge.css @@ -0,0 +1,89 @@ + +.small-userbadge-icon { + width: 1em; + height: 1em; + fill: black; + border-radius: 0; +} + +#profile-pic { + float: left; + width: 4em; + height: 4em; + padding: 0; + margin: 0; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + opacity: 0; + transition: opacity 500ms linear; +} + +#username { + text-decoration: none; + color: black; +} + + +#usertext { + width: max-content; + margin: 0; + + padding: 0.9em; + padding-left: 4.7em; /* Should be half of profile-pic's width + actual padding (same as padding-right)*/ + padding-right: 1.5em; + border-radius: 2em; /*Half border radius width/height*/ + height: 2.2em; /*SHould equal profile-pic height - padding*/ + z-index: 5000; + text-align: left; + background-color: white; + background-size: 100%; + display: block; + + line-height: 0.75em; +} + +#usertext a { + text-decoration: none; + color: black; +} + +#userbadge { + display: inline-block; + text-align: center; + background-color: white; + -webkit-border-radius: 2em; + -moz-border-radius: 2em; + border-radius: 2em; + border-bottom-right-radius: 1.5em; + border-top-right-radius: 1.5em; + margin: 0; + margin-bottom: 0.5em; + + min-width: 20em; + pointer-events: all; +} + +.userbadge-login { + font-weight: bold; + font-size: large; + background-color: #e5f5ff !important; + height:3em; + + display: inline-block; + text-align: center; + -webkit-border-radius: 2em; + -moz-border-radius: 2em; + border-radius: 2em; + border-bottom-right-radius: 1.5em; + border-top-right-radius: 1.5em; + margin: 0; + + min-width: 20em; + pointer-events: all; +} + +#userbadge-and-search { + display: inline-block; + width: min-content; +} diff --git a/customGenerator.ts b/customGenerator.ts index 19532fa..6d94d6e 100644 --- a/customGenerator.ts +++ b/customGenerator.ts @@ -12,6 +12,7 @@ if (window.location.hash.length > 10) { } else { const hash = LocalStorageSource.Get("last-custom-theme").data if (hash !== undefined) { + console.log("Using theme from local storage") layout = JSON.parse(atob(hash)) as LayoutConfigJson; } } diff --git a/index.css b/index.css index 3e528bb..dfcec51 100644 --- a/index.css +++ b/index.css @@ -4,23 +4,10 @@ padding: 0; } - body { font-family: 'Helvetica Neue', Arial, sans-serif; } - form { - display: inline; - } - - .invalid { - box-shadow: 0 0 10px #ff5353; - } - - .shadow { - box-shadow: 0 0 10px #00000066; - } - #leafletDiv { height: 100%; @@ -40,10 +27,6 @@ display: none; /*Hidden by default, only visible on mobile*/ } - #help-button-mobile { - display: none; - } - #geolocate-button img { width: 31px; height: 31px; @@ -54,8 +37,9 @@ display: block; } - .selected-element { - fill: black + + #help-button-mobile { + display: none; } /**************** GENERIC ****************/ @@ -78,6 +62,18 @@ padding-bottom: 0.15em; } + form { + display: inline; + } + + .invalid { + box-shadow: 0 0 10px #ff5353; + } + + .shadow { + box-shadow: 0 0 10px #00000066; + } + .soft { background-color: #e5f5ff; font-weight: bold; @@ -126,103 +122,6 @@ } -/**************** USER BADGE ****************/ - -.small-userbadge-icon { - width: 1em; - height: 1em; - fill: black; - border-radius: 0; -} - - - -#home { - cursor: pointer; -} - -#profile-pic { - float: left; - width: 4em; - height: 4em; - padding: 0; - margin: 0; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; - opacity: 0; - transition: opacity 500ms linear; -} - -#username { - text-decoration: none; - color: black; -} - - -#usertext { - width: max-content; - margin: 0; - - padding: 0.9em; - padding-left: 4.7em; /* Should be half of profile-pic's width + actual padding (same as padding-right)*/ - padding-right: 1.5em; - border-radius: 2em; /*Half border radius width/height*/ - height: 2.2em; /*SHould equal profile-pic height - padding*/ - z-index: 5000; - text-align: left; - background-color: white; - background-size: 100%; - display: block; - - line-height: 0.75em; -} - -#usertext a { - text-decoration: none; - color: black; -} - -#userbadge { - display: inline-block; - text-align: center; - background-color: white; - -webkit-border-radius: 2em; - -moz-border-radius: 2em; - border-radius: 2em; - border-bottom-right-radius: 1.5em; - border-top-right-radius: 1.5em; - margin: 0; - margin-bottom: 0.5em; - - min-width: 20em; - pointer-events: all; -} - -.userbadge-login { - font-weight: bold; - font-size: large; - background-color: #e5f5ff !important; - height:3em; - - display: inline-block; - text-align: center; - -webkit-border-radius: 2em; - -moz-border-radius: 2em; - border-radius: 2em; - border-bottom-right-radius: 1.5em; - border-top-right-radius: 1.5em; - margin: 0; - - min-width: 20em; - pointer-events: all; -} - -#userbadge-and-search { - display: inline-block; - width: min-content; -} - #searchbox { display: inline-block; @@ -614,7 +513,6 @@ #welcomeMessage { display: inline-block; background-color: white; - padding: 1em; border-radius: 0; width: 100%; max-width: 100%; @@ -719,90 +617,6 @@ /************ Slideshow *****************/ -.image-slideshow { - position: relative; - text-align: center; - max-width: 100%; - margin-top: 1em; - margin-bottom: 1em; -} - -.slides { - overflow: hidden; -} - -.prev-button { - background-color: black; - opacity: 0.3; - width: 4.0em; - - height: 100%; - padding-left: 0.5em; - padding-right: 0.5em; - position: absolute; - top: 50%; - left: 0; - transform: translate(0, -50%); - - z-index: 5060; - - border-radius: 1em; -} - - -.next-button { - background-color: black; - opacity: 0.3; - width: 4.0em; - height: 100%; - padding-left: 0.5em; - padding-right: 0.5em; - position: absolute; - top: 50%; - right: 0; - transform: translate(0, -50%); - border-radius: 1em; - - - z-index: 5060; - -} - -.vspan { - height: calc(50% - 3em); -} - -.prev-button img { - margin-left: -1em; - width: 6em; - text-align: center; -} - -.next-button img { - margin-left: -1em; - width: 6em; - text-align: center; -} - -.slide > span { - max-height: 40vh; -} - -.slide > span img { - height: auto; - width: auto; - max-width: 100%; - max-height: 30vh; - border-radius: 1em; -} - - -.hidden { - /* This is used by the slideshow, to hide non-active slides*/ - display: none !important; - -} - .imgWithAttr { max-height: 20em; @@ -1101,7 +915,6 @@ padding: 0.5em; padding-left: 0.75em; - height: 3em; width: 14em; border-radius: 1em; border-top-left-radius: 0; diff --git a/index.html b/index.html index 754b501..ede2540 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,8 @@ MapComplete + +