recent photos right, no hang of camera
This commit is contained in:
parent
49d9be5aae
commit
ac58a57190
@ -1,80 +1,105 @@
|
||||
<div class="flex flex-col items-center w-full"
|
||||
x-data="{ lightbox: null }"
|
||||
x-on:keydown.escape.window="lightbox = null">
|
||||
x-data="{ lightbox: null, deleteConfirmId: null }"
|
||||
x-on:keydown.escape.window="lightbox = null; deleteConfirmId = null">
|
||||
|
||||
<div class="relative w-full max-w-2xl">
|
||||
<video id="video" autoplay playsinline
|
||||
class="w-full rounded-2xl shadow-2xl bg-gray-900 aspect-video object-cover" style="transform: scaleX(-1);"></video>
|
||||
<div class="flex flex-col lg:flex-row lg:items-start gap-6 w-full max-w-6xl justify-center">
|
||||
<div class="flex flex-col items-center w-full lg:w-auto">
|
||||
<div class="relative w-full max-w-2xl">
|
||||
<video id="video" autoplay playsinline
|
||||
class="w-full rounded-2xl shadow-2xl bg-gray-900 aspect-video object-cover" style="transform: scaleX(-1);"></video>
|
||||
|
||||
<canvas id="canvas" class="hidden"></canvas>
|
||||
<canvas id="canvas" class="hidden"></canvas>
|
||||
|
||||
<div id="flash" class="absolute inset-0 rounded-2xl bg-white opacity-0 pointer-events-none transition-opacity duration-150"></div>
|
||||
<div id="flash" class="absolute inset-0 rounded-2xl bg-white opacity-0 pointer-events-none transition-opacity duration-150"></div>
|
||||
|
||||
<div id="countdown" class="absolute inset-0 rounded-2xl hidden items-center justify-center bg-black/40">
|
||||
<span id="countdown-num" class="text-white font-bold drop-shadow-lg" style="font-size: 8rem; line-height: 1;"></span>
|
||||
<div id="countdown" class="absolute inset-0 rounded-2xl hidden items-center justify-center bg-black/40">
|
||||
<span id="countdown-num" class="text-white font-bold drop-shadow-lg" style="font-size: 8rem; line-height: 1;"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 w-full max-w-xs">
|
||||
<select wire:model="photoprofileId"
|
||||
class="w-full rounded-full bg-black/50 text-white border border-white/20 px-5 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-white/40 appearance-none text-center">
|
||||
@foreach ($photoprofiles as $id => $name)
|
||||
<option value="{{ $id }}">{{ $name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div id="camera-select-wrap" class="mt-3 w-full max-w-xs hidden">
|
||||
<select id="camera-select"
|
||||
class="w-full rounded-full bg-black/50 text-white border border-white/20 px-5 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-white/40 appearance-none text-center"></select>
|
||||
</div>
|
||||
|
||||
<button id="capture-btn"
|
||||
wire:loading.attr="disabled"
|
||||
@disabled($hasProcessing)
|
||||
class="mt-8 px-10 py-4 bg-white text-gray-950 font-semibold text-lg rounded-full shadow-lg hover:bg-gray-200 active:scale-95 transition-all duration-150 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||
<span wire:loading.remove>{{ $hasProcessing ? 'Erstelle Bild...' : 'Foto aufnehmen' }}</span>
|
||||
<span wire:loading>Speichere…</span>
|
||||
</button>
|
||||
|
||||
<div class="mt-4 text-sm text-gray-400 h-6">{{ $status }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 w-full max-w-xs">
|
||||
<select wire:model="photoprofileId"
|
||||
class="w-full rounded-full bg-black/50 text-white border border-white/20 px-5 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-white/40 appearance-none text-center">
|
||||
@foreach ($photoprofiles as $id => $name)
|
||||
<option value="{{ $id }}">{{ $name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div id="camera-select-wrap" class="mt-3 w-full max-w-xs hidden">
|
||||
<select id="camera-select"
|
||||
class="w-full rounded-full bg-black/50 text-white border border-white/20 px-5 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-white/40 appearance-none text-center"></select>
|
||||
</div>
|
||||
|
||||
<button id="capture-btn"
|
||||
wire:loading.attr="disabled"
|
||||
@disabled($hasProcessing)
|
||||
class="mt-8 px-10 py-4 bg-white text-gray-950 font-semibold text-lg rounded-full shadow-lg hover:bg-gray-200 active:scale-95 transition-all duration-150 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||
<span wire:loading.remove>{{ $hasProcessing ? 'Erstelle Bild...' : 'Foto aufnehmen' }}</span>
|
||||
<span wire:loading>Speichere…</span>
|
||||
</button>
|
||||
|
||||
<div class="mt-4 text-sm text-gray-400 h-6">{{ $status }}</div>
|
||||
|
||||
@if ($recentPhotos->isNotEmpty())
|
||||
<div class="mt-10 w-full max-w-2xl">
|
||||
<h2 class="text-sm font-medium text-gray-400 mb-3 tracking-wide uppercase">Fotos</h2>
|
||||
<div class="grid grid-cols-5 gap-2" @if($hasProcessing) wire:poll.2000ms @endif>
|
||||
@foreach ($recentPhotos as $photo)
|
||||
<div class="relative">
|
||||
@if ($photo['status'] === 'processing')
|
||||
<div class="relative w-full aspect-square">
|
||||
<img src="{{ $photo['url'] }}" alt="Photo #{{ $photo['id'] }}"
|
||||
class="w-full aspect-square object-cover rounded-lg border border-gray-700">
|
||||
<div class="absolute inset-0 rounded-lg bg-black/50 flex items-center justify-center">
|
||||
<svg class="w-8 h-8 text-white animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8H4z"/>
|
||||
</svg>
|
||||
@if ($recentPhotos->isNotEmpty())
|
||||
<div class="w-full lg:w-64 lg:shrink-0">
|
||||
<h2 class="text-sm font-medium text-gray-400 mb-3 tracking-wide uppercase">Fotos</h2>
|
||||
<div class="grid grid-cols-5 lg:grid-cols-3 gap-2" @if($hasProcessing) wire:poll.2000ms @endif>
|
||||
@foreach ($recentPhotos as $photo)
|
||||
<div class="relative">
|
||||
@if ($photo['status'] === 'processing')
|
||||
<div class="relative w-full aspect-square">
|
||||
<img src="{{ $photo['url'] }}" alt="Photo #{{ $photo['id'] }}"
|
||||
class="w-full aspect-square object-cover rounded-lg border border-gray-700">
|
||||
<div class="absolute inset-0 rounded-lg bg-black/50 flex items-center justify-center">
|
||||
<svg class="w-8 h-8 text-white animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8H4z"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<img src="{{ $photo['url'] }}" alt="Photo #{{ $photo['id'] }}"
|
||||
class="w-full aspect-square object-cover rounded-lg border border-gray-700 cursor-pointer"
|
||||
x-on:click="lightbox = {{ Js::from($photo) }}">
|
||||
<button wire:click="delete({{ $photo['id'] }})" wire:confirm="Delete this photo?"
|
||||
class="absolute top-1 right-1 p-1 rounded bg-black/60 text-white hover:bg-red-600/80 transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</button>
|
||||
@endif
|
||||
<span class="absolute bottom-1 left-1 text-[10px] px-1.5 py-0.5 rounded bg-black/60 text-yellow-400">
|
||||
{{ $photo['status'] }}
|
||||
</span>
|
||||
</div>
|
||||
@endforeach
|
||||
@else
|
||||
<img src="{{ $photo['url'] }}" alt="Photo #{{ $photo['id'] }}"
|
||||
class="w-full aspect-square object-cover rounded-lg border border-gray-700 cursor-pointer"
|
||||
x-on:click="lightbox = {{ Js::from($photo) }}">
|
||||
<button x-on:click="deleteConfirmId = {{ $photo['id'] }}"
|
||||
class="absolute top-1 right-1 p-1 rounded bg-black/60 text-white hover:bg-red-600/80 transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</button>
|
||||
@endif
|
||||
<span class="absolute bottom-1 left-1 text-[10px] px-1.5 py-0.5 rounded bg-black/60 text-yellow-400">
|
||||
{{ $photo['status'] }}
|
||||
</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Delete confirmation --}}
|
||||
<div x-show="deleteConfirmId"
|
||||
wire:ignore
|
||||
x-on:click.self="deleteConfirmId = null"
|
||||
class="fixed inset-0 z-50 flex items-center justify-center bg-black/80 p-6"
|
||||
style="display:none">
|
||||
<div class="max-w-sm w-full rounded-2xl bg-gray-900 border border-white/10 p-6 shadow-2xl text-center">
|
||||
<p class="text-white mb-6">Foto wirklich löschen?</p>
|
||||
<div class="flex justify-center gap-3">
|
||||
<button x-on:click="deleteConfirmId = null"
|
||||
class="px-5 py-2 rounded-full bg-white/10 text-white hover:bg-white/20 transition-colors">
|
||||
Abbrechen
|
||||
</button>
|
||||
<button x-on:click="$wire.delete(deleteConfirmId); deleteConfirmId = null"
|
||||
class="px-5 py-2 rounded-full bg-red-600 text-white hover:bg-red-500 transition-colors">
|
||||
Löschen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Lightbox --}}
|
||||
<div x-show="lightbox"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user