|
|
@ -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> |
|
|
|