mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-03-26 17:52:29 +01:00
Improves stability of composables
This commit is contained in:
parent
7c974bc8ef
commit
c88dded01b
@ -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),
|
||||
|
@ -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<String> {
|
||||
val languageList = ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration())
|
||||
@ -118,8 +121,8 @@ class AccountSettings(
|
||||
var dontTranslateFrom: Set<String> = getLanguagesSpokenByUser(),
|
||||
var languagePreferences: Map<String, String> = mapOf(),
|
||||
var translateTo: String = Locale.getDefault().language,
|
||||
var zapAmountChoices: MutableStateFlow<List<Long>> = MutableStateFlow(DefaultZapAmounts),
|
||||
var reactionChoices: MutableStateFlow<List<String>> = MutableStateFlow(DefaultReactions),
|
||||
var zapAmountChoices: MutableStateFlow<ImmutableList<Long>> = MutableStateFlow(DefaultZapAmounts),
|
||||
var reactionChoices: MutableStateFlow<ImmutableList<String>> = MutableStateFlow(DefaultReactions),
|
||||
val defaultZapType: MutableStateFlow<LnZapEvent.ZapType> = MutableStateFlow(LnZapEvent.ZapType.PUBLIC),
|
||||
var defaultFileServer: Nip96MediaServers.ServerName = Nip96MediaServers.DEFAULT[0],
|
||||
val defaultHomeFollowList: MutableStateFlow<String> = MutableStateFlow(KIND3_FOLLOWS),
|
||||
@ -177,7 +180,7 @@ class AccountSettings(
|
||||
|
||||
fun changeZapAmounts(newAmounts: List<Long>) {
|
||||
if (zapAmountChoices.value != newAmounts) {
|
||||
zapAmountChoices.tryEmit(newAmounts)
|
||||
zapAmountChoices.tryEmit(newAmounts.toImmutableList())
|
||||
saveAccountSettings()
|
||||
}
|
||||
}
|
||||
@ -191,7 +194,7 @@ class AccountSettings(
|
||||
|
||||
fun changeReactionTypes(newTypes: List<String>) {
|
||||
if (reactionChoices.value != newTypes) {
|
||||
reactionChoices.tryEmit(newTypes)
|
||||
reactionChoices.tryEmit(newTypes.toImmutableList())
|
||||
saveAccountSettings()
|
||||
}
|
||||
}
|
||||
|
@ -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<Resource> = arrayListOf(),
|
||||
) : Resource(resourceType, id)
|
||||
|
||||
@Stable
|
||||
class VisionPrescription(
|
||||
resourceType: String? = null,
|
||||
id: String = "",
|
||||
@ -89,6 +96,7 @@ class VisionPrescription(
|
||||
var lensSpecification: List<LensSpecification> = 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,
|
||||
|
@ -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<String, GenericLoadable<List<CashuToken>>>(20)
|
||||
val cashuCache = LruCache<String, GenericLoadable<ImmutableList<CashuToken>>>(20)
|
||||
|
||||
fun cached(token: String): GenericLoadable<List<CashuToken>> = cashuCache[token] ?: GenericLoadable.Loading()
|
||||
fun cached(token: String): GenericLoadable<ImmutableList<CashuToken>> = cashuCache[token] ?: GenericLoadable.Loading()
|
||||
|
||||
fun parse(token: String): GenericLoadable<List<CashuToken>> {
|
||||
fun parse(token: String): GenericLoadable<ImmutableList<CashuToken>> {
|
||||
if (cashuCache[token] !is GenericLoadable.Loaded) {
|
||||
checkNotInMainThread()
|
||||
val newCachuData = CashuProcessor().parse(token)
|
||||
@ -91,7 +93,7 @@ class CashuProcessor {
|
||||
val proofs: List<Proof>,
|
||||
)
|
||||
|
||||
fun parse(cashuToken: String): GenericLoadable<List<CashuToken>> {
|
||||
fun parse(cashuToken: String): GenericLoadable<ImmutableList<CashuToken>> {
|
||||
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<List<CashuToken>> {
|
||||
fun parseCashuA(cashuToken: String): GenericLoadable<ImmutableList<CashuToken>> {
|
||||
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<List<CashuToken>>("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<List<CashuToken>> {
|
||||
fun parseCashuB(cashuToken: String): GenericLoadable<ImmutableList<CashuToken>> {
|
||||
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
|
||||
|
@ -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,
|
||||
|
@ -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<List<CashuToken>> -> CashuPreview(it.loaded, accountViewModel)
|
||||
is GenericLoadable.Error<List<CashuToken>> ->
|
||||
is GenericLoadable.Loaded<ImmutableList<CashuToken>> -> CashuPreview(it.loaded, accountViewModel)
|
||||
is GenericLoadable.Error<ImmutableList<CashuToken>> ->
|
||||
Text(
|
||||
text = "$cashutoken ",
|
||||
style = LocalTextStyle.current.copy(textDirection = TextDirection.Content),
|
||||
@ -111,7 +112,7 @@ fun CashuPreview(
|
||||
|
||||
@Composable
|
||||
fun CashuPreview(
|
||||
tokens: List<CashuToken>,
|
||||
tokens: ImmutableList<CashuToken>,
|
||||
accountViewModel: AccountViewModel,
|
||||
) {
|
||||
tokens.forEach {
|
||||
|
@ -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<Long>,
|
||||
zapAmountChoices: ImmutableList<Long>,
|
||||
accountViewModel: AccountViewModel,
|
||||
popupYOffset: Dp,
|
||||
onDismiss: () -> Unit,
|
||||
|
@ -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 = {
|
||||
|
@ -121,6 +121,7 @@ class TorrentEvent(
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
class TorrentFile(
|
||||
val fileName: String,
|
||||
val bytes: Long?,
|
||||
|
Loading…
x
Reference in New Issue
Block a user