Add gallery button

This commit is contained in:
Joscha 2025-03-26 23:52:26 +01:00
parent 15f6a517e7
commit 5ce7625f6b
2 changed files with 47 additions and 21 deletions

View file

@ -51,27 +51,9 @@ async function waitAtLeast(duration: number, since: number) {
}
}
async function onRecord() {
assert(video.value !== null);
const canvas = document.createElement("canvas");
const scale = 384 / video.value.videoWidth;
canvas.width = video.value.videoWidth * scale;
canvas.height = video.value.videoHeight * scale;
const ctx = canvas.getContext("2d");
assert(ctx !== null);
ctx.drawImage(video.value, 0, 0, canvas.width, canvas.height);
const blob = await new Promise<Blob | null>((resolve) => {
canvas.toBlob(resolve);
});
assert(blob !== null);
async function postImage(image: Blob | File) {
const form = new FormData();
form.append("image", blob);
form.append("image", image);
form.append("caption", new Date().toLocaleString());
const start = Date.now();
@ -85,6 +67,31 @@ async function onRecord() {
covered.value = false;
}
async function onGallery(file: File) {
await postImage(file);
}
async function onRecord() {
assert(video.value !== null);
const video_ = video.value;
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
assert(ctx !== null);
const scale = 384 / video_.videoWidth;
canvas.width = video_.videoWidth * scale; // Yes, slightly redundant
canvas.height = video_.videoHeight * scale;
ctx.drawImage(video_, 0, 0, canvas.width, canvas.height);
const blob = await new Promise<Blob | null>((resolve) => {
canvas.toBlob(resolve);
});
assert(blob !== null);
await postImage(blob);
}
async function onFlip() {
const facingOpposite = facing.value === "user" ? "environment" : "user";
await initStream(facingOpposite);
@ -98,7 +105,7 @@ onMounted(async () => {
<template>
<video ref="video" :class="{ mirrored }" autoplay playsinline></video>
<div class="buttons">
<CPhotoButtonGallery style="visibility: hidden" />
<CPhotoButtonGallery @click="onGallery" />
<CPhotoButtonRecord :disabled="stream === undefined" @click="onRecord" />
<CPhotoButtonFlip
:disabled="stream === undefined || facing === undefined"

View file

@ -1,10 +1,25 @@
<script setup lang="ts">
import { RiMultiImageFill } from "@remixicon/vue";
import { useTemplateRef } from "vue";
const emit = defineEmits<{
click: [file: File];
}>();
const image = useTemplateRef<HTMLInputElement>("image");
function onImageChange() {
const theFile = image.value?.files?.[0];
if (theFile === undefined) return;
if (!theFile.type.startsWith("image/")) return;
emit("click", theFile);
}
</script>
<template>
<label>
<RiMultiImageFill size="48px" />
<input ref="image" type="file" accept="image/*" @change="onImageChange" />
</label>
</template>
@ -27,4 +42,8 @@ label:active {
svg {
display: block;
}
input {
display: none;
}
</style>