This release adds a stats page and richer empty states with reading streaks, favicons, and a confetti celebration for owners; improves the premium upgrade flow with a privateIntent option so paying users can go private in one step; switches Twitter metadata extraction to the vxtwitter API for better title coverage; adds fuzzy duplicate detection for saved links; and ships a comprehensive Playwright E2E test suite covering registration, keyboard shortcuts, payment flows, and session handling.
New
- Stats page and per-user reading statsA new /~/stats page is now linked from the help page. Per-user stats now track streak, today's reads, median daily reads, pace (average days from save to read), top domains with favicons, and a global aggregate view across all users.
e2ddb640784bf3f9ce5fc4d55a40 - Richer empty states for owners, visitors, and the homepageThe empty-list view for owners now shows reading stats, a streak counter, favicon thumbnails of top domains, and a confetti celebration. Visitors, the homepage, and the 404 page each get distinct prose empty states. A nudge message appears until stats unlock at a threshold read count.
e2ddb640784bf32d8c4e9cabb60a - Premium upgrade flow supports going private in one paymentA new privateIntent option threads through the Stripe checkout and webhook so that clicking the lock button as a non-premium user on a short username triggers payment and enables private mode in a single step. The owner of an unpaid short username now sees a pay button; visitors see a normal profile rather than a payment-required message.
d3384a9cabb60a
Improved
- Save script falls back to a random Lobsters story when no URL is givenRunning the save script without a URL argument now fetches a random story from Lobsters and saves it, making it easier to seed a local database for development.
f9ce5fc
Fixed
- Twitter/X metadata now uses the vxtwitter APILink titles for tweets and X articles are fetched via the vxtwitter API, fixing cases where URL-only tweets showed a t.co URL as the title instead of the article headline.
113e7dc - Fuzzy duplicate detection catches near-identical link titlesThe duplicate check now uses 80% prefix similarity instead of exact title matching, so variants like titles with '[video]' or '| Hacker News' suffixes, or cases where the new title is a prefix of an existing one, are correctly identified as duplicates.
8912fac - Empty state visibility fixed when reading the last articleThe CSS :has() selector was not re-evaluating after HTMX removed items via out-of-band swaps. An explicit toggleEmptyState() call now shows or hides the empty state element whenever the list changes.
2120954