Setzt die Reihenfolge aus docs/EXTRAKTION.md um. **Qualitätssignal statt Vermutung.** `articleQuality()` unterscheidet vier Zustände: ok · unextracted (kein Text, aber keine Wand → Server-Versuch lohnt) · blocked (Quelle hat die Zustimmungsseite geliefert → Server kann das prinzipiell nicht lösen) · thin. Vorher beantwortete eine einzige Funktion zwei verschiedene Fragen und war deshalb an beiden Aufrufstellen ein Stück falsch — die eigenen Tests haben das aufgedeckt. Jetzt getrennt: `titleIsJustHost` für „ist der Titel unbrauchbar", `articleQuality` für „was ist mit dem Artikel los". **Neu extrahieren.** Der Web-Client emittiert jetzt `ArticleEnriched` — einzeln im Reader, als Stapel in der Liste („N ohne Text neu holen", seriell, weil jeder Versuch ein Fetch auf eine fremde Seite ist). Das Event lag samt nicht-destruktivem Reducer schon im Schema, wurde aber nur von Native genutzt. Kein Schema-Bump nötig. **Wand-Erkennung ohne Raten.** `redirectedToWall()` prüft das Redirect-Ziel: wer eine Artikel-URL anfragt und auf /sonstiges/zustimmung/ landet, hat keinen Artikel bekommen — unabhängig von der Wortzahl. Die alte Schwelle (300 Wörter) lag bei Golem mit 254 knapp richtig, hätte eine ausführlichere Consent-Seite aber durchgelassen. Dazu ein Metadaten-Fallback: hinter der Wand wenigstens og:title/og:description retten, damit die Karte nicht „golem.de" heisst. **Browser-Erweiterung** (apps/extension, MV3, Chrome + Firefox). Ein Klick speichert die gerenderte Seite mitsamt Sitzung — der einzige Weg an harte Wände. Nutzt denselben /lese-liste/add/receive-Transport wie das Bookmarklet, damit es einen gepflegten Eingang gibt statt zweier. Bewusst ohne API-Schlüssel, ohne dauerhafte Leseerlaubnis (activeTab), ohne Telemetrie; ein check.mjs wacht darüber, dass die Berechtigungen nicht stillschweigend wachsen. **Und ein ehrlicheres Schild.** Auf den Karten stand bisher „Cookie-Wand" auch dort, wo gar keine gemeldet war — genau das zeigte der Screenshot vom 27.07. Jetzt „Quelle blockiert" vs. „Ohne Text", mit je einer Aktion, die zum Zustand passt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
58 lines
1.8 KiB
JavaScript
58 lines
1.8 KiB
JavaScript
/**
|
|
* Einstellungen der Pageta-Erweiterung: nur die Instanz-Adresse.
|
|
*
|
|
* Bewusst das einzige, was hier einstellbar ist. Alles andere (Anmeldung,
|
|
* Darstellung, KI-Quelle) gehört in die App, nicht in die Erweiterung —
|
|
* sonst gibt es zwei Orte für dieselbe Wahrheit.
|
|
*/
|
|
|
|
const api = typeof browser !== 'undefined' ? browser : chrome;
|
|
|
|
const DEFAULT_INSTANCE = 'https://app.pageta.com';
|
|
const field = document.getElementById('instance');
|
|
const status = document.getElementById('status');
|
|
|
|
function say(text, ok = true) {
|
|
status.textContent = text;
|
|
status.style.color = ok ? '' : 'var(--fg)';
|
|
}
|
|
|
|
api.storage.sync.get('instance').then((stored) => {
|
|
field.value = stored?.instance ?? '';
|
|
});
|
|
|
|
document.getElementById('save').addEventListener('click', async () => {
|
|
const raw = field.value.trim();
|
|
|
|
if (!raw) {
|
|
await api.storage.sync.remove('instance');
|
|
say(`Gespeichert — es gilt wieder ${DEFAULT_INSTANCE}.`);
|
|
return;
|
|
}
|
|
|
|
let origin;
|
|
try {
|
|
origin = new URL(raw).origin;
|
|
} catch {
|
|
say('Das ist keine vollständige Adresse. Beispiel: https://pageta.example', false);
|
|
return;
|
|
}
|
|
|
|
if (!origin.startsWith('https://') && !origin.startsWith('http://localhost')) {
|
|
say('Nur https — oder http://localhost für die eigene Entwicklung.', false);
|
|
return;
|
|
}
|
|
|
|
// Für eine fremde Instanz braucht die Erweiterung die Erlaubnis, dorthin
|
|
// zu senden. Wir fragen sie hier, damit der Klick später nicht still
|
|
// scheitert.
|
|
const pattern = `${origin}/`;
|
|
const granted = await api.permissions.request({ origins: [pattern] }).catch(() => false);
|
|
if (!granted) {
|
|
say('Ohne die Erlaubnis für diese Adresse kann die Erweiterung dort nicht speichern.', false);
|
|
return;
|
|
}
|
|
|
|
await api.storage.sync.set({ instance: origin });
|
|
say(`Gespeichert — Artikel gehen jetzt an ${origin}.`);
|
|
});
|