Browse Source

make the photo show in a pop-up dialog

kb/add-usage-guide
Trent Larson 8 months ago
parent
commit
251986d2bc
  1. 1
      .env.development
  2. 10
      project.task.yaml
  3. 2
      src/components/GiftedDialog.vue
  4. 121
      src/components/GiftedPhotoDialog.vue
  5. 6
      src/router/index.ts
  6. 35
      src/views/GiftedDetails.vue

1
.env.development

@ -2,4 +2,5 @@
# this won't resolve as a URL on production; it's a URN only found in the test system
VUE_APP_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HNTZYJJXTGT0EZS3VEJGX7AK
VUE_APP_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000
VUE_APP_DEFAULT_IMAGE_API_SERVER=http://localhost:3001

10
project.task.yaml

@ -14,12 +14,10 @@ tasks :
- .2 list the "show more" contacts alphabetically
- 32 image on give :
- send image type (eg. portrait, give, project)
- upload to a public readable place at correct hosting location
- remove previous image when editing
- on gift details, if project then show, otherwise mark "gift for you"
- ping endpoint
- limits endpoint
- ping endpoint
- limits endpoint
- upload a photo from elsewhere
- go-live - create cert for new image domain, set up haproxy redirect
- 08 image on profile

2
src/components/GiftedDialog.vue

@ -25,7 +25,7 @@
</div>
<input
type="number"
class="border border-r-0 border-slate-400 px-2 py-2 text-center"
class="border border-r-0 border-slate-400 px-2 py-2 text-center w-20"
v-model="amountInput"
/>
<div

121
src/views/GiftedPhoto.vue → src/components/GiftedPhotoDialog.vue

