pageta/apps/extension/options.html
Till JS d56e007637 feat: Extraktion — Zustände trennen, reparieren, und der Weg an harte Wände
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>
2026-07-27 00:58:47 +02:00

97 lines
2 KiB
HTML

<meta charset="utf-8" />
<title>Pageta — Einstellungen</title>
<style>
:root {
color-scheme: light dark;
--bg: #f6f2ec;
--fg: #1c1e26;
--muted: #5b606e;
--border: #d9d8d2;
--surface: #fffdfa;
--primary: #8a6a4f;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #1a1614;
--fg: #e8e2d9;
--muted: #9a9088;
--border: #463e39;
--surface: #241f1c;
--primary: #d9ab86;
}
}
body {
margin: 0;
padding: 1.5rem;
min-width: 22rem;
background: var(--bg);
color: var(--fg);
font:
14px/1.55 system-ui,
-apple-system,
'Segoe UI',
sans-serif;
}
h1 {
margin: 0 0 0.25rem;
font-size: 1.05rem;
}
p {
margin: 0 0 1rem;
color: var(--muted);
}
label {
display: block;
margin-bottom: 0.35rem;
font-weight: 500;
}
input {
width: 100%;
box-sizing: border-box;
min-height: 2.75rem;
padding: 0.5rem 0.7rem;
border: 1px solid var(--border);
border-radius: 0.5rem;
background: var(--surface);
color: inherit;
font: inherit;
}
input:focus-visible {
outline: 2px solid var(--primary);
outline-offset: 2px;
}
button {
margin-top: 0.9rem;
min-height: 2.75rem;
padding: 0.5rem 1rem;
border: 1px solid transparent;
border-radius: 0.5rem;
background: var(--primary);
color: var(--bg);
font: inherit;
font-weight: 500;
cursor: pointer;
}
.hint,
#status {
margin-top: 0.7rem;
font-size: 0.85rem;
color: var(--muted);
}
</style>
<h1>Pageta-Adresse</h1>
<p>Wohin die Erweiterung speichert. Leer lassen, wenn du app.pageta.com nutzt.</p>
<label for="instance">Adresse deiner Pageta-Instanz</label>
<input id="instance" type="url" placeholder="https://app.pageta.com" />
<button id="save">Speichern</button>
<p id="status" role="status"></p>
<p class="hint">
Die Erweiterung liest eine Seite nur, wenn du auf ihr Symbol klickst — sie
sieht deinen Verlauf nicht. Sie speichert keinen Schlüssel; es zählt die
Anmeldung, die dein Browser ohnehin hat.
</p>
<script src="options.js"></script>