Repository navigation
News heading as menus: Sources (switch + Manage), Calendar, Filter - #226
Merged
Merged
Conversation
The News view's controls were a row of chips under the heading, an inline Sources table and a calendar in a sidebar column. They are now buttons in the heading, drawn alike, each opening a popup the way the menus do: - Sources: a menu of every source read, by kind, with an eye per row; a click switches the source on or off. It is real, not a view filter: POST /v1/news/feeds/switch writes feeds_off to ~/.swarm/settings.toml (store.setFeedOn, refused when config.toml or the policy sets the list), reconciles the rows at once, and reads a source back on immediately. - Manage sources… is pinned under the list (the list scrolls above it) and opens the sources table in a modal, now with Turn on / off per row. - Calendar: the month calendar in the same popup; a day narrows the items, closes it, and the button then names the day. - Filter: kinds, Unread only, All items in one menu that stays open. - Paper / Table: two heading buttons, the chosen one lit. The menus island gains a refresh for stay-open menus, a pinned footer action, and a panel for free content. core: feedsOffWith + test; the feeds report carries [security] kinds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… to its last row Favicons: the daemon asks each source's site for its icon (the one its home page names, near 32 px, never an SVG, else /favicon.ico), once a week, only for a host a source names, never offline or with [security] pictures = false, and keeps it in ~/.swarm/favicons/. Served at GET /v1/favicons/<host>; the feeds report carries each source's site (the host of its newest article, so a feedburner feed gets the publisher's icon). The menu rows show it with the eye moved to the end, a switched-off row faint; the Manage table shows it beside the name. core: iconLinks + siteHost, tested; daemon test with a stub fetch. Scrolling: fancy-menus caps .fm-list at 60vh whatever the menu may be, so a menu held shorter (its maxHeight, a short window, a footer) hid its last rows below the body with nothing left to scroll. The body is now a flex column that hands the list the height that is left. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
What
The News view's controls move into the heading as one row of buttons that open popups, the way the portal's Security › News does:
Sources ▾: a menu of every source read, grouped by kind, with an eye icon per row. Clicking a row switches that source on or off. The setting is saved in the daemon, not just hidden in the page:
POST /v1/news/feeds/switch→store.setFeedOnwritesfeeds_offto~/.swarm/settings.tomland reconcilesnews_feedsimmediately. A source switched back on is read right away. The switch is refused, with the file named, whenconfig.tomlor the policy already setsfeeds_off. The button label counts the sources that are off.Manage sources… is pinned as the menu's footer (the list scrolls above it). It opens the old Sources table in a modal, now with Turn on / Turn off per row next to Check, plus the add-a-feed check.
Calendar ▾: the month calendar opens in the same popup. Picking a day narrows the items, closes the popup, and the button then shows the day (
26 Oct).Filter ▾: kinds, Unread only and All items in one menu that stays open while you toggle.
Paper / Table: two heading buttons with the chosen one lit.
Site icons: every source in the menu and in the Manage table shows its site's favicon, and switched-off rows are drawn faint. The daemon fetches each icon itself via
GET /v1/favicons/<host>: it takes the icon the home page names (never an SVG, at most 256 KB), else/favicon.ico, fetched about once a week and kept in~/.swarm/favicons/. It only fetches for hosts that one of your sources names, never underSWARM_OFFLINE, and not with[security] pictures = false. Each source's site is the host of its newest article, so a feedburner feed gets the publisher's icon. The privacy page in the guide now says so.The end of a long menu can be reached again: fancy-menus caps
.fm-listat 60vh whatever height the menu is allowed. A menu held shorter than that (by itsmaxHeight, a short window, or a footer) hid its last rows with nothing to scroll to..fm-bodyis now a flex column that gives the list the height that is left.The chip row, the inline Sources panel and the calendar sidebar column are gone.
How
src/menus.tsx):MenuSpec.refreshredraws a stay-open menu after an item runs,MenuSpec.footerpins an action under a scrolling list, andopenPanel(anchor, render)puts free content in the same popup.core/src/newsfeeds.tsfeedsOffWith(unit test).NewsFeedsReport.kindslets the menu leave out built-ins whose kind is not read.calendar,eye-slash,funnel.core/src/newsfeed.tsiconLinks+siteHost(tested);SecurityService.faviconkeeps a cache in memory and on disk, and retries a failed site after 30 minutes.Verified
lint,typecheck,test(1110 pass),smoke,check:classes,docs:check. The daemon tests cover switching off, switching on, a refusal overconfig.toml, a 400 and a 404. The favicon test uses a stub fetch and checks that the icon is fetched once, kept on disk and served by a fresh daemon without fetching again, and that an unnamed host gets a 404. I also drove a scratch daemon in headless Chrome: the six heading buttons are all 22px tall, toggling a source updates the menu and its label, Manage opens the modal, and the calendar popup is 260px wide and narrows to a day.🤖 Generated with Claude Code