1 Commits

Author SHA1 Message Date
fabi
2e3097ca40 camera capture wip 2026-04-01 20:37:22 +02:00
2 changed files with 19 additions and 52 deletions

View File

@@ -8,8 +8,8 @@
let { oncapture, onclose }: Props = $props(); let { oncapture, onclose }: Props = $props();
let videoEl: HTMLVideoElement = $state()!; let videoEl: HTMLVideoElement;
let canvasEl: HTMLCanvasElement = $state()!; let canvasEl: HTMLCanvasElement;
let stream: MediaStream | null = $state(null); let stream: MediaStream | null = $state(null);
let facingMode = $state<'environment' | 'user'>('environment'); let facingMode = $state<'environment' | 'user'>('environment');
let recording = $state(false); let recording = $state(false);

View File

@@ -3,13 +3,11 @@
import { getToken } from '$lib/auth'; import { getToken } from '$lib/auth';
import { addToQueue, loadQueue } from '$lib/upload-queue'; import { addToQueue, loadQueue } from '$lib/upload-queue';
import UploadQueue from '$lib/components/UploadQueue.svelte'; import UploadQueue from '$lib/components/UploadQueue.svelte';
import CameraCapture from '$lib/components/CameraCapture.svelte';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
let caption = $state(''); let caption = $state('');
let hashtags = $state(''); let hashtags = $state('');
let fileInput: HTMLInputElement; let fileInput: HTMLInputElement;
let showCamera = $state(false);
onMount(() => { onMount(() => {
if (!getToken()) { if (!getToken()) {
@@ -32,23 +30,8 @@
hashtags = ''; hashtags = '';
if (fileInput) fileInput.value = ''; if (fileInput) fileInput.value = '';
} }
async function handleCapture(blob: Blob, type: 'photo' | 'video') {
const ext = type === 'photo' ? 'jpg' : blob.type.includes('mp4') ? 'mp4' : 'webm';
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const fileName = `${type}_${timestamp}.${ext}`;
const file = new File([blob], fileName, { type: blob.type });
await addToQueue(file, caption, hashtags);
}
</script> </script>
{#if showCamera}
<CameraCapture
oncapture={handleCapture}
onclose={() => (showCamera = false)}
/>
{/if}
<div class="min-h-screen bg-gray-50 p-4"> <div class="min-h-screen bg-gray-50 p-4">
<div class="mx-auto max-w-lg"> <div class="mx-auto max-w-lg">
<div class="mb-6 flex items-center justify-between"> <div class="mb-6 flex items-center justify-between">
@@ -57,16 +40,14 @@
</div> </div>
<div class="rounded-lg border border-gray-200 bg-white p-4"> <div class="rounded-lg border border-gray-200 bg-white p-4">
<div class="grid grid-cols-2 gap-3">
<!-- File picker -->
<label <label
class="flex cursor-pointer flex-col items-center justify-center rounded-lg border-2 border-dashed border-gray-300 bg-gray-50 p-6 transition hover:border-blue-400 hover:bg-blue-50" class="flex cursor-pointer flex-col items-center justify-center rounded-lg border-2 border-dashed border-gray-300 bg-gray-50 p-8 transition hover:border-blue-400 hover:bg-blue-50"
> >
<svg class="mb-2 h-8 w-8 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg class="mb-2 h-10 w-10 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 16V4m0 0l-4 4m4-4l4 4M4 20h16" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 16V4m0 0l-4 4m4-4l4 4M4 20h16" />
</svg> </svg>
<span class="text-center text-sm font-medium text-gray-600">Galerie</span> <span class="text-sm font-medium text-gray-600">Fotos oder Videos auswählen</span>
<span class="mt-1 text-center text-xs text-gray-400">Mehrere Dateien</span> <span class="mt-1 text-xs text-gray-400">Mehrere Dateien möglich</span>
<input <input
bind:this={fileInput} bind:this={fileInput}
type="file" type="file"
@@ -77,20 +58,6 @@
/> />
</label> </label>
<!-- Camera button -->
<button
onclick={() => (showCamera = true)}
class="flex flex-col items-center justify-center rounded-lg border-2 border-dashed border-gray-300 bg-gray-50 p-6 transition hover:border-blue-400 hover:bg-blue-50"
>
<svg class="mb-2 h-8 w-8 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15 13a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
<span class="text-sm font-medium text-gray-600">Kamera</span>
<span class="mt-1 text-xs text-gray-400">Foto & Video</span>
</button>
</div>
<div class="mt-4 space-y-3"> <div class="mt-4 space-y-3">
<input <input
type="text" type="text"