add photo to profile page (not yet saved)
This commit is contained in:
@@ -20,11 +20,12 @@ export type Settings = {
|
|||||||
filterFeedByNearby?: boolean; // filter by nearby
|
filterFeedByNearby?: boolean; // filter by nearby
|
||||||
filterFeedByVisible?: boolean; // filter by visible users ie. anyone not hidden
|
filterFeedByVisible?: boolean; // filter by visible users ie. anyone not hidden
|
||||||
|
|
||||||
firstName?: string; // User's first name
|
firstName?: string; // user's full name
|
||||||
isRegistered?: boolean;
|
isRegistered?: boolean;
|
||||||
lastName?: string; // deprecated - put all names in firstName
|
lastName?: string; // deprecated - put all names in firstName
|
||||||
lastNotifiedClaimId?: string; // Last notified claim ID
|
lastNotifiedClaimId?: string;
|
||||||
lastViewedClaimId?: string; // Last viewed claim ID
|
lastViewedClaimId?: string;
|
||||||
|
profileImageUrl?: string;
|
||||||
reminderTime?: number; // Time in milliseconds since UNIX epoch for reminders
|
reminderTime?: number; // Time in milliseconds since UNIX epoch for reminders
|
||||||
reminderOn?: boolean; // Toggle to enable or disable reminders
|
reminderOn?: boolean; // Toggle to enable or disable reminders
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,30 @@
|
|||||||
<router-link :to="{ name: 'new-edit-account' }">
|
<router-link :to="{ name: 'new-edit-account' }">
|
||||||
<fa icon="pen" class="text-xs text-blue-500 mb-1"></fa>
|
<fa icon="pen" class="text-xs text-blue-500 mb-1"></fa>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
<div class="flex justify-center mt-4">
|
||||||
|
<span v-if="profileImageUrl" class="flex justify-between">
|
||||||
|
<a
|
||||||
|
:href="profileImageUrl"
|
||||||
|
target="_blank"
|
||||||
|
class="text-blue-500 ml-4"
|
||||||
|
>
|
||||||
|
<img :src="profileImageUrl" class="h-24 rounded-xl" />
|
||||||
|
</a>
|
||||||
|
<fa
|
||||||
|
icon="trash-can"
|
||||||
|
@click="confirmDeleteImage"
|
||||||
|
class="text-red-500 fa-fw ml-8 mt-10"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
<fa
|
||||||
|
icon="camera"
|
||||||
|
class="bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-2 rounded-md"
|
||||||
|
@click="openPhotoDialog"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<GiftedPhotoDialog ref="photoDialog" />
|
||||||
|
</div>
|
||||||
</h2>
|
</h2>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
<router-link
|
<router-link
|
||||||
@@ -537,6 +561,7 @@ import { ref } from "vue";
|
|||||||
import { Component, Vue } from "vue-facing-decorator";
|
import { Component, Vue } from "vue-facing-decorator";
|
||||||
import { useClipboard } from "@vueuse/core";
|
import { useClipboard } from "@vueuse/core";
|
||||||
|
|
||||||
|
import GiftedPhotoDialog from "@/components/GiftedPhotoDialog.vue";
|
||||||
import QuickNav from "@/components/QuickNav.vue";
|
import QuickNav from "@/components/QuickNav.vue";
|
||||||
import TopMessage from "@/components/TopMessage.vue";
|
import TopMessage from "@/components/TopMessage.vue";
|
||||||
import {
|
import {
|
||||||
@@ -566,7 +591,7 @@ interface IAccount {
|
|||||||
const inputFileNameRef = ref<Blob>();
|
const inputFileNameRef = ref<Blob>();
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: { QuickNav, TopMessage },
|
components: { GiftedPhotoDialog, QuickNav, TopMessage },
|
||||||
})
|
})
|
||||||
export default class AccountViewView extends Vue {
|
export default class AccountViewView extends Vue {
|
||||||
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
||||||
@@ -586,10 +611,12 @@ export default class AccountViewView extends Vue {
|
|||||||
isRegistered = false;
|
isRegistered = false;
|
||||||
isSubscribed = false;
|
isSubscribed = false;
|
||||||
notificationMaybeChanged = false;
|
notificationMaybeChanged = false;
|
||||||
|
profileImageUrl: string | null = null;
|
||||||
publicHex = "";
|
publicHex = "";
|
||||||
publicBase64 = "";
|
publicBase64 = "";
|
||||||
webPushServer = "";
|
webPushServer = "";
|
||||||
webPushServerInput = "";
|
webPushServerInput = "";
|
||||||
|
|
||||||
limitsMessage = "";
|
limitsMessage = "";
|
||||||
loadingLimits = false;
|
loadingLimits = false;
|
||||||
showContactGives = false;
|
showContactGives = false;
|
||||||
@@ -1260,5 +1287,87 @@ export default class AccountViewView extends Vue {
|
|||||||
-1,
|
-1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openPhotoDialog() {
|
||||||
|
(this.$refs.photoDialog as GiftedPhotoDialog).open((imgUrl) => {
|
||||||
|
this.profileImageUrl = imgUrl;
|
||||||
|
console.log("Got image URL:", imgUrl);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmDeleteImage() {
|
||||||
|
this.$notify(
|
||||||
|
{
|
||||||
|
group: "modal",
|
||||||
|
type: "confirm",
|
||||||
|
title: "Are you sure you want to delete your profile picture?",
|
||||||
|
text: "",
|
||||||
|
onYes: this.deleteImage,
|
||||||
|
},
|
||||||
|
-1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteImage() {
|
||||||
|
if (!this.profileImageUrl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const identity = await this.getIdentity(this.activeDid);
|
||||||
|
if (!identity) {
|
||||||
|
throw Error("No identity found.");
|
||||||
|
}
|
||||||
|
const token = await accessToken(identity);
|
||||||
|
const response = await this.axios.delete(
|
||||||
|
DEFAULT_IMAGE_API_SERVER +
|
||||||
|
"/image/" +
|
||||||
|
encodeURIComponent(this.profileImageUrl),
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (response.status === 204) {
|
||||||
|
// don't bother with a notification
|
||||||
|
// (either they'll simply continue or they're canceling and going back)
|
||||||
|
} else {
|
||||||
|
console.error("Non-success deleting image:", response);
|
||||||
|
this.$notify(
|
||||||
|
{
|
||||||
|
group: "alert",
|
||||||
|
type: "danger",
|
||||||
|
title: "Error",
|
||||||
|
text: "There was a problem deleting the image.",
|
||||||
|
},
|
||||||
|
5000,
|
||||||
|
);
|
||||||
|
// keep the imageUrl in localStorage so the user can try again if they want
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.profileImageUrl = "";
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error deleting image:", error);
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
if ((error as any).response.status === 404) {
|
||||||
|
console.log("The image was already deleted:", error);
|
||||||
|
|
||||||
|
this.profileImageUrl = "";
|
||||||
|
|
||||||
|
// it already doesn't exist so we won't say anything to the user
|
||||||
|
} else {
|
||||||
|
this.$notify(
|
||||||
|
{
|
||||||
|
group: "alert",
|
||||||
|
type: "danger",
|
||||||
|
title: "Error",
|
||||||
|
text: "There was an error deleting the image.",
|
||||||
|
},
|
||||||
|
5000,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user