Repository navigation
fix: keep saved events when their feed stops carrying them - #15
Merged
Merged
Conversation
A collection stored {feedUrl, eventId} and resolved it against the live
feed on every render, so the day a publisher pruned an event it left the
collection without a word — and the pointer stayed in localStorage,
aimed at nothing. Unsubscribing from a feed did the same thing to every
saved event from it. Reproduced before fixing: two events in Favorites,
publisher removes one, Actualizar, "Favorites · 1 evento", no message.
The feeds this hits are the ones that prune: eventos.wiki publishes 485
events and Sarao 180. The collection that suffers most is "Mis charlas",
which by definition accumulates past talks.
So a collection now holds the event, not a pointer to it. The live event
still wins while the feed carries it — it may have been edited — and what
was saved is the fallback rather than nothing. Collections saved before
this are backfilled from the feed as it loads.
With the card no longer vanishing there is something left to mark, which
is where covers earns its keep: inside the window a feed declares itself
complete for, an absent event has been withdrawn and is badged as such;
outside it, or in a feed that declares no covers, nothing is claimed and
nothing is said. A feed that is still loading, failed, or returned a
truncated response claims nothing either — absence on its own is not a
statement.
Ajustes gains a cleanup for what can no longer be followed at all:
unsubscribed feeds, withdrawn events, and pre-snapshot pointers with
nothing left to point at. Not past events — a saved past event is the
only history this reader has, since the feed no longer carries it, and
"Solo futuros" already hides them from lists without deleting anything.
No preference toggle either: whether an absence means removal depends on
each feed's covers, which the reader cannot see.
Verified in a browser end to end: legacy pointers backfill, a pruned
event survives and is badged only when covers says so, an event before
covers.from survives unbadged, unsubscribing badges all three as
"Feed no suscrito", the cleanup removes exactly those and the summary
goes empty, and saving a new event through the picker writes a snapshot.
Refs #13
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…shots # Conflicts: # CHANGELOG.md # app.js # package.json
This was referenced Nov 5, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the last reader-side item in #13 — and the premise there was wrong, which is the finding.
The reader already pruned, silently
boardEvents()resolved every{feedUrl, eventId}against the live feed:So a saved event whose publisher stopped carrying it left the collection
without a word, and the pointer stayed in
localStorageaimed at nothing.Reproduced before fixing: two events in Favorites, the publisher removes one,
Actualizar →
Favorites · 1 evento, no message. Unsubscribing from a feed didthe same to every saved event from it.
And it did this for any absence — aged out, cancelled, recycled
id,truncated response, changed URL. None of those is "withdrawn".
Who it hits: eventos.wiki publishes 485 events and Sarao 180 — publishers who
prune are exactly these. The collection that suffers most is "Mis charlas",
which by definition accumulates past talks.
What changed
while the feed carries it (it may have been edited); the saved copy is the
fallback instead of nothing. Pre-existing pointers are backfilled from the
feed as it loads.
to mark, and
coversdecides whether the absence means anything: inside thewindow a feed declares complete, "Retirado del feed"; outside it, or without
covers, nothing. A feed still loading, failed, or truncated claims nothingeither. Events from an unsubscribed feed get "Feed no suscrito".
no longer be followed: unsubscribed feeds, withdrawn events, and
pre-snapshot pointers with nothing left to point at.
Two UX calls, both deliberate
No "remove past events". A saved past event is the only history this
reader has — the feed no longer carries it — and it is the one a reader asked
for by name. "Solo futuros" already keeps them out of lists, which is a view,
not a deletion.
No preference toggle. Whether an absence means removal depends on each
feed's
covers, which the reader cannot see. A setting here would hand theuser a decision the data already answers.
Verification
End to end in a browser: legacy pointers backfill; a pruned event survives and
is badged only when
coverscovers its date; an event beforecovers.fromsurvives unbadged; unsubscribing badges all three "Feed no suscrito"; the
cleanup removes exactly those and the summary goes empty; saving a new event
through the picker writes a snapshot with
savedAt.Aside, filed while testing: a value outside the
attendanceModeenum makes<ote-events>throw and render an empty widget rather than degrading. My test data was invalid, but one malformed event blanking the whole list is worth reporting upstream.🤖 Generated with Claude Code