Commit Graph
479 Commits
Author SHA1 Message Date
nrobi144andClaude Opus 4.7 aeb49c3cac fix(desktop): address PR review findings on feed UI refresh
5 issues from davotoula's review on PR #3124:

- #3 (protocol): inline reply emitted a minimal e/p tag set instead of
  NIP-10. Extract `commons/actions/ReplyActions.replyTo` wrapping
  `TextNoteEvent.build(replyingTo=)` (which already encodes root marker,
  reply marker, parent root-e-tag carry) + carry parent's p-tag chain via
  `notify(...)`. Replies to deep-thread notes now thread correctly in
  Damus/Primal/Coracle. Covered by `ReplyActionsTest`.

- #4 (architecture): reaction/follow/reply each inlined
  `localCache.consume + relayManager.broadcastToAll` in 5 sites with
  inconsistent ordering. Extract `desktopApp/cache/dispatch(...)` —
  canonical local-first order — and route all 5 sites through it.

- #1 (UX): related-content section scanned the cache once via
  `DisposableEffect(noteId)` and never refreshed. Switch to `produceState`
  collecting `DesktopLocalCache.eventStream.newEventBundles`; re-scan only
  when an arriving bundle contains a candidate (matching hashtag or
  author). `LargeCache.notes` is a ConcurrentSkipListMap (weakly consistent
  iterator) so the scan stays safe on the composition coroutine.

- #2 (UX): `DeckColumnContainer` re-requested focus on every
  `currentOverlay` change, stealing focus from sibling columns whenever
  any column mutated overlay state. Drop to `LaunchedEffect(Unit)` and
  wrap the column in `key(column.id)` in `DeckLayout` so the one-shot
  effect survives column reordering.

- #5 (consistency): zap totals bypassed the shared `ZapFormatter`. Wire
  `RelatedContentRow`, `CommentItem`, and `NoteActions` to
  `commons/util/ZapFormatter.{showAmount,toZapAmount}`; delete
  `formatZapAmount` and `formatSats` desktop-local helpers.
  `WalletColumnScreen.formatSats` intentionally kept — locale-aware full
  precision for wallet balance is by design.

Plan: docs/plans/2026-06-02-fix-desktop-feed-review-findings-plan.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-02 13:45:00 +03:00
nrobi144andClaude Opus 4.6 2ca8eb31dc fix: address root causes of 6 runtime log noise issues
1. LocalRelayStore: use batchInsert() with per-row savepoints instead of
   manual transaction — UNIQUE constraint violations skip that row instead
   of failing the whole batch

2. Robohash empty hex: guard blank input in CachedRobohash.get() with a
   fallback all-zeros hex key instead of passing empty string to assembler

