- Add optional r/p/e/a/emoji tags to StatusEvent.create() for full spec compliance
- Add GENERAL and MUSIC type constants to StatusEvent
- Filter expired statuses in UserStatusCache.addStatus() and add removeExpired()
- Add p tag (profile reference) display in DisplayStatusInner
- Add NIP-30 custom emoji rendering in status display via CreateTextWithEmoji
- Allow status type parameter in UserStatusAction.create()
https://claude.ai/code/session_0117asp4mDiR65dxbAGKi2hg
Replace raw MutableSet with synchronized EventDeduplicator class.
Remove dual dedup in addNoteResults — trackRelayEvent now gates all
event processing. SearchScreen callbacks skip dupes early via return
value.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pulsating green heart icon shows NIP-46 signer connection status in both
DeckSidebar and SinglePaneLayout NavigationRail. Tooltip displays last
ping time. SignerConnectionState moved to commons for KMP sharing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace boolean isSearching with counter-based activeSubscriptionCount
so loading state stays true until both subs (people + notes) complete
- Add indeterminate LinearProgressIndicator overlaid on search bar bottom
border with matching 12dp rounding, replacing "Searching relays..." text
- Send search REQs to all configured relays (relayStatuses) instead of
only connected ones — fixes NIP-50 relays never receiving search queries
- Move clearResults/startSearching out of remember() into LaunchedEffect
to avoid side effects during composition
- Fix history saving partial queries by replacing LaunchedEffect with
snapshotFlow to properly observe isSearching transitions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract DateUtils (isLeapYear, dateToUnix, timestampToDate) to deduplicate
identical implementations in QueryParser and QuerySerializer
- Move SavedSearch data class from desktopApp to commons/search
- Replace local formatTimestamp with existing toTimeAgo from commons/util
- Remove dead code: resolveAuthorName, _authorSuggestions (never called)
- Remove dead code: createOrFilters (never wired into SearchScreen)
- Remove unused ICacheProvider dependency from AdvancedSearchBarState
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 4: Desktop UI composables for advanced search.
- Rewrite SearchScreen.kt to use AdvancedSearchBarState with TextFieldValue
- Add AdvancedSearchPanel with kind presets, author chips, date range, hashtags, language
- Add SearchResultsList with sticky headers for People/Notes/Articles/Other sections
- Make QueryParser.parseDateToTimestamp and QuerySerializer.timestampToDate public
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 3: State holder with MutableStateFlow<SearchQuery> as SSOT,
sourceOfChange discriminator to prevent parse/serialize loops,
debounced query for subscriptions, results management, author
name resolution via cache autocomplete.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 1 of advanced search. Recursive descent parser for operators
(from:, kind:, since:, until:, lang:, domain:, #tag, -exclude, OR),
serializer for bidirectional sync, kind alias registry with pseudo-kind
support. 68 unit tests all passing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reorganize nip64Chess event classes into individual packages with
dedicated tag classes, TagArrayBuilderExt, and TagArrayExt files,
following the same structure used by nip88Polls.
New package structure:
- challenge/ - LiveChessGameChallengeEvent with PlayerColorTag, TimeControlTag
- accept/ - LiveChessGameAcceptEvent with ChallengeEventTag
- move/ - LiveChessMoveEvent with GameIdTag, MoveNumberTag, SanTag, FenTag
- end/ - LiveChessGameEndEvent with ResultTag, TerminationTag, WinnerTag
- draw/ - LiveChessDrawOfferEvent
- game/ - ChessGameEvent (Kind 64)
- jester/ - JesterEvent, JesterProtocol, JesterContent, JesterGameEvents
Each tag class follows the companion object pattern with isTag(),
parse(), and assemble() methods. Each event package includes
TagArrayBuilderExt for building and TagArrayExt for parsing.
https://claude.ai/code/session_01Qtzhka3p5N3Hbns4xrRbsv
Adds a new RelayUrlSegment type to RichTextParser that detects and
labels relay URIs (ws:// and wss:// schemes) as a distinct segment
type, separate from generic LinkSegments.
https://claude.ai/code/session_01U21sGdEEMLo4hY8dwxNzPr