189 lines
7.9 KiB
HTML
189 lines
7.9 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}{{ config.name }} – Steuerung{% endblock %}
|
||
|
||
{% block content %}
|
||
|
||
<div class="container my-4">
|
||
|
||
<!-- Status-Anzeige (oben rechts fixiert) -->
|
||
<div class="position-fixed top-0 end-0 m-3" style="z-index: 1050;">
|
||
<div id="connection-status" class="badge bg-secondary px-3 py-2 fs-6">
|
||
<i class="bi bi-circle-fill me-2 text-muted"></i> Nicht verbunden
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row">
|
||
<!-- Linke Spalte: Kanal-Steuerung (8/12) -->
|
||
<div class="col-lg-8">
|
||
<div class="row mb-4 align-items-center">
|
||
<div class="col-md-8">
|
||
<h1 class="mb-1">{{ config.name }}</h1>
|
||
<p class="text-muted">
|
||
Hub-ID: {{ config.hub_id | default('unbekannt') }} •
|
||
Typ: {{ config.hub_type | default('unbekannt') }} •
|
||
Datei: {{ config.filename }}
|
||
</p>
|
||
</div>
|
||
<div class="col-md-4 text-md-end">
|
||
{% if config.image %}
|
||
<img src="{{ url_for('main.serve_config_file', filename=config.image) }}"
|
||
alt="{{ config.name }}"
|
||
class="img-fluid rounded shadow"
|
||
style="max-height: 180px; object-fit: cover;">
|
||
{% else %}
|
||
<div class="bg-light rounded d-flex align-items-center justify-content-center shadow"
|
||
style="height: 180px; width: 100%; max-width: 300px; margin-left: auto;">
|
||
<i class="bi bi-train-freight-front display-1 text-muted"></i>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Connect-Bereich -->
|
||
<div id="connect-section" class="text-center mb-5">
|
||
<button id="connect-btn" class="btn btn-lg btn-success px-5 py-3">
|
||
<i class="bi bi-bluetooth me-2"></i> Mit Hub verbinden
|
||
</button>
|
||
<p class="mt-3 text-muted small">Stelle sicher, dass der Hub eingeschaltet ist und im Bluetooth-Modus ausgewählt wurde.</p>
|
||
</div>
|
||
|
||
<!-- Steuerbereich – anfangs versteckt -->
|
||
<div id="control-section" style="display: none;">
|
||
<div class="card shadow">
|
||
<div class="card-header bg-primary text-white">
|
||
<h5 class="mb-0">Steuerung</h5>
|
||
</div>
|
||
<div class="card-body" id="channels-container">
|
||
<!-- Dynamische Kanäle werden hier per JavaScript eingefügt -->
|
||
</div>
|
||
<div class="card-footer text-center">
|
||
<button id="stop-all-btn" class="btn btn-danger btn-lg px-5">
|
||
<i class="bi bi-stop-fill me-2"></i> Alle stoppen
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Reconnect-Bereich -->
|
||
<div id="reconnect-section" class="text-center mt-5" style="display: none;">
|
||
<div class="alert alert-warning">
|
||
<strong>Verbindung unterbrochen</strong><br>
|
||
Der Hub reagiert nicht mehr. Bitte erneut verbinden.
|
||
</div>
|
||
<button id="reconnect-btn" class="btn btn-warning btn-lg px-5 py-3">
|
||
<i class="bi bi-arrow-repeat me-2"></i> Erneut verbinden
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Rechte Spalte: Soundboard (4/12) -->
|
||
<div class="col-lg-4">
|
||
<div class="card shadow sticky-top" style="top: 20px;">
|
||
<div class="card-header bg-info text-white">
|
||
<h5 class="mb-0">Soundboard</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
|
||
<!-- Volume-Regler (global) -->
|
||
<div class="mb-4">
|
||
<label for="volume-slider" class="form-label fw-bold">Lautstärke</label>
|
||
<input type="range" class="form-range" id="volume-slider" min="0" max="100" value="80" step="5">
|
||
<div class="text-center mt-1">
|
||
<span id="volume-display">80 %</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tabs -->
|
||
<ul class="nav nav-tabs mb-3" id="soundTabs" role="tablist">
|
||
{% if config.sounds and config.sounds|length > 0 %}
|
||
<li class="nav-item" role="presentation">
|
||
<button class="nav-link active" id="lok-tab" data-bs-toggle="tab" data-bs-target="#lok-sounds" type="button" role="tab">
|
||
Lok-spezifisch
|
||
</button>
|
||
</li>
|
||
{% endif %}
|
||
<li class="nav-item" role="presentation">
|
||
<button class="nav-link {% if not config.sounds or config.sounds|length == 0 %}active{% endif %}" id="global-tab" data-bs-toggle="tab" data-bs-target="#global-sounds" type="button" role="tab">
|
||
Standard-Sounds
|
||
</button>
|
||
</li>
|
||
</ul>
|
||
|
||
<div class="tab-content" id="soundTabContent" style="max-height: 50vh; overflow-y: auto;">
|
||
<!-- Lok-spezifische Sounds -->
|
||
{% if config.sounds and config.sounds|length > 0 %}
|
||
<div class="tab-pane fade show active" id="lok-sounds" role="tabpanel">
|
||
<div class="d-grid gap-2">
|
||
{% for sound in config.sounds %}
|
||
<div class="d-flex gap-2">
|
||
<button class="btn btn-outline-primary flex-grow-1 play-sound-btn"
|
||
data-sound-id="{{ sound.id }}"
|
||
data-channel="{{ sound.channel | default('') }}"
|
||
data-loop="{{ 1 if sound.loop else 0 }}">
|
||
{{ sound.name }}
|
||
{% if sound.description %}
|
||
<small class="d-block text-muted">{{ sound.description }}</small>
|
||
{% endif %}
|
||
</button>
|
||
<button class="btn btn-outline-danger stop-sound-btn"
|
||
data-channel="{{ sound.channel | default('') }}"
|
||
title="Aktuellen Sound stoppen">
|
||
<i class="bi bi-stop-fill"></i>
|
||
</button>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
|
||
<!-- Globale Standard-Sounds -->
|
||
<div class="tab-pane fade {% if not config.sounds or config.sounds|length == 0 %}show active{% endif %}" id="global-sounds" role="tabpanel">
|
||
<div class="d-grid gap-2">
|
||
{% for sound in global_sounds %}
|
||
<div class="d-flex gap-2">
|
||
<button class="btn btn-outline-secondary flex-grow-1 play-sound-btn"
|
||
data-sound-id="{{ sound.id }}"
|
||
data-channel="{{ sound.channel | default('') }}"
|
||
data-loop="{{ 1 if sound.loop else 0 }}">
|
||
{{ sound.name }}
|
||
{% if sound.description %}
|
||
<small class="d-block text-muted">{{ sound.description }}</small>
|
||
{% endif %}
|
||
</button>
|
||
<button class="btn btn-outline-danger stop-sound-btn"
|
||
data-channel="{{ sound.channel | default('') }}"
|
||
title="Aktuellen Sound stoppen">
|
||
<i class="bi bi-stop-fill"></i>
|
||
</button>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{% if (not config.sounds or config.sounds|length == 0) and (not global_sounds or global_sounds|length == 0) %}
|
||
<p class="text-muted text-center py-4">Keine Sounds konfiguriert</p>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{% endblock %}
|
||
|
||
<!-- Seiten-spezifische Config setzen (nur wenn config existiert) -->
|
||
{% block scripts %}
|
||
<script>
|
||
// Config + globale Sounds global verfügbar machen (muss VOR initConfig passieren)
|
||
window.mkConfig = {{ config | tojson | safe }};
|
||
window.mkGlobalSounds = {{ global_sounds | tojson | safe }};
|
||
|
||
console.log("control.html → mkConfig gesetzt:", window.mkConfig);
|
||
console.log("control.html → mkGlobalSounds:", window.mkGlobalSounds);
|
||
</script>
|
||
|
||
{{ super() }} <!-- Basis-Skripte + Initialisierung -->
|
||
{% endblock %}
|