Skip to content

Commit

Permalink
implmenetation of a coordinate picker
Browse files Browse the repository at this point in the history
  • Loading branch information
CommanderStorm committed Jul 9, 2023
1 parent 13ab1d4 commit 2d5955a
Show file tree
Hide file tree
Showing 9 changed files with 317 additions and 18 deletions.
4 changes: 1 addition & 3 deletions webclient/src/components/DetailsInfoSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ const state = useDetailsStore();
</div>
<div class="card-body">
<DetailsPropertyTable />
<div class="toast toast-warning" v-if="state.data?.coords.accuracy === 'building'">
{{ $t("view_view.msg.inaccurate_only_building.primary_msg") }}<br />
</div>
<div id="maybe-coordinate-inacurate-warning-toast" />
<div
class="toast toast-warning"
v-if="state.data?.type === 'room' && state.data?.maps?.overlays?.default === null"
Expand Down
14 changes: 0 additions & 14 deletions webclient/src/components/DetailsInteractiveMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -296,20 +296,6 @@ function setOverlayImage(imgUrl: string | null, coords: Coordinates | undefined)
padding: 0 8px;
}
.toast.location-picker {
animation: fade-in 0.1s linear 0.05s;
animation-fill-mode: both;
& .btns {
margin: auto 0;
}
.toast {
// Mobile
margin-bottom: 9px;
font-size: 0.7rem;
}
}
/* --- Interactive map display --- */
#interactive-map-container {
margin-bottom: 10px;
Expand Down
121 changes: 121 additions & 0 deletions webclient/src/components/feedback/DetailsCoordinatePicker.vue
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>
41 changes: 41 additions & 0 deletions webclient/src/components/feedback/EditRequestModal.vue
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>
19 changes: 19 additions & 0 deletions webclient/src/locales/de.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ core_js:
feedback:
cancel: Abbrechen
category: Feedback-Kategorie
coordinatepicker:
helptext:
enter_serveral: Falls du mehrere Koordinaten gleichzeitig korrigieren willst, kannst du dieses Fenster schließen und weitere Koordinaten editieren.
saved_for_12h: Wir speichern deine Veränderungen für 12 Stunden bei dir lokal.
title: Koordinate auswählen
delete: Das zugehörige GitHub Issue löschen, sobald es gelöst wurde.
error:
feedback_not_configured: Das Senden von Feedback ist auf dem Server aktuell nicht konfiguriert.
Expand Down Expand Up @@ -55,6 +60,7 @@ feedback:
response_at: Antwort auf dein Feedback findest du auf
thank_you: Vielen Dank für dein Feedback! Wir werden es schnellstmöglich bearbeiten.
this_issue: diesem GitHub Issue
this_pull_request: diesem GitHub Pull Request
title: Vielen Dank!
title: Feedback senden
type:
Expand Down Expand Up @@ -173,7 +179,20 @@ view_view:
meta:
details_for: Details für
msg:
coordinate-counter:
delete: Löschen
delete-confirm: Wirklich löschen?
info: Änderungen werden lokal \n für 12h gespeichert
msg-1: Aktuell
msg-2: ausstehende Koordinatenänderung|ausstehende Koordinatenänderungen
send: Senden
correct_location:
btn-cancel: Abbrechen
btn-done: Fertig
msg: Um die richtige Position zu setzen, ziehe den roten Marker über die Karte.
inaccurate_only_building:
btn: Koordinate eintragen
help_others_and: Falls du sie herausfindest, kannst du die
primary_msg: Die angezeigte Position zeigt nur die Position des Gebäude(teils). Die genaue Lage innerhalb des Gebäudes ist uns nicht bekannt.
no_floor_overlay: Für den angezeigten Raum gibt es leider keine Indoor Karte.
roomfinder_modal:
Expand Down
6 changes: 6 additions & 0 deletions webclient/src/locales/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ core_js:
feedback:
cancel: Cancel
category: Feedback category
coordinatepicker:
helptext:
enter_serveral: If you want to correct several coordinates at the same time, you can close this window and edit more coordinates.
saved_for_12h: We will save your changes locally for 12 hours.
title: Select coordinate
delete: Delete this GitHub issue when resolved.
error:
feedback_not_configured: Sending feedback is currently not configured on the server.
Expand Down Expand Up @@ -55,6 +60,7 @@ feedback:
response_at: You can see our response at
thank_you: Thank you for giving your feedback. We will work on this as soon as possible.
this_issue: this GitHub issue
this_pull_request: this GitHub pull request
title: Thank you!
title: Send Feedback
type:
Expand Down
Loading

0 comments on commit 2d5955a

Please sign in to comment.