Browse Source

allow viewing and deletion of an image

photo-upload
Trent Larson 7 months ago
parent
commit
c58f012d2c
  1. 2
      project.task.yaml
  2. 31
      src/App.vue
  3. 1
      src/constants/app.ts
  4. 67
      src/views/GiftedDetails.vue
  5. 10
      src/views/GiftedPhoto.vue

2
project.task.yaml

@ -22,6 +22,8 @@ tasks :
- put the image URL in the claim - put the image URL in the claim
- Rates - images erased? - Rates - images erased?
- image not associated with JWT ULID since that's assigned later - image not associated with JWT ULID since that's assigned later
- remove previous image
- send image type (eg. portrait, give, project)
- ask to detect location & record it in settings - ask to detect location & record it in settings
- if personal location is set, show potential local affiliations - if personal location is set, show potential local affiliations

31
src/App.vue

@ -148,6 +148,37 @@
class="w-full" class="w-full"
role="alert" role="alert"
> >
<div
v-if="notification.type === 'confirm'"
class="absolute inset-0 h-screen flex flex-col items-center justify-center bg-slate-900/50"
>
<div
class="flex w-11/12 max-w-sm mx-auto mb-3 overflow-hidden bg-white rounded-lg shadow-lg"
>
<div class="w-full px-6 py-6 text-slate-900 text-center">
<p class="text-lg mb-4">
{{ notification.title }}
</p>
<button
@click="
notification.onYes();
close(notification.id);
"
class="block w-full text-center text-md font-bold uppercase bg-blue-600 text-white px-2 py-2 rounded-md mb-2"
>
Yes
</button>
<button
@click="close(notification.id)"
class="block w-full text-center text-md font-bold uppercase bg-slate-600 text-white px-2 py-2 rounded-md"
>
Cancel
</button>
</div>
</div>
</div>
<div <div
v-if="notification.type === 'notification-permission'" v-if="notification.type === 'notification-permission'"
class="absolute inset-0 h-screen flex flex-col items-center justify-center bg-slate-900/50" class="absolute inset-0 h-screen flex flex-col items-center justify-center bg-slate-900/50"

1
src/constants/app.ts

@ -39,4 +39,5 @@ export interface NotificationIface {
type: string; // "toast" | "info" | "success" | "warning" | "danger" type: string; // "toast" | "info" | "success" | "warning" | "danger"
title: string; title: string;
text: string; text: string;
onYes?: () => Promise<void>;
} }

67
src/views/GiftedDetails.vue

