118 lines
4.2 KiB
HTML
118 lines
4.2 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}Soundboard – {{ config.name }}{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="container my-5">
|
||
<h1>Soundboard – {{ config.name }}</h1>
|
||
<p class="lead mb-4">Wähle einen Sound aus – wird direkt über den Raspberry Pi ausgegeben.</p>
|
||
|
||
{% set has_local = sounds_local and sounds_local|length > 0 %}
|
||
{% set has_global = sounds_global and sounds_global|length > 0 %}
|
||
|
||
{% if has_local %}
|
||
<h4 class="mt-3 mb-3">Lok-spezifische Sounds</h4>
|
||
<div class="row g-3">
|
||
{% for sound in sounds_local %}
|
||
<div class="col-md-4 col-lg-3">
|
||
<div class="card h-100 shadow-sm">
|
||
<div class="card-body text-center">
|
||
<h5 class="card-title">{{ sound.name }}</h5>
|
||
{% if sound.description %}
|
||
<p class="card-text text-muted small">{{ sound.description }}</p>
|
||
{% endif %}
|
||
<button class="btn btn-primary mt-3 play-sound-btn"
|
||
data-sound-id="{{ sound.id }}"
|
||
data-channel="{{ sound.channel | default('') }}"
|
||
data-loop="{{ 1 if sound.loop else 0 }}">
|
||
<i class="bi bi-play-fill me-2"></i> Abspielen
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
{% endif %}
|
||
|
||
{% if has_global %}
|
||
<h4 class="mt-5 mb-3">Standard-Sounds</h4>
|
||
<div class="row g-3">
|
||
{% for sound in sounds_global %}
|
||
<div class="col-md-4 col-lg-3">
|
||
<div class="card h-100 shadow-sm">
|
||
<div class="card-body text-center">
|
||
<h5 class="card-title">{{ sound.name }}</h5>
|
||
{% if sound.description %}
|
||
<p class="card-text text-muted small">{{ sound.description }}</p>
|
||
{% endif %}
|
||
<button class="btn btn-outline-secondary mt-3 play-sound-btn"
|
||
data-sound-id="{{ sound.id }}"
|
||
data-channel="{{ sound.channel | default('') }}"
|
||
data-loop="{{ 1 if sound.loop else 0 }}">
|
||
<i class="bi bi-play-fill me-2"></i> Abspielen
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
{% endif %}
|
||
|
||
{% if not has_local and not has_global %}
|
||
<div class="alert alert-info">
|
||
In dieser Konfiguration sind keine Sounds definiert und keine Default-Sounds vorhanden.
|
||
</div>
|
||
{% endif %}
|
||
|
||
<div class="mt-5 text-center">
|
||
<a href="{{ url_for('main.control_page') }}" class="btn btn-secondary">Zurück zur Steuerung</a>
|
||
</div>
|
||
</div>
|
||
|
||
{% endblock %}
|
||
|
||
{% block scripts %}
|
||
<script>
|
||
document.querySelectorAll('.play-sound-btn').forEach(btn => {
|
||
btn.addEventListener('click', async () => {
|
||
const soundId = btn.dataset.soundId;
|
||
const channel = btn.dataset.channel || null;
|
||
const loopFlag = btn.dataset.loop === '1' || btn.dataset.loop === 'true';
|
||
btn.disabled = true;
|
||
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span> Spielt...';
|
||
|
||
try {
|
||
const res = await fetch('/api/play_sound', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ sound_id: soundId, channel, loop: loopFlag })
|
||
});
|
||
|
||
const data = await res.json();
|
||
|
||
if (data.success) {
|
||
btn.classList.remove('btn-primary');
|
||
btn.classList.add('btn-success');
|
||
btn.innerHTML = '<i class="bi bi-check-lg me-2"></i> Gespielt';
|
||
setTimeout(() => {
|
||
btn.classList.remove('btn-success');
|
||
btn.classList.add('btn-primary');
|
||
btn.innerHTML = '<i class="bi bi-play-fill me-2"></i> Abspielen';
|
||
btn.disabled = false;
|
||
}, 2000);
|
||
} else {
|
||
alert('Fehler: ' + (data.message || 'Unbekannt'));
|
||
btn.disabled = false;
|
||
btn.innerHTML = '<i class="bi bi-play-fill me-2"></i> Abspielen';
|
||
}
|
||
} catch (err) {
|
||
console.error('Sound-Play-Fehler:', err);
|
||
alert('Netzwerkfehler beim Abspielen');
|
||
btn.disabled = false;
|
||
btn.innerHTML = '<i class="bi bi-play-fill me-2"></i> Abspielen';
|
||
}
|
||
});
|
||
});
|
||
</script>
|
||
{% endblock %}
|