"Since you last visited" cue + PWA install (add to home screen)
Two calm returning-reader features. Since-last-visit (Highlights companion, not a nav lane — per Codex): * queries.feed gains a `since` filter; GET /api/since?ts= returns the count + a few accepted/non-dup/visible articles discovered since the reader's last visit (boundary-respecting; invalid/future ts → 0, no error). * Home stores last_seen in localStorage (reads prev, then stamps now); on Highlights, a gentle "Since you were last here, N new calm reads came in" note with a "See what's new" reveal of a compact inline section. Dismissible. No badges, no unread counts, no "missed" language. PWA: * Real PNG icons (192/512 + full-bleed maskable) rasterized from favicon.svg; manifest fixed (azure theme to match the brand, PNG icons); apple-touch-icon. * Minimal service worker: precache the app shell, always-fresh API + /a/ pages. * Gentle, dismissible install banner (beforeinstallprompt → Install; iOS → the Share → Add to Home Screen hint). Never nags. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -265,3 +265,19 @@ def test_follows_and_following_feed(tmp_path, monkeypatch):
|
||||
assert TestClient(app).get("/api/feed?following=true").json()["count"] == 0
|
||||
assert TestClient(app).get("/api/follows").status_code == 401
|
||||
assert tc.post("/api/follows", json={"kind": "source", "value": "999"}).status_code == 404
|
||||
|
||||
|
||||
def test_since_endpoint(tmp_path, monkeypatch):
|
||||
import os, sqlite3
|
||||
app, api = _make(tmp_path, monkeypatch, admin_email="boss@x.com")
|
||||
c = sqlite3.connect(os.environ["GOODNEWS_DB"])
|
||||
for aid, when in [(2, "2020-01-01 00:00:00"), (3, "2030-01-01 00:00:00")]:
|
||||
c.execute("INSERT INTO articles (id,source_id,canonical_url,title,url_hash,discovered_at) VALUES (?,1,?,?,?,?)",
|
||||
(aid, f"http://s/{aid}", f"t{aid}", f"h{aid}", when))
|
||||
c.execute("INSERT INTO article_scores (article_id,accepted) VALUES (?,1)", (aid,))
|
||||
c.commit(); c.close()
|
||||
tc = TestClient(app)
|
||||
r = tc.get("/api/since?ts=2027-01-01T00:00:00Z").json()
|
||||
assert r["count"] == 1 and [i["id"] for i in r["items"]] == [3] # only the post-2027 article
|
||||
assert tc.get("/api/since?ts=2099-01-01T00:00:00Z").json()["count"] == 0 # nothing newer
|
||||
assert tc.get("/api/since?ts=not-a-date").json()["count"] == 0 # invalid ts → quiet 0
|
||||
|
||||
Reference in New Issue
Block a user