diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt index 6241b7303..ee0a90908 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt @@ -51,6 +51,7 @@ import com.vitorpamplona.quartz.events.MetadataEvent import com.vitorpamplona.quartz.events.MuteListEvent import com.vitorpamplona.quartz.events.PrivateOutboxRelayListEvent import com.vitorpamplona.quartz.events.SearchRelayListEvent +import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -555,8 +556,8 @@ object LocalPreferences { dontTranslateFrom = dontTranslateFrom, languagePreferences = languagePreferences, translateTo = translateTo, - zapAmountChoices = MutableStateFlow(zapAmountChoices), - reactionChoices = MutableStateFlow(reactionChoices), + zapAmountChoices = MutableStateFlow(zapAmountChoices.toImmutableList()), + reactionChoices = MutableStateFlow(reactionChoices.toImmutableList()), defaultZapType = MutableStateFlow(defaultZapType), defaultFileServer = defaultFileServer, defaultHomeFollowList = MutableStateFlow(defaultHomeFollowList), diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSettings.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSettings.kt index c8fced48d..bc14a8cbf 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSettings.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSettings.kt @@ -45,6 +45,9 @@ import com.vitorpamplona.quartz.events.SearchRelayListEvent import com.vitorpamplona.quartz.signers.ExternalSignerLauncher import com.vitorpamplona.quartz.signers.NostrSignerExternal import com.vitorpamplona.quartz.signers.NostrSignerInternal +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map @@ -61,7 +64,7 @@ val DefaultChannels = ) val DefaultReactions = - listOf( + persistentListOf( "\uD83D\uDE80", "\uD83E\uDEC2", "\uD83D\uDC40", @@ -92,7 +95,7 @@ val DefaultSearchRelayList = RelayUrlFormatter.normalize("wss://relay.noswhere.com"), ) -val DefaultZapAmounts = listOf(100L, 500L, 1000L) +val DefaultZapAmounts = persistentListOf(100L, 500L, 1000L) fun getLanguagesSpokenByUser(): Set { val languageList = ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()) @@ -118,8 +121,8 @@ class AccountSettings( var dontTranslateFrom: Set = getLanguagesSpokenByUser(), var languagePreferences: Map = mapOf(), var translateTo: String = Locale.getDefault().language, - var zapAmountChoices: MutableStateFlow> = MutableStateFlow(DefaultZapAmounts), - var reactionChoices: MutableStateFlow> = MutableStateFlow(DefaultReactions), + var zapAmountChoices: MutableStateFlow> = MutableStateFlow(DefaultZapAmounts), + var reactionChoices: MutableStateFlow> = MutableStateFlow(DefaultReactions), val defaultZapType: MutableStateFlow = MutableStateFlow(LnZapEvent.ZapType.PUBLIC), var defaultFileServer: Nip96MediaServers.ServerName = Nip96MediaServers.DEFAULT[0], val defaultHomeFollowList: MutableStateFlow = MutableStateFlow(KIND3_FOLLOWS), @@ -177,7 +180,7 @@ class AccountSettings( fun changeZapAmounts(newAmounts: List) { if (zapAmountChoices.value != newAmounts) { - zapAmountChoices.tryEmit(newAmounts) + zapAmountChoices.tryEmit(newAmounts.toImmutableList()) saveAccountSettings() } } @@ -191,7 +194,7 @@ class AccountSettings( fun changeReactionTypes(newTypes: List) { if (reactionChoices.value != newTypes) { - reactionChoices.tryEmit(newTypes) + reactionChoices.tryEmit(newTypes.toImmutableList()) saveAccountSettings() } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/MiniFhir.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/MiniFhir.kt index e770d9d6c..be000225b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/MiniFhir.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/MiniFhir.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.amethyst.model import android.util.Log +import androidx.compose.runtime.Stable import com.fasterxml.jackson.annotation.JsonSubTypes import com.fasterxml.jackson.annotation.JsonTypeInfo import com.fasterxml.jackson.databind.DeserializationFeature @@ -40,11 +41,13 @@ import kotlinx.collections.immutable.toImmutableMap JsonSubTypes.Type(value = Bundle::class, name = "Bundle"), JsonSubTypes.Type(value = VisionPrescription::class, name = "VisionPrescription"), ) +@Stable open class Resource( var resourceType: String? = null, var id: String = "", ) +@Stable class Practitioner( resourceType: String? = null, id: String = "", @@ -53,6 +56,7 @@ class Practitioner( var gender: String? = null, ) : Resource(resourceType, id) +@Stable class Patient( resourceType: String? = null, id: String = "", @@ -61,6 +65,7 @@ class Patient( var gender: String? = null, ) : Resource(resourceType, id) +@Stable class HumanName( var use: String? = null, var family: String? = null, @@ -69,6 +74,7 @@ class HumanName( fun assembleName(): String = given.joinToString(" ") + " " + family } +@Stable class Bundle( resourceType: String? = null, id: String = "", @@ -77,6 +83,7 @@ class Bundle( var entry: List = arrayListOf(), ) : Resource(resourceType, id) +@Stable class VisionPrescription( resourceType: String? = null, id: String = "", @@ -89,6 +96,7 @@ class VisionPrescription( var lensSpecification: List = arrayListOf(), ) : Resource(resourceType, id) +@Stable class LensSpecification( var eye: String? = null, var sphere: Double? = null, @@ -105,6 +113,7 @@ class LensSpecification( var note: String? = null, ) +@Stable class Prism( var amount: Double? = null, var base: String? = null, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CashuProcessor.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CashuProcessor.kt index 0b3d465e7..485189e11 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CashuProcessor.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/CashuProcessor.kt @@ -32,6 +32,8 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.ammolite.service.HttpClientManager import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.events.Event +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.Serializable import kotlinx.serialization.cbor.ByteString @@ -61,11 +63,11 @@ class Proof( ) object CachedCashuProcessor { - val cashuCache = LruCache>>(20) + val cashuCache = LruCache>>(20) - fun cached(token: String): GenericLoadable> = cashuCache[token] ?: GenericLoadable.Loading() + fun cached(token: String): GenericLoadable> = cashuCache[token] ?: GenericLoadable.Loading() - fun parse(token: String): GenericLoadable> { + fun parse(token: String): GenericLoadable> { if (cashuCache[token] !is GenericLoadable.Loaded) { checkNotInMainThread() val newCachuData = CashuProcessor().parse(token) @@ -91,7 +93,7 @@ class CashuProcessor { val proofs: List, ) - fun parse(cashuToken: String): GenericLoadable> { + fun parse(cashuToken: String): GenericLoadable> { checkNotInMainThread() if (cashuToken.startsWith("cashuA")) { @@ -105,7 +107,7 @@ class CashuProcessor { return GenericLoadable.Error("Could not parse this cashu token") } - fun parseCashuA(cashuToken: String): GenericLoadable> { + fun parseCashuA(cashuToken: String): GenericLoadable> { checkNotInMainThread() try { @@ -129,10 +131,10 @@ class CashuProcessor { CashuToken(cashuToken, mint, totalAmount, proofs) } - return GenericLoadable.Loaded(converted) + return GenericLoadable.Loaded(converted.toImmutableList()) } catch (e: Exception) { if (e is CancellationException) throw e - return GenericLoadable.Error>("Could not parse this cashu token") + return GenericLoadable.Error("Could not parse this cashu token") } } @@ -172,7 +174,7 @@ class CashuProcessor { ) @OptIn(ExperimentalSerializationApi::class) - fun parseCashuB(cashuToken: String): GenericLoadable> { + fun parseCashuB(cashuToken: String): GenericLoadable> { checkNotInMainThread() try { @@ -205,7 +207,7 @@ class CashuProcessor { CashuToken(cashuToken, mint, totalAmount, proofs) } - return GenericLoadable.Loaded(converted) + return GenericLoadable.Loaded(converted.toImmutableList()) } catch (e: Exception) { e.printStackTrace() if (e is CancellationException) throw e diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/AudioWaveformReadOnly.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/AudioWaveformReadOnly.kt index ac1006b0f..2882d4179 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/AudioWaveformReadOnly.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/AudioWaveformReadOnly.kt @@ -40,7 +40,6 @@ import androidx.compose.ui.graphics.BlendMode import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.graphics.drawscope.DrawStyle import androidx.compose.ui.graphics.drawscope.Fill import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.unit.Dp @@ -67,7 +66,6 @@ private const val DEFAULT_GRAPHICS_LAYER_ALPHA: Float = 0.99F @Composable fun AudioWaveformReadOnly( modifier: Modifier = Modifier, - style: DrawStyle = Fill, waveformBrush: Brush = SolidColor(Color.White), progressBrush: Brush = SolidColor(Color.Blue), waveformAlignment: WaveformAlignment = WaveformAlignment.Center, @@ -131,7 +129,7 @@ fun AudioWaveformReadOnly( height = amplitude, ), cornerRadius = CornerRadius(spikeRadiusState.toPx(), spikeRadiusState.toPx()), - style = style, + style = Fill, ) drawRect( brush = progressBrush, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/CashuRedeem.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/CashuRedeem.kt index ba03e2147..b8c4294f7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/CashuRedeem.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/CashuRedeem.kt @@ -75,6 +75,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size18Modifier import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.SmallishBorder import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer +import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -98,8 +99,8 @@ fun CashuPreview( CrossfadeIfEnabled(targetState = cashuData, label = "CashuPreview", accountViewModel = accountViewModel) { when (it) { - is GenericLoadable.Loaded> -> CashuPreview(it.loaded, accountViewModel) - is GenericLoadable.Error> -> + is GenericLoadable.Loaded> -> CashuPreview(it.loaded, accountViewModel) + is GenericLoadable.Error> -> Text( text = "$cashutoken ", style = LocalTextStyle.current.copy(textDirection = TextDirection.Content), @@ -111,7 +112,7 @@ fun CashuPreview( @Composable fun CashuPreview( - tokens: List, + tokens: ImmutableList, accountViewModel: AccountViewModel, ) { tokens.forEach { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt index 592369453..0a4f2fb1d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt @@ -1329,7 +1329,7 @@ fun ReactionChoicePopup( onDismissRequest = { onDismiss() }, ) { ReactionChoicePopupContent( - reactions.toImmutableList(), + reactions, toRemove = toRemove, onClick = { reactionType -> accountViewModel.reactToOrDelete( @@ -1487,7 +1487,7 @@ fun ZapAmountChoicePopup( @Composable fun ZapAmountChoicePopup( baseNote: Note, - zapAmountChoices: List, + zapAmountChoices: ImmutableList, accountViewModel: AccountViewModel, popupYOffset: Dp, onDismiss: () -> Unit, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/NIP90ContentDiscoveryScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/NIP90ContentDiscoveryScreen.kt index 7f693f13b..ba760f832 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/NIP90ContentDiscoveryScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/NIP90ContentDiscoveryScreen.kt @@ -461,7 +461,7 @@ fun ZapDVMButton( if (wantsToZap != null) { ZapAmountChoicePopup( baseNote = baseNote, - zapAmountChoices = listOf(amount / 1000), + zapAmountChoices = persistentListOf(amount / 1000), popupYOffset = iconSize, accountViewModel = accountViewModel, onDismiss = { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/TorrentEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/TorrentEvent.kt index 6d00f0c67..9c6a1291e 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/TorrentEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/TorrentEvent.kt @@ -121,6 +121,7 @@ class TorrentEvent( } } +@Immutable class TorrentFile( val fileName: String, val bytes: Long?,