- FeedDefinition data model with FeedSource sealed interface (Filter, Following, Global, DVM, PeopleList, InterestSet, SingleRelay) - FeedDefinitionRepository with StateFlow, groupedFeeds, pin/unpin/reorder (max 3 pinned) - JSON serialization via Jackson with round-trip tests (18 unit tests) - SearchQuery.toFeedDefinition() bridge for creating feeds from search - FeedBuilderDialog with author search (cache lookup + npub decode), hashtag/relay inputs, kind filter checkboxes, exclude authors/keywords, Cmd+S save, Enter to add - FeedsDrawerTab in app drawer with edit/delete/pin/unpin actions - Feeds tab in top header (FilterChips) with inline mode switching - CustomFeedScreen + DesktopCustomFeedFilter + createCustomFeedSubscription for relay-based custom feed content - FeedDefinitionEvent (kind 31890) in quartz for future publish/import - Local persistence via java.util.prefs.Preferences (auto-save on change) - DeckColumnType.CustomFeed for navigation integration - Renamed Home to Feeds in nav rail - Fix: AnimatedGifImage race condition (coerceIn on frame index) - Fix: search results margins (sidePadding applied consistently) - Fix: app drawer search includes feeds in results Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2.9 KiB
Feed Builder Enhancements
Date: 2026-05-05 Status: Implementation
Scope
Enhance FeedBuilderDialog with 6 items:
- npub auto-decode (paste npub -> hex + display name)
- Author search (type name -> search LocalCache -> pick)
- Kind filter checkboxes (Notes, Reposts, Articles)
- Edit + Delete feeds (CRUD completeness)
- "Save as Feed" button in search results
- Exclude authors field in dialog
Implementation
1. npub Auto-Decode
Where: FeedBuilderDialog.kt ChipInputField for Authors
Logic:
- On add: if input starts with
npub1, decode viadecodePublicKeyAsHexOrNull() - If decode succeeds, add hex to authors list
- Show display name in chip (resolve from LocalCache)
2. Author Search
Where: New AuthorSearchField composable in FeedBuilderDialog.kt
Flow:
- Replace plain text field for authors with search field
- Type >= 2 chars -> filter
DesktopLocalCache.usersby displayName/nip05 - Show dropdown with matching profiles (avatar placeholder + name + npub short)
- Click adds hex to authors list
- Still allow raw npub/hex paste (falls through to auto-decode)
Data source: DesktopLocalCache.users (already populated from metadata subscriptions)
3. Kind Filter Checkboxes
Where: FeedBuilderDialog.kt, new section between relays and exclude
UI: FlowRow of FilterChips:
- Notes (kind 1)
- Reposts (kind 6, 16)
- Articles (kind 30023)
- Highlights (kind 9802)
- Reactions (kind 7)
Default: Notes + Reposts checked. Maps to FeedBuilderState.kinds.
4. Edit + Delete in Drawer
Where: FeedsDrawerTab.kt
Edit: Add edit button on each FeedRow -> opens FeedBuilderDialog(initial = feed)
- On save: calls
feedRepository.update(feed)
Delete: Add delete in context or as swipe action
- Confirm dialog: "Delete feed X?"
- Calls
feedRepository.delete(feed.id)
5. "Save as Feed" from Search
Where: SearchScreen.kt or SearchResultsList.kt
UI: Show "Save as Feed" button when query.canBecomeFeed() is true
- Button appears in the header area, next to the search bar actions
- Click opens
FeedBuilderDialogpre-filled fromquery.toFeedDefinition()
6. Exclude Authors in Dialog
Where: FeedBuilderDialog.kt
UI: Same chip input pattern as regular authors but for excludes
- Uses same author search/npub-decode logic
- Maps to
FeedBuilderState.excludeAuthors
File Changes
| File | Change |
|---|---|
FeedBuilderDialog.kt |
Author search field, npub decode, kind checkboxes, exclude authors |
FeedsDrawerTab.kt |
Edit/delete buttons on feed rows |
SearchScreen.kt |
"Save as Feed" button |
FeedBuilderState.kt |
No changes needed (already has all fields) |
Dependencies
decodePublicKeyAsHexOrNullfromquartz/nip19Bech32DesktopLocalCache.usersfor profile searchSearchQuery.canBecomeFeed()+toFeedDefinition()already exist