83 lines
3.4 KiB
PHP
83 lines
3.4 KiB
PHP
<div x-data="screenPreview()" class="glass p-4 space-y-3">
|
|
<div class="flex items-center justify-between">
|
|
<h3 class="text-xs uppercase tracking-widest text-white/50 font-medium">Screen</h3>
|
|
@if ($analyzing)
|
|
<span class="text-[10px] text-primary flex items-center gap-1">
|
|
<span class="typing-dot"></span>
|
|
<span>analysiert</span>
|
|
</span>
|
|
@endif
|
|
</div>
|
|
|
|
<div class="aspect-video bg-black/40 border border-white/10 rounded-lg overflow-hidden relative">
|
|
<video x-ref="video" autoplay muted playsinline class="w-full h-full object-contain"
|
|
x-show="streaming"></video>
|
|
<div x-show="!streaming" class="absolute inset-0 flex flex-col items-center justify-center gap-2 text-white/30">
|
|
<svg class="w-8 h-8" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
|
<rect x="2" y="3" width="20" height="14" rx="2"/>
|
|
<path d="M8 21h8M12 17v4"/>
|
|
</svg>
|
|
<span class="text-[10px] uppercase tracking-widest">Inactive</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex gap-2">
|
|
<button type="button" x-on:click="toggleShare()"
|
|
class="flex-1 text-xs px-3 py-1.5 rounded-lg bg-white/5 hover:bg-white/10 border border-white/10 text-white/80 transition">
|
|
<span x-show="!streaming">Screen teilen</span>
|
|
<span x-show="streaming" x-cloak>Stop</span>
|
|
</button>
|
|
<button type="button" x-on:click="snapshot()" x-bind:disabled="!streaming"
|
|
class="text-xs px-3 py-1.5 rounded-lg bg-primary/20 hover:bg-primary/30 border border-primary/40 text-primary disabled:opacity-30 disabled:hover:bg-primary/20 transition">
|
|
Snapshot
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
@assets
|
|
<script>
|
|
document.addEventListener('alpine:init', () => {
|
|
Alpine.data('screenPreview', () => ({
|
|
streaming: false,
|
|
stream: null,
|
|
|
|
async toggleShare() {
|
|
if (this.streaming) {
|
|
this.stopStream();
|
|
return;
|
|
}
|
|
try {
|
|
this.stream = await navigator.mediaDevices.getDisplayMedia({
|
|
video: { frameRate: 5 },
|
|
audio: false,
|
|
});
|
|
this.$refs.video.srcObject = this.stream;
|
|
this.streaming = true;
|
|
this.stream.getVideoTracks()[0].onended = () => this.stopStream();
|
|
} catch (err) {
|
|
console.warn('Screen share denied:', err);
|
|
}
|
|
},
|
|
|
|
stopStream() {
|
|
this.stream?.getTracks().forEach(t => t.stop());
|
|
this.stream = null;
|
|
this.$refs.video.srcObject = null;
|
|
this.streaming = false;
|
|
},
|
|
|
|
snapshot() {
|
|
if (!this.streaming) return;
|
|
const video = this.$refs.video;
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = video.videoWidth;
|
|
canvas.height = video.videoHeight;
|
|
canvas.getContext('2d').drawImage(video, 0, 0);
|
|
const base64 = canvas.toDataURL('image/jpeg', 0.7);
|
|
this.$wire.dispatch('screen-shot-captured', { base64 });
|
|
},
|
|
}));
|
|
});
|
|
</script>
|
|
@endassets
|