UX: add location picker to new not input element, fix #1665

This commit is contained in:
Pieter Vander Vennet 2023-10-15 10:55:56 +02:00
parent 5f918b607b
commit a0d450407f
5 changed files with 103 additions and 59 deletions

View file

@ -1100,14 +1100,22 @@ video {
height: 12rem; height: 12rem;
} }
.h-40 { .h-56 {
height: 10rem; height: 14rem;
}
.h-20 {
height: 5rem;
} }
.h-10 { .h-10 {
height: 2.5rem; height: 2.5rem;
} }
.h-40 {
height: 10rem;
}
.h-80 { .h-80 {
height: 20rem; height: 20rem;
} }
@ -1124,14 +1132,14 @@ video {
max-height: 3rem; max-height: 3rem;
} }
.max-h-7 {
max-height: 1.75rem;
}
.max-h-24 { .max-h-24 {
max-height: 6rem; max-height: 6rem;
} }
.max-h-7 {
max-height: 1.75rem;
}
.max-h-screen { .max-h-screen {
max-height: 100vh; max-height: 100vh;
} }
@ -1753,6 +1761,10 @@ video {
padding-right: 0.25rem; padding-right: 0.25rem;
} }
.pb-10 {
padding-bottom: 2.5rem;
}
.pb-2 { .pb-2 {
padding-bottom: 0.5rem; padding-bottom: 0.5rem;
} }

View file

