TV-App komplett ueberarbeitet: i18n (DE/EN), Multi-User Quick-Switch, 3 Themes (Dark/Medium/Light), 3 Ansichten (Grid/Liste/Detail), Filter (Quellen/Genre/Rating/Sortierung), Merkliste, 5-Sterne-Bewertung, Watch-Status, Player-Overlay (Audio/Untertitel/Qualitaet/Naechste Episode), Episoden-Thumbnails, Suchverlauf, Queue-Bugfix (delete_source). 5 neue DB-Tabellen, 10+ neue API-Endpunkte, ~3800 neue Zeilen Code. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
176 lines
10 KiB
HTML
176 lines
10 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') }} ✓</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>
|
|
<label class="settings-label">
|
|
{{ t('settings.avatar_color') }}
|
|
<input type="color" name="avatar_color" value="{{ user.avatar_color or '#64b5f6' }}"
|
|
class="settings-color" data-focusable>
|
|
</label>
|
|
</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>
|
|
</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>
|
|
</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 %}
|