allow file choice for gift, plus other UI fixes

This commit is contained in:
2024-05-12 17:55:54 -06:00
parent 6c28828c0a
commit 7d6b210ee1
7 changed files with 164 additions and 60 deletions

View File

@@ -0,0 +1,124 @@
<template>
<div v-if="visible" class="dialog-overlay z-[60]">
<div class="dialog relative">
<div class="text-lg text-center font-light relative z-50">
<div
id="ViewHeading"
class="text-center font-bold absolute top-0 left-0 right-0 px-4 py-0.5 bg-black/50 text-white leading-none"
>
Camera or Other?
</div>
<div
class="text-lg text-center px-2 py-0.5 leading-none absolute right-0 top-0 text-white"
@click="close()"
>
<fa icon="xmark" class="w-[1em]"></fa>
</div>
</div>
<div>
<div class="text-center mt-8">
<div class>
<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()"
/>
</div>
<div class="mt-4">
<input type="file" @change="uploadImageFile" />
</div>
</div>
</div>
</div>
</div>
<PhotoDialog ref="photoDialog" />
</template>
<script lang="ts">
import { ref } from "vue";
import { Component, Vue } from "vue-facing-decorator";
import PhotoDialog from "@/components/PhotoDialog.vue";
const inputImageFileNameRef = ref<Blob>();
@Component({
components: { PhotoDialog },
})
export default class ImageMethodDialog extends Vue {
claimType: string;
crop: boolean = false;
imageCallback: (imageUrl?: string) => void = () => {};
visible = false;
open(setImageFn: (arg: string) => void, claimType: string, crop?: boolean) {
this.claimType = claimType;
this.crop = !!crop;
this.imageCallback = setImageFn;
this.visible = true;
}
openPhotoDialog(blob?: Blob, fileName?: string) {
this.visible = false;
(this.$refs.photoDialog as PhotoDialog).open(
this.imageCallback,
this.claimType,
this.crop,
blob,
fileName,
);
}
async uploadImageFile(event: Event) {
this.visible = false;
inputImageFileNameRef.value = event.target.files[0];
// https://developer.mozilla.org/en-US/docs/Web/API/File
// ... plus it has a `type` property from my testing
const file = inputImageFileNameRef.value;
if (file != null) {
const reader = new FileReader();
reader.onload = async (e) => {
const data = e.target?.result as ArrayBuffer;
if (data) {
const blob = new Blob([new Uint8Array(data)], {
type: file.type,
});
this.openPhotoDialog(blob, file.name as string);
}
};
reader.readAsArrayBuffer(file as Blob);
}
}
close() {
this.visible = false;
}
}
</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>

View File

@@ -29,7 +29,6 @@
<div v-if="crop">
<VuePictureCropper
:boxStyle="{
height: window80(),
backgroundColor: '#f8f8f8',
margin: 'auto',
}"
@@ -39,6 +38,7 @@
dragMode: 'crop',
aspectRatio: 9 / 9,
}"
class="max-h-[90vh] max-w-[90vw] object-contain"
/>
<!-- This gives a round cropper.
:presetMode="{
@@ -48,7 +48,10 @@
</div>
<div v-else>
<div class="flex justify-center">
<img :src="createBlobURL(blob)" class="mt-2 rounded" />
<img
:src="createBlobURL(blob)"
class="mt-2 rounded max-h-[90vh] max-w-[90vw] object-contain"
/>
</div>
</div>
<div class="absolute bottom-[1rem] left-[1rem] px-2 py-1">
@@ -135,7 +138,7 @@ export default class PhotoDialog extends Vue {
activeDeviceNumber = 0;
activeDid = "";
blob?: Blob;
claimType = "GiveAction";
claimType = "";
crop = false;
fileName?: string;
mirror = false;
@@ -169,14 +172,14 @@ export default class PhotoDialog extends Vue {
open(
setImageFn: (arg: string) => void,
claimType: string,
crop?: boolean,
claimType?: string,
blob?: Blob, // for image upload, just to use the cropping function
inputFileName?: string,
) {
this.visible = true;
this.claimType = claimType;
this.crop = !!crop;
this.claimType = claimType || "GiveAction";
const bottomNav = document.querySelector("#QuickNav") as HTMLElement;
if (bottomNav) {
bottomNav.style.display = "none";
@@ -185,6 +188,7 @@ export default class PhotoDialog extends Vue {
if (blob) {
this.blob = blob;
this.fileName = inputFileName;
// doesn't make sense to retry the file upload; they can cancel if they picked the wrong one
this.showRetry = false;
} else {
this.blob = undefined;
@@ -366,8 +370,7 @@ export default class PhotoDialog extends Vue {
);
this.uploading = false;
this.visible = false;
this.blob = undefined;
this.close();
this.setImageCallback(response.data.url as string);
} catch (error) {
console.error("Error uploading the image", error);