Filipe, 22.09.2026: "ersetze die zentrale durch, Die IrrenAnstalt.
genau so geschrieben bitte. und alles was treff heißt oder wo treff
steht soll durch Rudel ersetzt werden bitte."
Die Schreibweise "IrrenAnstalt" mit grossem A in der Mitte ist so
gewollt. Das steht als Hinweis daneben, damit sie beim naechsten Mal
niemand "korrigiert".
WAS UMBENANNT WURDE: alles, was jemand LIEST -- Kachelnamen,
Ueberschriften, Markenzeilen, Saetze, Meldungen, Aufgabenvorlagen.
116 Zeilen in 42 Dateien.
WAS BLEIBT: Adressen (treff-regeln.html), Bezeichner (TREFF_ROLLEN),
Datenbankwerte (bereich = 'treff'), Abfrageteile (b=treff). Eine
Adresse umzubenennen bricht jedes Lesezeichen, und ein Datenbankwert
umzuschreiben waere eine Umstellung ohne Gegenwert. Dieselbe
Entscheidung wie heute frueh bei Dogi-Media, wo material.html auch
material.html geblieben ist.
DREI GRAMMATIKFEHLER IM EIGENEN ENTWURF, alle vor dem Ausliefern
gefunden -- ein blindes Ersetzen reicht hier nicht:
1. "der Treff" ist maennlich, "das Rudel" saechlich. Ohne Tabelle
waere ueberall "Der Rudel" gestanden. (Und "Treffer" waere zu
"Rudeler" geworden, "Treffen" zu "Rudelen" -- deshalb greift die
Regel nur bei Wortgrenze und nie vor einem Kleinbuchstaben.)
2. BINDESTRICH-ZUSAMMENSETZUNGEN. In "der Treff-Chat" gehoert der
Artikel zu "Chat", nicht zu "Treff". Der erste Durchlauf machte
daraus "das Rudel-Chat", "das Rudel-Kacheln" und "ein Rudel-Raum".
Jetzt greift die Artikelregel nur, wenn das Wort allein steht.
3. GESCHUETZTE LEERZEICHEN. In den Markenzeilen steht
`Der Treff`, damit die zwei Woerter nicht umbrechen. Das
Muster hat daran vorbeigegriffen: "Der Rudel", auf fuenf
Seiten. Jetzt wird das Trennzeichen mitgefasst und unveraendert
wieder eingesetzt.
Gefunden wurden alle drei, weil jede einzelne der 116 Zeilen vor dem
Schreiben als ALT/NEU ausgegeben und gelesen wurde -- und danach
gezielt nach falschen Artikeln gesucht ("den Rudel", "der Rudel",
"einen Rudel"). Uebrig blieben sechs Treffer, und die sind alle
richtig: "einen Rudel-Raum", "der Rudel-Chat", "den Rudel-Regeln" --
Zusammensetzungen, bei denen der Artikel zum letzten Wort gehoert.
UND ZWEI PRUEFUNGEN, die die Umbenennung nicht mitbekommen haetten:
`/Treff/.test(...)` und `/Treff/i.test(...)`. Ein regulaerer Ausdruck
ist keine Zeichenkette -- sie haetten ab sofort nach einem Wort
gesucht, das die Seite nicht mehr sagt, und waeren still rot geworden,
ohne dass etwas kaputt ist.
Geprueft, alle gruen: pruef-treff, pruef-treffchat,
pruef-deutsche-texte, pruef-uebernahme, pruef-crew-adresse,
pruef-willkommen, pruef-wege-nach-draussen, pruef-vorlagen,
pruef-start-ansicht, pruef-struktur.
Co-Authored-By: Claude Opus 5 <[email protected]>
181 lines
6.9 KiB
JavaScript
181 lines
6.9 KiB
JavaScript
/* =====================================================================
|
||
AUS „TEILEN" WIRD EIN TIPP (17.09.2026) — Schritt 4 des Video-Plans
|
||
|
||
Filipe: „damit meine videos auch da auf der app rein kommen … sobald
|
||
ich ein video poste erscheint es sofort in der app."
|
||
|
||
Diese Seite ist das Ziel des Teilen-Menüs auf dem Handy. Sie liest,
|
||
was angekommen ist, zeigt es und trägt es auf Tipp ein.
|
||
|
||
---------------------------------------------------------------------
|
||
DER STOLPERSTEIN, DEN JEDE ANLEITUNG VERSCHWEIGT
|
||
|
||
Das Teilen-Ziel im Manifest kennt drei Felder: `title`, `text`,
|
||
`url`. Man erwartet, dass der Link in `url` steht.
|
||
|
||
TUT ER MEISTENS NICHT. Android-Apps – TikTok eingeschlossen – teilen
|
||
in aller Regel als reinen Text: `text` enthält dann einen Satz, in
|
||
dem die Adresse irgendwo drinsteht („Sieh dir das an!
|
||
https://vm.tiktok.com/xyz/"), und `url` ist leer. Wer nur `url`
|
||
liest, bekommt eine leere Seite und weiß nicht, warum.
|
||
|
||
Deshalb wird in ALLEN drei Feldern gesucht, und zwar nach einem
|
||
Muster, nicht nach einem Feldnamen.
|
||
|
||
---------------------------------------------------------------------
|
||
UND SIE TRÄGT NICHT VON SELBST EIN
|
||
|
||
Sie kann nicht wissen, ob der Griff in die Tasche gemeint war. Ein
|
||
Video, das ungefragt in den Highlights landet, muss jemand wieder
|
||
löschen — und das ist mehr Arbeit als ein Tipp auf „Übernehmen".
|
||
===================================================================== */
|
||
(() => {
|
||
'use strict';
|
||
const $ = (id) => document.getElementById(id);
|
||
const el = (art, klasse, text) => {
|
||
const n = document.createElement(art);
|
||
if (klasse) n.className = klasse;
|
||
if (text !== undefined) n.textContent = text;
|
||
return n;
|
||
};
|
||
|
||
const melde = (t) => { const f = $('fehler'); if (f) f.textContent = t || ''; };
|
||
|
||
/* WOHIN ES GEHEN KANN. Highlights zuerst und vorausgewählt – dort
|
||
gehören Videos hin. Die beiden anderen sind die Fälle, in denen
|
||
ein Clip etwas anderes ist: eine Antwort auf einen Wunsch oder
|
||
eine Ansage. */
|
||
const BRETTER = [
|
||
{ wert: 'highlight', name: 'Highlights', satz: 'Die Videos der Community.' },
|
||
{ wert: 'treff', name: 'Das Rudel', satz: 'Wenn es eher ein Gesprächsanlass ist.' },
|
||
{ wert: 'anschlag', name: 'Anschlagbrett', satz: 'Wenn es eine Ansage ist.' },
|
||
];
|
||
let brett = 'highlight';
|
||
|
||
/* ---------------------------------------------------------------------
|
||
DEN LINK FINDEN
|
||
------------------------------------------------------------------- */
|
||
|
||
/** Die erste Adresse in einem Text. Ohne abschliessende Satzzeichen —
|
||
* „… https://vm.tiktok.com/xyz/." endet nicht auf einen Punkt. */
|
||
function adresseAus(text) {
|
||
const treffer = String(text || '').match(/https?:\/\/[^\s<>"']+/i);
|
||
if (!treffer) return '';
|
||
return treffer[0].replace(/[.,;:!?)\]]+$/, '');
|
||
}
|
||
|
||
/** Aus dem, was das Teilen-Menü geschickt hat. */
|
||
function geteilterLink() {
|
||
const p = new URLSearchParams(location.search);
|
||
/* IN DIESER REIHENFOLGE: `url` ist das saubere Feld, wenn es
|
||
gefüllt ist. `text` ist der Normalfall bei Android. `title`
|
||
enthält bei manchen Apps den Link, wenn sonst nichts da ist. */
|
||
for (const feld of ['url', 'text', 'title']) {
|
||
const a = adresseAus(p.get(feld));
|
||
if (a) return a;
|
||
}
|
||
return '';
|
||
}
|
||
|
||
/* ---------------------------------------------------------------------
|
||
DIE SEITE
|
||
------------------------------------------------------------------- */
|
||
function brettwahlBauen() {
|
||
const ziel = $('bretter');
|
||
ziel.textContent = '';
|
||
for (const b of BRETTER) {
|
||
const k = el('button', 'tl-brett');
|
||
k.type = 'button';
|
||
k.dataset.brett = b.wert;
|
||
k.setAttribute('aria-pressed', String(brett === b.wert));
|
||
k.append(el('span', 'tl-brett-name', b.name));
|
||
k.append(el('span', 'tl-brett-satz', b.satz));
|
||
k.addEventListener('click', () => {
|
||
brett = b.wert;
|
||
for (const x of ziel.querySelectorAll('.tl-brett')) {
|
||
x.setAttribute('aria-pressed', String(x.dataset.brett === brett));
|
||
}
|
||
});
|
||
ziel.append(k);
|
||
}
|
||
}
|
||
|
||
async function uebernehmen(url) {
|
||
const knopf = $('uebernehmen');
|
||
knopf.disabled = true;
|
||
const alterText = knopf.textContent;
|
||
knopf.textContent = 'wird geholt …';
|
||
melde('');
|
||
try {
|
||
const a = await fetch(`/workspace/api/bereich/${brett}/video`, {
|
||
method: 'POST',
|
||
credentials: 'same-origin',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ url }),
|
||
});
|
||
const daten = await a.json().catch(() => null);
|
||
if (!a.ok) {
|
||
melde(sagWas(daten?.fehler, 'Das hat nicht geklappt.'));
|
||
knopf.disabled = false;
|
||
knopf.textContent = alterText;
|
||
return;
|
||
}
|
||
/* FERTIG. Der Weg dorthin steht als Knopf da – wer teilt, will
|
||
meistens gleich sehen, wie es aussieht. */
|
||
$('fund').hidden = true;
|
||
$('wahl').hidden = true;
|
||
$('knoepfe').hidden = true;
|
||
$('haendisch').hidden = true;
|
||
const name = BRETTER.find((b) => b.wert === brett)?.name || brett;
|
||
$('fertig-satz').textContent = daten?.schon
|
||
? `Das Video lag schon bei „${name}“ – es wurde kein zweites angelegt.`
|
||
: `Angekommen bei „${name}“.`
|
||
+ (daten?.titel ? ` Titel: „${daten.titel}“` : '');
|
||
$('hin').href = `bereich.html?b=${encodeURIComponent(brett)}`;
|
||
$('fertig').hidden = false;
|
||
} catch {
|
||
melde('Keine Verbindung. Versuch es gleich noch einmal.');
|
||
knopf.disabled = false;
|
||
knopf.textContent = alterText;
|
||
}
|
||
}
|
||
|
||
function los() {
|
||
const teilen = $('teilen');
|
||
const link = geteilterLink();
|
||
$('ladezeile').hidden = true;
|
||
teilen.setAttribute('aria-busy', 'false');
|
||
brettwahlBauen();
|
||
$('wahl').hidden = false;
|
||
$('knoepfe').hidden = false;
|
||
|
||
if (link) {
|
||
$('url-text').textContent = link;
|
||
$('fund').hidden = false;
|
||
} else {
|
||
/* KEIN LINK DABEI. Das ist kein Fehler – manche Apps teilen nur
|
||
einen Text ohne Adresse, und manchmal kommt jemand einfach so
|
||
auf diese Seite. Ein Feld zum Einfügen ist die freundlichere
|
||
Antwort als eine Meldung. */
|
||
$('haendisch').hidden = false;
|
||
$('eingabe').focus();
|
||
}
|
||
|
||
$('uebernehmen').addEventListener('click', () => {
|
||
const url = link || $('eingabe')?.value?.trim();
|
||
if (!url) { melde('Da fehlt noch der Link zum Video.'); $('eingabe')?.focus(); return; }
|
||
uebernehmen(url);
|
||
});
|
||
|
||
/* Enter im Feld tut dasselbe wie der Knopf. Wer auf dem Handy
|
||
tippt, drückt die grüne Taste und nicht daneben. */
|
||
$('eingabe')?.addEventListener('keydown', (e) => {
|
||
if (e.key === 'Enter') { e.preventDefault(); $('uebernehmen').click(); }
|
||
});
|
||
}
|
||
|
||
if (document.readyState === 'loading') {
|
||
document.addEventListener('DOMContentLoaded', los);
|
||
} else { los(); }
|
||
})();
|