Fix opening of various views when set by url-parameters, small styling tweaks in the popups

This commit is contained in:
pietervdvn 2021-10-23 02:46:37 +02:00
parent d40bf15bc7
commit 933c0f0073
14 changed files with 237 additions and 248 deletions

View file

@ -10,7 +10,7 @@ import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
* Makes sure the hash shows the selected element and vice-versa. * Makes sure the hash shows the selected element and vice-versa.
*/ */
export default class SelectedFeatureHandler { export default class SelectedFeatureHandler {
private static readonly _no_trigger_on = new Set(["welcome", "copyright", "layers", "new", "", undefined]) private static readonly _no_trigger_on = new Set(["welcome", "copyright", "layers", "new", "filter","", undefined])
private readonly hash: UIEventSource<string>; private readonly hash: UIEventSource<string>;
private readonly state: { private readonly state: {
selectedElement: UIEventSource<any>, selectedElement: UIEventSource<any>,
@ -85,6 +85,11 @@ export default class SelectedFeatureHandler {
return; return;
} }
if (!(hash.startsWith("node") || hash.startsWith("way") || hash.startsWith("relation"))) {
return;
}
OsmObject.DownloadObjectAsync(hash).then(obj => { OsmObject.DownloadObjectAsync(hash).then(obj => {
try { try {
@ -131,24 +136,23 @@ export default class SelectedFeatureHandler {
private zoomToSelectedFeature() { private zoomToSelectedFeature() {
const selected = this.state.selectedElement.data const selected = this.state.selectedElement.data
if(selected === undefined){ if (selected === undefined) {
return return
} }
const centerpoint= GeoOperations.centerpointCoordinates(selected) const centerpoint = GeoOperations.centerpointCoordinates(selected)
const location = this.state.locationControl; const location = this.state.locationControl;
location.data.lon = centerpoint[0] location.data.lon = centerpoint[0]
location.data.lat = centerpoint[1] location.data.lat = centerpoint[1]
const minZoom = Math.max(14, ...(this.state.layoutToUse?.layers?.map(l => l.minzoomVisible) ?? [])) const minZoom = Math.max(14, ...(this.state.layoutToUse?.layers?.map(l => l.minzoomVisible) ?? []))
if(location.data.zoom < minZoom ){ if (location.data.zoom < minZoom) {
location.data.zoom = minZoom location.data.zoom = minZoom
} }
location.ping(); location.ping();
} }
} }

View file

@ -144,31 +144,20 @@ export default class FeatureSwitchState {
} }
this.featureSwitchIsTesting = QueryParameters.GetQueryParameter( this.featureSwitchIsTesting = QueryParameters.GetBooleanQueryParameter(
"test", "test",
""+testingDefaultValue, ""+testingDefaultValue,
"If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org" "If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org"
).map( )
(str) => str === "true",
[],
(b) => "" + b
);
this.featureSwitchIsDebugging = QueryParameters.GetQueryParameter( this.featureSwitchIsDebugging = QueryParameters.GetBooleanQueryParameter(
"debug", "debug",
"false", "false",
"If true, shows some extra debugging help such as all the available tags on every object" "If true, shows some extra debugging help such as all the available tags on every object"
).map( )
(str) => str === "true",
[],
(b) => "" + b
);
this.featureSwitchFakeUser = QueryParameters.GetQueryParameter("fake-user", "false", this.featureSwitchFakeUser = QueryParameters.GetBooleanQueryParameter("fake-user", "false",
"If true, 'dryrun' mode is activated and a fake user account is loaded") "If true, 'dryrun' mode is activated and a fake user account is loaded")
.map(str => str === "true", [], b => "" + b);
this.overpassUrl = QueryParameters.GetQueryParameter("overpassUrl", this.overpassUrl = QueryParameters.GetQueryParameter("overpassUrl",

View file

@ -119,7 +119,7 @@ export default class MapState extends UserRelatedState {
this.overlayToggles = this.layoutToUse.tileLayerSources.filter(c => c.name !== undefined).map(c => ({ this.overlayToggles = this.layoutToUse.tileLayerSources.filter(c => c.name !== undefined).map(c => ({
config: c, config: c,
isDisplayed: QueryParameters.GetQueryParameter("overlay-" + c.id, "" + c.defaultState, "Wether or not the overlay " + c.id + " is shown").map(str => str === "true", [], b => "" + b) isDisplayed: QueryParameters.GetBooleanQueryParameter("overlay-" + c.id, "" + c.defaultState, "Wether or not the overlay " + c.id + " is shown")
})) }))
this.filteredLayers = this.InitializeFilteredLayers() this.filteredLayers = this.InitializeFilteredLayers()
@ -170,17 +170,12 @@ export default class MapState extends UserRelatedState {
.map(value => value === "yes", [], enabled => { .map(value => value === "yes", [], enabled => {
return enabled ? "yes" : ""; return enabled ? "yes" : "";
}) })
isDisplayed.addCallbackAndRun(d => console.log("IsDisplayed for layer", layer.id, "is currently", d))
} else { } else {
isDisplayed = QueryParameters.GetQueryParameter( isDisplayed = QueryParameters.GetBooleanQueryParameter(
"layer-" + layer.id, "layer-" + layer.id,
"true", "true",
"Wether or not layer " + layer.id + " is shown" "Wether or not layer " + layer.id + " is shown"
).map<boolean>( )
(str) => str !== "false",
[],
(b) => b.toString()
);
} }
const flayer = { const flayer = {
isDisplayed: isDisplayed, isDisplayed: isDisplayed,

View file

@ -55,6 +55,10 @@ export class QueryParameters {
return source; return source;
} }
public static GetBooleanQueryParameter(key: string, deflt: string, documentation?: string): UIEventSource<boolean>{
return QueryParameters.GetQueryParameter(key, deflt, documentation).map(str => str === "true", [], b => ""+b)
}
public static GenerateQueryParameterDocs(): string { public static GenerateQueryParameterDocs(): string {
const docs = [QueryParameters.QueryParamDocsIntro]; const docs = [QueryParameters.QueryParamDocsIntro];
for (const key in QueryParameters.documentation) { for (const key in QueryParameters.documentation) {

View file

@ -1,11 +0,0 @@
import {FixedUiElement} from "./FixedUiElement";
export default class Ornament extends FixedUiElement {
constructor() {
super("");
this.SetClass("pt-3 pb-3 flex justify-center box-border")
}
}

View file

@ -1,11 +1,11 @@
import {UIElement} from "../UIElement"; import {UIElement} from "../UIElement";
import Svg from "../../Svg"; import Svg from "../../Svg";
import Combine from "./Combine"; import Combine from "./Combine";
import Ornament from "./Ornament";
import {FixedUiElement} from "./FixedUiElement"; import {FixedUiElement} from "./FixedUiElement";
import {UIEventSource} from "../../Logic/UIEventSource"; import {UIEventSource} from "../../Logic/UIEventSource";
import Hash from "../../Logic/Web/Hash"; import Hash from "../../Logic/Web/Hash";
import BaseUIElement from "../BaseUIElement"; import BaseUIElement from "../BaseUIElement";
import Img from "./Img";
/** /**
* *
@ -18,24 +18,20 @@ import BaseUIElement from "../BaseUIElement";
*/ */
export default class ScrollableFullScreen extends UIElement { export default class ScrollableFullScreen extends UIElement {
private static readonly empty = new FixedUiElement(""); private static readonly empty = new FixedUiElement("");
private static readonly _actor = ScrollableFullScreen.InitActor();
private static _currentlyOpen: ScrollableFullScreen; private static _currentlyOpen: ScrollableFullScreen;
public isShown: UIEventSource<boolean>; public isShown: UIEventSource<boolean>;
private _component: BaseUIElement; private _component: BaseUIElement;
private _fullscreencomponent: BaseUIElement; private _fullscreencomponent: BaseUIElement;
private _hashToSet: string;
constructor(title: ((mode: string) => BaseUIElement), content: ((mode: string) => BaseUIElement), constructor(title: ((mode: string) => BaseUIElement), content: ((mode: string) => BaseUIElement),
hashToSet: string,
isShown: UIEventSource<boolean> = new UIEventSource<boolean>(false) isShown: UIEventSource<boolean> = new UIEventSource<boolean>(false)
) { ) {
super(); super();
this.isShown = isShown; this.isShown = isShown;
this._hashToSet = hashToSet;
this._component = this.BuildComponent(title("desktop"), content("desktop"), isShown) this._component = this.BuildComponent(title("desktop"), content("desktop"), isShown)
.SetClass("hidden md:block"); .SetClass("hidden md:block");
this._fullscreencomponent = this.BuildComponent(title("mobile"), content("mobile"), isShown); this._fullscreencomponent = this.BuildComponent(title("mobile"), content("mobile").SetClass("pb-20"), isShown);
const self = this; const self = this;
@ -56,15 +52,6 @@ export default class ScrollableFullScreen extends UIElement {
Hash.hash.setData(undefined); Hash.hash.setData(undefined);
} }
private static InitActor() {
Hash.hash.addCallback(hash => {
if (hash === undefined || hash === "") {
ScrollableFullScreen.clear()
}
});
return true;
}
InnerRender(): BaseUIElement { InnerRender(): BaseUIElement {
return this._component; return this._component;
} }
@ -72,9 +59,6 @@ export default class ScrollableFullScreen extends UIElement {
Activate(): void { Activate(): void {
this.isShown.setData(true) this.isShown.setData(true)
this._fullscreencomponent.AttachTo("fullscreen"); this._fullscreencomponent.AttachTo("fullscreen");
if (this._hashToSet != undefined) {
Hash.hash.setData(this._hashToSet)
}
const fs = document.getElementById("fullscreen"); const fs = document.getElementById("fullscreen");
ScrollableFullScreen._currentlyOpen = this; ScrollableFullScreen._currentlyOpen = this;
fs.classList.remove("hidden") fs.classList.remove("hidden")
@ -83,25 +67,26 @@ export default class ScrollableFullScreen extends UIElement {
private BuildComponent(title: BaseUIElement, content: BaseUIElement, isShown: UIEventSource<boolean>) { private BuildComponent(title: BaseUIElement, content: BaseUIElement, isShown: UIEventSource<boolean>) {
const returnToTheMap = const returnToTheMap =
new Combine([ new Combine([
Svg.back_svg().SetClass("block md:hidden"), new Img(Svg.back.replace(/#000000/g,"#cccccc"),true)
Svg.close_svg().SetClass("hidden md:block") .SetClass("block md:hidden w-12 h-12 p-2"),
]) new Img(Svg.close.replace(/#000000/g,"#cccccc"),true)
.onClick(() => { .SetClass("hidden md:block w-12 h-12 p-3")
isShown.setData(false) ]).SetClass("rounded-full p-0 flex-shrink-0 self-center")
}).SetClass("mb-2 bg-blue-50 rounded-full w-12 h-12 p-1.5 flex-shrink-0")
title.SetClass("block text-l sm:text-xl md:text-2xl w-full font-bold p-2 pl-4 max-h-20vh overflow-y-auto") returnToTheMap.onClick(() => {
const ornament = new Combine([new Ornament().SetStyle("height:5em;")]) isShown.setData(false)
.SetClass("md:hidden h-5") })
title.SetClass("block text-l sm:text-xl md:text-2xl w-full font-bold p-0 max-h-20vh overflow-y-auto")
return new Combine([ return new Combine([
new Combine([ new Combine([
new Combine([returnToTheMap, title]) new Combine([returnToTheMap, title])
.SetClass("border-b-2 border-black shadow md:shadow-none bg-white p-2 pb-0 md:p-0 flex flex-shrink-0"), .SetClass("border-b-1 border-black shadow bg-white flex flex-shrink-0 pt-1 pb-1 md:pt-0 md:pb-0"),
new Combine([content, ornament]) new Combine([content])
.SetClass("block p-2 md:pt-4 w-full h-full overflow-y-auto md:max-h-65vh"), .SetClass("block p-2 md:pt-4 w-full h-full overflow-y-auto md:max-h-65vh"),
// We add an ornament which takes around 5em. This is in order to make sure the Web UI doesn't hide // We add an ornament which takes around 5em. This is in order to make sure the Web UI doesn't hide
]).SetClass("flex flex-col h-full relative bg-white") ]).SetClass("flex flex-col h-full relative bg-white")
]).SetClass("fixed top-0 left-0 right-0 h-screen w-screen md:max-h-65vh md:w-auto md:relative z-above-controls"); ]).SetClass("fixed top-0 left-0 right-0 h-screen w-screen md:max-h-65vh md:w-auto md:relative z-above-controls md:rounded-xl overflow-hidden");
} }

View file

@ -9,12 +9,11 @@ import {DownloadPanel} from "./DownloadPanel";
import {SubtleButton} from "../Base/SubtleButton"; import {SubtleButton} from "../Base/SubtleButton";
import Svg from "../../Svg"; import Svg from "../../Svg";
import ExportPDF from "../ExportPDF"; import ExportPDF from "../ExportPDF";
import {FixedUiElement} from "../Base/FixedUiElement";
export default class AllDownloads extends ScrollableFullScreen { export default class AllDownloads extends ScrollableFullScreen {
constructor(isShown: UIEventSource<boolean>) { constructor(isShown: UIEventSource<boolean>) {
super(AllDownloads.GenTitle, AllDownloads.GeneratePanel, "layers", isShown); super(AllDownloads.GenTitle, AllDownloads.GeneratePanel, isShown);
} }
private static GenTitle(): BaseUIElement { private static GenTitle(): BaseUIElement {

View file

@ -30,7 +30,7 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen {
super( super(
() => layoutToUse.title.Clone(), () => layoutToUse.title.Clone(),
() => FullWelcomePaneWithTabs.GenerateContents(state, currentTab, isShown), () => FullWelcomePaneWithTabs.GenerateContents(state, currentTab, isShown),
undefined, isShown isShown
) )
} }

View file

@ -26,12 +26,12 @@ export default class LeftControls extends Combine {
featureSwitchEnableExport: UIEventSource<boolean>, featureSwitchEnableExport: UIEventSource<boolean>,
featureSwitchExportAsPdf: UIEventSource<boolean>, featureSwitchExportAsPdf: UIEventSource<boolean>,
filteredLayers: UIEventSource<FilteredLayer[]>, filteredLayers: UIEventSource<FilteredLayer[]>,
featureSwitchFilter: UIEventSource<boolean>, featureSwitchFilter: UIEventSource<boolean>
selectedElement: UIEventSource<any>
}, },
guiState: { guiState: {
downloadControlIsOpened: UIEventSource<boolean>, downloadControlIsOpened: UIEventSource<boolean>,
filterViewIsOpened: UIEventSource<boolean>, filterViewIsOpened: UIEventSource<boolean>,
copyrightViewIsOpened: UIEventSource<boolean>
}) { }) {
const toggledCopyright = new ScrollableFullScreen( const toggledCopyright = new ScrollableFullScreen(
@ -41,7 +41,7 @@ export default class LeftControls extends Combine {
state.layoutToUse, state.layoutToUse,
new ContributorCount(state).Contributors new ContributorCount(state).Contributors
), ),
undefined guiState.copyrightViewIsOpened
); );
const copyrightButton = new Toggle( const copyrightButton = new Toggle(
@ -49,8 +49,7 @@ export default class LeftControls extends Combine {
new MapControlButton(Svg.copyright_svg()) new MapControlButton(Svg.copyright_svg())
.onClick(() => toggledCopyright.isShown.setData(true)), .onClick(() => toggledCopyright.isShown.setData(true)),
toggledCopyright.isShown toggledCopyright.isShown
) ).SetClass("p-0.5");
.SetClass("p-0.5");
const toggledDownload = new Toggle( const toggledDownload = new Toggle(
new AllDownloads( new AllDownloads(
@ -73,11 +72,10 @@ export default class LeftControls extends Combine {
() => Translations.t.general.layerSelection.title.Clone(), () => Translations.t.general.layerSelection.title.Clone(),
() => () =>
new FilterView(state.filteredLayers, state.overlayToggles).SetClass( new FilterView(state.filteredLayers, state.overlayToggles).SetClass(
"block p-1 rounded-full" "block p-1"
), ),
undefined,
guiState.filterViewIsOpened guiState.filterViewIsOpened
), ).SetClass("rounded-lg"),
new MapControlButton(Svg.filter_svg()) new MapControlButton(Svg.filter_svg())
.onClick(() => guiState.filterViewIsOpened.setData(true)), .onClick(() => guiState.filterViewIsOpened.setData(true)),
guiState.filterViewIsOpened guiState.filterViewIsOpened
@ -90,18 +88,6 @@ export default class LeftControls extends Combine {
); );
state.locationControl.addCallback(() => {
// Close the layer selection when the map is moved
toggledDownload.isEnabled.setData(false);
copyrightButton.isEnabled.setData(false);
toggledFilter.isEnabled.setData(false);
});
state.selectedElement.addCallbackAndRunD((_) => {
toggledDownload.isEnabled.setData(false);
copyrightButton.isEnabled.setData(false);
toggledFilter.isEnabled.setData(false);
});
super([filterButton, super([filterButton,
downloadButtonn, downloadButtonn,
copyrightButton]) copyrightButton])

View file

@ -26,44 +26,71 @@ import StrayClickHandler from "../Logic/Actors/StrayClickHandler";
import Lazy from "./Base/Lazy"; import Lazy from "./Base/Lazy";
export class DefaultGuiState { export class DefaultGuiState {
public readonly welcomeMessageIsOpened; public readonly welcomeMessageIsOpened : UIEventSource<boolean>;
public readonly downloadControlIsOpened: UIEventSource<boolean>; public readonly downloadControlIsOpened: UIEventSource<boolean>;
public readonly filterViewIsOpened: UIEventSource<boolean>; public readonly filterViewIsOpened: UIEventSource<boolean>;
public readonly welcomeMessageOpenedTab public readonly copyrightViewIsOpened: UIEventSource<boolean>;
public readonly welcomeMessageOpenedTab: UIEventSource<number>
public readonly allFullScreenStates: UIEventSource<boolean>[] = []
constructor() { constructor() {
this.filterViewIsOpened = QueryParameters.GetQueryParameter(
"filter-toggle",
"false",
"Whether or not the filter view is shown"
).map<boolean>(
(str) => str !== "false",
[],
(b) => "" + b
);
this.welcomeMessageIsOpened = new UIEventSource<boolean>(Hash.hash.data === undefined ||
Hash.hash.data === "" ||
Hash.hash.data == "welcome");
this.welcomeMessageOpenedTab = QueryParameters.GetQueryParameter(
this.welcomeMessageOpenedTab = UIEventSource.asFloat(QueryParameters.GetQueryParameter(
"tab", "tab",
"0", "0",
`The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 = more themes, 4 = about mapcomplete (user must be logged in and have >${Constants.userJourney.mapCompleteHelpUnlock} changesets)` `The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 = more themes, 4 = about mapcomplete (user must be logged in and have >${Constants.userJourney.mapCompleteHelpUnlock} changesets)`
).map<number>( ));
(str) => (isNaN(Number(str)) ? 0 : Number(str)), this.welcomeMessageIsOpened = QueryParameters.GetBooleanQueryParameter(
[], "welcome-control-toggle",
(n) => "" + n "false",
); "Whether or not the welcome panel is shown"
this.downloadControlIsOpened = )
QueryParameters.GetQueryParameter( this.downloadControlIsOpened = QueryParameters.GetBooleanQueryParameter(
"download-control-toggle", "download-control-toggle",
"false", "false",
"Whether or not the download panel is shown" "Whether or not the download panel is shown"
).map<boolean>( )
(str) => str !== "false", this.filterViewIsOpened = QueryParameters.GetBooleanQueryParameter(
[], "filter-toggle",
(b) => "" + b "false",
); "Whether or not the filter view is shown"
)
this.copyrightViewIsOpened = QueryParameters.GetBooleanQueryParameter(
"copyright-toggle",
"false",
"Whether or not the copyright view is shown"
)
if(Hash.hash.data === "download"){
this.downloadControlIsOpened.setData(true)
}
if(Hash.hash.data === "filter"){
this.filterViewIsOpened.setData(true)
}
if(Hash.hash.data === "copyright"){
this.copyrightViewIsOpened.setData(true)
}
if(Hash.hash.data === "" || Hash.hash.data === undefined || Hash.hash.data === "welcome"){
this.welcomeMessageIsOpened.setData(true)
}
this.allFullScreenStates.push(this.downloadControlIsOpened, this.filterViewIsOpened, this.copyrightViewIsOpened, this.welcomeMessageIsOpened)
for (let i = 0; i < this.allFullScreenStates.length; i++){
const fullScreenState = this.allFullScreenStates[i];
for (let j = 0; j < this.allFullScreenStates.length; j++){
if(i == j){
continue
}
const otherState = this.allFullScreenStates[j];
fullScreenState.addCallbackAndRunD(isOpened => {
if(isOpened){
otherState.setData(false)
}
})
}
}
} }
} }
@ -155,6 +182,7 @@ export default class DefaultGUI {
state.featureSwitchWelcomeMessage state.featureSwitchWelcomeMessage
).AttachTo("messagesbox"); ).AttachTo("messagesbox");
new LeftControls(state, guiState).AttachTo("bottom-left"); new LeftControls(state, guiState).AttachTo("bottom-left");
new RightControls(state).AttachTo("bottom-right"); new RightControls(state).AttachTo("bottom-right");
@ -162,6 +190,21 @@ export default class DefaultGUI {
document document
.getElementById("centermessage") .getElementById("centermessage")
.classList.add("pointer-events-none"); .classList.add("pointer-events-none");
// We have to ping the welcomeMessageIsOpened and other isOpened-stuff to activate the FullScreenMessage if needed
for (const state of guiState.allFullScreenStates) {
if(state.data){
state.ping()
}
}
/**
* At last, if the map moves or an element is selected, we close all the panels just as well
*/
state.selectedElement.addCallbackAndRunD((_) => {
guiState.allFullScreenStates.forEach(s => s.setData(false))
});
} }
private InitWelcomeMessage() : BaseUIElement{ private InitWelcomeMessage() : BaseUIElement{
@ -211,7 +254,6 @@ export default class DefaultGUI {
const addNewPoint = new ScrollableFullScreen( const addNewPoint = new ScrollableFullScreen(
() => Translations.t.general.add.title.Clone(), () => Translations.t.general.add.title.Clone(),
() => new SimpleAddUI(newPointDialogIsShown, filterViewIsOpened, state), () => new SimpleAddUI(newPointDialogIsShown, filterViewIsOpened, state),
"new",
newPointDialogIsShown newPointDialogIsShown
); );
addNewPoint.isShown.addCallback((isShown) => { addNewPoint.isShown.addCallback((isShown) => {

View file

@ -26,8 +26,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
layerConfig: LayerConfig, layerConfig: LayerConfig,
) { ) {
super(() => FeatureInfoBox.GenerateTitleBar(tags, layerConfig), super(() => FeatureInfoBox.GenerateTitleBar(tags, layerConfig),
() => FeatureInfoBox.GenerateContent(tags, layerConfig), () => FeatureInfoBox.GenerateContent(tags, layerConfig));
undefined);
if (layerConfig === undefined) { if (layerConfig === undefined) {
throw "Undefined layerconfig"; throw "Undefined layerconfig";

View file

@ -5,18 +5,19 @@
xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#" xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns="http://www.w3.org/2000/svg"
width="100" width="100"
height="100" height="100"
viewBox="0 0 26.458333 26.458334" viewBox="0 0 26.458333 26.458334"
version="1.1" version="1.1"
id="svg8" id="svg8"
sodipodi:docname="close.svg" sodipodi:docname="close.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<defs <defs
id="defs2"/> id="defs2" />
<sodipodi:namedview <sodipodi:namedview
id="base" id="base"
pagecolor="#ffffff" pagecolor="#ffffff"
@ -25,7 +26,7 @@
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="2.8284271" inkscape:zoom="2.8284271"
inkscape:cx="-12.514944" inkscape:cx="-14.459488"
inkscape:cy="118.94409" inkscape:cy="118.94409"
inkscape:document-units="px" inkscape:document-units="px"
inkscape:current-layer="layer1" inkscape:current-layer="layer1"
@ -34,7 +35,7 @@
showguides="true" showguides="true"
inkscape:guide-bbox="true" inkscape:guide-bbox="true"
inkscape:window-width="1920" inkscape:window-width="1920"
inkscape:window-height="1001" inkscape:window-height="1003"
inkscape:window-x="0" inkscape:window-x="0"
inkscape:window-y="0" inkscape:window-y="0"
inkscape:window-maximized="1"> inkscape:window-maximized="1">
@ -42,12 +43,12 @@
position="13.229167,23.859748" position="13.229167,23.859748"
orientation="1,0" orientation="1,0"
id="guide815" id="guide815"
inkscape:locked="false"/> inkscape:locked="false" />
<sodipodi:guide <sodipodi:guide
position="14.944824,13.229167" position="14.944824,13.229167"
orientation="0,1" orientation="0,1"
id="guide817" id="guide817"
inkscape:locked="false"/> inkscape:locked="false" />
</sodipodi:namedview> </sodipodi:namedview>
<metadata <metadata
id="metadata5"> id="metadata5">
@ -56,8 +57,8 @@
rdf:about=""> rdf:about="">
<dc:format>image/svg+xml</dc:format> <dc:format>image/svg+xml</dc:format>
<dc:type <dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title/> <dc:title></dc:title>
</cc:Work> </cc:Work>
</rdf:RDF> </rdf:RDF>
</metadata> </metadata>
@ -66,19 +67,15 @@
inkscape:groupmode="layer" inkscape:groupmode="layer"
id="layer1" id="layer1"
transform="translate(0,-270.54165)"> transform="translate(0,-270.54165)">
<g
id="g836"
transform="matrix(1.7481308,0,0,1.7481308,-10.001295,-212.27744)">
<path <path
inkscape:connector-curvature="0" style="fill:none;stroke:#000000;stroke-width:6.0128417;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 23.165802,293.60329 3.541361,273.97885 v 0"
id="path815" id="path815"
d="M 18.972892,289.3838 7.7469352,278.15784 v 0" inkscape:connector-curvature="0" />
style="fill:none;stroke:#000000;stroke-width:3.4395833;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
<path <path
inkscape:connector-curvature="0" style="fill:none;stroke:#000000;stroke-width:6.01292087;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 23.195394,273.88422 3.5709485,293.50867 v 0"
id="path815-3" id="path815-3"
d="M 18.98982,278.10371 7.7638604,289.32967 v 0" inkscape:connector-curvature="0" />
style="fill:none;stroke:#000000;stroke-width:3.4395833;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
</g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -856,10 +856,6 @@ video {
margin-left: 0.75rem; margin-left: 0.75rem;
} }
.mb-2 {
margin-bottom: 0.5rem;
}
.mr-4 { .mr-4 {
margin-right: 1rem; margin-right: 1rem;
} }
@ -924,6 +920,14 @@ video {
margin-right: 0.75rem; margin-right: 0.75rem;
} }
.mb-2 {
margin-bottom: 0.5rem;
}
.mb-0 {
margin-bottom: 0px;
}
.box-border { .box-border {
box-sizing: border-box; box-sizing: border-box;
} }
@ -988,10 +992,6 @@ video {
height: 3rem; height: 3rem;
} }
.h-5 {
height: 1.25rem;
}
.h-screen { .h-screen {
height: 100vh; height: 100vh;
} }
@ -1279,10 +1279,6 @@ video {
border-width: 2px; border-width: 2px;
} }
.border-b-2 {
border-bottom-width: 2px;
}
.border-b { .border-b {
border-bottom-width: 1px; border-bottom-width: 1px;
} }
@ -1316,11 +1312,6 @@ video {
background-color: rgba(255, 255, 255, var(--tw-bg-opacity)); background-color: rgba(255, 255, 255, var(--tw-bg-opacity));
} }
.bg-blue-50 {
--tw-bg-opacity: 1;
background-color: rgba(239, 246, 255, var(--tw-bg-opacity));
}
.bg-blue-100 { .bg-blue-100 {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgba(219, 234, 254, var(--tw-bg-opacity)); background-color: rgba(219, 234, 254, var(--tw-bg-opacity));
@ -1386,32 +1377,28 @@ video {
padding: 0.5rem; padding: 0.5rem;
} }
.p-0\.5 {
padding: 0.125rem;
}
.p-0 { .p-0 {
padding: 0px; padding: 0px;
} }
.p-0\.5 {
padding: 0.125rem;
}
.pl-2 { .pl-2 {
padding-left: 0.5rem; padding-left: 0.5rem;
} }
.pt-3 { .pb-20 {
padding-top: 0.75rem; padding-bottom: 5rem;
} }
.pb-3 { .pt-1 {
padding-bottom: 0.75rem; padding-top: 0.25rem;
} }
.pl-4 { .pb-1 {
padding-left: 1rem; padding-bottom: 0.25rem;
}
.pb-0 {
padding-bottom: 0px;
} }
.pl-1 { .pl-1 {
@ -1426,6 +1413,10 @@ video {
padding-top: 1.5rem; padding-top: 1.5rem;
} }
.pb-3 {
padding-bottom: 0.75rem;
}
.pl-5 { .pl-5 {
padding-left: 1.25rem; padding-left: 1.25rem;
} }
@ -1434,6 +1425,10 @@ video {
padding-right: 0.75rem; padding-right: 0.75rem;
} }
.pl-4 {
padding-left: 1rem;
}
.pr-4 { .pr-4 {
padding-right: 1rem; padding-right: 1rem;
} }
@ -2187,6 +2182,7 @@ li::marker {
.leaflet-popup-content { .leaflet-popup-content {
width: 45em !important; width: 45em !important;
margin: 0.25rem !important;
} }
.leaflet-div-icon { .leaflet-div-icon {
@ -2422,8 +2418,8 @@ li::marker {
flex-direction: row; flex-direction: row;
} }
.md\:p-0 { .md\:rounded-xl {
padding: 0px; border-radius: 0.75rem;
} }
.md\:p-1 { .md\:p-1 {
@ -2442,6 +2438,14 @@ li::marker {
padding: 0.75rem; padding: 0.75rem;
} }
.md\:pt-0 {
padding-top: 0px;
}
.md\:pb-0 {
padding-bottom: 0px;
}
.md\:pt-4 { .md\:pt-4 {
padding-top: 1rem; padding-top: 1rem;
} }
@ -2461,11 +2465,6 @@ li::marker {
line-height: 1.75rem; line-height: 1.75rem;
} }
.md\:shadow-none {
--tw-shadow: 0 0 #0000;
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.md\:w-160 { .md\:w-160 {
width: 40rem; width: 40rem;
} }

View file

@ -424,6 +424,7 @@ li::marker {
.leaflet-popup-content { .leaflet-popup-content {
width: 45em !important; width: 45em !important;
margin: 0.25rem !important;
} }
.leaflet-div-icon { .leaflet-div-icon {