Browse Source

add map and location for user profile

master
Trent Larson 1 month ago
parent
commit
8eb8b746d7
  1. 105
      src/views/AccountViewView.vue

105
src/views/AccountViewView.vue

@ -278,12 +278,54 @@
/>
</div>
<textarea
v-model="userProfile"
v-model="userProfileDesc"
class="w-full h-32 p-2 border border-slate-300 rounded-md"
placeholder="Write something about yourself for the public..."
:readonly="loadingProfile || savingProfile"
:class="{ 'bg-slate-100': loadingProfile || savingProfile }"
></textarea>
<div
class="flex items-center mb-4"
@click="toggleUserProfileLocation"
>
<input
type="checkbox"
class="mr-2"
v-model="includeUserProfileLocation"
/>
<label for="includeUserProfileLocation">Include Location</label>
</div>
<div v-if="includeUserProfileLocation" class="mb-4 aspect-video">
<p class="text-sm mb-2 text-slate-500">
For your security, choose a location nearby but not exactly at your
place.
</p>
<l-map
ref="map"
v-model:zoom="zoom"
:center="[userProfileLatitude, userProfileLongitude]"
class="!z-40 rounded-md"
@click="
(event: LeafletMouseEvent) => {
userProfileLatitude = event.latlng.lat;
userProfileLongitude = event.latlng.lng;
}
"
>
<l-tile-layer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
layer-type="base"
name="OpenStreetMap"
/>
<l-marker
v-if="userProfileLatitude && userProfileLongitude"
:lat-lng="[userProfileLatitude, userProfileLongitude]"
@click="confirmEraseLatLong()"
/>
</l-map>
</div>
<button
@click="saveProfile"
class="mt-2 px-4 py-2 bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white rounded-md"
@ -830,17 +872,21 @@
</template>
<script lang="ts">
import "leaflet/dist/leaflet.css";
import { AxiosError } from "axios";
import { Buffer } from "buffer/";
import Dexie from "dexie";
import "dexie-export-import";
import { ImportProgress } from "dexie-export-import/dist/import";
import { LeafletMouseEvent } from "leaflet";
import * as R from "ramda";
import { IIdentifier } from "@veramo/core";
import { ref } from "vue";
import { Component, Vue } from "vue-facing-decorator";
import { Router } from "vue-router";
import { useClipboard } from "@vueuse/core";
import { LMap, LMarker, LTileLayer } from "@vue-leaflet/vue-leaflet";
import EntityIcon from "@/components/EntityIcon.vue";
import ImageMethodDialog from "@/components/ImageMethodDialog.vue";
@ -891,6 +937,10 @@ const inputImportFileNameRef = ref<Blob>();
components: {
EntityIcon,
ImageMethodDialog,
LeafletMouseEvent,
LMap,
LMarker,
LTileLayer,
PushNotificationPermission,
QuickNav,
TopMessage,
@ -915,6 +965,7 @@ export default class AccountViewView extends Vue {
hideRegisterPromptOnNewContact = false;
imageLimits: ImageRateLimits | null = null;
imageServer = "";
includeUserProfileLocation = false;
isRegistered = false;
limitsMessage = "";
loadingLimits = false;
@ -948,7 +999,10 @@ export default class AccountViewView extends Vue {
warnIfTestServer = false;
webPushServer = "";
webPushServerInput = "";
userProfile = "";
userProfileDesc = "";
userProfileLatitude = 0;
userProfileLongitude = 0;
zoom = 2;
/**
* Async function executed when the component is mounted.
@ -971,7 +1025,12 @@ export default class AccountViewView extends Vue {
{ headers },
);
if (response.status === 200) {
this.userProfile = response.data.description || "";
this.userProfileDesc = response.data.description || "";
this.userProfileLatitude = response.data.locLat || 0;
this.userProfileLongitude = response.data.locLon || 0;
if (this.userProfileLatitude && this.userProfileLongitude) {
this.includeUserProfileLocation = true;
}
} else {
// won't get here because axios throws an error instead
throw Error("Unable to load profile.");
@ -1734,11 +1793,16 @@ export default class AccountViewView extends Vue {
this.savingProfile = true;
try {
const headers = await getHeaders(this.activeDid);
const payload = {
description: this.userProfileDesc,
};
if (this.userProfileLatitude && this.userProfileLongitude) {
payload.locLat = this.userProfileLatitude;
payload.locLon = this.userProfileLongitude;
}
const response = await this.axios.post(
this.apiServer + "/api/partner/user-profile",
{
description: this.userProfile,
},
payload,
{ headers },
);
if (response.status === 201) {
@ -1775,5 +1839,34 @@ export default class AccountViewView extends Vue {
this.savingProfile = false;
}
}
toggleUserProfileLocation() {
this.includeUserProfileLocation = !this.includeUserProfileLocation;
if (!this.includeUserProfileLocation) {
this.userProfileLatitude = 0;
this.userProfileLongitude = 0;
}
}
confirmEraseLatLong() {
this.$notify(
{
group: "modal",
type: "confirm",
title: "Erase Marker",
text: "Are you sure you don't want to mark a location? This will erase the current location.",
onYes: async () => {
this.eraseLatLong();
},
},
-1,
);
}
eraseLatLong() {
this.userProfileLatitude = 0;
this.userProfileLongitude = 0;
this.includeUserProfileLocation = false;
}
}
</script>

Loading…
Cancel
Save