|
|
@ -2,10 +2,7 @@ |
|
|
|
<div v-if="visible" class="dialog-overlay z-[60]"> |
|
|
|
<div class="dialog relative"> |
|
|
|
<div class="text-lg text-center font-bold relative"> |
|
|
|
<h1 |
|
|
|
id="ViewHeading" |
|
|
|
class="text-center font-bold" |
|
|
|
> |
|
|
|
<h1 id="ViewHeading" class="text-center font-bold"> |
|
|
|
<span v-if="uploading">Uploading Image…</span> |
|
|
|
<span v-else-if="blob">Crop Image</span> |
|
|
|
<span v-else-if="showCameraPreview">Upload Image</span> |
|
|
@ -29,7 +26,10 @@ |
|
|
|
Take a photo with your camera |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
<div v-if="showCameraPreview" class="camera-preview relative flex bg-black overflow-hidden mb-4"> |
|
|
|
<div |
|
|
|
v-if="showCameraPreview" |
|
|
|
class="camera-preview relative flex bg-black overflow-hidden mb-4" |
|
|
|
> |
|
|
|
<div class="camera-container w-full h-full relative"> |
|
|
|
<video |
|
|
|
ref="videoElement" |
|
|
@ -56,8 +56,8 @@ |
|
|
|
<div class="mt-4"> |
|
|
|
<input |
|
|
|
type="file" |
|
|
|
@change="uploadImageFile" |
|
|
|
class="w-full file:text-center file:bg-gradient-to-b file:from-slate-400 file:to-slate-700 file:shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] file:text-white file:px-3 file:py-2 file:rounded-md file:border-none file:cursor-pointer file:me-2" |
|
|
|
@change="uploadImageFile" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
<div |
|
|
@ -115,7 +115,12 @@ |
|
|
|
/> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div :class="['grid gap-2 mt-2', showRetry ? 'grid-cols-2' : 'grid-cols-1']"> |
|
|
|
<div |
|
|
|
:class="[ |
|
|
|
'grid gap-2 mt-2', |
|
|
|
showRetry ? 'grid-cols-2' : 'grid-cols-1', |
|
|
|
]" |
|
|
|
> |
|
|
|
<button |
|
|
|
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 py-2 px-3 rounded-md" |
|
|
|
@click="uploadImage" |
|
|
@ -227,7 +232,7 @@ export default class ImageMethodDialog extends Vue { |
|
|
|
* @throws {Error} When settings retrieval fails |
|
|
|
*/ |
|
|
|
async mounted() { |
|
|
|
console.log('ImageMethodDialog mounted'); |
|
|
|
console.log("ImageMethodDialog mounted"); |
|
|
|
try { |
|
|
|
const settings = await retrieveSettingsForActiveAccount(); |
|
|
|
this.activeDid = settings.activeDid || ""; |
|
|
@ -260,7 +265,7 @@ export default class ImageMethodDialog extends Vue { |
|
|
|
this.crop = !!crop; |
|
|
|
this.imageCallback = setImageFn; |
|
|
|
this.visible = true; |
|
|
|
|
|
|
|
|
|
|
|
// Start camera preview immediately if not on mobile |
|
|
|
if (!this.platformCapabilities.isMobile) { |
|
|
|
this.startCameraPreview(); |
|
|
@ -359,12 +364,12 @@ export default class ImageMethodDialog extends Vue { |
|
|
|
try { |
|
|
|
this.showCameraPreview = true; |
|
|
|
await this.$nextTick(); |
|
|
|
|
|
|
|
|
|
|
|
const stream = await navigator.mediaDevices.getUserMedia({ |
|
|
|
video: { facingMode: "environment" }, |
|
|
|
}); |
|
|
|
this.cameraStream = stream; |
|
|
|
|
|
|
|
|
|
|
|
await this.$nextTick(); |
|
|
|
|
|
|
|
const videoElement = this.$refs.videoElement as HTMLVideoElement; |
|
|
@ -412,14 +417,18 @@ export default class ImageMethodDialog extends Vue { |
|
|
|
const ctx = canvas.getContext("2d"); |
|
|
|
ctx?.drawImage(videoElement, 0, 0, canvas.width, canvas.height); |
|
|
|
|
|
|
|
canvas.toBlob((blob) => { |
|
|
|
if (blob) { |
|
|
|
this.blob = blob; |
|
|
|
this.fileName = `photo_${Date.now()}.jpg`; |
|
|
|
this.showRetry = true; |
|
|
|
this.stopCameraPreview(); |
|
|
|
} |
|
|
|
}, "image/jpeg", 0.95); |
|
|
|
canvas.toBlob( |
|
|
|
(blob) => { |
|
|
|
if (blob) { |
|
|
|
this.blob = blob; |
|
|
|
this.fileName = `photo_${Date.now()}.jpg`; |
|
|
|
this.showRetry = true; |
|
|
|
this.stopCameraPreview(); |
|
|
|
} |
|
|
|
}, |
|
|
|
"image/jpeg", |
|
|
|
0.95, |
|
|
|
); |
|
|
|
} catch (error) { |
|
|
|
logger.error("Error capturing photo:", error); |
|
|
|
this.$notify( |
|
|
|