docker.videokonverter/video-konverter/app/templates/tv/settings.html
data 61ca20bf8b fix: TV-App UX-Verbesserungen - Navigation, Ordner-Ansicht, Duplikate
- FocusManager: SELECT-Elemente, sequentielle Nav-Navigation, Zone-basiert
- Ordner-Ansicht (4. View) fuer Serien + Filme mit Quellen-Gruppierung
- Login-Flow: Lade-Spinner statt Form-Flash, Auto-Login bei 1 Profil
- Farbauswahl: Farbkreise statt input type=color (Samsung TV kompatibel)
- Duplikat-Episoden: Orange Markierung + Badge bei gleicher Episodennummer
- i18n: Neue Keys fuer Ordner-Ansicht und Duplikat-Markierung

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 07:57:57 +01:00

200 lines
11 KiB
HTML

{% extends "tv/base.html" %}
{% block title %}{{ t('settings.title') }} - VideoKonverter TV{% endblock %}
{% block content %}
<section class="tv-section">
<h1 class="tv-page-title">{{ t('settings.title') }}</h1>
{% if request.query.get('saved') %}
<div class="tv-success-msg">{{ t('settings.saved') }}</div>
{% endif %}
{% if request.query.get('reset') %}
<div class="tv-success-msg">{{ t('status.reset_progress') }} &#10003;</div>
{% endif %}
<form method="post" action="/tv/settings" class="settings-form">
<!-- Profil -->
<fieldset class="settings-group">
<legend>{{ t('settings.profile') }}</legend>
<label class="settings-label">
{{ t('settings.display_name') }}
<input type="text" name="display_name" value="{{ user.display_name or '' }}"
class="settings-input" data-focusable>
</label>
<div class="settings-label">
{{ t('settings.avatar_color') }}
<input type="hidden" name="avatar_color" id="avatar-color-input"
value="{{ user.avatar_color or '#64b5f6' }}">
<div class="color-picker-grid">
{% set colors = ['#64b5f6', '#42a5f5', '#5c6bc0', '#7e57c2', '#ab47bc',
'#ec407a', '#ef5350', '#ff7043', '#ffa726', '#ffca28',
'#66bb6a', '#26a69a', '#26c6da', '#78909c', '#8d6e63'] %}
{% for c in colors %}
<button type="button" class="color-swatch {% if (user.avatar_color or '#64b5f6') == c %}active{% endif %}"
style="background:{{ c }}" data-color="{{ c }}" data-focusable
onclick="selectColor(this, '{{ c }}')"></button>
{% endfor %}
</div>
</div>
</fieldset>
<!-- Sprache -->
<fieldset class="settings-group">
<legend>{{ t('settings.language') }}</legend>
<label class="settings-label">
{{ t('settings.menu_language') }}
<select name="ui_lang" class="settings-select" data-focusable>
<option value="de" {% if user.ui_lang == 'de' %}selected{% endif %}>Deutsch</option>
<option value="en" {% if user.ui_lang == 'en' %}selected{% endif %}>English</option>
</select>
</label>
<label class="settings-label">
{{ t('settings.audio_language') }}
<select name="preferred_audio_lang" class="settings-select" data-focusable>
<option value="deu" {% if user.preferred_audio_lang == 'deu' %}selected{% endif %}>{{ t('lang.deu') }}</option>
<option value="eng" {% if user.preferred_audio_lang == 'eng' %}selected{% endif %}>{{ t('lang.eng') }}</option>
<option value="fra" {% if user.preferred_audio_lang == 'fra' %}selected{% endif %}>{{ t('lang.fra') }}</option>
<option value="spa" {% if user.preferred_audio_lang == 'spa' %}selected{% endif %}>{{ t('lang.spa') }}</option>
<option value="jpn" {% if user.preferred_audio_lang == 'jpn' %}selected{% endif %}>{{ t('lang.jpn') }}</option>
</select>
</label>
<label class="settings-label">
{{ t('settings.subtitle_language') }}
<select name="preferred_subtitle_lang" class="settings-select" data-focusable>
<option value="" {% if not user.preferred_subtitle_lang %}selected{% endif %}>{{ t('player.subtitles_off') }}</option>
<option value="deu" {% if user.preferred_subtitle_lang == 'deu' %}selected{% endif %}>{{ t('lang.deu') }}</option>
<option value="eng" {% if user.preferred_subtitle_lang == 'eng' %}selected{% endif %}>{{ t('lang.eng') }}</option>
<option value="fra" {% if user.preferred_subtitle_lang == 'fra' %}selected{% endif %}>{{ t('lang.fra') }}</option>
</select>
</label>
<label class="settings-label settings-check">
<input type="checkbox" name="subtitles_enabled"
{% if user.subtitles_enabled %}checked{% endif %} data-focusable>
{{ t('settings.subtitles_enabled') }}
</label>
</fieldset>
<!-- Ansichten & Theme -->
<fieldset class="settings-group">
<legend>{{ t('settings.views') }}</legend>
<label class="settings-label">
{{ t('settings.theme') }}
<select name="theme" class="settings-select" data-focusable
onchange="document.documentElement.setAttribute('data-theme', this.value)">
<option value="dark" {% if user.theme == 'dark' or not user.theme %}selected{% endif %}>{{ t('settings.theme_dark') }}</option>
<option value="medium" {% if user.theme == 'medium' %}selected{% endif %}>{{ t('settings.theme_medium') }}</option>
<option value="light" {% if user.theme == 'light' %}selected{% endif %}>{{ t('settings.theme_light') }}</option>
</select>
</label>
<label class="settings-label">
{{ t('settings.series_view') }}
<select name="series_view" class="settings-select" data-focusable>
<option value="grid" {% if user.series_view == 'grid' %}selected{% endif %}>{{ t('settings.view_grid') }}</option>
<option value="list" {% if user.series_view == 'list' %}selected{% endif %}>{{ t('settings.view_list') }}</option>
<option value="detail" {% if user.series_view == 'detail' %}selected{% endif %}>{{ t('settings.view_detail') }}</option>
<option value="folder" {% if user.series_view == 'folder' %}selected{% endif %}>{{ t('settings.view_folder') }}</option>
</select>
</label>
<label class="settings-label">
{{ t('settings.movies_view') }}
<select name="movies_view" class="settings-select" data-focusable>
<option value="grid" {% if user.movies_view == 'grid' %}selected{% endif %}>{{ t('settings.view_grid') }}</option>
<option value="list" {% if user.movies_view == 'list' %}selected{% endif %}>{{ t('settings.view_list') }}</option>
<option value="detail" {% if user.movies_view == 'detail' %}selected{% endif %}>{{ t('settings.view_detail') }}</option>
<option value="folder" {% if user.movies_view == 'folder' %}selected{% endif %}>{{ t('settings.view_folder') }}</option>
</select>
</label>
</fieldset>
<!-- Auto-Play -->
<fieldset class="settings-group">
<legend>{{ t('settings.autoplay') }}</legend>
<label class="settings-label settings-check">
<input type="checkbox" name="autoplay_enabled"
{% if user.autoplay_enabled %}checked{% endif %} data-focusable>
{{ t('settings.autoplay_enabled') }}
</label>
<label class="settings-label">
{{ t('settings.autoplay_countdown') }}
<select name="autoplay_countdown_sec" class="settings-select" data-focusable>
{% for s in [5, 10, 15, 20, 30] %}
<option value="{{ s }}" {% if user.autoplay_countdown_sec == s %}selected{% endif %}>{{ s }} {{ t('settings.seconds') }}</option>
{% endfor %}
</select>
</label>
<label class="settings-label">
{{ t('settings.autoplay_max') }}
<select name="autoplay_max_episodes" class="settings-select" data-focusable>
<option value="0" {% if user.autoplay_max_episodes == 0 %}selected{% endif %}>{{ t('settings.autoplay_max_desc') }}</option>
{% for n in [3, 5, 8, 10, 15, 20] %}
<option value="{{ n }}" {% if user.autoplay_max_episodes == n %}selected{% endif %}>{{ n }}</option>
{% endfor %}
</select>
</label>
</fieldset>
<!-- Geraete-Einstellungen -->
{% if client %}
<fieldset class="settings-group">
<legend>{{ t('settings.client_settings') }}</legend>
<label class="settings-label">
{{ t('settings.device_name') }}
<input type="text" name="client_name" value="{{ client.name or '' }}"
placeholder="z.B. Samsung TV Wohnzimmer"
class="settings-input" data-focusable>
</label>
<label class="settings-label">
{{ t('settings.sound_mode') }}
<select name="sound_mode" class="settings-select" data-focusable>
<option value="stereo" {% if client.sound_mode == 'stereo' %}selected{% endif %}>{{ t('settings.sound_stereo') }}</option>
<option value="surround" {% if client.sound_mode == 'surround' %}selected{% endif %}>{{ t('settings.sound_surround') }}</option>
<option value="original" {% if client.sound_mode == 'original' %}selected{% endif %}>{{ t('settings.sound_original') }}</option>
</select>
</label>
<label class="settings-label">
{{ t('settings.stream_quality') }}
<select name="stream_quality" class="settings-select" data-focusable>
<option value="uhd" {% if client.stream_quality == 'uhd' %}selected{% endif %}>{{ t('player.quality_uhd') }}</option>
<option value="hd" {% if client.stream_quality == 'hd' %}selected{% endif %}>{{ t('player.quality_hd') }}</option>
<option value="sd" {% if client.stream_quality == 'sd' %}selected{% endif %}>{{ t('player.quality_sd') }}</option>
<option value="low" {% if client.stream_quality == 'low' %}selected{% endif %}>{{ t('player.quality_low') }}</option>
</select>
</label>
</fieldset>
{% endif %}
<button type="submit" class="tv-play-btn settings-save" data-focusable>
{{ t('settings.save') }}
</button>
</form>
<!-- Gefahrenzone -->
<div class="settings-danger">
<form method="post" action="/tv/settings/reset"
onsubmit="return confirm('{{ t('settings.reset_confirm') }}')">
<button type="submit" class="settings-danger-btn" data-focusable>
{{ t('settings.reset_all') }}
</button>
</form>
<form method="post" action="/tv/api/search/history"
onsubmit="fetch('/tv/api/search/history',{method:'DELETE'});this.querySelector('button').textContent='✓';return false;">
<button type="button" class="settings-danger-btn" data-focusable>
{{ t('settings.clear_search') }}
</button>
</form>
</div>
</section>
{% endblock %}
{% block scripts %}
<script>
function selectColor(btn, color) {
// Aktive Markierung wechseln
document.querySelectorAll('.color-swatch').forEach(s => s.classList.remove('active'));
btn.classList.add('active');
// Hidden-Input aktualisieren
document.getElementById('avatar-color-input').value = color;
}
</script>
{% endblock %}