3. GiftWrapEvent decrypt: downgrade from WARN to DEBUG — expected when
   gift wraps from local relay cache aren't addressed to current user
   (subscription filter is correct, but hydration doesn't filter by p-tag)

4. Relay URL %20: decode percent-encoded spaces before rejection check in
   RelayUrlNormalizer.fix() — wss://relay.example.com/%20 now normalizes
   to wss://relay.example.com/ instead of being rejected

5. NIP19 Parser: downgrade from ERROR/WARN to DEBUG — malformed bech32
   from relay content is expected in the wild, catch+log is correct

6. VLC macOS: add --avcodec-hw=none (disables VideoToolbox that causes
   CVPN chroma failures) and --reset-plugins-cache (rebuilds stale cache
   on startup instead of logging hundreds of stale-cache errors)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 10:47:58 +03:00
nrobi144andClaude Opus 4.6 1b17ce6975 fix(desktop): wire like and zap on comment items
- Fix like: read replyNote.event inside lambda (not captured val)
  to avoid stale null reference. Consume reaction into local cache.
- Wire zap on comments: uses zapNote (now internal) with 21 sats default
  via NWC connection, same flow as main action row
- Wire like/zap in both FeedScreen (inline expansion) and ThreadScreen

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-01 12:20:01 +03:00
nrobi144andClaude Opus 4.6 4b021351d3 fix(desktop): wire comment reactions + fix related content click navigation
- Wire onLike on CommentItem: ReactionAction.reactTo + broadcast
- Related content clicks use overlay navigation (ThreadScreen) since
  related notes may not be in the feed LazyColumn
- Add onNavigateToThreadOverlay param to ExpandedNoteContent
- Zap from comments deferred (requires full NWC flow)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-01 12:13:33 +03:00
nrobi144andClaude Opus 4.6 3f862637d1 fix(desktop): load comment author metadata on inline expansion
- Observe note.flow().replies so replyNotes recomputes when replies arrive
- Use loadMetadataBatched with explicit author pubkeys from reply events
- DisposableEffect for proper flow cleanup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-01 12:09:28 +03:00
nrobi144andClaude Opus 4.6 08c7b5f214 fix(desktop): remove auto-scroll on card expansion
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-01 12:08:35 +03:00
nrobi144andClaude Opus 4.6 4fddfef5dd feat(desktop): inline card expansion in feed
- Add expandedNoteId state to FeedScreen — clicking a card expands it
  in-place instead of navigating to separate ThreadScreen
- AnimatedVisibility(expandVertically + fadeIn) for smooth expansion
- ExpandedNoteContent composable renders CommentsCard + RelatedContentSection
  below the expanded card within the same LazyColumn item
- Auto-scroll expanded card to top of viewport
- Thread reply subscriptions start on expand, cancel on collapse
- Only one card expanded at a time — clicking another collapses current
- Search bar stays visible (floating header above LazyColumn)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-01 12:03:16 +03:00
nrobi144andClaude Opus 4.6 92e210a584 fix(desktop): follow pill visibility, metadata loading, reply + view all wiring
- Fix follow pill layout: author row uses weight(1f) so pill has room
  (was invisible due to SpaceBetween squeezing)
- Fix comment metadata: observe metadataState so author info recomposes
  when kind:0 arrives from relay
- Wire "View all" on related content to navigate to author profile
- Wire reply button on CommentItem to open reply compose dialog

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-01 11:45:32 +03:00
nrobi144andClaude Opus 4.6 5aa2f519e7 feat(desktop): visual overhaul of thread detail view matching Layers design
- Create CommentsCard: OutlinedCard with "Comments N" header + badge,
  "Most recent" label, reply input slot, comment items slot
- Create CommentItem: lightweight comment row with avatar, name, handle,
  time, content, Reply/Like/Zap actions (replaces heavy FeedNoteCard for replies)
- Restyle InlineReplyInput: cyan "Send" pill button instead of plain icon
- Revise RelatedContentRow: image-overlay cards (200x140dp) with AsyncImage
  background, dark gradient overlay, white title + author + zaps
- Restructure ThreadScreen: root note card → CommentsCard → Related section

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-01 11:34:18 +03:00
nrobi144andClaude Opus 4.6 9194dac8f9 feat(desktop): related content section in thread view
- Create CompactNoteData @Immutable data class in commons for reuse
- Create RelatedContentSection composable with horizontal LazyRow
- Scan LocalCache for hashtag-matching + same-author notes
- Compact cards (160dp) with title, author, zap count
- Wire into ThreadScreen below reply notes
- Hidden when no related content found
- Subscriptions cancel on dispose

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-01 11:07:31 +03:00
nrobi144andClaude Opus 4.6 25c9cf4611 feat(desktop): share menu with copy/broadcast options
- Create ShareMenu composable with ShareMenuState
- 6 share options: Copy Text, Copy Note ID, Copy Event Link, Copy Raw JSON,
  Copy Web Link (njump.me), Broadcast
- Replace MoreVert overflow menu with Share icon + ShareMenu
- Use existing copyToClipboard helper for clipboard operations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-01 11:07:19 +03:00
nrobi144andClaude Opus 4.6 cc1330adb6 feat(desktop): inline reply in thread view
- Create InlineReplyInput composable (avatar + TextField + Send button)
- SendState sealed interface (Idle/Sending/Error)
- Ctrl/Cmd+Enter keyboard shortcut to send
- Build kind:1 reply with NIP-10 e-tag + p-tag
- Optimistic display via localCache.consume + broadcastToAll
- Error shown inline with text preserved for retry
- Hidden for logged-out users

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-01 11:06:50 +03:00
nrobi144andClaude Opus 4.6 1294283937 feat(desktop): follow pill in feed card header
- Add headerTrailingContent slot to NoteCard for follow pill placement
- Add FollowPill composable (FilterChip with PersonAdd icon)
- Wire follow action in FeedScreen: FollowAction.follow + broadcastToAll
- Mutex guards concurrent follows to prevent kind:3 overwrites
- Expose lastContactListEvent on DesktopLocalCache for follow operations
- Hidden for own notes, already-followed users, and logged-out users

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-01 10:31:53 +03:00
nrobi144andClaude Opus 4.6 fd6e37b84a feat(desktop): slide-animated inline navigation with 2-level back stack cap
- Refactor ColumnNavigationState to use mutableStateListOf with direction tracking
- Add pushWithCap(maxDepth=2) — replaces top entry when cap reached
- Replace instant Surface overlay with AnimatedContent slide transitions (200ms)
- Add Esc key handler (onPreviewKeyEvent) for back navigation
- Add FocusRequester for keyboard nav to work after slide
- Apply to both DeckColumnContainer and SinglePaneLayout

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-01 10:23:24 +03:00
nrobi144andClaude Opus 4.6 144b911867 feat(desktop): move actions inside card + fix sidebar double active state
- Add bottomContent slot to NoteCard for actions to render inside card boundary
- Move NoteActionsRow into the slot in FeedNoteCard (both regular and repost paths)
- Add muted parameter to SidebarNavItem; mute Home when feed tabs are visible
- Resolves feedback: actions clearly belong to their card, sidebar doesn't
  compete with feed tab active state

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-01 10:17:08 +03:00
Claude d8899eedf8 refactor(commons): move feature-specific UI out of ui/ into <feature>/ui
Make the feature-UI vs cross-cutting-UI rule consistent (feature-first):
- ui/nip53LiveActivities -> nip53LiveActivities/ui
- ui/article + ui/editor -> new nip23LongContent/ui (article reader + editor)

ui/ now holds only cross-cutting composables (theme, components, layouts,
elements, markdown, signing, thread, feeds, notifications, screens, state,
text). Tighten ARCHITECTURE.md with the deciding test ('could a second
unrelated feature reuse this as-is?') and reconcile the NIP-second-axis
section so a single-NIP feature owns its UI under <feature>/ui rather than
ui/nipNN.

https://claude.ai/code/session_01KXLzsvx9Gyrm3Yz4Rims55
2026-05-30 19:02:55 +00:00
Claude 79a9bf78f8 refactor(commons): name single-NIP feature packages after their quartz NIP
Rename the two single-NIP feature packages to mirror their quartz
counterparts for 1:1 traceability:
- chess -> nip64Chess
- call  -> nipACWebRtcCalls

marmot and nip53LiveActivities already match quartz and are unchanged.
Document the rule in commons/ARCHITECTURE.md: layer is the primary axis,
NIP is the secondary axis (nipNN<slug> matching quartz), and commons is
deliberately NOT reorganized NIP-first at the top level. Also remove
stray markup that leaked into the end of the doc.

https://claude.ai/code/session_01KXLzsvx9Gyrm3Yz4Rims55
2026-05-30 18:46:36 +00:00
Claude b0c6ffb821 refactor(commons): consolidate package taxonomy + add architecture doc
Document the commons module's purpose, source-set layout, and the CLI-safe vs
UI boundary in commons/ARCHITECTURE.md, then clean up the clearest package
overlaps that had accumulated:

- merge duplicate util/utils -> util (all source sets)
- unify service/services -> service (jvmAndroid)
- move data/UserMetadataCache -> model/cache
- fold compose/ into ui/ (ui/article, editor, elements, layouts, markdown,
  nip53LiveActivities, and Compose helpers in ui/state + ui/text)
- move ProfileBroadcastBanner composable into profile/ui

All changes are whole-file/whole-package moves with import rewrites; no logic
changed. The chess logic/UI split is documented as deferred debt (it needs
file-level surgery, not moves). Marks docs/shared-ui-analysis.md superseded.

https://claude.ai/code/session_01KXLzsvx9Gyrm3Yz4Rims55
2026-05-30 17:03:57 +00:00
Claude 30a845a6c1 Merge remote-tracking branch 'origin/main' into claude/cashu-wallet-amethyst-sdOWe
# Conflicts:
#	amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt
2026-05-29 13:32:49 +00:00
Vitor PamplonaandGitHub fd88e2f8a5 Merge pull request #3095 from vitorpamplona/claude/amazing-ptolemy-26Nek
Use locale-aware date/time formatting throughout the app
2026-05-29 08:30:41 -04:00
nrobi144andClaude Opus 4.6 dd5b61a6f0 feat(desktop): add "All Screens" item before feeds in sidebar
Opens the App Drawer (same as Cmd+K) for quick access to all
available screen types. Positioned between main nav and FEEDS section.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:09:50 +03:00
nrobi144andClaude Opus 4.6 71a38674b0 fix(desktop): first feed item 16dp top padding via LazyColumn contentPadding
- Revert spacer change (back to 60dp)
- Add top = 16.dp to LazyColumn contentPadding so first card has
  extra spacing and slides nicely under the floating search header

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:53 +03:00
nrobi144andClaude Opus 4.6 cc698c5e91 fix(desktop): sidebar starts expanded + extra 16dp feed margin
- Sidebar always starts expanded (ignores persisted collapsed state)
- Feed spacer 60dp → 76dp (extra 16dp gap between header card and first item)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:52 +03:00
nrobi144andClaude Opus 4.6 0e431d674c feat(desktop): branded loading screen instead of login flash on startup
- Add AccountState.Loading as initial state (was LoggedOut)
- Show centered "Amethyst" + spinner while accounts load from storage
- After loadSavedAccount(): transition to LoggedIn or LoggedOut
- No more 0.5s flash of login screen when account exists

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:52 +03:00
nrobi144andClaude Opus 4.6 da0aaaa281 fix(desktop): wider collapsed sidebar + filled Tor icon when connected
- COLLAPSED_WIDTH 56dp → 64dp so icons aren't truncated
- Tor connected: use Security icon (filled shield) instead of Shield
- Tor off/connecting/error: keep outlined Shield icon

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:52 +03:00
nrobi144andClaude Opus 4.6 12918e7045 feat(desktop): Tor/Bunker status as proper sidebar nav items
- Replace compact icon Row at bottom with SidebarNavItem-style items
- Tor: shows "Tor: Off/Connecting/Connected/Error" with Shield icon
- Bunker: shows "Bunker: OK" with Favorite icon (only when connected)
- Both use same shape, hover, and label pattern as other sidebar items
- Collapsed mode: icon-only with tooltip, same as nav items

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:52 +03:00
nrobi144andClaude Opus 4.6 7ff4d8e3b7 fix(desktop): avatar ripple + P3 hardcoded colors + inline shapes
Avatar/Account switcher:
- Rewrite SidebarAccountHeader with same shape/hover as other nav items
- Entire row (avatar + display name) is clickable with rounded clip
- Inline DropdownMenu replaces overlaid AccountSwitcherDropdown
- Collapsed: compact avatar with same rounded hover treatment

P3 #004 — Hardcoded status colors:
- Add StatusGreen/StatusRed/StatusAmber to commons Colors.kt
- Replace 32 inline Color() values across 10 files with theme tokens
- Color.Red → MaterialTheme.colorScheme.error where appropriate
- Color.Green/Gray → StatusGreen/onSurfaceVariant

P3 #005 — Inline shapes:
- RoundedCornerShape(8.dp) → MaterialTheme.shapes.small (~20 files)
- RoundedCornerShape(12.dp) → MaterialTheme.shapes.medium
- RoundedCornerShape(16.dp) → MaterialTheme.shapes.large
- Pill shapes (100dp/999dp) kept as-is

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:52 +03:00
nrobi144andClaude Opus 4.6 41a59a9499 fix(desktop): wire Open Full Search via LocalOpenFullSearch CompositionLocal
- Add LocalOpenFullSearch CompositionLocal (navigates to Search column)
- Provided at Main.kt level alongside LocalFeedSearchActive
- FeedScreen reads it directly — no param threading needed
- "Open full search" link in expanded header now actually opens Search column
- Removed unused onOpenSearch param from DeckColumnContainer

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:52 +03:00
nrobi144andClaude Opus 4.6 b8f6751a68 fix(desktop): address P2 todos — feed margin + history click
Todo #001: Feed content margin under search
- Animate spacer height: 60dp collapsed → 300dp expanded (tween 200ms)
- Feed items no longer hidden by expanded search card

Todo #002: History item click populates input
- SearchHistorySection gains onHistoryItemClick callback
- Clicking recent search populates searchText with query text
- LaunchedEffect(searchText.text) triggers updateFromText() → relay search

Todo #003: Cmd+F context (deferred — P2 stays open)
- Currently Cmd+F toggles inline search on feeds only
- On non-feed screens it's a no-op (user can click Search in sidebar)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:52 +03:00
nrobi144andClaude Opus 4.6 c7483a4f0d fix(desktop): SearchPill hover bounds + AccountSwitcher ripple size
- SearchPill: move hoverHighlight() inside Surface content Row so it's
  clipped to the pill's 36dp height (was drawing on parent Row height)
- AccountSwitcherDropdown: reduce IconButton from 48dp to 40dp so ripple
  circle fits within collapsed sidebar width

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:51 +03:00
nrobi144andClaude Opus 4.6 c53c8238fb fix(desktop): theming + modifier review fixes from multi-agent analysis
Shapes:
- DeckSidebar: RoundedCornerShape(8.dp) → MaterialTheme.shapes.small
- NoteCard images: RoundedCornerShape(8.dp) → MaterialTheme.shapes.small

Modifier patterns:
- NoteCard: remove hardcoded .fillMaxWidth() — callers now pass it
- FeedScreen NoteCard callers: add explicit Modifier.fillMaxWidth()

Ripple clipping (from prior commit):
- SearchPill: clip(pill shape) before hoverHighlight()
- Sidebar items: clip before clickable
- ColumnHeader: padding before pointerInput

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:51 +03:00
nrobi144andClaude Opus 4.6 55704d520b fix(desktop): ripple/hover clipping — correct modifier ordering
- SidebarNavItem/SidebarFeedItem: .clip().clickable().background()
  — ripple now clipped to RoundedCornerShape(8dp) bounds
- ColumnHeader: .padding() before .pointerInput() — gesture detection
  respects horizontal padding
- SearchPill: .clip(pill shape) before .hoverHighlight() — hover
  drawBehind rect clipped to pill shape, not parent rectangle

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:51 +03:00
nrobi144andClaude Opus 4.6 5e128cb535 fix(desktop): clear search scrim when navigating via sidebar
Sidebar onNavigate callback now sets searchActiveState.value = false,
clearing the feed search expansion and sidebar dim overlay when the
user clicks any nav item (Home, Messages, Settings, etc.)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:51 +03:00
nrobi144andClaude Opus 4.6 971d20be77 fix(desktop): revert relay debounce to 300ms, separate 1s history save
- Relay query debounce stays at 300ms (AdvancedSearchBarState default)
- Separate 1s debounce on searchText: when user stops typing for 1s,
  save the query to SearchHistoryStore (assumes intent confirmed)
- LaunchedEffect(searchText.text) auto-cancels on each keystroke,
  so only fires after 1s of inactivity
- No duplicates: addToHistory() deduplicates by serialized query

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:51 +03:00
nrobi144andClaude Opus 4.6 956eee67d7 feat(desktop): 1s debounce + auto-save search history on collapse
- Increase relay query debounce from 300ms to 1000ms for inline search
  (reduces unnecessary relay load while typing)
- Save query to SearchHistoryStore when search collapses (if non-empty)
- SearchHistoryStore.addToHistory() already deduplicates by serialized query

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:51 +03:00
nrobi144andClaude Opus 4.6 28e8fc627e feat(desktop): polished inline search states — loading, empty, streaming
- LinearProgressIndicator at top of expanded card (animated in/out)
- Loading state: centered icon + "Searching N relays..."
- Empty state: "No results found" / "No search relays configured"
- Results stream in incrementally from relays
- 1s debounce for relay queries, save to search history (no dupes)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:51 +03:00
nrobi144andClaude Opus 4.6 e9756d41aa fix(desktop): add loading indicator + relay diagnostics for inline search
- Show "Searching N relays..." with spinner while waiting for results
- Show "No search relays configured" if searchRelays is empty
- Observe isSearching, peopleResults, noteResults directly for state

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:51 +03:00
nrobi144andClaude Opus 4.6 e587bb946e feat(desktop): wire relay subscriptions for inline search results
FeedTabsHeader now creates actual NIP-50 relay subscriptions when
typing in the inline search, matching the full SearchScreen wiring:

- Collect debouncedQuery (300ms) from AdvancedSearchBarState
- Access searchRelays from LocalRelayCategories
- rememberSubscription for people search (MetadataEvent kind 0)
- rememberSubscription for note search (SearchFilterFactory filters)
- Results flow into SearchResultsList (reused from search/ package)
- 10s timeout for silent relays
- Subscriptions auto-cleanup on collapse via DisposableEffect

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:50 +03:00
nrobi144andClaude Opus 4.6 02679cc596 feat(desktop): animated search expand, tab-collapse, reuse SearchResultsList
1. AnimatedVisibility for search card expand/collapse (expandVertically
   + fadeIn 200ms, shrinkVertically + fadeOut 150ms)
2. Feed tab clicks now collapse the search (onSearchExpandedChange(false)
   before switching feed)
3. When typing in search: reuses SearchResultsList composable from
   search/ package with AdvancedSearchBarState (same as full SearchScreen)
   - Empty input shows search history (recent + saved)
   - Typing shows live people + note results grouped by kind
   - "Open full search" link at bottom for advanced filtering

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:50 +03:00
nrobi144andClaude Opus 4.6 bec8fd81ea fix(desktop): search card floats above scrim, sidebar dims separately
- Header card pulled OUT of ReadingColumn into outer Box layer 3
  (rendered after scrim, so it floats visually above it)
- Feed content in layer 1 with spacer for header height
- Scrim in layer 2 covers only feed content
- Sidebar gets its own scrim overlay via Box wrapper in Main.kt
- Search card stays sharp/visible while everything else dims

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:50 +03:00
nrobi144andClaude Opus 4.6 c8e9a4fa6a fix(desktop): search card extends downward, tabs always visible
- Feed tabs + compose button always visible (never hidden)
- Search pill becomes active input when focused, card extends downward
  with history section below the always-visible header row
- Scrim only covers feed content below, header stays sharp via zIndex(10f)
- Cmd+F focuses search, Escape or click-scrim dismisses

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:50 +03:00
nrobi144andClaude Opus 4.6 ec8fbd3980 feat(desktop): full-width search expansion with Cmd+F via CompositionLocal
- FeedTabsHeader expands to full-width search card when active
  - Feed tabs hidden, search input fills entire header width
  - History section (recent + saved) shown below input
  - "Open full search" link at bottom
- Scrim overlay dims feed content when search is active
- Cmd+F toggles search via LocalFeedSearchActive CompositionLocal
  - MutableState<Boolean> provided at Window level
  - FeedScreen reads it directly, no param threading needed
- SearchPill simplified back to clickable-only (no inline expansion)
- Escape or click scrim dismisses search

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:50 +03:00
nrobi144andClaude Opus 4.6 c69c4462b9 fix(desktop): search pill visibility, sidebar + Add Feed button
- SearchPill: fix collapsed state not rendering — removed nested
  Box/Surface/matchParentSize, replaced with simple if/else on
  expanded state within single Surface+Row
- Sidebar: add "+ Add Feed" item below custom feeds in FEEDS section
- Dropdown menu moves outside Surface to render properly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:50 +03:00
nrobi144andClaude Opus 4.6 55e7fcb903 fix(desktop): feed header card design, inline search, compact tabs
- FeedTabsHeader wrapped in Surface card (border + rounded corners)
- Feed tabs compact with spacedBy(4dp), removed "+ More" (in sidebar)
- SearchPill centered with weight(1f), expands inline to BasicTextField
  with DropdownMenu showing recent + saved searches
- Removed Dialog-based SearchSpotlight (wrong UX — created separate AWT window)
- Cmd+F now navigates to Search column via navigateToScreen callback
- All feed tab types (Following/Global/Custom) properly handled in onClick

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:49 +03:00
nrobi144andClaude Opus 4.6 c21b85c83e feat(desktop): add search spotlight overlay with Cmd+F shortcut
- SearchSpotlight: global overlay with scrim, auto-focused input, recent/saved
  searches, hashtag quick-jump, and "Open full search" link
- SearchPill: compact reusable pill component with hover highlight and shortcut hint
- Cmd+F keyboard shortcut wired in MenuBar to open/close spotlight
- SearchPill added to FeedTabsHeader (Home/Feeds column headers)
- Result selection dispatches to deckState (deck mode) or singlePaneState (single-pane)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:49 +03:00
nrobi144andClaude Opus 4.6 eb114f0a58 refactor(desktop): share MainSidebar across single-pane and deck modes
- Rename DeckSidebar -> MainSidebar (it's not deck-specific anymore)
- Hoist MainSidebar from DECK-only to shared Row in Main.kt
- Remove inline 80dp NavigationRail from SinglePaneLayout
- SinglePaneLayout now only renders content pane (sidebar is external)
- onNavigate dispatches to singlePaneState.navigate() or deckState.addColumn()
  based on active layoutMode
- Active item highlighting works in both modes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:49 +03:00
nrobi144andClaude Opus 4.6 b431c1efab feat(desktop): visual personality overhaul — unified theme, sidebar, cards
Phase 1: Replace per-OS color schemes with unified Amethyst brand
- Cyan/blue accent (#0096FF light, #4DB8FF dark) replacing OS-adaptive colors
- Amethyst purple as tertiary heritage color
- Unified shapes (8/12/16/24dp) replacing per-OS variants
- Standardized typography weights (Light for display, SemiBold for headlines)
- Letter spacing unified to -0.3sp

Phase 2: Spacing system
- AmethystSpacing CompositionLocal with design tokens
- LocalIsDarkTheme for M3-compatible dark mode detection

Phase 3: Sidebar redesign
- 240dp wide sidebar with icon + text labels (was 56dp icon-only)
- Animated collapse/expand with smooth width transition
- Avatar + username at top with account switcher
- Custom feeds section from FeedDefinitionRepository
- Active item cyan pill indicator with hover effects
- Collapse state persisted in Preferences
- Debounced fitColumnsToWidth to prevent animation thrash

Phase 4: Card refinement
- OutlinedCard with 1dp border replacing 1dp shadow elevation
- 16dp internal padding (was 12dp)
- Converted NoteCard, ReadsScreen, DraftsScreen, MyHighlightsScreen, UserProfileScreen

Phase 5: Column header restyling
- 48dp height (was 40dp) with surfaceContainer background
- 12dp horizontal padding (was 8dp)

Phase 6: Polish
- HoverModifiers.kt — shared hover highlight using onPointerEvent + drawBehind
- ShimmerPlaceholder.kt — skeleton loading animation in commons/commonMain

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 07:02:49 +03:00
Claude c679a870ab Respect Android system date/time format preferences
Hardcoded date/time patterns ignored the user's Locale (date order:
dd/mm/yyyy vs mm/dd/yyyy vs yyyy-mm-dd) and the system 12/24-hour
override. Replace them with locale-aware formatters that resolve order
from the active Locale via DateFormat.getBestDateTimePattern() and pick
the time-of-day pattern via DateFormat.is24HourFormat(context).

- TimeAgoFormatter (amethyst + commons): build SimpleDateFormat from
  Unicode LDML skeletons (yMMMd / MMMd / yMMM) so "May 28, 2026" in
  en-US becomes "28 May 2026" in en-GB, "28.05.2026" in de-DE, etc.
- CalendarTimeFormat: same skeleton approach for date pieces; time
  uses DateFormat.getTimeFormat(context) so a 24-hour Android user
  sees 14:32 even on a 12-hour locale.
- New LocalizedDateTimeFormat helper with formatMonthDayTime,
  formatMediumDate, formatMediumDateTime — used by wallet, vanish,
  attestation, namecoin, eventsync screens to replace inline
  SimpleDateFormat("MMM d, HH:mm") / ("MMM dd, yyyy  hh:mm a") etc.
- Material3 TimePicker callers (calendar/nest/poll/zap-poll/expiration
  date pickers + vanish request) now pass is24Hour from the system
  setting instead of hardcoding false.
- Desktop article/reads/highlights screens use
  java.text.DateFormat.getDateInstance(MEDIUM, locale).
- Drop dead formattedDateTime() in RelayCompose (was unused).

Intentionally left alone: notification feed bucket keys ("yyyy-MM-dd"
used as Map keys), TakePicture file naming (Locale.US), iCalendar
RFC 5545 stamps, NIP-52 ISO date storage, internal logging, and
ThreadLevelCalculator sort keys — none are user-facing.
2026-05-28 22:22:59 +00:00
Claude 82e1096e69 Merge remote-tracking branch 'origin/main' into claude/cashu-wallet-amethyst-sdOWe 2026-05-28 15:57:39 +00:00
Vitor PamplonaandGitHub 097f9a9a5b Merge pull request #3077 from mstrofnone/feat/desktop-namecoin-core-rpc-backend
feat(desktop): Namecoin Core RPC backend + composite fallback
2026-05-27 16:07:01 -04:00