Improving cache of cashu tokens

This commit is contained in:
Vitor Pamplona
2024-02-29 18:03:07 -05:00
parent 0755bd2474
commit 3495866017
2 changed files with 57 additions and 19 deletions
@@ -21,6 +21,7 @@
package com.vitorpamplona.amethyst.service package com.vitorpamplona.amethyst.service
import android.content.Context import android.content.Context
import android.util.LruCache
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
@@ -42,6 +43,24 @@ data class CashuToken(
val proofs: JsonNode, val proofs: JsonNode,
) )
object CachedCashuProcessor {
val cashuCache = LruCache<String, GenericLoadable<CashuToken>>(20)
fun cached(token: String): GenericLoadable<CashuToken> {
return cashuCache[token] ?: GenericLoadable.Loading()
}
fun parse(token: String): GenericLoadable<CashuToken> {
if (cashuCache[token] !is GenericLoadable.Loaded) {
val newCachuData = CashuProcessor().parse(token)
cashuCache.put(token, newCachuData)
}
return cashuCache[token]
}
}
class CashuProcessor { class CashuProcessor {
fun parse(cashuToken: String): GenericLoadable<CashuToken> { fun parse(cashuToken: String): GenericLoadable<CashuToken> {
checkNotInMainThread() checkNotInMainThread()
@@ -42,9 +42,9 @@ import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@@ -66,7 +66,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.fasterxml.jackson.databind.node.TextNode import com.fasterxml.jackson.databind.node.TextNode
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.ThemeType import com.vitorpamplona.amethyst.model.ThemeType
import com.vitorpamplona.amethyst.service.CashuProcessor import com.vitorpamplona.amethyst.service.CachedCashuProcessor
import com.vitorpamplona.amethyst.service.CashuToken import com.vitorpamplona.amethyst.service.CashuToken
import com.vitorpamplona.amethyst.ui.actions.LoadingAnimation import com.vitorpamplona.amethyst.ui.actions.LoadingAnimation
import com.vitorpamplona.amethyst.ui.note.CashuIcon import com.vitorpamplona.amethyst.ui.note.CashuIcon
@@ -85,25 +85,26 @@ import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.subtleBorder import com.vitorpamplona.amethyst.ui.theme.subtleBorder
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.withContext
@Composable @Composable
fun CashuPreview( fun CashuPreview(
cashutoken: String, cashutoken: String,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
) { ) {
var cachuData by remember { val cashuData by produceState(
mutableStateOf<GenericLoadable<CashuToken>>(GenericLoadable.Loading()) initialValue = CachedCashuProcessor.cached(cashutoken),
} key1 = cashutoken,
) {
LaunchedEffect(key1 = cashutoken) { withContext(Dispatchers.IO) {
launch(Dispatchers.IO) { val newToken = CachedCashuProcessor.parse(cashutoken)
val newCachuData = CashuProcessor().parse(cashutoken) if (value != newToken) {
launch(Dispatchers.Main) { cachuData = newCachuData } value = newToken
}
} }
} }
Crossfade(targetState = cachuData, label = "CashuPreview(") { Crossfade(targetState = cashuData, label = "CashuPreview") {
when (it) { when (it) {
is GenericLoadable.Loaded<CashuToken> -> CashuPreview(it.loaded, accountViewModel) is GenericLoadable.Loaded<CashuToken> -> CashuPreview(it.loaded, accountViewModel)
is GenericLoadable.Error<CashuToken> -> is GenericLoadable.Error<CashuToken> ->
@@ -160,17 +161,24 @@ fun CashuPreview(
Column( Column(
modifier = modifier =
Modifier.fillMaxWidth() Modifier
.fillMaxWidth()
.padding(start = 20.dp, end = 20.dp, top = 10.dp, bottom = 10.dp) .padding(start = 20.dp, end = 20.dp, top = 10.dp, bottom = 10.dp)
.clip(shape = QuoteBorder) .clip(shape = QuoteBorder)
.border(1.dp, MaterialTheme.colorScheme.subtleBorder, QuoteBorder), .border(1.dp, MaterialTheme.colorScheme.subtleBorder, QuoteBorder),
) { ) {
Column( Column(
modifier = Modifier.fillMaxWidth().padding(20.dp), modifier =
Modifier
.fillMaxWidth()
.padding(20.dp),
) { ) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth().padding(bottom = 10.dp), modifier =
Modifier
.fillMaxWidth()
.padding(bottom = 10.dp),
) { ) {
Icon( Icon(
painter = painterResource(R.drawable.cashu), painter = painterResource(R.drawable.cashu),
@@ -193,11 +201,17 @@ fun CashuPreview(
text = "${token.totalAmount} ${stringResource(id = R.string.sats)}", text = "${token.totalAmount} ${stringResource(id = R.string.sats)}",
fontSize = 25.sp, fontSize = 25.sp,
fontWeight = FontWeight.W500, fontWeight = FontWeight.W500,
modifier = Modifier.fillMaxWidth().padding(vertical = 10.dp), modifier =
Modifier
.fillMaxWidth()
.padding(vertical = 10.dp),
) )
Row( Row(
modifier = Modifier.padding(top = 5.dp).fillMaxWidth(), modifier =
Modifier
.padding(top = 5.dp)
.fillMaxWidth(),
) { ) {
var isRedeeming by remember { mutableStateOf(false) } var isRedeeming by remember { mutableStateOf(false) }
@@ -289,13 +303,17 @@ fun CashuPreviewNew(
Card( Card(
modifier = modifier =
Modifier.fillMaxWidth() Modifier
.fillMaxWidth()
.padding(start = 10.dp, end = 10.dp, top = 10.dp, bottom = 10.dp) .padding(start = 10.dp, end = 10.dp, top = 10.dp, bottom = 10.dp)
.clip(shape = QuoteBorder), .clip(shape = QuoteBorder),
) { ) {
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxWidth().padding(10.dp), modifier =
Modifier
.fillMaxWidth()
.padding(10.dp),
) { ) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@@ -317,6 +335,7 @@ fun CashuPreviewNew(
Text( Text(
text = "${token.totalAmount} ${stringResource(id = R.string.sats)}", text = "${token.totalAmount} ${stringResource(id = R.string.sats)}",
fontSize = 20.sp, fontSize = 20.sp,
modifier = Modifier.padding(top = 5.dp),
) )
Row(modifier = Modifier.padding(top = 5.dp)) { Row(modifier = Modifier.padding(top = 5.dp)) {