mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-12 01:07:46 +00:00
Merge pull request #3109 from vitorpamplona/claude/great-knuth-sJVYl
Reorganize commons packages: NIP-64 chess, NIP-AC WebRTC, and model caches
This commit is contained in:
+6
-1
@@ -76,7 +76,12 @@ amethyst/
|
||||
|
||||
**Sharing Philosophy:**
|
||||
- `quartz/` = Nostr business logic, protocol, data (no UI)
|
||||
- `commons/` = Shared UI components, icons, composables, flows and ViewModels
|
||||
- `commons/` = Shared code for every front end (Android, Desktop, iOS, and the
|
||||
headless `cli`): domain models, state holders, ViewModels, the relay client,
|
||||
shared services, **and** the Compose UI that ≥1 GUI front end renders. The
|
||||
package taxonomy, the CLI-safe / UI boundary, and a "where does my code go?"
|
||||
guide are documented in **`commons/ARCHITECTURE.md`** — read it before adding
|
||||
a new package or dropping code into `commons`.
|
||||
- `quic/` = Transport library (QUIC + HTTP/3 + WebTransport); reusable for any
|
||||
KMP project that needs MoQ. Has no Android-framework dependencies.
|
||||
- `nestsClient/` = MoQ + audio-rooms client; takes `:quic` as transport,
|
||||
|
||||
@@ -26,7 +26,7 @@ import coil3.disk.DiskCache
|
||||
import coil3.memory.MemoryCache
|
||||
import com.vitorpamplona.amethyst.commons.model.NoteState
|
||||
import com.vitorpamplona.amethyst.commons.robohash.CachedRobohash
|
||||
import com.vitorpamplona.amethyst.commons.services.lnurl.OkHttpLnurlEndpointResolver
|
||||
import com.vitorpamplona.amethyst.commons.service.lnurl.OkHttpLnurlEndpointResolver
|
||||
import com.vitorpamplona.amethyst.commons.tor.TorSettings
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
|
||||
@@ -39,7 +39,7 @@ import com.vitorpamplona.amethyst.commons.model.observables.NewEventMatchingFilt
|
||||
import com.vitorpamplona.amethyst.commons.model.observables.NoteListMatchingFilter
|
||||
import com.vitorpamplona.amethyst.commons.model.observables.Observable
|
||||
import com.vitorpamplona.amethyst.commons.model.privateChats.ChatroomList
|
||||
import com.vitorpamplona.amethyst.commons.services.nwc.NwcPaymentTracker
|
||||
import com.vitorpamplona.amethyst.commons.service.nwc.NwcPaymentTracker
|
||||
import com.vitorpamplona.amethyst.isDebug
|
||||
import com.vitorpamplona.amethyst.model.LocalCache.observeEvents
|
||||
import com.vitorpamplona.amethyst.model.nip51Lists.HiddenUsersState
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.ServiceCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.call.CallState
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallState
|
||||
import com.vitorpamplona.amethyst.ui.call.CallActivity
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.service.call
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.call.CallManager
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallManager
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
|
||||
/**
|
||||
|
||||
+5
-5
@@ -20,17 +20,17 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.service.call
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.call.IceCandidateData
|
||||
import com.vitorpamplona.amethyst.commons.call.PeerSession
|
||||
import com.vitorpamplona.amethyst.commons.call.SdpType
|
||||
import com.vitorpamplona.amethyst.commons.call.SignalingState
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.IceCandidateData
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.PeerSession
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.SdpType
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.SignalingState
|
||||
import org.webrtc.IceCandidate
|
||||
import org.webrtc.PeerConnection
|
||||
import org.webrtc.SessionDescription
|
||||
|
||||
/**
|
||||
* Adapts a [WebRtcCallSession] to the platform-independent [PeerSession] interface,
|
||||
* allowing [com.vitorpamplona.amethyst.commons.call.PeerSessionManager] to manage
|
||||
* allowing [com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.PeerSessionManager] to manage
|
||||
* ICE buffering, answer routing, and renegotiation glare without depending on org.webrtc.
|
||||
*/
|
||||
class WebRtcPeerSessionAdapter(
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ import coil3.request.allowHardware
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.LocalPreferences
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.call.CallManager
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallManager
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.service.playback.composable.mediaitem
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import com.vitorpamplona.amethyst.commons.compose.produceCachedState
|
||||
import com.vitorpamplona.amethyst.commons.ui.state.produceCachedState
|
||||
import com.vitorpamplona.amethyst.service.playback.composable.WaveformData
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
|
||||
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import androidx.core.net.toUri
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.MediaMetadata
|
||||
import androidx.media3.common.MimeTypes
|
||||
import com.vitorpamplona.amethyst.commons.compose.GenericBaseCache
|
||||
import com.vitorpamplona.amethyst.commons.ui.state.GenericBaseCache
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@@ -30,9 +30,9 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.compose.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.compose.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.richtext.RichTextParser
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
|
||||
@@ -40,7 +40,7 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.call.CallState
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallState
|
||||
import com.vitorpamplona.amethyst.service.call.CallSessionBridge
|
||||
import com.vitorpamplona.amethyst.service.call.notification.CallNotifier
|
||||
import com.vitorpamplona.amethyst.service.relayClient.authCommand.compose.RelayAuthSubscription
|
||||
|
||||
@@ -53,10 +53,10 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.call.CallManager
|
||||
import com.vitorpamplona.amethyst.commons.call.CallState
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallManager
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallState
|
||||
import com.vitorpamplona.amethyst.ui.call.session.CallSession
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
|
||||
@@ -56,9 +56,9 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.call.CallState
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallState
|
||||
import com.vitorpamplona.amethyst.service.call.AudioRoute
|
||||
import com.vitorpamplona.amethyst.ui.call.session.CallSession
|
||||
import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.ShowUserSuggestionList
|
||||
|
||||
@@ -42,7 +42,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.vitorpamplona.amethyst.commons.call.CallState
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallState
|
||||
import com.vitorpamplona.amethyst.ui.call.session.CallSession
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
@@ -27,14 +27,14 @@ import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.NetworkRequest
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.vitorpamplona.amethyst.commons.call.AnswerRouteAction
|
||||
import com.vitorpamplona.amethyst.commons.call.CallManager
|
||||
import com.vitorpamplona.amethyst.commons.call.CallState
|
||||
import com.vitorpamplona.amethyst.commons.call.IceCandidateData
|
||||
import com.vitorpamplona.amethyst.commons.call.PeerSession
|
||||
import com.vitorpamplona.amethyst.commons.call.PeerSessionManager
|
||||
import com.vitorpamplona.amethyst.commons.call.SdpType
|
||||
import com.vitorpamplona.amethyst.commons.call.SignalingState
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.AnswerRouteAction
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallManager
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallState
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.IceCandidateData
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.PeerSession
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.PeerSessionManager
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.SdpType
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.SignalingState
|
||||
import com.vitorpamplona.amethyst.service.call.AudioRoute
|
||||
import com.vitorpamplona.amethyst.service.call.CallAudioManager
|
||||
import com.vitorpamplona.amethyst.service.call.CallForegroundService
|
||||
@@ -148,23 +148,23 @@ class CallSession(
|
||||
callManager.sessionEvents.collect { event ->
|
||||
if (closed) return@collect
|
||||
when (event) {
|
||||
is com.vitorpamplona.amethyst.commons.call.CallSessionEvent.AnswerReceived -> {
|
||||
is com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallSessionEvent.AnswerReceived -> {
|
||||
onCallAnswerReceived(event.event.pubKey, event.event.sdpAnswer())
|
||||
}
|
||||
|
||||
is com.vitorpamplona.amethyst.commons.call.CallSessionEvent.IceCandidateReceived -> {
|
||||
is com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallSessionEvent.IceCandidateReceived -> {
|
||||
onIceCandidateReceived(event.event)
|
||||
}
|
||||
|
||||
is com.vitorpamplona.amethyst.commons.call.CallSessionEvent.NewPeerInGroupCall -> {
|
||||
is com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallSessionEvent.NewPeerInGroupCall -> {
|
||||
onNewPeerInGroupCall(event.peerPubKey)
|
||||
}
|
||||
|
||||
is com.vitorpamplona.amethyst.commons.call.CallSessionEvent.MidCallOfferReceived -> {
|
||||
is com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallSessionEvent.MidCallOfferReceived -> {
|
||||
onMidCallOfferReceived(event.peerPubKey, event.sdpOffer)
|
||||
}
|
||||
|
||||
is com.vitorpamplona.amethyst.commons.call.CallSessionEvent.PeerLeft -> {
|
||||
is com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallSessionEvent.PeerLeft -> {
|
||||
disposePeerSession(event.peerPubKey)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.em
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.commons.compose.produceCachedState
|
||||
import com.vitorpamplona.amethyst.commons.emojicoder.EmojiCoder
|
||||
import com.vitorpamplona.amethyst.commons.model.EmptyTagList
|
||||
import com.vitorpamplona.amethyst.commons.model.ImmutableListOfLists
|
||||
@@ -92,6 +91,7 @@ import com.vitorpamplona.amethyst.commons.richtext.SecretEmoji
|
||||
import com.vitorpamplona.amethyst.commons.richtext.Segment
|
||||
import com.vitorpamplona.amethyst.commons.richtext.VideoSegment
|
||||
import com.vitorpamplona.amethyst.commons.richtext.WithdrawSegment
|
||||
import com.vitorpamplona.amethyst.commons.ui.state.produceCachedState
|
||||
import com.vitorpamplona.amethyst.model.HashtagIcon
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
|
||||
@@ -40,7 +40,7 @@ import androidx.core.util.Consumer
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.call.CallState
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallState
|
||||
import com.vitorpamplona.amethyst.service.crashreports.DisplayCrashMessages
|
||||
import com.vitorpamplona.amethyst.service.relayClient.notifyCommand.compose.DisplayNotifyMessages
|
||||
import com.vitorpamplona.amethyst.ui.actions.NewUserMetadataScreen
|
||||
|
||||
@@ -57,10 +57,10 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.compose.produceCachedStateAsync
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel
|
||||
import com.vitorpamplona.amethyst.commons.ui.state.produceCachedStateAsync
|
||||
import com.vitorpamplona.amethyst.model.AddressableNote
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
|
||||
+1
-1
@@ -40,8 +40,8 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import coil3.compose.AsyncImage
|
||||
import com.vitorpamplona.amethyst.commons.compose.produceCachedState
|
||||
import com.vitorpamplona.amethyst.commons.richtext.RichTextParser
|
||||
import com.vitorpamplona.amethyst.commons.ui.state.produceCachedState
|
||||
import com.vitorpamplona.amethyst.model.UrlCachedPreviewer
|
||||
import com.vitorpamplona.amethyst.service.playback.composable.VideoView
|
||||
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
||||
|
||||
+4
-4
@@ -33,11 +33,11 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.compose.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.compose.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.compose.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.commons.compose.setTextAndPlaceCursorAtBeginning
|
||||
import com.vitorpamplona.amethyst.commons.model.nip30CustomEmojis.EmojiPackState
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.setTextAndPlaceCursorAtBeginning
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
|
||||
@@ -44,8 +44,8 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessChallenge
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessGameViewer
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessChallenge
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessGameViewer
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.ui.components.SensitivityWarning
|
||||
|
||||
+3
-3
@@ -37,17 +37,17 @@ import com.vitorpamplona.amethyst.AccountInfo
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.LocalPreferences
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.call.CallManager
|
||||
import com.vitorpamplona.amethyst.commons.compose.GenericBaseCache
|
||||
import com.vitorpamplona.amethyst.commons.compose.GenericBaseCacheAsync
|
||||
import com.vitorpamplona.amethyst.commons.model.LiveHiddenUsers
|
||||
import com.vitorpamplona.amethyst.commons.model.emphChat.EphemeralChatChannel
|
||||
import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel
|
||||
import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActivitiesChannel
|
||||
import com.vitorpamplona.amethyst.commons.model.observables.CreatedAtComparator
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallManager
|
||||
import com.vitorpamplona.amethyst.commons.tor.TorType
|
||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
||||
import com.vitorpamplona.amethyst.commons.ui.notifications.CardFeedState
|
||||
import com.vitorpamplona.amethyst.commons.ui.state.GenericBaseCache
|
||||
import com.vitorpamplona.amethyst.commons.ui.state.GenericBaseCacheAsync
|
||||
import com.vitorpamplona.amethyst.logTime
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.AccountSettings
|
||||
|
||||
+1
-1
@@ -21,8 +21,8 @@
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn
|
||||
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.commons.call.CallManager
|
||||
import com.vitorpamplona.amethyst.commons.model.privateChats.ChatroomList
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallManager
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.compose.nip53LiveActivities.StreamSystemCard
|
||||
import com.vitorpamplona.amethyst.commons.nip53LiveActivities.ui.StreamSystemCard
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.service.playback.composable.VideoView
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
|
||||
+1
-1
@@ -35,9 +35,9 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.compose.nip53LiveActivities.StreamSystemCard
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
import com.vitorpamplona.amethyst.commons.nip53LiveActivities.ui.StreamSystemCard
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.compose.nip53LiveActivities.StreamSystemCard
|
||||
import com.vitorpamplona.amethyst.commons.nip53LiveActivities.ui.StreamSystemCard
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.note.CrossfadeToDisplayComment
|
||||
|
||||
+3
-3
@@ -32,10 +32,10 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.commons.compose.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.compose.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.compose.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.commons.model.nip30CustomEmojis.EmojiPackState
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
|
||||
+3
-3
@@ -33,15 +33,15 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.compose.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.compose.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.compose.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.commons.model.Channel
|
||||
import com.vitorpamplona.amethyst.commons.model.emphChat.EphemeralChatChannel
|
||||
import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel
|
||||
import com.vitorpamplona.amethyst.commons.model.nip30CustomEmojis.EmojiPackState
|
||||
import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActivitiesChannel
|
||||
import com.vitorpamplona.amethyst.commons.richtext.UrlParser
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
|
||||
+9
-9
@@ -20,15 +20,15 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chess
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessConfig
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessEventBroadcaster
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessEventPublisher
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessRelayFetchHelper
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessRelayFetcher
|
||||
import com.vitorpamplona.amethyst.commons.chess.IUserMetadataProvider
|
||||
import com.vitorpamplona.amethyst.commons.chess.RelayFetchProgress
|
||||
import com.vitorpamplona.amethyst.commons.chess.RelayGameSummary
|
||||
import com.vitorpamplona.amethyst.commons.chess.subscription.ChessFilterBuilder
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessConfig
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessEventBroadcaster
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessEventPublisher
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessRelayFetchHelper
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessRelayFetcher
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.IUserMetadataProvider
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.RelayFetchProgress
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.RelayGameSummary
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.subscription.ChessFilterBuilder
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.quartz.nip64Chess.ChessGameEnd
|
||||
|
||||
+4
-4
@@ -59,12 +59,12 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessBroadcastBanner
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessBroadcastStatus
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessSyncBanner
|
||||
import com.vitorpamplona.amethyst.commons.chess.LiveChessGameScreen
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessBroadcastBanner
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessBroadcastStatus
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessSyncBanner
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.LiveChessGameScreen
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
|
||||
+10
-10
@@ -60,18 +60,18 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.chess.ActiveGameCard
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChallengeCard
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessChallenge
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessSyncBanner
|
||||
import com.vitorpamplona.amethyst.commons.chess.CompletedGameCard
|
||||
import com.vitorpamplona.amethyst.commons.chess.NewChessGameDialog
|
||||
import com.vitorpamplona.amethyst.commons.chess.OutgoingChallengeCard
|
||||
import com.vitorpamplona.amethyst.commons.chess.OverlappingAvatars
|
||||
import com.vitorpamplona.amethyst.commons.chess.PublicGameCard
|
||||
import com.vitorpamplona.amethyst.commons.chess.SpectatingGameCard
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ActiveGameCard
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChallengeCard
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessChallenge
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessSyncBanner
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.CompletedGameCard
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.NewChessGameDialog
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.OutgoingChallengeCard
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.OverlappingAvatars
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.PublicGameCard
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.SpectatingGameCard
|
||||
import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox
|
||||
import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
|
||||
+1
-1
@@ -44,9 +44,9 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessConfig
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessConfig
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
|
||||
+8
-8
@@ -23,14 +23,14 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.chess
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessBroadcastStatus
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessChallenge
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessDismissedGamesStorage
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessLobbyLogic
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessPollingDefaults
|
||||
import com.vitorpamplona.amethyst.commons.chess.ChessSyncStatus
|
||||
import com.vitorpamplona.amethyst.commons.chess.CompletedGame
|
||||
import com.vitorpamplona.amethyst.commons.chess.PublicGame
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessBroadcastStatus
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessChallenge
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessDismissedGamesStorage
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessLobbyLogic
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessPollingDefaults
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.ChessSyncStatus
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.CompletedGame
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.PublicGame
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip64Chess.Color
|
||||
|
||||
+2
-2
@@ -20,8 +20,8 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chess.datasource
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.chess.subscription.ChessFilterBuilder
|
||||
import com.vitorpamplona.amethyst.commons.chess.subscription.ChessSubscriptionState
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.subscription.ChessFilterBuilder
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.subscription.ChessSubscriptionState
|
||||
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||
|
||||
|
||||
+3
-3
@@ -34,10 +34,10 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.compose.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.compose.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.compose.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.commons.model.nip30CustomEmojis.EmojiPackState.EmojiMedia
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
|
||||
+3
-3
@@ -33,10 +33,10 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.compose.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.compose.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.compose.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.commons.model.nip30CustomEmojis.EmojiPackState
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
|
||||
+1
-1
@@ -29,9 +29,9 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.chess.NewChessGameDialog
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.NewChessGameDialog
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chess.ChessViewModelFactory
|
||||
|
||||
+4
-4
@@ -35,11 +35,11 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.compose.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.compose.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.compose.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.commons.compose.setTextAndPlaceCursorAtBeginning
|
||||
import com.vitorpamplona.amethyst.commons.model.nip30CustomEmojis.EmojiPackState.EmojiMedia
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.setTextAndPlaceCursorAtBeginning
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.BooleanType
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
|
||||
+3
-3
@@ -33,12 +33,12 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.compose.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.compose.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.compose.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.commons.model.AddressableNote
|
||||
import com.vitorpamplona.amethyst.commons.model.nip30CustomEmojis.EmojiPackState
|
||||
import com.vitorpamplona.amethyst.commons.richtext.UrlParser
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
|
||||
+1
-1
@@ -27,5 +27,5 @@ fun <T> equalImmutableLists(
|
||||
list1: ImmutableList<T>,
|
||||
list2: ImmutableList<T>,
|
||||
): Boolean =
|
||||
com.vitorpamplona.amethyst.commons.utils
|
||||
com.vitorpamplona.amethyst.commons.util
|
||||
.equalImmutableLists(list1, list2)
|
||||
|
||||
+3
-3
@@ -33,10 +33,10 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.compose.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.compose.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.compose.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.commons.model.nip30CustomEmojis.EmojiPackState
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.currentWord
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.insertUrlAtCursor
|
||||
import com.vitorpamplona.amethyst.commons.ui.text.replaceCurrentWord
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ import com.vitorpamplona.amethyst.commons.actions.SearchActions
|
||||
import com.vitorpamplona.amethyst.commons.actions.ZapActions
|
||||
import com.vitorpamplona.amethyst.commons.defaults.DefaultNIP65RelaySet
|
||||
import com.vitorpamplona.amethyst.commons.relayClient.nip17Dm.unwrapAndUnsealOrNull
|
||||
import com.vitorpamplona.amethyst.commons.services.lnurl.LightningAddressResolver
|
||||
import com.vitorpamplona.amethyst.commons.service.lnurl.LightningAddressResolver
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.dal.HomeNewThreadFeedFilter
|
||||
import com.vitorpamplona.quartz.lightning.LnInvoiceUtil
|
||||
import com.vitorpamplona.quartz.marmot.RecipientRelayFetcher
|
||||
|
||||
@@ -25,7 +25,7 @@ import com.vitorpamplona.amethyst.cli.Context
|
||||
import com.vitorpamplona.amethyst.cli.DataDir
|
||||
import com.vitorpamplona.amethyst.cli.Output
|
||||
import com.vitorpamplona.amethyst.commons.actions.ZapActions
|
||||
import com.vitorpamplona.amethyst.commons.services.lnurl.LightningAddressResolver
|
||||
import com.vitorpamplona.amethyst.commons.service.lnurl.LightningAddressResolver
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
# `commons` — Shared Module Architecture & Goals
|
||||
|
||||
`commons` is the **shared layer** between every Amethyst front end:
|
||||
|
||||
| Consumer | Kind | Uses from `commons` |
|
||||
|----------------|------------------------------|----------------------------------------------|
|
||||
| `amethyst` | Android app (touch-first) | everything (models, state, ViewModels, UI) |
|
||||
| `desktopApp` | Desktop JVM app (mouse-first)| everything (models, state, ViewModels, UI) |
|
||||
| `cli` (`amy`) | Headless JVM CLI (no UI) | **non-UI only** — models, actions, relay, services |
|
||||
| iOS (future) | iOS app | everything; expected to share most UI with Android |
|
||||
|
||||
`commons` sits **above** `quartz` (the protocol-only Nostr KMP library) and
|
||||
**below** the apps. The split between the three is:
|
||||
|
||||
- **`quartz/`** — Nostr protocol: events, NIPs, crypto, relay framing. No app
|
||||
state, no UI, no caches of "what this user follows."
|
||||
- **`commons/`** — everything an Amethyst *client* needs that isn't a
|
||||
platform-native screen or navigation shell: domain models (`Note`, `User`),
|
||||
in-memory state holders, ViewModels, the relay-subscription client, shared
|
||||
business services, **and** the Compose UI components that more than one front
|
||||
end renders.
|
||||
- **`amethyst/` & `desktopApp/`** — platform-native screens, navigation
|
||||
(bottom-nav vs sidebar), gestures, system integration. They assemble
|
||||
`commons` pieces; they should not re-implement them.
|
||||
|
||||
> The goal is **"write it once in `commons`"**. Before adding a manager, cache,
|
||||
> filter, ViewModel, or composable to an app module, check whether it already
|
||||
> exists here or belongs here. See the "Where does my code go?" guide below.
|
||||
|
||||
---
|
||||
|
||||
## 1. The one rule that shapes the package tree: the **UI / non-UI boundary**
|
||||
|
||||
`commons` is a single module that contains **both** Compose UI and headless
|
||||
logic. That is deliberate (it keeps a feature's model, state, and UI together —
|
||||
see §3), but it creates one hard constraint, because **`cli` and any headless
|
||||
consumer cannot use Compose**:
|
||||
|
||||
> **CLI-safe code** = does not depend on Compose UI. It may use the
|
||||
> `androidx.compose.runtime` *annotations* `@Stable` / `@Immutable` (they are
|
||||
> just stability tags) and snapshot state, but it must **not** import
|
||||
> `androidx.compose.ui`, `androidx.compose.foundation`,
|
||||
> `androidx.compose.material3`, declare `@Composable` functions, or build
|
||||
> `ImageVector`s.
|
||||
>
|
||||
> **UI code** = anything that does. It is only usable by the GUI front ends
|
||||
> (Android, Desktop, iOS), never by `cli`.
|
||||
|
||||
Compose is an `implementation` dependency of `commonMain`, so `cli` pulling in
|
||||
`commons` does **not** force it to render anything — but a `cli` command must
|
||||
only reach for CLI-safe packages. When you add code, know which side of this
|
||||
line it is on, and put it in a package that matches (§2).
|
||||
|
||||
This boundary is **not** a top-level `ui/` vs `logic/` partition of the whole
|
||||
module (we chose to stay feature-oriented, §3). It is a property of each file
|
||||
that you keep track of via package placement and the table in §2.
|
||||
|
||||
---
|
||||
|
||||
## 2. Package taxonomy
|
||||
|
||||
Top-level packages under
|
||||
`commonMain/.../commons/`, grouped by concern. **UI?** marks whether the
|
||||
package contains Compose UI (and is therefore *not* CLI-safe).
|
||||
|
||||
### Domain models & data
|
||||
| Package | UI? | Purpose |
|
||||
|----------------|-----|---------|
|
||||
| `model` | no¹ | Core domain types (`Note`, `User`, `Channel`), thread assembly, and per-NIP event model extensions in `model/nipNN…` subpackages. `model/cache` holds the in-memory event-store interfaces + `UserMetadataCache`. `model/account`, `model/observables`. The largest package; keep it organized by NIP. |
|
||||
| `defaults` | no | Static bootstrap data (default relays, channels). |
|
||||
|
||||
¹ `model` uses only the `@Stable`/`@Immutable` runtime annotations — CLI-safe.
|
||||
|
||||
### Protocol-adjacent business logic (CLI-safe)
|
||||
| Package | UI? | Purpose |
|
||||
|----------------|-----|---------|
|
||||
| `actions` | no | Event builders for user actions (follow, zap…). The canonical entry point for non-UI callers. |
|
||||
| `account` | no | New-account bootstrap events. |
|
||||
| `onchain` | no | On-chain zap splitting/broadcasting. |
|
||||
| `marmot` | no | MLS group-chat event processing. |
|
||||
| `nip53LiveActivities` | mixed | Live-activity zapper aggregation (logic) + the stream card in `nip53LiveActivities/ui`. |
|
||||
| `search` | no | Event search filtering/ranking, kind registry. |
|
||||
| `preview` | no | OpenGraph / meta-tag link-preview parsing. |
|
||||
| `emojicoder` | no | Variation-selector emoji encode/decode. |
|
||||
| `richtext` | no | URL/media/pattern parsing for rich text. |
|
||||
| `blurhash` | no | BlurHash encode/decode (pure math; platform image bridge in platform sets). |
|
||||
| `thumbhash` | no | ThumbHash encode/decode. |
|
||||
| `nipACWebRtcCalls` | no | NIP-AC WebRTC **call state machine** + peer-session abstraction. See `nipACWebRtcCalls/ARCHITECTURE.md`. (Mirrors `quartz/.../nipACWebRtcCalls`.) |
|
||||
|
||||
### State holders & ViewModels
|
||||
| Package | UI? | Purpose |
|
||||
|----------------|-----|---------|
|
||||
| `state` | no² | Small feature `StateFlow` machines (`FollowState`, `UserMetadataState`, `LoadingState`). |
|
||||
| `viewmodels` | no² | Larger list/feed-backed ViewModels (`androidx.lifecycle.ViewModel`). Shared by all GUI front ends; `cli` usually drives the layers below instead. |
|
||||
| `feeds` | no | `FeedDefinitionRepository` — custom-feed definitions & ordering. |
|
||||
| `profile` | mixed | `ProfileBroadcastStatus` (state) + `EditProfileFields` at the root; the `ProfileBroadcastBanner` composable lives in `profile/ui`. |
|
||||
|
||||
² may touch `compose.runtime`/`foundation` state types (e.g. `LazyListState`);
|
||||
they are shared across the GUI apps. Treat as GUI-shared, not strictly headless.
|
||||
|
||||
### Relay client
|
||||
| Package | UI? | Purpose |
|
||||
|----------------|-----|---------|
|
||||
| `relayClient` | no | Compose-scoped subscription managers, filter assemblers, EOSE managers, preloaders. (Despite a `composeSubscriptionManagers` subpackage name, this is subscription-lifecycle logic, not UI.) |
|
||||
| `relays` | no | Low-level EOSE/relay-timing bookkeeping (`EOSECache`, `EOSERelayList`). |
|
||||
|
||||
### Platform abstractions (`expect`/`actual`)
|
||||
| Package | UI? | Purpose |
|
||||
|----------------|-----|---------|
|
||||
| `util` | no | KMP primitives: `KmpLock`, `WeakReference`, number/URL/codepoint helpers, list/debug helpers. **This is the only general-utility package** — there is no `utils`. |
|
||||
| `keystorage` | no | Secure key storage interface (Keystore / keychain / keyring actuals). |
|
||||
| `threading` | no | `checkNotInMainThread` assertion. |
|
||||
| `tor` | no | Tor manager interface + settings. |
|
||||
| `service` | no | Cross-cutting services: `BundledUpdate` batching (common); `service/upload` (JVM), `service/nwc`, `service/lnurl` (jvmAndroid). **Singular `service`** — there is no `services`. |
|
||||
|
||||
### UI (Compose — **not** CLI-safe)
|
||||
| Package | UI? | Purpose |
|
||||
|----------------|-----|---------|
|
||||
| `ui` | yes | **Cross-cutting** shared composables only, organized by area: `ui/components`, `ui/theme`, `ui/signing`, `ui/thread`, `ui/feeds` (feed DAL + filters — see debt §4), `ui/notifications`, `ui/screens`, `ui/elements`, `ui/layouts`, `ui/markdown`, plus Compose helpers in `ui/state` (cached-state) and `ui/text` (TextField extensions). Feature-specific UI lives in `<feature>/ui`, **not** here. |
|
||||
| `nip23LongContent` | yes | Long-form (NIP-23) article UI: `nip23LongContent/ui/article` (reader) + `…/ui/editor` (authoring). The model lives in `model/nip23LongContent`. |
|
||||
| `icons` | yes | `ImageVector` icon definitions + builders. |
|
||||
| `hashtags` | yes | Custom hashtag `ImageVector`s. |
|
||||
| `robohash` | yes | Procedural robohash avatar `ImageVector` assembly. |
|
||||
|
||||
### Mixed (documented debt — see §4)
|
||||
| Package | UI? | Purpose |
|
||||
|----------------|-----|---------|
|
||||
| `nip64Chess` | mixed | Live-chess feature: game/lobby/subscription logic **and** board/lobby composables in one flat package. Needs a `nip64Chess/ui` split. (Mirrors `quartz/.../nip64Chess`.) |
|
||||
| `domain` | no | Currently only `domain/nip46` (Nostr Connect signer flows). Sparse; candidate to fold into a clearer home. |
|
||||
|
||||
---
|
||||
|
||||
## 3. Conventions
|
||||
|
||||
### Feature-oriented, not layer-partitioned
|
||||
We keep a feature's model, state, and UI **together** under one feature
|
||||
package rather than splitting the whole module into top-level `ui/` /
|
||||
`viewmodels/` / `model/` layers. Within a feature, separate UI from logic with a
|
||||
`ui` **subpackage** (e.g. `profile/ProfileBroadcastStatus` vs
|
||||
`profile/ui/ProfileBroadcastBanner`) so the CLI-safe boundary (§1) stays
|
||||
visible.
|
||||
|
||||
The big shared cross-feature packages (`model`, `ui`, `relayClient`, `util`,
|
||||
`icons`) are the exception — they are organized by layer because many features
|
||||
share them.
|
||||
|
||||
### Naming
|
||||
- **Singular, no synonyms.** `util` (not `utils`), `service` (not `services`).
|
||||
One concept → one package name.
|
||||
- **Feature UI vs cross-cutting UI — the deciding test.** A composable goes in
|
||||
`<feature>/ui` if it renders/edits *one* feature's content (it would make no
|
||||
sense outside that feature) — e.g. `profile/ui`, `nip53LiveActivities/ui`,
|
||||
`nip23LongContent/ui`. It goes in `ui/<area>` only if it is reusable across
|
||||
features (theme, avatars, buttons, layouts, markdown rendering, shimmer…).
|
||||
When in doubt, ask "could a second, unrelated feature reuse this as-is?" —
|
||||
yes → `ui/<area>`, no → `<feature>/ui`. The top-level `ui/` package holds
|
||||
**no** feature-specific composables.
|
||||
|
||||
### NIP as the second axis (mirror `quartz`)
|
||||
`quartz` is ~94% organized by NIP (`nipNN<slug>` per spec), and that is correct
|
||||
*there* — the protocol layer is naturally NIP-partitioned. `commons` is **not**
|
||||
organized by NIP at the top level, and should not be: most of it is
|
||||
cross-cutting infrastructure (`ui`, `relayClient`, `viewmodels`, `feeds`,
|
||||
`util`…) that serves many NIPs at once, and the load-bearing UI/non-UI boundary
|
||||
(§1) cuts *across* NIPs, so a NIP-first top level would just nest the same
|
||||
problem one level down.
|
||||
|
||||
Instead, **layer is the primary axis, NIP is the secondary axis**:
|
||||
|
||||
- The big shared layers stay layer-organized (`model`, `relayClient`, the
|
||||
cross-cutting `ui`, …).
|
||||
- **Inside a layer, NIP-specific code goes in a `nipNN<slug>` subpackage whose
|
||||
name matches `quartz` exactly** — e.g. `model/nip57Zaps`. This gives a clean
|
||||
trace: `quartz/nip57Zaps` → `commons/model/nip57Zaps`.
|
||||
- **A top-level package that *is* a single self-contained NIP feature takes the
|
||||
same name as its `quartz` counterpart**, and owns its own UI under
|
||||
`<feature>/ui`: `nip64Chess`, `nipACWebRtcCalls`, `nip53LiveActivities`,
|
||||
`nip23LongContent`, `marmot`. (`marmot` is un-numbered in `quartz` too.)
|
||||
Generic/multi-NIP packages keep their concern name (`search`, `preview`,
|
||||
`actions`, `richtext`…).
|
||||
- **Feature UI is never under `ui/`.** A single-NIP feature's composables live
|
||||
in `<feature>/ui` (e.g. `nip53LiveActivities/ui`), not `ui/nip53LiveActivities`.
|
||||
`ui/` is exclusively cross-cutting (§2, Naming).
|
||||
|
||||
### Source sets
|
||||
| Source set | For |
|
||||
|---------------|-----|
|
||||
| `commonMain` | KMP code for **all** targets (Android, JVM, iOS). Gated by `verifyKmpPurity` — no Jackson/OkHttp/`System.currentTimeMillis`/`java.util.UUID`/JVM `@Synchronized`/`@Volatile`. Use the KMP replacements. |
|
||||
| `jvmAndroid` | Shared by Android + Desktop, **not** iOS. Where JVM-bound deps live (`nestsClient`, Coil-OkHttp, markdown, `viewModel()` helper, NWC/LNURL). |
|
||||
| `jvmMain` | Desktop-only (keyring, EXIF, `service/upload`). `dependsOn(jvmAndroid)`. |
|
||||
| `androidMain` | Android-only (Keystore, DataStore). `dependsOn(jvmAndroid)`. |
|
||||
| `iosMain` | iOS `actual`s. Compile-only spike today. |
|
||||
|
||||
When adding platform code, prefer the **most common** source set that still
|
||||
compiles: `commonMain` → `jvmAndroid` → platform-specific. See
|
||||
`/kotlin-multiplatform`.
|
||||
|
||||
### Where does my code go? (quick guide)
|
||||
1. **Pure Nostr protocol** (events/NIPs/crypto)? → not here, it's `quartz`.
|
||||
2. **A composable** rendered by ≥2 front ends, or that you want iOS to share? →
|
||||
`ui/<area>` or `<feature>/ui`. Never in `cli`.
|
||||
3. **A ViewModel / `StateFlow` state holder**? → `viewmodels` or `state` (or
|
||||
`<feature>` if feature-scoped). Keep it CLI-safe where practical.
|
||||
4. **Relay subscription / filter assembly**? → `relayClient`.
|
||||
5. **A domain model or per-NIP event wrapper**? → `model` (`model/nipNN…`).
|
||||
6. **A platform capability behind `expect`/`actual`** (storage, crypto,
|
||||
threading)? → the matching abstraction package + actuals in platform sets.
|
||||
7. **A generic helper**? → `util`. (Resist creating a new top-level package for
|
||||
one file.)
|
||||
|
||||
---
|
||||
|
||||
## 4. Known debt / follow-ups
|
||||
|
||||
These are intentionally *documented*, not silently tolerated. Fix opportunistically.
|
||||
|
||||
- **`nip64Chess` is UI+logic in one flat package.** `LiveChessGame.kt` mixes a
|
||||
state class with composables. Split into `nip64Chess/` (logic) +
|
||||
`nip64Chess/ui/` (composables); this needs file-level surgery (extracting
|
||||
composables out of logic files), not just moves, so it is deferred.
|
||||
- **`ui/feeds` holds the feed data-access layer** (`FeedFilter`,
|
||||
`ChangesFlowFilter`, `FeedContentState`), which is logic, not UI, and overlaps
|
||||
conceptually with the top-level `feeds` (custom-feed definitions). Consider
|
||||
moving the DAL out of `ui/`.
|
||||
- **`domain` is sparse** (only `nip46`). Either grow it as the home for
|
||||
use-case/flow types or rename it to the matching `nip46RemoteSigner` per the
|
||||
NIP-second-axis rule.
|
||||
- **`relays` vs `relayClient`** are coherent but close in name; `relays` is
|
||||
low-level EOSE bookkeeping, `relayClient` is the subscription client. Keep the
|
||||
distinction in mind when adding files.
|
||||
- Several **single-file feature packages** (`account`, `marmot`,
|
||||
`nip53LiveActivities`, `keystorage`, `threading`) are kept as feature/abstraction
|
||||
namespaces expected to grow; do not fold them into `util` just for size.
|
||||
- **`onchain`** (on-chain zap splitting) is `quartz`-adjacent but un-numbered;
|
||||
leave readable unless a clear NIP number lands.
|
||||
|
||||
---
|
||||
|
||||
## 5. See also
|
||||
- `nipACWebRtcCalls/ARCHITECTURE.md` — WebRTC call state machine deep-dive.
|
||||
- Root `.claude/CLAUDE.md` — module overview, sharing philosophy, build commands.
|
||||
- `/kotlin-multiplatform`, `/compose-expert`, `/feed-patterns`, `/relay-client`,
|
||||
`/account-state` skills for the patterns referenced above.
|
||||
@@ -0,0 +1,312 @@
|
||||
# Amethyst → Commons Migration Plan
|
||||
|
||||
**Date:** 2026-05-30 · **Owning module:** `commons` · **Status:** plan (no code moved yet)
|
||||
|
||||
Goal: move the **shared** parts of the `amethyst` Android app down into `commons`
|
||||
so Desktop, the headless `cli`, and future iOS reuse them, leaving `amethyst`
|
||||
as a thin Android-native shell (Activity, navigation, notifications, platform
|
||||
services). This is the inverse direction of the `commons` package refactor that
|
||||
preceded it (see `commons/ARCHITECTURE.md`) — that cleaned up *where* shared
|
||||
code lives; this plan decides *what* still needs to move there.
|
||||
|
||||
## Scope surveyed
|
||||
|
||||
`amethyst/src/main` ≈ **1817 Kotlin files**. Coupling signals:
|
||||
|
||||
| Signal | Files | Meaning |
|
||||
|---|---|---|
|
||||
| `androidx.compose.*` | 1075 | UI |
|
||||
| `R.string` / `amethyst.R` | 559 | localized strings — see §"Strings" |
|
||||
| `android.content.Context` | 142 | platform handle to abstract |
|
||||
| Activity / Service / `android.app` | 40 | clearly stays native |
|
||||
| `com.fasterxml.jackson` | 6 | purity-gate only matters for commonMain/iOS |
|
||||
|
||||
Three structured passes (model/, service/, ui/) produced the matrices below.
|
||||
|
||||
---
|
||||
|
||||
## 0. What is ALREADY in commons (do NOT re-extract)
|
||||
|
||||
The agents that surveyed `amethyst` did not all know commons' current state.
|
||||
These already exist and the amethyst copies are **dedup / re-point** targets,
|
||||
not new extractions:
|
||||
|
||||
- **Account scaffolding:** `model/IAccount`, `model/account/{AccountInfo,
|
||||
AccountStorage,SignerType}`, `state/{FollowState,UserMetadataState,
|
||||
LoadingState,EventCollectionState}`, `model/cache/*`. **But the concrete
|
||||
`Account.kt` (3565 LOC) and `LocalCache.kt` (3917 LOC) are NOT extracted** —
|
||||
only their interfaces/scaffolding are. They are the keystone (§Phase A).
|
||||
- **Relay layer:** `relayClient/*` (assemblers, eoseManagers, composeSubscription
|
||||
managers, preload, subscriptions, nip17Dm) and `relays/*`.
|
||||
- **Formatters / util:** `util/PubKeyFormatter`, `util/NumberFormatters`,
|
||||
`util/PlatformNumberFormatter` (expect/actual). amethyst's
|
||||
`ui/note/PubKeyFormatter.kt` is a **duplicate**.
|
||||
- **Services:** `service/lnurl/{LightningAddressResolver,OkHttpLnurlEndpointResolver}`,
|
||||
`service/nwc`, `service/upload`. amethyst's `service/lnurl/LightningAddressResolver.kt`
|
||||
is a **duplicate**.
|
||||
- **Strings:** commons localizes through **Compose Multiplatform Resources**
|
||||
(`composeResources/values/strings.xml`, `stringResource(Res.string.x)`),
|
||||
already 41 strings. ← This is the migration path for `R.string`, NOT a custom
|
||||
`StringProvider`.
|
||||
- **Image loading:** Coil 3 is already KMP — `coil.compose` in `commonMain`,
|
||||
`coil.okhttp` in `jvmAndroid`. Shared composables can call `AsyncImage`
|
||||
directly; **image loading is largely a non-blocker**.
|
||||
- **Misc:** `tor/`, `keystorage/` (interface + actuals), `richtext/`,
|
||||
`preview/` (OpenGraph/MetaTags parsers), `feeds/`, `ui/feeds` (feed DAL).
|
||||
|
||||
---
|
||||
|
||||
## 1. Cross-cutting blockers (the real Phase 0)
|
||||
|
||||
Ranked by how much extraction they unblock. Note the corrections vs. the raw
|
||||
survey (Coil and Strings are *less* of a blocker than assumed; account state is
|
||||
*more*).
|
||||
|
||||
| Blocker | Reality | Resolution |
|
||||
|---|---|---|
|
||||
| **Account state** (`Account.kt`, `LocalCache.kt`, `AccountViewModel`) | The dominant blocker. ~53 UI files read it; nearly every ViewModel depends on it. commons has only the interfaces. | Extract `Account`/`LocalCache` business logic to `commons/model/account` + `model/cache`, behind the existing `IAccount`/cache interfaces. Keep Android-only bits (LocationState wiring, `@Stable`) in a thin adapter. **Keystone — §Phase A.** |
|
||||
| **`R.string`** (559) | Solved pattern already in use. | Migrate needed strings into `commons/.../composeResources/values/strings.xml`; replace `R.string.x` → `Res.string.x`. No new abstraction. Crowdin config already exists at repo root. |
|
||||
| **`Context`** (142) | Mostly file pick / clipboard / intents / cacheDir. | Small `expect`/`actual` platform-service interfaces (file picker, clipboard, URI open). Most are confined to `ui/actions/uploads` and a few service packages. |
|
||||
| **`INav`** (nav callbacks) | Already an interface; low friction. | Shared composables take `onNavigate: (route) -> Unit` lambdas, not `INav` directly. |
|
||||
| **Image loading (Coil)** | Already KMP in commons. | Use commons Coil directly; only the Android `ImageLoaderSetup`/fetchers stay native (or move to `jvmAndroid`). |
|
||||
| **OkHttp / Jackson** | Allowed in `jvmAndroid`; banned only in `commonMain`/iOS. | HTTP/JSON code → `jvmAndroid`. Only promote to `commonMain` (for iOS) by swapping to Ktor + kotlinx.serialization, and only when iOS needs it. |
|
||||
|
||||
---
|
||||
|
||||
## 2. model/ — migration matrix
|
||||
|
||||
Most of `amethyst/model` is CLI-safe Nostr state and extracts cleanly. Verdicts:
|
||||
**Extract** (pure) · **Abstract** (needs storage/HTTP/keystore seam) ·
|
||||
**Keystone** · **Native**.
|
||||
|
||||
| Area | Verdict | Destination | Note |
|
||||
|---|---|---|---|
|
||||
| `Account.kt`, `LocalCache.kt`, `accountsCache/` | **Keystone** | `model/account`, `model/cache` | 3565+3917 LOC; behind `IAccount`/cache ifaces; LocationState → adapter |
|
||||
| `AccountSettings`, `AccountSyncedSettings*` | Extract | `model/account` | pure data + event (de)serialization |
|
||||
| `UiSettings`, `UiSettingsFlow` | Abstract | `model/` | drop `R.string` (use string keys / `Res`) |
|
||||
| `nip01UserMetadata`, `nip02FollowLists`, `nip17Dms`, `nip30CustomEmojis`, `nip47WalletConnect`, `nip51Lists`, `nip65RelayList`, `nip72Communities`, `nip78AppSpecific`, `nip86RelayManagement`, `nipA3PaymentTargets`, `nipB7Blossom`, `nipBCOnchainZaps`, `trustedAssertions`, `zap` | Extract | `model/nipNN<slug>` (mirror quartz) | pure event-state wrappers; bulk move |
|
||||
| `topNavFeeds/`, `algoFeeds/`, `serverList/` | Extract | `feeds/`, `model/relayLists` | feed query orchestration is platform-agnostic |
|
||||
| `edits/` | Extract | `model/nip51Lists` or `model/nip37Drafts` | encrypted list/draft state |
|
||||
| `preferences/` (DataStore, KeyStoreEncryption, *SharedPreferences) | Abstract | `keystorage/`, `model/preferences` | schemas → commons; persistence actuals stay Android |
|
||||
| `marmot/` (Android*Store) | Abstract | `keystorage/marmot` + commons logic | KeyStore-backed stores → expect/actual |
|
||||
| `nip03Timestamp`, `nip11RelayInfo`, `privacyOptions` (OkHttp), `localRelays` | Abstract | `jvmAndroid` (HTTP) + commonMain (logic) | OkHttp → jvmAndroid; ContentResolver stays native |
|
||||
| `torState/` | Extract | `tor/`, `model/torState` | relay-eval logic is pure |
|
||||
| `EncryptedStorage`, `LocalPreferences` | Abstract | `keystorage/` | core logic + iface; SharedPrefs impl stays Android |
|
||||
| `Amethyst.kt` (Application), `AppModules.kt` (DI) | **Native** | — | Android lifecycle / Context assembly |
|
||||
|
||||
**Highest value, lowest friction:** the ~16 `nipNN` state packages + `topNavFeeds`
|
||||
(bulk pure moves), then `AccountSettings`/`AccountSyncedSettings`.
|
||||
|
||||
---
|
||||
|
||||
## 3. service/ — migration matrix
|
||||
|
||||
| Package (files) | Verdict | Destination | Note |
|
||||
|---|---|---|---|
|
||||
| `relayClient` (81) | **Native** | — (dedup) | Android orchestration wiring over commons `relayClient`; do NOT duplicate. Lift any LocalCache-free EOSE managers into commons. |
|
||||
| `playback` (60) | Native | — | ExoPlayer/Media3, PIP — Android-only |
|
||||
| `notifications` (15) | Native | — | foreground service, NotificationManager |
|
||||
| `okhttp` (17) | Extract | `jvmAndroid` | OkHttp clients/interceptors/WS bridge; already JVM-shaped |
|
||||
| `uploads` (25) | Abstract | `jvmAndroid` + commonMain iface | compression/codecs stay Android; orchestration → common |
|
||||
| `images` (10) | Abstract | `jvmAndroid` (Coil setup) + commonMain (hashes already in commons) | |
|
||||
| `cashu` (10) | Extract | `commonMain` (e.g. `model/nip60Cashu` or `service/cashu`) | parser is pure; split off Compose `GenericLoadable` |
|
||||
| `call` (10) | Abstract | commonMain (state) + `jvmAndroid` (AudioManager/WebRTC) | WebRTC hard to abstract |
|
||||
| `location` (6) | Abstract | commonMain (geohash) + `jvmAndroid` (Geocoder) | |
|
||||
| `connectivity` (3) | Abstract | commonMain (model) + actual | trivial seam |
|
||||
| `broadcast` (2), `ai` (2), `previews` (2) | Extract | commonMain (`service/`, `preview`) | previews already wraps commons parsers — consolidate |
|
||||
| `lnurl` (2) | Extract / **dedup** | `jvmAndroid` `service/lnurl` | `LightningAddressResolver` duplicates commons — reconcile |
|
||||
| `namecoin` (1) | Abstract | `jvmAndroid` | ElectrumX over OkHttp |
|
||||
| `relays` (1, EOSE) | Extract / dedup | `relayClient`/`relays` | consolidate EOSE state |
|
||||
| `eventCache` (1) | Abstract | commonMain | eviction logic pure; trim trigger via iface |
|
||||
| `scheduledposts` (4), `calendar` (4) | Native (model extractable) | — | WorkManager-bound; model → commonMain if needed |
|
||||
| `crashreports` (4), `logging` (3) | Native (DTO extractable) | — | Choreographer/Build native |
|
||||
| `tts` (2), `cast` (2), `nests` (2) | Native | — | TTS / Cast / foreground service |
|
||||
| root utils (`ByteFormatter`, `CountFormatter`, etc.) | Extract | `util/` | some may already exist — check first |
|
||||
|
||||
**Highest value, lowest friction:** `okhttp`→`jvmAndroid`, `cashu`, `broadcast`,
|
||||
`ai`, `previews` consolidation, `lnurl` dedup, EOSE consolidation.
|
||||
|
||||
---
|
||||
|
||||
## 4. ui/ — migration matrix
|
||||
|
||||
commons rule (from `ARCHITECTURE.md`): cross-cutting composables → `ui/<area>`;
|
||||
feature-specific → `<feature>/ui`. Deciding test: "could an unrelated feature
|
||||
reuse this as-is?"
|
||||
|
||||
| Area (files) | Shareable | Destination | Blockers |
|
||||
|---|---|---|---|
|
||||
| `ui/dal` (5) | already re-exports | — | none — delete shims, point at `ui/feeds` |
|
||||
| `ui/theme` (5) | ~90%, **dup** | merge into `ui/theme` | system-chrome (status/nav bar) stays Android |
|
||||
| `ui/feeds` (12) | ~95% | `ui/feeds` | a few `R.string`, AccountVM |
|
||||
| `ui/layouts` (9) | ~85% | `ui/layouts` | 2× `R.string`, 1× `INav` |
|
||||
| `ui/components` (59) | ~75% | split `ui/components` (atoms) + `<feature>/ui` (galleries) | ~30 atoms clean; Coil/AccountVM/`R.string` on the rest |
|
||||
| `ui/note` (184) | ~50–70% | formatters→`ui/text`; avatars→`ui/elements`/`profile/ui`; renderers→`<nipNN>/ui` | AccountVM (29), `R.string` (24), Note model coupling |
|
||||
| `ui/actions` (41) | ~65% | transforms→commonMain; VMs→`viewmodels`; media→stay Android | Context (7), AccountVM (7), `R.string` (8) |
|
||||
| `ui/screen` (971) | mostly native | — | app screens; harvest reusable atoms opportunistically |
|
||||
| `ui/navigation`, `ui/call`, `ui/cast`, `ui/broadcast`, `ui/tor` | native | — | platform wiring |
|
||||
|
||||
**Lowest-friction UI wins** (after string migration): TimeAgo/date formatters →
|
||||
`ui/text`; `ClickableUrl/Email/Phone`; `GenericLoadable` → `ui/state`; input
|
||||
transforms; `DisappearingBar*` → `ui/layouts`; feed-state composables; `ui/dal`
|
||||
shim deletion; `ui/theme` consolidation. ~42% of note/components/actions
|
||||
composables (112/266) carry no `R.string` at all.
|
||||
|
||||
---
|
||||
|
||||
## 5. Reconciliation / dedup backlog (do early — prevents drift)
|
||||
|
||||
1. `service/relayClient` (Android) vs `commons/relayClient` — keep Android as
|
||||
wiring only; lift cache-independent EOSE managers down.
|
||||
2. `service/lnurl/LightningAddressResolver` vs `commons/service/lnurl/…` — one
|
||||
canonical copy.
|
||||
3. `ui/note/PubKeyFormatter` vs `commons/util/PubKeyFormatter` — delete the dup.
|
||||
4. `ui/theme` vs `commons/ui/theme` — single color/type source.
|
||||
5. `ui/dal` vs `commons/ui/feeds` — delete re-export shims.
|
||||
6. `service/relays/EOSE*` scattered — one EOSE-state home.
|
||||
|
||||
---
|
||||
|
||||
## 6. Phased roadmap
|
||||
|
||||
- **Phase A — Account keystone (largest, gates the rest).** Extract `Account` +
|
||||
`LocalCache` business logic into `commons/model/account` + `model/cache`
|
||||
behind the existing interfaces; amethyst keeps a thin Android adapter
|
||||
(LocationState, Compose `@Stable`). Unblocks ViewModels + interactive UI.
|
||||
- **Phase B — pure model & service extracts (parallel, low risk).** The ~16
|
||||
`nipNN` model packages, `topNavFeeds`, `cashu`, `broadcast`, `ai`,
|
||||
`previews`, EOSE/lnurl/PubKeyFormatter dedups, `okhttp`→`jvmAndroid`.
|
||||
- **Phase C — storage/network seams.** `keystorage` expect/actual for prefs +
|
||||
KeyStore + marmot stores; HTTP packages (nip11/nip03/namecoin/privacyOptions)
|
||||
→ `jvmAndroid`.
|
||||
- **Phase D — string migration + shared UI atoms.** Migrate the needed strings
|
||||
into `composeResources`, then extract the low-friction UI list in §4.
|
||||
- **Phase E — feature UI.** Note type renderers → `<nipNN>/ui`; read-only
|
||||
renderers (Badge, Emoji, Poll display) before interactive ones (reactions,
|
||||
composers). Much of `ui/note/creators` and reaction/zap rows may stay native
|
||||
unless Desktop/iOS need them.
|
||||
- **Never moves:** Application/DI, notifications, playback, WorkManager jobs,
|
||||
TTS, Cast, foreground services, navigation shells, Activity-bound code.
|
||||
|
||||
## 7. Suggested first PR (smallest valuable slice)
|
||||
|
||||
Phase B subset — zero account dependency, immediately reusable by Desktop:
|
||||
the dedups (§5.2–5.5) + a bulk move of 4–6 pure `nipNN` model packages
|
||||
(`nip17Dms`, `nip30CustomEmojis`, `nip47WalletConnect`, `nip65RelayList`,
|
||||
`trustedAssertions`, `zap`). Mechanical, compile-verifiable, no new abstractions.
|
||||
Phase A is its own large PR and should be planned separately.
|
||||
|
||||
---
|
||||
|
||||
## 8. Architecture end-state (why the tree below is shaped this way)
|
||||
|
||||
The ports already exist in commons (`IAccount`, `ICacheProvider`,
|
||||
`ICacheEventStream`) but **every app reimplements them** — `amethyst`
|
||||
(`object LocalCache` 3917 LOC + `class Account` 3565 LOC), `desktopApp`
|
||||
(`class DesktopLocalCache` 739 LOC + `DesktopIAccount` 278 LOC), `cli`
|
||||
(stateless). Crucially these implementations are **platform-agnostic already**
|
||||
(`Account.kt` has one android import — `@Stable` — plus a single `LocationState`
|
||||
coupling; `LocalCache.kt` has two; `DesktopLocalCache` has zero). So this is
|
||||
**accidental forking, not essential divergence.** The end-state is **one
|
||||
canonical implementation per port, living in commons**, with apps keeping only
|
||||
thin platform adapters.
|
||||
|
||||
Two consequences shape the package tree:
|
||||
|
||||
1. **Decompose the monoliths; don't relocate them.** `Account` (28 `StateFlow`s +
|
||||
~170 `suspend fun`s) splits into *state* (per-user reactive state), *actions*
|
||||
(the verbs), and a thin *façade* implementing `IAccount`. `LocalCache`
|
||||
becomes the cache *engine* as a `class` (so every platform gets multi-account;
|
||||
Desktop already needed it).
|
||||
2. **Litmus test = CLI-constructibility.** `signer → cache → account state →
|
||||
actions → relay client → pure services` must build in a headless `main()`
|
||||
with no Compose/Android. Anything that can't is mislayered or missing a port.
|
||||
|
||||
Layer is the primary axis; NIP is the secondary axis (`nipNN<slug>` matching
|
||||
quartz). The raw per-NIP list **state** lives in `model/nipNN<slug>`; the
|
||||
account's *composed/derived* view of those lists lives in `model/account/*`. The
|
||||
generic `state/` package (load-a-thing `StateFlow` machines) is **not** where
|
||||
account-specific state goes.
|
||||
|
||||
## 9. Target package hierarchy (the destination tree)
|
||||
|
||||
`commonMain/.../commons/` (✚ = new package, ⤺ = merge into existing, ✔ = exists):
|
||||
|
||||
```
|
||||
model/
|
||||
├─ cache/
|
||||
│ ├─ ICacheProvider.kt ICacheEventStream.kt ✔ read ports
|
||||
│ ├─ ILocalCache.kt ✚ write port (from amethyst)
|
||||
│ ├─ LocalCache.kt ← unified cache ENGINE as a CLASS (amethyst object + DesktopLocalCache collapse here)
|
||||
│ └─ UserMetadataCache.kt ✔
|
||||
├─ account/
|
||||
│ ├─ Account.kt ← façade implementing IAccount (from amethyst Account)
|
||||
│ ├─ AccountInfo.kt AccountStorage.kt SignerType.kt ✔
|
||||
│ ├─ settings/ AccountSettings, AccountSyncedSettings(+Internal) ✚
|
||||
│ ├─ follows/ derived per-feed live-follow lists + all-follows merge ✚
|
||||
│ ├─ relays/ account relay sets + outbox relay cache ✚
|
||||
│ └─ hidden/ LiveHiddenUsers — mute/spam aggregated view ✚
|
||||
├─ nip02FollowList/ ⤺ raw Kind-3 follow-list state (amethyst nip02FollowLists)
|
||||
├─ nip65RelayList/ ⤺ relay-list state
|
||||
├─ nip51Lists/ ⤺ mute / bookmark / people lists
|
||||
├─ nip30CustomEmojis/ ⤺ emoji-pack state
|
||||
├─ nip01Core/ ⤺ kind-0 user-metadata relay-hint state (amethyst nip01UserMetadata)
|
||||
├─ nip17Dm/ nip47WalletConnect/ nip60Cashu/ nip72ModCommunities/
|
||||
│ nip78AppData/ nip85TrustedAssertions/ nip86RelayManagement/
|
||||
│ nipA3PaymentTargets/ nipB7Blossom/ nipBCOnchainZaps/ ✚ per-NIP state holders (bulk)
|
||||
└─ settings/ ✚ UiSettings / UiSettingsFlow (global, NOT account-scoped)
|
||||
|
||||
state/ ✔ generic StateFlow machines (FollowState, …) — unchanged
|
||||
actions/ ✔ the account "verbs" — extend, don't duplicate
|
||||
│ existing: DmActions FollowActions SearchActions ZapActions ZapSplitResolver
|
||||
│ add: PostActions ReactionActions BookmarkActions MuteActions
|
||||
│ RelayActions ProfileActions GroupActions DeletionActions …
|
||||
feeds/
|
||||
├─ custom/ ✔
|
||||
├─ topNav/ ✚ (amethyst model/topNavFeeds)
|
||||
└─ algo/ ✚ (amethyst model/algoFeeds)
|
||||
relayClient/ ✔ + cache-free EOSE managers lifted from amethyst service/relays
|
||||
keystorage/
|
||||
├─ SecureKeyStorage.kt ✔
|
||||
├─ preferences/ ✚ LocalPreferences logic + DataStore/SharedPrefs schema (+actuals)
|
||||
├─ account/ ✚ account persistence (pairs with model/account/AccountStorage)
|
||||
└─ marmot/ ✚ MLS key-package / message / group-state store ports (+actuals)
|
||||
service/
|
||||
├─ upload/ nwc/ lnurl/ ✔ (lnurl: dedup amethyst LightningAddressResolver)
|
||||
├─ broadcast/ ai/ connectivity/ eventCache/ ✚ commonMain (pure)
|
||||
└─ okhttp/ nip11RelayInfo/ nip03Timestamp/ namecoin/ privacyOptions/ ✚ jvmAndroid (OkHttp/Jackson)
|
||||
tor/ ✔ + torState relay-evaluation logic
|
||||
```
|
||||
|
||||
UI destinations follow `commons/ARCHITECTURE.md` (cross-cutting → `ui/<area>`,
|
||||
feature-specific → `<feature>/ui`) and are detailed in §4 — out of scope for the
|
||||
"common objects" core tier above.
|
||||
|
||||
## 10. Package-naming decisions (the rules behind §9)
|
||||
|
||||
1. **`model/nipNN<slug>` (raw list state) vs `model/account/*` (composed view).**
|
||||
`model/nip02FollowList` holds the raw Kind-3 list; `model/account/follows`
|
||||
holds the user's *derived* per-feed follow flows that compose it. Same for
|
||||
relays (`nip65RelayList` vs `account/relays`) and mutes (`nip51Lists` vs
|
||||
`account/hidden`).
|
||||
2. **NIP slugs match quartz exactly**, normalizing amethyst's drift:
|
||||
`nip02FollowLists→nip02FollowList`, `nip01UserMetadata→nip01Core`,
|
||||
`nip30CustomEmojis` (keep — existing commons name), `nip72Communities→
|
||||
nip72ModCommunities`, `nip78AppSpecific→nip78AppData`,
|
||||
`trustedAssertions→nip85TrustedAssertions` (or keep the existing readable
|
||||
`model/trustedAssertions` — pick one and converge).
|
||||
3. **`state/` stays generic.** Account-specific state never goes here; it goes in
|
||||
`model/account/*`. `state/` is reusable load-a-thing `StateFlow` machines.
|
||||
4. **`actions/` = verbs, `model/` = nouns/state, `cache/` = the store.** The 170
|
||||
`Account` methods become `*Actions` files grouped by concern, taking
|
||||
`signer + cache + relayClient`.
|
||||
5. **`keystorage/` = persistence ports + actuals; the settings *schema* is
|
||||
`model/account/settings`.** Schema (what) and persistence (how/where) are
|
||||
separate packages.
|
||||
6. **`service/` name is source-set-agnostic.** Pure services sit in `commonMain`,
|
||||
OkHttp/Jackson ones in `jvmAndroid` — same `service/<x>` path, different
|
||||
source set (per `ARCHITECTURE.md` §"Source sets").
|
||||
7. **Keep the name `LocalCache`** for the engine class (222 amethyst files / 560
|
||||
call-sites reference it); amethyst keeps a thin `object LocalCache` delegating
|
||||
to one shared `class` instance during transition.
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.compose
|
||||
package com.vitorpamplona.amethyst.commons.ui.text
|
||||
|
||||
import androidx.compose.ui.text.TextRange
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.utils
|
||||
package com.vitorpamplona.amethyst.commons.util
|
||||
|
||||
// Debug flag for commons module - kept false to avoid application dependencies
|
||||
// Application-level modules (amethyst, desktopApp) can implement their own debug timing
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.data
|
||||
package com.vitorpamplona.amethyst.commons.model.cache
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.UserMetadata
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.compose.article
|
||||
package com.vitorpamplona.amethyst.commons.nip23LongContent.ui.article
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.compose.article
|
||||
package com.vitorpamplona.amethyst.commons.nip23LongContent.ui.article
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.compose.editor
|
||||
package com.vitorpamplona.amethyst.commons.nip23LongContent.ui.editor
|
||||
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.compose.editor
|
||||
package com.vitorpamplona.amethyst.commons.nip23LongContent.ui.editor
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.compose.editor
|
||||
package com.vitorpamplona.amethyst.commons.nip23LongContent.ui.editor
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.compose.nip53LiveActivities
|
||||
package com.vitorpamplona.amethyst.commons.nip53LiveActivities.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.util.KmpLock
|
||||
import com.vitorpamplona.amethyst.commons.util.withLock
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.animateContentSize
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.normalizeRelayUrl
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
/**
|
||||
* Persists dismissed chess game IDs locally per user.
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.util.KmpLock
|
||||
import com.vitorpamplona.amethyst.commons.util.withLock
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import com.vitorpamplona.quartz.nip64Chess.ChessEngine
|
||||
import com.vitorpamplona.quartz.nip64Chess.ChessStateReconstructor
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.clickable
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.util.KmpLock
|
||||
import com.vitorpamplona.amethyst.commons.util.withLock
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip64Chess.Color
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.util.KmpLock
|
||||
import com.vitorpamplona.amethyst.commons.util.withLock
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.animateContentSize
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
/**
|
||||
* Platform-specific metadata provider for enriching chess challenges with display info.
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.tween
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess.subscription
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess.subscription
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess.subscription
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess.subscription
|
||||
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess.subscription
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess.subscription
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.chess.subscription
|
||||
package com.vitorpamplona.amethyst.commons.nip64Chess.subscription
|
||||
|
||||
/**
|
||||
* Shared time window constants for chess subscriptions.
|
||||
+3
-3
@@ -34,7 +34,7 @@ quartz/commonMain/.../nipACWebRtcCalls/
|
||||
├── tags/ # CallType, CallIdTag, etc.
|
||||
└── WebRtcCallFactory.kt # Sign + gift-wrap helpers (P2P + group variants)
|
||||
|
||||
commons/commonMain/.../call/ # ← this package
|
||||
commons/commonMain/.../nipACWebRtcCalls/ # ← this package
|
||||
├── CallState.kt # Sealed state + EndReason enum
|
||||
├── CallManager.kt # State machine, signaling dispatch, timeouts
|
||||
├── PeerSession.kt # Platform-neutral per-peer signaling interface
|
||||
@@ -54,7 +54,7 @@ amethyst/.../ui/call/ # Android call UI
|
||||
```
|
||||
|
||||
`quartz` is pure Kotlin/Multiplatform protocol code with **zero** WebRTC or
|
||||
Android dependencies. `commons/.../call/` is also platform-neutral — it holds
|
||||
Android dependencies. `commons/.../nipACWebRtcCalls/` is also platform-neutral — it holds
|
||||
the state machine and a `PeerSession` abstraction. All `org.webrtc` code lives
|
||||
in `amethyst/service/call/`.
|
||||
|
||||
@@ -255,7 +255,7 @@ coverage.
|
||||
|
||||
## 10. Testing
|
||||
|
||||
`commons/commonTest/.../call/CallManagerTest.kt` is the canonical reference
|
||||
`commons/commonTest/.../nipACWebRtcCalls/CallManagerTest.kt` is the canonical reference
|
||||
for expected state transitions. It uses real `NostrSignerInternal` keys so
|
||||
the factory-sign-wrap pipeline is exercised end-to-end, with `publishEvent`
|
||||
captured into a list for assertions. Construct events directly with the
|
||||
+3
-3
@@ -18,10 +18,10 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.call
|
||||
package com.vitorpamplona.amethyst.commons.nipACWebRtcCalls
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.call.CallManager.Companion.CALL_TIMEOUT_MS
|
||||
import com.vitorpamplona.amethyst.commons.call.CallManager.Companion.CONNECTING_TIMEOUT_MS
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallManager.Companion.CALL_TIMEOUT_MS
|
||||
import com.vitorpamplona.amethyst.commons.nipACWebRtcCalls.CallManager.Companion.CONNECTING_TIMEOUT_MS
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.call
|
||||
package com.vitorpamplona.amethyst.commons.nipACWebRtcCalls
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallAnswerEvent
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.call
|
||||
package com.vitorpamplona.amethyst.commons.nipACWebRtcCalls
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.Stable
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.call
|
||||
package com.vitorpamplona.amethyst.commons.nipACWebRtcCalls
|
||||
|
||||
/**
|
||||
* Represents a single ICE candidate received from a peer.
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.call
|
||||
package com.vitorpamplona.amethyst.commons.nipACWebRtcCalls
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.util.KmpLock
|
||||
import com.vitorpamplona.amethyst.commons.util.withLock
|
||||
+2
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.profile
|
||||
package com.vitorpamplona.amethyst.commons.profile.ui
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.animateContentSize
|
||||
@@ -52,6 +52,7 @@ import androidx.compose.ui.unit.dp
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbol
|
||||
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
|
||||
import com.vitorpamplona.amethyst.commons.profile.ProfileBroadcastStatus
|
||||
|
||||
/**
|
||||
* Shared banner showing profile metadata broadcast progress.
|
||||
+2
-2
@@ -20,9 +20,9 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.search
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.chess.RelaySyncState
|
||||
import com.vitorpamplona.amethyst.commons.chess.RelaySyncStatus
|
||||
import com.vitorpamplona.amethyst.commons.model.User
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.RelaySyncState
|
||||
import com.vitorpamplona.amethyst.commons.nip64Chess.RelaySyncStatus
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.displayUrl
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.compose.elements
|
||||
package com.vitorpamplona.amethyst.commons.ui.elements
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.ui.feeds
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.utils.logTime
|
||||
import com.vitorpamplona.amethyst.commons.util.logTime
|
||||
|
||||
abstract class AdditiveFeedFilter<T> :
|
||||
FeedFilter<T>(),
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider
|
||||
import com.vitorpamplona.amethyst.commons.service.BasicBundledInsert
|
||||
import com.vitorpamplona.amethyst.commons.service.BasicBundledUpdate
|
||||
import com.vitorpamplona.amethyst.commons.threading.checkNotInMainThread
|
||||
import com.vitorpamplona.amethyst.commons.utils.equalImmutableLists
|
||||
import com.vitorpamplona.amethyst.commons.util.equalImmutableLists
|
||||
import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent
|
||||
import com.vitorpamplona.quartz.utils.flattenToSet
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.ui.feeds
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.utils.logTime
|
||||
import com.vitorpamplona.amethyst.commons.util.logTime
|
||||
|
||||
abstract class FeedFilter<T> : IFeedFilter<T> {
|
||||
override fun loadTop(): List<T> {
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.compose.layouts
|
||||
package com.vitorpamplona.amethyst.commons.ui.layouts
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.padding
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.compose
|
||||
package com.vitorpamplona.amethyst.commons.ui.state
|
||||
|
||||
import androidx.collection.LruCache
|
||||
import androidx.compose.runtime.Composable
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.compose
|
||||
package com.vitorpamplona.amethyst.commons.ui.state
|
||||
|
||||
import androidx.collection.LruCache
|
||||
import androidx.compose.runtime.Composable
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.compose
|
||||
package com.vitorpamplona.amethyst.commons.ui.text
|
||||
|
||||
import androidx.compose.foundation.text.input.TextFieldState
|
||||
import androidx.compose.ui.text.TextRange
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.compose
|
||||
package com.vitorpamplona.amethyst.commons.ui.text
|
||||
|
||||
import androidx.compose.ui.text.TextRange
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.utils
|
||||
package com.vitorpamplona.amethyst.commons.util
|
||||
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlin.time.DurationUnit
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.utils
|
||||
package com.vitorpamplona.amethyst.commons.util
|
||||
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.call
|
||||
package com.vitorpamplona.amethyst.commons.nipACWebRtcCalls
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user