<template> <QuickNav /> <!-- CONTENT --> <section id="Content" class="p-6 pb-24 max-w-3xl mx-auto"> <!-- Heading --> <h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-8"> Image </h1> <div v-if="imageBlob"> <div v-if="uploading" class="text-center mb-4"> <fa icon="spinner" class="fa-spin-pulse" /> </div> <div v-else> <div class="text-center mb-4">Choose how to use this image</div> <div class="grid grid-cols-1 sm:grid-cols-3 gap-4"> <button @click="recordGift" class="text-center text-md font-bold 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-3 rounded-md" > <fa icon="gift" class="fa-fw" /> Record a Gift </button> <button @click="recordProfile" class="text-center text-md font-bold 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-3 rounded-md" > <fa icon="circle-user" class="fa-fw" /> Save as Profile Image </button> <button @click="cancel" class="text-center text-md font-bold bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md" > <fa icon="ban" class="fa-fw" /> Cancel </button> </div> <PhotoDialog ref="photoDialog" /> </div> <div class="flex justify-center"> <img :src="URL.createObjectURL(imageBlob)" alt="Shared Image" class="rounded mt-4" /> </div> </div> <div v-else class="text-center mb-4"> <p>No image found.</p> </div> </section> </template> <script lang="ts"> import axios from "axios"; import { Component, Vue } from "vue-facing-decorator"; import PhotoDialog from "@/components/PhotoDialog.vue"; import QuickNav from "@/components/QuickNav.vue"; import { DEFAULT_IMAGE_API_SERVER, IMAGE_TYPE_PROFILE, NotificationIface, } from "@/constants/app"; import { db } from "@/db/index"; import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; import { getIdentity } from "@/libs/util"; import { accessToken } from "@/libs/crypto"; @Component({ components: { PhotoDialog, QuickNav } }) export default class SharedPhotoView extends Vue { $notify!: (notification: NotificationIface, timeout?: number) => void; activeDid: string | undefined = undefined; imageBlob: Blob | undefined = undefined; imageFileName: string | undefined = undefined; uploading = false; URL = window.URL || window.webkitURL; // 'created' hook runs when the Vue instance is first created async mounted() { try { await db.open(); const settings = await db.settings.get(MASTER_SETTINGS_KEY); this.activeDid = settings?.activeDid as string; const temp = await db.temp.get("shared-photo"); if (temp) { this.imageBlob = temp.blob; // clear the temp image db.temp.delete("shared-photo"); this.imageFileName = this.$route.query.fileName as string; } } catch (err: unknown) { console.error("Got an error loading an identifier:", err); this.$notify( { group: "alert", type: "danger", title: "Error", text: "Got an error loading this data.", }, -1, ); } } async recordGift() { await this.sendToImageServer("GiveAction").then((url) => { if (url) { this.$router.push({ name: "gifted-details", query: { destinationNameAfter: "home", hideBackButton: true, imageUrl: url, recipientDid: this.activeDid, }, }); } }); } recordProfile() { (this.$refs.photoDialog as PhotoDialog).open( async (imgUrl) => { db.settings.update(MASTER_SETTINGS_KEY, { profileImageUrl: imgUrl, }); this.$router.push({ name: "account" }); }, true, IMAGE_TYPE_PROFILE, this.imageBlob, this.imageFileName, ); } async cancel() { this.imageBlob = undefined; this.imageFileName = undefined; this.$router.push({ name: "home" }); } async sendToImageServer(imageType: string) { this.uploading = true; let result; try { // send the image to the server const identifier = await getIdentity(this.activeDid as string); const token = await accessToken(identifier); const headers = { Authorization: "Bearer " + token, }; const formData = new FormData(); formData.append( "image", this.imageBlob as Blob, this.imageFileName as string, ); formData.append("claimType", imageType); console.log( "Sending image to server", formData, headers, DEFAULT_IMAGE_API_SERVER + "/image", ); const response = await axios.post( DEFAULT_IMAGE_API_SERVER + "/image", formData, { headers }, ); if (response?.data?.url) { this.imageBlob = undefined; this.imageFileName = undefined; result = response.data.url as string; } else { console.error("Problem uploading the image", response.data); this.$notify( { group: "alert", type: "danger", title: "Error", text: "There was a problem saving the picture. " + (response?.data?.message || ""), }, 5000, ); } this.uploading = false; } catch (error) { console.error("Error uploading the image", error); this.$notify( { group: "alert", type: "danger", title: "Error", text: "There was an error saving the picture.", }, 5000, ); this.uploading = false; } return result; } } </script>