Hide GameInfo/MoveHistory/Actions panel by default in deck view
with a chevron toggle to expand. Add Chess to AddColumnDialog.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolves merge conflicts in Main.kt, adds Chess column type
to deck layout (DeckColumnType, ColumnHeader, DeckColumnContainer,
DeckState, SinglePaneLayout, View menu). Updates DesktopMessagesScreen
calls for new relayManager/localCache params.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add LayoutMode enum (SINGLE_PANE/DECK) persisted in DesktopPreferences
- SinglePaneLayout: NavigationRail + single content area reusing deck routing
- View menu "Deck Layout" toggle with Cmd+Shift+D shortcut
- Column resize: redistribute width on add/remove, double-click header to expand
- Constrain drag resize to window bounds via BoxWithConstraints
- FlowRow headers in FeedScreen/ReadsScreen to wrap on narrow columns
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the 80dp NavigationRail + single content area with a TweetDeck-style
multi-column deck. Default layout: Home Feed + Notifications + Messages.
New deck system:
- DeckColumnType sealed class with 12 column types
- DeckState with StateFlow-based column management
- Per-column navigation stack for in-column drill-down
- Draggable dividers for column resize (300-800dp)
- Column config persisted via Jackson JSON in DesktopPreferences
- 48dp thin sidebar with add-column and settings buttons
- AddColumnDialog for picking column types
Keyboard shortcuts:
- Cmd+T: Add column
- Cmd+W: Close focused column
- Cmd+1-9: Focus column by index
- Cmd+Shift+Left/Right: Move column left/right
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix ListChangeFeedViewModel stuck on Loading for empty chatrooms by
adding invalidateData() call in init block
- Add DmBroadcastStatus sealed class and DmBroadcastBanner composable
in commons for relay send progress display
- Add DmSendTracker using sendAndWaitForResponse for confirmed delivery
- Wire send tracking through DesktopIAccount into ChatPane banner
- Fix audit risks: unsubscribe DMs on account change, wait for relay
connect before subscribing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The sendWrappedReaction function was creating NIP-17 gift wraps via
NIP17Factory but never broadcasting them. Added sendGiftWraps() to
IAccount interface with implementations in both Desktop and Android.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace TODO stub with sendWrappedReaction using NIP17Factory.
createReactionWithinGroup creates gift-wrapped reactions for group privacy.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- DesktopIAccount: sign + broadcast NIP-04/NIP-17 messages via relay layer
- Main.kt: activate DM subscriptions on login, consume events into cache
- NewDmDialog: user search dialog with SearchBarState + UserSearchCard
- DesktopMessagesScreen: wire Cmd+Shift+N and "+" button to NewDmDialog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ChessPosition: include all fields in equals/hashCode
- AcceptedGamesRegistry: add thread safety with synchronized
- ChessEventBroadcaster: use valid filter for connection trigger
- ChessEventBroadcaster: fix misleading relayResults
- Remove println debug logging from ChessSubscription/Broadcaster
- UserProfileScreen: use proper JSON parsing via MetadataEvent
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add focused game mode to ChessPollingDelegate: when viewing a game,
only that game is polled instead of all active games
- Fix pawn promotion by parsing promotion suffix in publishMove
(e.g., "e8q" -> "e8" + QUEEN)
- Add game end overlay with victory/defeat/draw celebration
- Remove all debug println statements for production readiness
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Step 7: ChessViewModelNew.kt - Slim Android ViewModel (~130 lines)
- Delegates all business logic to ChessLobbyLogic
- Exposes StateFlows from logic.state
- Platform adapter creation only
Step 8: DesktopChessViewModelNew.kt - Slim Desktop ViewModel (~120 lines)
- Same pattern as Android, delegates to ChessLobbyLogic
- UserMetadataCache for profile display
- External CoroutineScope injection
Step 9: ChessBroadcastBanner.kt - Shared Compose banner in commons
- Uses ChessBroadcastStatus from ChessLobbyState
- Works on both Android and Desktop via Compose Multiplatform
- Shows broadcasting progress, sync status, errors
Step 10: UI consumers ready for migration
- New ViewModels use ChessChallenge (enriched display data)
- Shared banner ready to replace Android-only ChessStatusBanner
- Existing screens continue to work with old ViewModel
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add ChessLobbyState with completedGames, replaceGameState(), moveToCompleted()
- Add challengerAvatarUrl to ChessChallenge
- Add CompletedGame data class for game history
Platform Adapters:
- AndroidChessAdapter: AndroidChessPublisher, AndroidRelayFetcher, AndroidMetadataProvider
- DesktopChessAdapter: DesktopChessPublisher, DesktopRelayFetcher, DesktopMetadataProvider
Shared Infrastructure:
- ChessRelayFetchHelper for one-shot relay queries
- IUserMetadataProvider interface for platform-specific metadata
- ChessFilterBuilder with simple filter methods for fetchers
- ChessSubscriptionController interface for subscription management
Fix ChessSubscription.kt to remove broken dataSources().chess reference
(subscriptions now managed by ChessLobbyLogic)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove Moko Resources dependency that blocks AGP 9.0 migration.
Migrate to built-in Compose Multiplatform Resources which is compatible
with the new KMP Android plugin.
- Remove moko-resources plugin and libraries from commons module
- Move strings.xml from moko-resources/ to composeResources/values/
- Update imports from SharedRes.strings.* to Res.string.*
- Add compose.components.resources dependency to desktopApp
- Configure resource package as com.vitorpamplona.amethyst.commons.resources
Closes#1675
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix import paths to use desktop.subscriptions instead of commons.subscriptions
- Update DesktopLocalCache to match ICacheProvider interface changes
- Use correct commons.relayClient paths for ComposeSubscriptionManager
- Add missing justConsumeMyOwnEvent and getOrCreateAddressableNote methods
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Resolved import conflicts caused by package reorganization:
- upstream moved classes to amethyst/service/relayClient/*
- upstream moved models to commons/model/*
- kept our desktop additions (zaps, bookmarks, search)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- NotificationsScreen: Show "No notifications yet" after EOSE instead of infinite loading
- FeedScreen: Show "No notes found" after EOSE for both Global and Following feeds
- ThreadScreen: Show "Note not found" if root note missing after EOSE, "No replies yet" for empty threads
Uses existing EmptyState component from commons. Tracks EOSE (End of Stored Events) from relays to distinguish between "still loading" and "no data".
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>