Skip to content

## v4.2.0: the Add Feed UX pair (2026-10-02)

Choose a tag to compare

@VirInvictus VirInvictus released this 09 Oct 22:04
· 11 commits to main since this release

v4.2.0: the Add Feed UX pair (2026-10-02)

The two Add Feed dialog refinements from the October 2 sync's deferred list (NNW b4361413f #4221, 7ea15d7f7 #3758, plus 8795b7926's wording pass). The existing discovery flow is untouched. 288 tests; clippy -D warnings clean.

  • Added: the dialog's folder picker opens on the sidebar's current selection. A selected feed preselects its containing folder (SidebarView::selected_add_feed_folder: feed → tree-parent folder, the port of containerForNode), a selected folder preselects itself, and everything else (standalone feed, smart feeds, group rows, no selection) opens on top-level. Upstream's substituteContainerIfNeeded branch has no counterpart here: viaduct's account model has no .disallowFeedInRootFolder behavior (local and Inoreader both allow top-level feeds), so the account container maps to "None" (top-level); NNW's last-used-default fallback for smart-feed rows maps to the same, since the dialog keeps no last-used memory. The selection is read live at dialog-open (ViaductWindow::selected_add_feed_folder_public, beside the list_folder_names_public precedent), so nothing new is stored on the window.
  • Added: subscribing to an already-subscribed feed now says where it lives instead of proceeding into the silent dedupe. The dialog checks the in-memory OPML at two sites mirroring upstream's two call sites: the entered URL before discovery runs (a short-circuit with no network round trip), and the resolved feed URL after discovery (redirects and HTML link resolution can land on a URL the pasted one doesn't show). A hit produces "Can’t add this feed because you’ve already added it in “News” and “Reading”." (folder names sorted, upstream's formatted(.list(type: .and)) shape, 8795b7926's "added" wording); a feed that lives only at top level yields the generic "already added it." text, exactly upstream, because existingContainers(withFeed:)'s account entry contributes no folder name to the list. The lookup is existing_feed_with_url (exact URL match; standalone feeds first, then folders: the same walk Account::remove_feed uses). Account::add_feed itself is unchanged and still silently dedupes for its other callers, so the welcome dialog's suggested-feed path is untouched, and the dialog stays open with the status row carrying the message.
  • Tests: 7 new, all on the pure logic. Folder derivation (initial_add_feed_folder): a folder selects itself, a feed selects its containing folder, and the non-container rows (standalone feed with no folder parent, smart feeds, group rows) fall back to top-level. Message path: existing_feed_with_url across standalone / folder-nested / absent, containing_folder_names listing every container a duplicated URL lives in (sorted, and empty for a top-level-only feed), the one / two / four-item list formatting, and the generic-vs-named text split.