Flixy heißt ab hier Halo
Reine Umbenennung, kein Verhalten geändert — bewusst als eigener Commit, damit „umbenannt" und „umgebaut" im Nachhinein auseinanderzuhalten sind. 712 mal `Flixy`, 778 mal `flixy`, 7 mal `FLIXY` in 169 Dateien, dazu 25 Pfade. Ziele: `Halo`, `HaloTV`, `HaloTopShelf`, `HaloUITests`, `HaloKit` mit `HaloDesign`, `HaloDownloads`, `HaloPlayback` und `HaloProbe`. `MediaKit`, `JellyfinKit` und `DownloadWidget` tragen den Namen nicht und bleiben. `docs/superpowers/specs/` ist ausgenommen. Datierte Entwurfsdokumente sind ein Protokoll getroffener Entscheidungen; sie nachträglich umzuschreiben hiesse, die Vergangenheit zu glätten. **Die Bundle-ID wandert mit** — ausdrücklich so gewollt, mit bekanntem Preis: `com.scarriffleservices.halo` ist für iOS eine *andere* App. Die installierte Fassung bleibt daneben stehen, mit Downloads und Anmeldung in ihrem Container; Halo startet leer. Einmal neu anmelden, heruntergeladene Folgen einmal neu laden. Dasselbe gilt für die App-Gruppe, die sich TV-App und Top Shelf teilen. **Eine Folge davon, die beim Entscheiden noch nicht auf dem Tisch lag:** der Aufräumschritt aus dem vorigen Commit kommt an die alten Plex-Token nicht mehr heran. Der Schlüsselbund grenzt nach Team und Bundle-Kennung ab — was unter `…flixy` liegt, ist für `…halo` unerreichbar. Erledigt wird es trotzdem, nur anders: **die alte App löschen.** iOS räumt deren Schlüsselbund-Einträge beim Deinstallieren mit ab. Der Code bleibt stehen, weil er für jeden Stand vor dieser Umbenennung richtig ist und im Jahr einen Startvergleich kostet. Die Projektdatei ist aus `project.yml` neu erzeugt, der alte Ordner gelöscht statt umbenannt — sie steht ohnehin nicht im Repo. Das Verzeichnis des Repos selbst heißt weiter `Flixy`; das umzubenennen ist ein Handgriff ausserhalb des Projekts. 368 Tests grün. iOS und tvOS bauen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
2fcf6821c8
commit
4b9a1e7b67
+37
-37
@@ -3,12 +3,12 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<title>Flixy</title>
|
||||
<title>Halo</title>
|
||||
<style>
|
||||
/* ============================================================================
|
||||
Flixy Web — ein Frontend für Jellyfin
|
||||
Halo Web — ein Frontend für Jellyfin
|
||||
----------------------------------------------------------------------------
|
||||
Die Werte stammen aus FlixyDesign, nicht aus dem Augenmaß: dieselben
|
||||
Die Werte stammen aus HaloDesign, nicht aus dem Augenmaß: dieselben
|
||||
Flächen, dieselben Radien, dieselben Abstände wie in der App.
|
||||
========================================================================= */
|
||||
:root {
|
||||
@@ -568,7 +568,7 @@ input[type=range] { width: 100%; accent-color: var(--accent); }
|
||||
<!-- ---------- Anmeldung ---------- -->
|
||||
<section id="login">
|
||||
<form class="login-card" id="login-form">
|
||||
<h1>Flixy</h1>
|
||||
<h1>Halo</h1>
|
||||
<p class="sub">Deine Mediathek, schöner.</p>
|
||||
<div class="field">
|
||||
<label for="server">Serveradresse</label>
|
||||
@@ -607,18 +607,18 @@ input[type=range] { width: 100%; accent-color: var(--accent); }
|
||||
Jellyfin die Zeile falsch und meldet, man sei nicht angemeldet.
|
||||
========================================================================= */
|
||||
const S = {
|
||||
base: localStorage.getItem('flixy.server') || '',
|
||||
token: localStorage.getItem('flixy.token') || '',
|
||||
userId: localStorage.getItem('flixy.user') || '',
|
||||
deviceId: localStorage.getItem('flixy.device') || (() => {
|
||||
const id = 'flixy-web-' + Math.random().toString(36).slice(2, 12);
|
||||
localStorage.setItem('flixy.device', id); return id;
|
||||
base: localStorage.getItem('halo.server') || '',
|
||||
token: localStorage.getItem('halo.token') || '',
|
||||
userId: localStorage.getItem('halo.user') || '',
|
||||
deviceId: localStorage.getItem('halo.device') || (() => {
|
||||
const id = 'halo-web-' + Math.random().toString(36).slice(2, 12);
|
||||
localStorage.setItem('halo.device', id); return id;
|
||||
})(),
|
||||
};
|
||||
|
||||
function authHeader() {
|
||||
const f = [
|
||||
'Client="Flixy Web"', 'Device="Browser"',
|
||||
'Client="Halo Web"', 'Device="Browser"',
|
||||
`DeviceId="${S.deviceId}"`, 'Version="0.1"',
|
||||
];
|
||||
if (S.token) f.push(`Token="${S.token}"`);
|
||||
@@ -675,9 +675,9 @@ el('login-form').addEventListener('submit', async (e) => {
|
||||
body: JSON.stringify({ Username: el('user').value, Pw: el('pass').value }),
|
||||
});
|
||||
S.token = r.AccessToken; S.userId = r.User.Id;
|
||||
localStorage.setItem('flixy.server', S.base);
|
||||
localStorage.setItem('flixy.token', S.token);
|
||||
localStorage.setItem('flixy.user', S.userId);
|
||||
localStorage.setItem('halo.server', S.base);
|
||||
localStorage.setItem('halo.token', S.token);
|
||||
localStorage.setItem('halo.user', S.userId);
|
||||
start();
|
||||
} catch (e2) {
|
||||
err.textContent = /Failed to fetch/.test(e2.message)
|
||||
@@ -689,7 +689,7 @@ el('login-form').addEventListener('submit', async (e) => {
|
||||
});
|
||||
|
||||
function signOut() {
|
||||
['flixy.server', 'flixy.token', 'flixy.user'].forEach((k) => localStorage.removeItem(k));
|
||||
['halo.server', 'halo.token', 'halo.user'].forEach((k) => localStorage.removeItem(k));
|
||||
location.reload();
|
||||
}
|
||||
|
||||
@@ -707,28 +707,28 @@ const PALETTE = [
|
||||
];
|
||||
|
||||
const P = {
|
||||
accent: localStorage.getItem('flixy.accent') || '#C04AC9',
|
||||
nav: localStorage.getItem('flixy.nav') || 'top', // 'top' | 'side'
|
||||
cardW: +(localStorage.getItem('flixy.cardW') || 150),
|
||||
accent: localStorage.getItem('halo.accent') || '#C04AC9',
|
||||
nav: localStorage.getItem('halo.nav') || 'top', // 'top' | 'side'
|
||||
cardW: +(localStorage.getItem('halo.cardW') || 150),
|
||||
// Startseite — dieselben Stellschrauben wie in der App.
|
||||
heroSource: localStorage.getItem('flixy.heroSource') || 'continueFirst',
|
||||
heroCount: +(localStorage.getItem('flixy.heroCount') || 5),
|
||||
heroHeight: +(localStorage.getItem('flixy.heroHeight') || 82),
|
||||
combineContinue: localStorage.getItem('flixy.combineContinue') !== 'false',
|
||||
hideWatched: localStorage.getItem('flixy.hideWatched') === 'true',
|
||||
heroSource: localStorage.getItem('halo.heroSource') || 'continueFirst',
|
||||
heroCount: +(localStorage.getItem('halo.heroCount') || 5),
|
||||
heroHeight: +(localStorage.getItem('halo.heroHeight') || 82),
|
||||
combineContinue: localStorage.getItem('halo.combineContinue') !== 'false',
|
||||
hideWatched: localStorage.getItem('halo.hideWatched') === 'true',
|
||||
// Welche Reihen ausgeblendet sind und in welcher Reihenfolge der Rest
|
||||
// steht — dieselbe Aufteilung wie `Arrangement` in der App.
|
||||
hiddenRows: JSON.parse(localStorage.getItem('flixy.hiddenRows') || '[]'),
|
||||
rowOrder: JSON.parse(localStorage.getItem('flixy.rowOrder') || '[]'),
|
||||
hiddenRows: JSON.parse(localStorage.getItem('halo.hiddenRows') || '[]'),
|
||||
rowOrder: JSON.parse(localStorage.getItem('halo.rowOrder') || '[]'),
|
||||
// Wiedergabe — dieselben Stufen wie in der App, damit derselbe Begriff
|
||||
// überall dasselbe heißt.
|
||||
rate: +(localStorage.getItem('flixy.rate') || 1.0),
|
||||
skipForward: +(localStorage.getItem('flixy.skipForward') || 30),
|
||||
skipBackward: +(localStorage.getItem('flixy.skipBackward') || 10),
|
||||
quality: +(localStorage.getItem('flixy.quality') || 0), // 0 = Original
|
||||
rate: +(localStorage.getItem('halo.rate') || 1.0),
|
||||
skipForward: +(localStorage.getItem('halo.skipForward') || 30),
|
||||
skipBackward: +(localStorage.getItem('halo.skipBackward') || 10),
|
||||
quality: +(localStorage.getItem('halo.quality') || 0), // 0 = Original
|
||||
// Sprachen. Leer heißt: was der Server vorgibt.
|
||||
audioLanguage: localStorage.getItem('flixy.audioLanguage') || '',
|
||||
subtitleLanguage: localStorage.getItem('flixy.subtitleLanguage') || '',
|
||||
audioLanguage: localStorage.getItem('halo.audioLanguage') || '',
|
||||
subtitleLanguage: localStorage.getItem('halo.subtitleLanguage') || '',
|
||||
};
|
||||
|
||||
/// Die Stufen der App, damit die Begriffe sich decken.
|
||||
@@ -759,7 +759,7 @@ function setPref(key, value) {
|
||||
P[key] = value;
|
||||
// Listen müssen als JSON abgelegt werden — ein Array landete sonst als
|
||||
// "a,b,c" im Speicher und käme als Zeichenkette zurück.
|
||||
localStorage.setItem('flixy.' + key, Array.isArray(value) ? JSON.stringify(value) : value);
|
||||
localStorage.setItem('halo.' + key, Array.isArray(value) ? JSON.stringify(value) : value);
|
||||
applyPrefs();
|
||||
}
|
||||
|
||||
@@ -833,7 +833,7 @@ function buildIsland() {
|
||||
|
||||
// Die Marke steht nur in der Spalte — oben nähme sie Platz weg, den die
|
||||
// Einträge brauchen.
|
||||
bit('brand', 'Flixy');
|
||||
bit('brand', 'Halo');
|
||||
add('Start', 'home');
|
||||
add('Einstellungen', 'settings');
|
||||
|
||||
@@ -929,7 +929,7 @@ function go(key) {
|
||||
/* ---------- Einstellungen ---------- */
|
||||
/* Kontrastrechnung nach WCAG 2.1 — dieselbe wie in der App.
|
||||
----------------------------------------------------------------------------
|
||||
Flixy lässt jede Farbe zu, aber ein dunkles Marineblau auf fast schwarzem
|
||||
Halo lässt jede Farbe zu, aber ein dunkles Marineblau auf fast schwarzem
|
||||
Grund ist als Schrift unlesbar. Solche Farben werden angehoben, bis sie den
|
||||
geforderten Kontrast erreichen — und es wird gesagt, statt die Farbe
|
||||
stillschweigend zu verändern.
|
||||
@@ -1809,7 +1809,7 @@ function openPlayer(item) {
|
||||
const anteil = lauf.sitzung?.stelle && v.duration
|
||||
? lauf.sitzung.stelle / v.duration : 0;
|
||||
if (anteil > 0 && anteil < 0.05) {
|
||||
console.info(`[Flixy] Bei ${(anteil * 100).toFixed(1)} % beendet — `
|
||||
console.info(`[Halo] Bei ${(anteil * 100).toFixed(1)} % beendet — `
|
||||
+ 'Jellyfin merkt sich das erst ab 5 %. Einstellbar im Dashboard unter '
|
||||
+ 'Wiedergabe → Fortsetzen.');
|
||||
}
|
||||
@@ -2114,9 +2114,9 @@ function wireProgress(video, session) {
|
||||
...extra,
|
||||
}),
|
||||
}).then(() => {
|
||||
console.debug(`[Flixy] ${path} → ${(stelle / 60).toFixed(1)} min angenommen`);
|
||||
console.debug(`[Halo] ${path} → ${(stelle / 60).toFixed(1)} min angenommen`);
|
||||
}).catch((e) => {
|
||||
console.warn(`[Flixy] ${path} abgelehnt: ${e.message}`);
|
||||
console.warn(`[Halo] ${path} abgelehnt: ${e.message}`);
|
||||
});
|
||||
};
|
||||
session.melden = send;
|
||||
|
||||
Reference in New Issue
Block a user