From 35850eaf73cfe930104bd44950654b2178d4f657 Mon Sep 17 00:00:00 2001 From: prosolis <5590409+prosolis@users.noreply.github.com> Date: Tue, 7 Jul 2026 01:25:23 -0700 Subject: [PATCH] Fix push-digest sentinel filter, watermark, and cleanups from review - push digest queries now exclude _duplicate channel like every other visibility query (bookmarks list/count and NewClassifiedSince) - advance push watermark to newest scanned story, not pass-start now, so stories arriving during a long send pass aren't re-counted next pass - replace hand-rolled escapeHTMLText with stdlib html.EscapeString - drop em-dashes from user-facing copy; bump PWA CACHE_VERSION so clients pick up the changed shell assets --- internal/storage/push.go | 2 +- internal/storage/userstate.go | 4 +++- internal/web/feed.go | 15 ++------------- internal/web/push_sender.go | 9 ++++++--- internal/web/static/js/pwa.js | 2 +- internal/web/static/js/reader.js | 2 +- internal/web/static/sw.js | 4 ++-- 7 files changed, 16 insertions(+), 22 deletions(-) diff --git a/internal/storage/push.go b/internal/storage/push.go index 49b0efa..ed5c338 100644 --- a/internal/storage/push.go +++ b/internal/storage/push.go @@ -96,7 +96,7 @@ func NewClassifiedSince(sinceUnix int64, limit int) ([]Story, error) { rows, err := Get().Query( `SELECT id, headline, source, channel, seen_at FROM stories - WHERE classified = 1 AND channel <> '_discarded' AND seen_at > ? + WHERE classified = 1 AND channel NOT IN ('_discarded', '_duplicate') AND seen_at > ? ORDER BY seen_at DESC LIMIT ?`, sinceUnix, limit) if err != nil { diff --git a/internal/storage/userstate.go b/internal/storage/userstate.go index 72e0379..a360888 100644 --- a/internal/storage/userstate.go +++ b/internal/storage/userstate.go @@ -104,6 +104,7 @@ func ListBookmarks(sub string, limit, offset int) ([]Story, error) { WHERE u.user_sub = ? AND u.bookmarked_at IS NOT NULL AND s.classified = 1 + AND s.channel NOT IN ('_discarded', '_duplicate') ORDER BY u.bookmarked_at DESC, u.story_id DESC LIMIT ? OFFSET ?`, sub, limit, offset) if err != nil { @@ -129,7 +130,8 @@ func CountBookmarks(sub string) (int, error) { err := Get().QueryRow( `SELECT COUNT(*) FROM user_story_state u JOIN stories s ON s.id = u.story_id - WHERE u.user_sub = ? AND u.bookmarked_at IS NOT NULL AND s.classified = 1`, + WHERE u.user_sub = ? AND u.bookmarked_at IS NOT NULL AND s.classified = 1 + AND s.channel NOT IN ('_discarded', '_duplicate')`, sub).Scan(&n) return n, err } diff --git a/internal/web/feed.go b/internal/web/feed.go index 2bd03b3..85030bf 100644 --- a/internal/web/feed.go +++ b/internal/web/feed.go @@ -3,6 +3,7 @@ package web import ( "encoding/json" "encoding/xml" + "html" "log/slog" "net/http" "strings" @@ -284,20 +285,8 @@ func contentToHTML(text string) string { continue } b.WriteString("
")
- b.WriteString(strings.ReplaceAll(escapeHTMLText(para), "\n", "
"))
+ b.WriteString(strings.ReplaceAll(html.EscapeString(para), "\n", "
"))
b.WriteString("
' + - (it.paywalled ? "This source is paywalled — the text above may be partial. " : "") + + (it.paywalled ? "This source is paywalled, so the text above may be partial. " : "") + (href ? 'Read it at the source: ' + escapeHTML(it.source || "original article") + " ↗." : "") + "
"; diff --git a/internal/web/static/sw.js b/internal/web/static/sw.js index 74964f3..f3e8776 100644 --- a/internal/web/static/sw.js +++ b/internal/web/static/sw.js @@ -4,7 +4,7 @@ // // Bump CACHE_VERSION whenever the precached shell assets change; activate() // drops every cache that doesn't match the current version. -var CACHE_VERSION = "v2"; +var CACHE_VERSION = "v3"; var SHELL_CACHE = "pete-shell-" + CACHE_VERSION; var RUNTIME_CACHE = "pete-runtime-" + CACHE_VERSION; @@ -77,7 +77,7 @@ function offlineFallback() { "Pete can't reach the news right now. Articles you've already opened are still readable — head back and try one of those.
" + + "Pete can't reach the news right now. Articles you've already opened are still readable, so head back and try one of those.
" + "