Add FCM device registration and Gitea bug reporter

This commit is contained in:
2026-09-15 01:01:08 +02:00
parent b2af866cf0
commit b96b1890d2
33 changed files with 1232 additions and 18 deletions
+10
View File
@@ -0,0 +1,10 @@
<script id="native-push-config" type="application/json">{{ {
'permission': _('Möchtest du Benachrichtigungen von MetalCircle auf diesem Gerät erhalten?'),
'enable': _('Benachrichtigungen aktivieren'),
'later': _('Später'),
'denied': _('Benachrichtigungen sind deaktiviert. Du kannst sie in den Android-Einstellungen für MetalCircle erlauben.'),
'ready': _('Dieses Gerät ist für Benachrichtigungen registriert.'),
'failed': _('Die Push-Registrierung ist momentan nicht möglich. Bitte versuche es später erneut.'),
'debug': _('FCM-Testtoken anzeigen (nur Debug-App)')
} | tojson }}</script>
<script src="/static/js/native-push.js" defer></script>
+2
View File
@@ -8,8 +8,10 @@
{% if user.is_admin %}<a href="/admin">{{ _('⚙️ Verwaltung') }}</a>{% endif %}
<a href="/datenschutz">{{ _('Datenschutz') }}</a>
<a href="/impressum">{{ _('Impressum') }}</a>
<a href="{{ bug_report_url() }}">{{ _('🐛 Bug melden') }}</a>
<form method="post" action="/logout">
<button type="submit">{{ _('Abmelden') }}</button>
</form>
</div>
</details>
{% include '_native_push.html' %}
+57
View File
@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html lang="{{ language() }}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ _('Bug melden · MetalCircle') }}</title>
<link rel="icon" href="/static/images/metalcircle-circle.png">
<link rel="stylesheet" href="/static/css/style.css">
<link rel="stylesheet" href="/static/css/language.css">
</head>
<body>
<header><div class="header-inner">
<a href="/" class="logo"><img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle"></a>
{% include '_user_menu.html' %}
</div>{% include '_language_switch.html' %}</header>
<main>
<div class="page-title"><h1>{{ _('🐛 Bug melden') }}</h1><p>{{ _('Hilf uns, MetalCircle zu verbessern.') }}</p></div>
<section class="admin-section bug-report-section">
{% if issue_number %}
<p class="bug-success" role="status">{{ _('Bugreport #{number} wurde erfolgreich erstellt. Danke!').format(number=issue_number) }}</p>
<a class="button" href="/">{{ _('Zurück zur Übersicht') }}</a>
{% else %}
<p>{{ _('Deine Meldung geht direkt an unser internes Ticketsystem. Sie ist für das Projektteam sichtbar.') }}</p>
{% if error %}<p class="bug-error" role="alert">{{ error }}</p>{% endif %}
<form method="post" action="/bug-report" class="bug-report-form">
<input type="hidden" name="submission_id" value="{{ submission_id }}">
<label for="bug-title">{{ _('Titel') }} <small>{{ _('(Pflichtfeld)') }}</small></label>
<input id="bug-title" name="title" required minlength="3" maxlength="160" value="{{ form.title }}">
<label for="bug-description">{{ _('Bugbeschreibung') }} <small>{{ _('(Pflichtfeld)') }}</small></label>
<textarea id="bug-description" name="description" required minlength="10" maxlength="5000" rows="5">{{ form.description }}</textarea>
<label for="bug-expected">{{ _('Erwartetes Verhalten') }} <small>{{ _('(Pflichtfeld)') }}</small></label>
<textarea id="bug-expected" name="expected" required minlength="3" maxlength="3000" rows="3">{{ form.expected }}</textarea>
<label for="bug-steps">{{ _('Schritte zum Reproduzieren') }} <small>(optional)</small></label>
<textarea id="bug-steps" name="steps" maxlength="3000" rows="3">{{ form.steps }}</textarea>
<div class="bug-report-options">
<label for="bug-category">{{ _('Kategorie') }}
<select id="bug-category" name="category">{% for value, label in categories.items() %}<option value="{{ value }}"{% if form.category == value %} selected{% endif %}>{{ label | t }}</option>{% endfor %}</select>
</label>
<label for="bug-severity">{{ _('Schweregrad') }}
<select id="bug-severity" name="severity">{% for value, label in severities.items() %}<option value="{{ value }}"{% if form.severity == value %} selected{% endif %}>{{ label | t }}</option>{% endfor %}</select>
</label>
</div>
<label class="bug-context"><input type="checkbox" name="technical" value="true"{% if form.technical %} checked{% endif %}> {{ _('Technische Informationen mitsenden (optional)') }}</label>
<p class="bug-help">{{ _('Enthalten sind die betroffene Seite ohne URL-Parameter, Plattform, App-Version und Browsertyp. Dein Benutzername und deine User-ID werden immer aus deiner Anmeldung übernommen.') }}</p>
<p class="bug-help">{{ _('Betroffene Seite:') }} <code>{{ form.route }}</code></p>
<input type="hidden" name="route" value="{{ form.route }}">
<input type="hidden" name="platform" id="bug-platform" value="Web">
<input type="hidden" name="app_version" id="bug-app-version" value="">
<p class="bug-help">{{ _('Bitte keine Passwörter, Zugangstoken oder privaten Schlüssel eintragen.') }}</p>
<button type="submit" class="button"{% if blocked %} disabled{% endif %}>{{ _('Bugreport senden') }}</button>
</form>
{% endif %}
</section>
</main>
<script src="/static/js/bug-report.js" defer></script>
</body>
</html>
+2
View File
@@ -18,6 +18,8 @@
<p>{{ _('Die Verarbeitung erfolgt im geschlossenen Projektbetrieb zur Bereitstellung der gewünschten Funktionen und soweit erforderlich auf Grundlage deiner Einwilligung. Daten bleiben gespeichert, solange dein Konto besteht oder gesetzliche Aufbewahrungspflichten gelten. Nicht mehr benötigte Daten werden gelöscht.') }}</p>
<h2>{{ _('Weitergabe und externe Dienste') }}</h2>
<p>{{ _('Es werden keine Werbe- oder Trackingdienste eingesetzt. Bei der Veranstaltungsortsuche können Suchanfragen an einen externen Geocoding-Dienst übermittelt werden. Externe Flyer- und Instagram-Links werden beim Aufruf direkt von deinem Browser geladen; dafür gelten die Datenschutzbestimmungen des jeweiligen Anbieters.') }}</p>
<p>{{ _('Für Android-Benachrichtigungen speichern wir die Gerätekennung, den FCM-Registrierungstoken, die App-Version und die Zuordnung zur aktuellen Anmeldung. Beim Abmelden wird die Zuordnung gelöscht. Firebase verarbeitet die für die Push-Zustellung erforderlichen Gerätedaten.') }}</p>
<p>{{ _('Bugmeldungen werden mit Benutzername und User-ID an unser internes Gitea-Ticketsystem übertragen. Technische Zusatzinformationen werden nur auf Wunsch mitgesendet. Lokale Versandkennungen zur Vermeidung doppelter Meldungen laufen nach 24 Stunden ab.') }}</p>
<h2>{{ _('Deine Rechte') }}</h2>
<p>{{ _('Du kannst Auskunft, Berichtigung, Löschung, Einschränkung der Verarbeitung und soweit anwendbar Datenübertragbarkeit verlangen. Einen Export deiner gespeicherten Anwendungsdaten findest du klein am Ende des eigenen Profilbereichs. Anfragen bitte an') }} <a href="mailto:konzert@pinguholic.de">konzert@pinguholic.de</a>.</p>
<h2>{{ _('Cookies und Sicherheit') }}</h2>
+1
View File
@@ -39,5 +39,6 @@
</form>
</section>
</main>
{% include '_native_push.html' %}
</body>
</html>
+1
View File
@@ -88,5 +88,6 @@
</form>
{% include '_native_push.html' %}
</body>
</html>