@ -29,16 +29,25 @@
* The start coordinate * The start coordinate
*/ */
export let coordinate: { lon: number; lat: number } export let coordinate: { lon: number; lat: number }
export let snapToLayers: string[] | undefined
export let targetLayer: LayerConfig
export let maxSnapDistance: number = undefined
export let snappedTo: UIEventSource<string | undefined>
/**
* The center of the map at all times
* If undefined at the beginning, 'coordinate' will be used
*/
export let value: UIEventSource<{ lon: number; lat: number }> export let value: UIEventSource<{ lon: number; lat: number }>
if (value.data === undefined) { if (value.data === undefined) {
value.setData(coordinate) value.setData(coordinate)
} }
if(coordinate === undefined){
coordinate = value.data
}
export let snapToLayers: string[] | undefined
export let targetLayer: LayerConfig | undefined
export let maxSnapDistance: number = undefined
export let snappedTo: UIEventSource<string | undefined>
let preciseLocation: UIEventSource<{ lon: number; lat: number }> = new UIEventSource<{ let preciseLocation: UIEventSource<{ lon: number; lat: number }> = new UIEventSource<{
lon: number lon: number
@ -66,12 +75,14 @@
rasterLayer: UIEventSource.feedFrom(state.mapProperties.rasterLayer), rasterLayer: UIEventSource.feedFrom(state.mapProperties.rasterLayer),
} }
const featuresForLayer = state.perLayer.get(targetLayer.id) if(targetLayer){
if (featuresForLayer) { const featuresForLayer = state.perLayer.get(targetLayer.id)
new ShowDataLayer(map, { if (featuresForLayer) {
layer: targetLayer, new ShowDataLayer(map, {
features: featuresForLayer, layer: targetLayer,
}) features: featuresForLayer,
})
}
} }
if (snapToLayers?.length > 0) { if (snapToLayers?.length > 0) {
@ -114,4 +125,8 @@
value={preciseLocation} value={preciseLocation}
initialCoordinate={coordinate} initialCoordinate={coordinate}
maxDistanceInMeters="50" maxDistanceInMeters="50"
/> >
<slot name="image" slot="image">
<img class="h-full max-h-24" src="./assets/svg/move-arrows.svg" />
</slot>
</LocationInput>

View file

@ -89,7 +89,9 @@
<div <div
class="pointer-events-none absolute top-0 left-0 flex h-full w-full items-center p-8 opacity-50" class="pointer-events-none absolute top-0 left-0 flex h-full w-full items-center p-8 opacity-50"
> >
<img class="h-full max-h-24" src="./assets/svg/move-arrows.svg" /> <slot name="image">
<img class="h-full max-h-24" src="./assets/svg/move-arrows.svg" />
</slot>
</div> </div>
<DragInvitation hideSignal={mla.location} /> <DragInvitation hideSignal={mla.location} />

View file

@ -2,47 +2,50 @@
/** /**
* UIcomponent to create a new note at the given location * UIcomponent to create a new note at the given location
*/ */
import type { SpecialVisualizationState } from "../SpecialVisualization" import type { SpecialVisualizationState } from "../SpecialVisualization";
import { UIEventSource } from "../../Logic/UIEventSource" import { UIEventSource } from "../../Logic/UIEventSource";
import { LocalStorageSource } from "../../Logic/Web/LocalStorageSource" import { LocalStorageSource } from "../../Logic/Web/LocalStorageSource";
import ValidatedInput from "../InputElement/ValidatedInput.svelte" import ValidatedInput from "../InputElement/ValidatedInput.svelte";
import SubtleButton from "../Base/SubtleButton.svelte" import SubtleButton from "../Base/SubtleButton.svelte";
import Tr from "../Base/Tr.svelte" import Tr from "../Base/Tr.svelte";
import Translations from "../i18n/Translations.js" import Translations from "../i18n/Translations.js";
import type { Feature, Point } from "geojson" import type { Feature, Point } from "geojson";
import LoginToggle from "../Base/LoginToggle.svelte" import LoginToggle from "../Base/LoginToggle.svelte";
import FilteredLayer from "../../Models/FilteredLayer" import FilteredLayer from "../../Models/FilteredLayer";
import NewPointLocationInput from "../BigComponents/NewPointLocationInput.svelte";
import ToSvelte from "../Base/ToSvelte.svelte";
import Svg from "../../Svg";
export let coordinate: { lon: number; lat: number } export let coordinate: UIEventSource<{ lon: number; lat: number }>;
export let state: SpecialVisualizationState export let state: SpecialVisualizationState;
let comment: UIEventSource<string> = LocalStorageSource.Get("note-text") let comment: UIEventSource<string> = LocalStorageSource.Get("note-text");
let created = false let created = false;
let notelayer: FilteredLayer = state.layerState.filteredLayers.get("note") let notelayer: FilteredLayer = state.layerState.filteredLayers.get("note");
let hasFilter = notelayer?.hasFilter let hasFilter = notelayer?.hasFilter;
let isDisplayed = notelayer?.isDisplayed let isDisplayed = notelayer?.isDisplayed;
function enableNoteLayer() { function enableNoteLayer() {
state.guistate.closeAll() state.guistate.closeAll();
isDisplayed.setData(true) isDisplayed.setData(true);
} }
async function uploadNote() { async function uploadNote() {
let txt = comment.data let txt = comment.data;
if (txt === undefined || txt === "") { if (txt === undefined || txt === "") {
return return;
} }
const loc = coordinate const loc = coordinate.data;
txt += "\n\n #MapComplete #" + state?.layout?.id txt += "\n\n #MapComplete #" + state?.layout?.id;
const id = await state?.osmConnection?.openNote(loc.lat, loc.lon, txt) const id = await state?.osmConnection?.openNote(loc.lat, loc.lon, txt);
console.log("Created a note, got id", id) console.log("Created a note, got id", id);
const feature = <Feature<Point>>{ const feature = <Feature<Point>>{
type: "Feature", type: "Feature",
geometry: { geometry: {
type: "Point", type: "Point",
coordinates: [loc.lon, loc.lat], coordinates: [loc.lon, loc.lat]
}, },
properties: { properties: {
id: "" + id.id, id: "" + id.id,
@ -53,22 +56,22 @@
text: txt, text: txt,
html: txt, html: txt,
user: state.osmConnection?.userDetails?.data?.name, user: state.osmConnection?.userDetails?.data?.name,
uid: state.osmConnection?.userDetails?.data?.uid, uid: state.osmConnection?.userDetails?.data?.uid
}, }
]), ])
}, }
} };
// Normally, the 'Changes' will generate the new element. The 'notes' are an exception to this // Normally, the 'Changes' will generate the new element. The 'notes' are an exception to this
state.newFeatures.features.data.push(feature) state.newFeatures.features.data.push(feature);
state.newFeatures.features.ping() state.newFeatures.features.ping();
state.selectedElement?.setData(feature) state.selectedElement?.setData(feature);
if (state.featureProperties.trackFeature) { if (state.featureProperties.trackFeature) {
state.featureProperties.trackFeature(feature) state.featureProperties.trackFeature(feature);
} }
comment.setData("") comment.setData("");
created = true created = true;
state.selectedElement.setData(feature) state.selectedElement.setData(feature);
state.selectedLayer.setData(state.layerState.filteredLayers.get("note")) state.selectedLayer.setData(state.layerState.filteredLayers.get("note"));
} }
</script> </script>
@ -106,6 +109,15 @@
<ValidatedInput type="text" value={comment} /> <ValidatedInput type="text" value={comment} />
</div> </div>
<div class="w-full h-56">
<NewPointLocationInput value={coordinate} {state} >
<div class="h-20 w-full pb-10" slot="image">
<ToSvelte construct={Svg.note_svg().SetClass("h-10 w-full")}/>
</div>
</NewPointLocationInput>
</div>
<LoginToggle {state}> <LoginToggle {state}>
<span slot="loading"><!--empty: don't show a loading message--></span> <span slot="loading"><!--empty: don't show a loading message--></span>
<div slot="not-logged-in" class="alert"> <div slot="not-logged-in" class="alert">

View file

@ -563,7 +563,10 @@ export default class SpecialVisualizations {
feature: Feature feature: Feature
): BaseUIElement { ): BaseUIElement {
const [lon, lat] = GeoOperations.centerpointCoordinates(feature) const [lon, lat] = GeoOperations.centerpointCoordinates(feature)
return new SvelteUIElement(CreateNewNote, { state, coordinate: { lon, lat } }) return new SvelteUIElement(CreateNewNote, {
state,
coordinate: new UIEventSource({ lon, lat }),
})
}, },
}, },
new CloseNoteButton(), new CloseNoteButton(),