@ -1,15 +1,14 @@
<template>
<!-- CONTENT -->
<section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
<div v-if="visible" class="dialog-overlay">
<!-- Breadcrumb -->
<div class="mb-8">
<div class="dialog">
<!-- Back -->
<div class="text-lg text-center font-light relative px-7">
<h1
class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
@click="$router.back()"
class="text-lg text-center px-2 py-1 absolute -right-2 -top-1"
@click="close()"
>
<fa icon="chevron-left" class="fa-fw"></fa>
<fa icon="xmark" class="fa-fw"></fa>
</h1>
</div>
@ -19,46 +18,46 @@
<span v-else-if="blob"> Look Good? </span>
<span v-else> Say "Cheese"! </span>
</h1>
</div>
<div v-if="uploading" class="flex justify-center">
<fa icon="spinner" class="fa-spin fa-3x text-center block" />
</div>
<div v-else-if="blob">
<div class="flex justify-around">
<button
@click="uploadImage"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-2 rounded-full"
>
<span>Upload</span>
</button>
<button
@click="retryImage"
class="bg-slate-500 hover:bg-slate-700 text-white font-bold py-2 px-2 rounded-full"
>
<span>Retry</span>
</button>
<div v-if="uploading" class="flex justify-center">
<fa icon="spinner" class="fa-spin fa-3x text-center block" />
</div>
<img :src="URL.createObjectURL(blob)" class="mt-2 w-full" />
</div>
<div v-else>
<!--
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 }"
-->
<camera facingMode="environment" autoplay ref="camera">
<div class="absolute bottom-0 w-full flex justify-center pb-4">
<!-- Button -->
<div v-else-if="blob">
<div class="flex justify-around">
<button
@click="takeImage"
@click="uploadImage"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-2 rounded-full"
>
<fa icon="camera" class="fa-fw"></fa>
<span>Upload</span>
</button>
<button
@click="retryImage"
class="bg-slate-500 hover:bg-slate-700 text-white font-bold py-2 px-2 rounded-full"
>
<span>Retry</span>
</button>
</div>
</camera>
<img :src="URL.createObjectURL(blob)" class="mt-2 w-full" />
</div>
<div v-else>
<!--
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 }"
-->
<camera facingMode="environment" autoplay ref="camera">
<div class="absolute bottom-0 w-full flex justify-center pb-4">
<!-- Button -->
<button
@click="takeImage"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-2 rounded-full"
>
<fa icon="camera" class="fa-fw"></fa>
</button>
</div>
</camera>
</div>
</div>
</section>
</div>
</template>
<script lang="ts">
@ -73,12 +72,14 @@ import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import { accessToken } from "@/libs/crypto";
@Component({ components: { Camera } })
export default class GiftedPhoto extends Vue {
export default class GiftedPhotoDialog extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
activeDid = "";
blob: Blob | null = null;
setImage: (arg: string) => void = () => {};
uploading = false;
visible = false;
URL = window.URL || window.webkitURL;
@ -102,6 +103,16 @@ export default class GiftedPhoto extends Vue {
}
}
open(setImageFn: (arg: string) => void) {
this.visible = true;
this.setImage = setImageFn;
}
close() {
this.visible = false;
this.blob = null;
}
async takeImage(/* payload: MouseEvent */) {
const cameraComponent = this.$refs.camera as InstanceType<typeof Camera>;
this.blob = await cameraComponent?.snapshot(); // png is default; if that changes, change extension in formData.append
@ -145,7 +156,7 @@ export default class GiftedPhoto extends Vue {
this.uploading = false;
return;
}
formData.append("image", this.blob, "snapshot.png");
formData.append("image", this.blob, "snapshot.png"); // png is set in snapshot()
formData.append("claimType", "GiveAction");
try {
const response = await axios.post(
@ -155,10 +166,9 @@ export default class GiftedPhoto extends Vue {
);
this.uploading = false;
// we won't give a notification here because the user will be taken back to finish
localStorage.setItem("imageUrl", response.data.url as string);
this.$router.back();
this.visible = false;
this.blob = null;
this.setImage(response.data.url as string);
} catch (error) {
console.error("Error uploading the image", error);
this.$notify(
@ -176,3 +186,26 @@ export default class GiftedPhoto extends Vue {
}
}
</script>
<style>
.dialog-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
padding: 1.5rem;
}
.dialog {
background-color: white;
padding: 1rem;
border-radius: 0.5rem;
width: 100%;
max-width: 700px;
}
</style>

6
src/router/index.ts

@ -92,12 +92,6 @@ const routes: Array<RouteRecordRaw> = [
/* webpackChunkName: "gifted-details" */ "../views/GiftedDetails.vue"
),
},
{
path: "/gifted-photo",
name: "gifted-photo",
component: () =>
import(/* webpackChunkName: "gifted-photo" */ "../views/GiftedPhoto.vue"),
},
{
path: "/help",
name: "help",

35
src/views/GiftedDetails.vue

@ -40,7 +40,7 @@
</div>
<input
type="number"
class="border border-r-0 border-slate-400 px-2 py-2 text-center"
class="border border-r-0 border-slate-400 px-2 py-2 text-center w-20"
v-model="amountInput"
/>
<div
@ -55,25 +55,26 @@
<label class="text-sm">This is given to a project</label>
</div>
<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>
<div class="flex justify-center mt-4">
<span v-if="imageUrl" class="flex justify-between">
<a :href="imageUrl" target="_blank" class="text-blue-500 ml-4">
<img :src="imageUrl" class="h-24 rounded-xl" />
</a>
<fa
icon="trash-can"
@click="confirmDeleteImage"
class="text-red-500 fa-fw ml-8"
class="text-red-500 fa-fw ml-8 mt-10"
/>
</span>
<span v-else>
<router-link
:to="{ name: 'gifted-photo' }"
class="bg-blue-500 text-white px-1.5 py-1 rounded-md"
>
<fa icon="camera" class="fa-fw" />
</router-link>
<fa
icon="camera"
class="bg-blue-500 text-white px-2 py-2 rounded-md"
@click="openPhotoDialog"
/>
</span>
</div>
<GiftedPhotoDialog ref="photoDialog" />
<div v-if="!projectId" class="mt-4">
<input type="checkbox" class="h-6 w-6 mr-2" v-model="givenToUser" />
@ -114,9 +115,13 @@ import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
import { createAndSubmitGive } from "@/libs/endorserServer";
import * as libsUtil from "@/libs/util";
import { accessToken } from "@/libs/crypto";
import GiftedDialog from "@/components/GiftedDialog.vue";
import GiftedPhotoDialog from "@/components/GiftedPhotoDialog.vue";
@Component({
components: {
GiftedDialog,
GiftedPhotoDialog,
QuickNav,
TopMessage,
},
@ -198,6 +203,12 @@ export default class GiftedDetails extends Vue {
this.$router.back();
}
openPhotoDialog() {
(this.$refs.photoDialog as GiftedPhotoDialog).open((imgUrl) => {
this.imageUrl = imgUrl;
});
}
confirmDeleteImage() {
this.$notify(
{

Loading…
Cancel
Save