@ -52,12 +52,23 @@
</div> </div>
<div class="flex justify-center mb-4 mt-4"> <div class="flex justify-center mb-4 mt-4">
<span v-if="imageUrl">
Includes Image:
<a :href="imageUrl" target="_blank" class="text-blue-500 ml-4">View</a>
<fa
icon="trash-can"
@click="confirmDeleteImage"
class="text-red-500 fa-fw ml-8"
/>
</span>
<span v-else>
<router-link <router-link
:to="{ name: 'gifted-photo' }" :to="{ name: 'gifted-photo' }"
class="bg-blue-500 text-white px-1.5 py-1 rounded-md" class="bg-blue-500 text-white px-1.5 py-1 rounded-md"
> >
<fa icon="camera" class="fa-fw" /> <fa icon="camera" class="fa-fw" />
</router-link> </router-link>
</span>
</div> </div>
<div class="mt-4"> <div class="mt-4">
<input type="checkbox" class="h-6 w-6 mr-2" v-model="givenToUser" /> <input type="checkbox" class="h-6 w-6 mr-2" v-model="givenToUser" />
@ -88,13 +99,14 @@
<script lang="ts"> <script lang="ts">
import { Component, Vue } from "vue-facing-decorator"; import { Component, Vue } from "vue-facing-decorator";
import { NotificationIface } from "@/constants/app"; import { DEFAULT_IMAGE_API_SERVER, NotificationIface } from "@/constants/app";
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 { db } from "@/db/index"; import { db } from "@/db/index";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings"; import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import { createAndSubmitGive } from "@/libs/endorserServer"; import { createAndSubmitGive } from "@/libs/endorserServer";
import * as libsUtil from "@/libs/util"; import * as libsUtil from "@/libs/util";
import { accessToken } from "@/libs/crypto";
@Component({ @Component({
components: { components: {
@ -113,6 +125,7 @@ export default class GiftedDetails extends Vue {
givenToUser = false; givenToUser = false;
giverDid: string | undefined; giverDid: string | undefined;
giverName = ""; giverName = "";
imageUrl = "";
isTrade = false; isTrade = false;
message = ""; message = "";
offerId = ""; offerId = "";
@ -126,6 +139,7 @@ export default class GiftedDetails extends Vue {
this.description = this.$route.query.description as string; this.description = this.$route.query.description as string;
this.giverDid = this.$route.query.giverDid as string; this.giverDid = this.$route.query.giverDid as string;
this.giverName = this.$route.query.giverName as string; this.giverName = this.$route.query.giverName as string;
this.imageUrl = localStorage.getItem("imageUrl") || "";
this.message = this.$route.query.message as string; this.message = this.$route.query.message as string;
this.offerId = this.$route.query.offerId as string; this.offerId = this.$route.query.offerId as string;
this.projectId = this.$route.query.projectId as string; this.projectId = this.$route.query.projectId as string;
@ -173,6 +187,57 @@ export default class GiftedDetails extends Vue {
this.$router.back(); this.$router.back();
} }
confirmDeleteImage() {
this.$notify(
{
group: "modal",
type: "confirm",
title: "Are you sure you want to delete the image?",
text: "",
onYes: this.deleteImage,
},
-1,
);
}
async deleteImage() {
const identity = await libsUtil.getIdentity(this.activeDid);
const token = await accessToken(identity);
const response = await this.axios.delete(
DEFAULT_IMAGE_API_SERVER + "/image/" + encodeURIComponent(this.imageUrl),
{
headers: {
Authorization: `Bearer ${token}`,
},
},
);
if (response.status === 204) {
this.$notify(
{
group: "alert",
type: "success",
title: "Deleted",
text: "That image record was deleted.",
},
5000,
);
} else {
console.error("Error deleting image:", response);
this.$notify(
{
group: "alert",
type: "danger",
title: "Error",
text: "There was an error deleting the image.",
},
5000,
);
return;
}
localStorage.removeItem("imageUrl");
this.imageUrl = "";
}
async confirm() { async confirm() {
this.$notify( this.$notify(
{ {

10
src/views/GiftedPhoto.vue

@ -46,12 +46,7 @@
Camera "resolution" doesn't change how it shows on screen but rather stretches the result, eg the following which just stretches it vertically: Camera "resolution" doesn't change how it shows on screen but rather stretches the result, eg the following which just stretches it vertically:
:resolution="{ width: 375, height: 812 }" :resolution="{ width: 375, height: 812 }"
--> -->
<camera <camera facingMode="environment" autoplay ref="camera">
facingMode="environment"
autoplay
ref="camera"
class="relative h-full"
>
<div class="absolute bottom-0 w-full flex justify-center pb-4"> <div class="absolute bottom-0 w-full flex justify-center pb-4">
<!-- Button --> <!-- Button -->
<button <button
@ -157,6 +152,7 @@ export default class GiftedPhoto extends Vue {
formData, formData,
{ headers }, { headers },
); );
this.uploading = false;
this.$notify( this.$notify(
{ {
@ -167,7 +163,7 @@ export default class GiftedPhoto extends Vue {
}, },
3000, 3000,
); );
console.log("Sent. Response:", response.data); localStorage.setItem("imageUrl", response.data.url as string);
this.$router.back(); this.$router.back();
} catch (error) { } catch (error) {
console.error("Error uploading the image", error); console.error("Error uploading the image", error);

Loading…
Cancel
Save