-
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implmenetation of a coordinate picker
- Loading branch information
1 parent
058d5f6
commit ef94f29
Showing
9 changed files
with
317 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
webclient/src/components/feedback/DetailsCoordinatePicker.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
<script setup lang="ts"> | ||
import { selectedMap, useDetailsStore } from "@/stores/details"; | ||
import { Coord, useGlobalStore } from "@/stores/global"; | ||
import { ref } from "vue"; | ||
import { getLocalStorageWithExpiry, setLocalStorageWithExpiry } from "@/composables/storage"; | ||
const state = useDetailsStore(); | ||
const global = useGlobalStore(); | ||
// The coordinate picker keeps backups of the subject and body | ||
// in case someone writes a text and then after that clicks | ||
// the set coordinate button in the feedback form. | ||
// If we no backup has been made then, this would be lost after clicking confirm there. | ||
const coord_picker = ref({ | ||
backup_id: null as string | null, | ||
subject_backup: null as string | null, | ||
body_backup: null as string | null, | ||
force_reopen: false, | ||
}); | ||
const emit = defineEmits<{ | ||
(e: "openFeedbackForm", callback: EventListener): void; | ||
}>(); | ||
function addLocationPicker() { | ||
// If this is called from the feedback form using the edit coordinate | ||
// button, we temporarily save the current subject and body, so it is | ||
// not lost when being reopened | ||
if (global.feedback.open) { | ||
coord_picker.value.backup_id = state.data?.id || "undefined"; | ||
coord_picker.value.subject_backup = global.feedback.subject; | ||
coord_picker.value.body_backup = global.feedback.body; | ||
coord_picker.value.force_reopen = true; // reopen after confirm | ||
global.temporarilyCloseFeedback(); | ||
} | ||
state.map.selected = selectedMap.interactive; | ||
// Verify that there isn't already a marker (could happen if you click 'assign | ||
// a location' multiple times from the 'missing accurate location' toast) | ||
if (marker2.value === null) { | ||
// Coordinates are either taken from the entry, or if there are already | ||
// some in the localStorage use them | ||
const currentEdits = getLocalStorageWithExpiry<{ [index: string]: Coord }>("feedback-coords", {}); | ||
const { coords } = currentEdits[state.data?.id || "undefined"] || state.data; | ||
marker2.value = new Marker({ | ||
draggable: true, | ||
color: "#ff0000", | ||
}); | ||
if (coords.lat !== undefined && coords.lon !== undefined) | ||
marker2.value.setLngLat([coords.lon, coords.lat]).addTo(map.value as Map); | ||
} | ||
} | ||
function confirmLocationPicker() { | ||
// add the current edits to the feedback | ||
const currentEdits = getLocalStorageWithExpiry<{ [index: string]: Coord }>("feedback-coords", {}); | ||
const location = marker2.value?.getLngLat(); | ||
currentEdits[state.data?.id || "undefined"] = { | ||
coords: { lat: location?.lat, lon: location?.lng }, | ||
}; | ||
// save to local storage with ttl of 12h (garbage-collected on next read) | ||
setLocalStorageWithExpiry("feedback-coords", currentEdits, 12); | ||
marker2.value?.remove(); | ||
marker2.value = null; | ||
// A feedback form is only opened when this is the only (and therefore | ||
// first coordinate). If there are more coordinates we can assume | ||
// someone is doing batch edits. They can then use the send button in | ||
// the coordinate counter at the top of the page. | ||
if (Object.keys(currentEdits).length === 1 || state.coord_picker.force_reopen) { | ||
state.coord_picker.force_reopen = false; | ||
emit("openFeedbackForm", () => addLocationPicker()); | ||
} | ||
// The helptext (which says thet you can edit multiple coordinates in bulk) | ||
// is also only shown if there is one edit. | ||
if (Object.keys(currentEdits).length === 1) { | ||
document.getElementById("feedback-coordinate-picker-helptext")?.classList.remove("d-none"); | ||
} | ||
} | ||
function cancelLocationPicker() { | ||
marker2.value?.remove(); | ||
marker2.value = null; | ||
if (state.coord_picker.force_reopen) { | ||
state.coord_picker.force_reopen = false; | ||
emit("openFeedbackForm", () => addLocationPicker()); | ||
} | ||
} | ||
</script> | ||
<template> | ||
<Teleport to="maybe-coordinate-inacurate-warning-toast"> | ||
<div class="toast toast-warning" v-if="state.data?.coords.accuracy === 'building'"> | ||
{{ $t("view_view.msg.inaccurate_only_building.primary_msg") }}<br /> | ||
<i> | ||
{{ $t("view_view.msg.inaccurate_only_building.help_others_and") }} | ||
<button class="btn btn-sm" @click="addLocationPicker"> | ||
{{ $t("view_view.msg.inaccurate_only_building.btn") }} | ||
</button> | ||
</i> | ||
</div> | ||
</Teleport> | ||
|
||
<div class="toast toast-primary location-picker mb-2" v-if="marker2"> | ||
<div class="columns"> | ||
<div class="column col col-sm-12"> | ||
{{ $t("view_view.msg.correct_location.msg") }} | ||
</div> | ||
<div class="column col-auto col-sm-12 btns"> | ||
<button class="btn btn-sm" @click="cancelLocationPicker"> | ||
{{ $t("view_view.msg.correct_location.btn-cancel") }} | ||
</button> | ||
<button class="btn btn-sm" @click="confirmLocationPicker"> | ||
<i class="icon icon-check" /> | ||
{{ $t("view_view.msg.correct_location.btn-done") }} | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</template> | ||
<style lang="scss"></style> |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<script setup lang="ts"> | ||
import BasicFeedbackModal from "@/components/feedback/TokenBasedModal.vue"; | ||
import { useGlobalStore } from "@/stores/global"; | ||
const global = useGlobalStore(); | ||
</script> | ||
|
||
<template> | ||
<BasicFeedbackModal :data="global.propose_edits.data"> | ||
<template v-slot:modal> | ||
<div class="form-group"> | ||
<label class="form-label" for="additional_context">{{ $t("feedback.message") }}</label> | ||
<textarea | ||
class="form-input" | ||
id="additional_context" | ||
:placeholder="$t('feedback.message')" | ||
v-model="global.propose_edits.data.additional_context" | ||
rows="6" | ||
/> | ||
</div> | ||
<h2>{{ $t("feedback.coordinates") }}</h2> | ||
coordinates can be previewed here | ||
</template> | ||
<template v-slot:success="{ successUrl }"> | ||
<p>{{ $t("feedback.success.thank_you") }}</p> | ||
<p> | ||
{{ $t("feedback.success.response_at") }} | ||
<a id="feedback-success-url" class="btn-link" :href="successUrl">{{ $t("feedback.success.this_pull_request") }}</a> | ||
</p> | ||
</template> | ||
</BasicFeedbackModal> | ||
</template> | ||
|
||
<style lang="scss" scoped> | ||
@import "@/assets/variables"; | ||
.modal { | ||
#additional_context { | ||
min-width: 100%; | ||
} | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.