Reducing the amount of co-routines being launched in each LiveData update.

pull/812/head
Vitor Pamplona 2024-03-19 19:30:49 -04:00
rodzic bfbfcb6ed2
commit 87fafd9451
2 zmienionych plików z 69 dodań i 51 usunięć

Wyświetl plik

@ -67,6 +67,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
@ -98,6 +99,7 @@ import coil.request.CachePolicy
import coil.request.ImageRequest
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.zap
import com.vitorpamplona.amethyst.service.ZapPaymentHandler
import com.vitorpamplona.amethyst.ui.actions.NewPostView
import com.vitorpamplona.amethyst.ui.components.GenericLoadable
@ -663,11 +665,11 @@ fun TextCount(
@Composable
fun SlidingAnimationAmount(
amount: MutableState<String>,
amount: String,
textColor: Color,
) {
AnimatedContent(
targetState = amount.value,
targetState = amount,
transitionSpec = AnimatedContentTransitionScope<String>::transitionSpec,
label = "SlidingAnimationAmount",
) { count ->
@ -788,7 +790,7 @@ fun LikeReaction(
),
) {
ObserveLikeIcon(baseNote, accountViewModel) { reactionType ->
Crossfade(targetState = reactionType.value, label = "LikeIcon") {
Crossfade(targetState = reactionType, label = "LikeIcon") {
if (it != null) {
RenderReactionType(it, heartSizeModifier, iconFontSize)
} else {
@ -826,19 +828,17 @@ fun LikeReaction(
fun ObserveLikeIcon(
baseNote: Note,
accountViewModel: AccountViewModel,
inner: @Composable (MutableState<String?>) -> Unit,
inner: @Composable (String?) -> Unit,
) {
val reactionType = remember(baseNote) { mutableStateOf<String?>(null) }
val reactionsState by baseNote.live().reactions.observeAsState()
LaunchedEffect(key1 = reactionsState) {
accountViewModel.loadReactionTo(reactionsState?.note) { newReactionType ->
if (reactionType.value != newReactionType) {
reactionType.value = newReactionType
val reactionType by
produceState(initialValue = null as String?, key1 = reactionsState) {
val newReactionType = accountViewModel.loadReactionTo(reactionsState?.note)
if (value != newReactionType) {
value = newReactionType
}
}
}
inner(reactionType)
}
@ -1119,9 +1119,11 @@ fun ObserveZapIcon(
val zapsState by baseNote.live().zaps.observeAsState()
LaunchedEffect(key1 = zapsState) {
accountViewModel.calculateIfNoteWasZappedByAccount(baseNote) { newWasZapped ->
if (wasZappedByLoggedInUser.value != newWasZapped) {
wasZappedByLoggedInUser.value = newWasZapped
if (zapsState?.note?.zapPayments?.isNotEmpty() == true || zapsState?.note?.zaps?.isNotEmpty() == true) {
accountViewModel.calculateIfNoteWasZappedByAccount(baseNote) { newWasZapped ->
if (wasZappedByLoggedInUser.value != newWasZapped) {
wasZappedByLoggedInUser.value = newWasZapped
}
}
}
}
@ -1134,20 +1136,24 @@ fun ObserveZapIcon(
fun ObserveZapAmountText(
baseNote: Note,
accountViewModel: AccountViewModel,
inner: @Composable (MutableState<String>) -> Unit,
inner: @Composable (String) -> Unit,
) {
val zapAmountTxt = remember(baseNote) { mutableStateOf(showAmount(baseNote.zapsAmount)) }
val zapsState by baseNote.live().zaps.observeAsState()
LaunchedEffect(key1 = zapsState) {
accountViewModel.calculateZapAmount(baseNote) { newZapAmount ->
if (zapAmountTxt.value != newZapAmount) {
zapAmountTxt.value = newZapAmount
if (zapsState?.note?.zapPayments?.isNotEmpty() == true) {
val zapAmountTxt by
produceState(initialValue = showAmount(baseNote.zapsAmount), key1 = baseNote) {
accountViewModel.calculateZapAmount(baseNote) { newZapAmount ->
if (value != newZapAmount) {
value = newZapAmount
}
}
}
}
}
inner(zapAmountTxt)
inner(zapAmountTxt)
} else {
inner(showAmount(zapsState?.note?.zapsAmount))
}
}
@Composable

Wyświetl plik

@ -221,21 +221,21 @@ class AccountViewModel(val account: Account, val settings: SettingsState) : View
viewModelScope.launch(Dispatchers.IO) { account.delete(account.boostsTo(note)) }
}
fun calculateIfNoteWasZappedByAccount(
suspend fun calculateIfNoteWasZappedByAccount(
zappedNote: Note,
onWasZapped: (Boolean) -> Unit,
) {
viewModelScope.launch(Dispatchers.Default) {
withContext(Dispatchers.IO) {
account.calculateIfNoteWasZappedByAccount(zappedNote) { onWasZapped(true) }
}
}
fun calculateZapAmount(
suspend fun calculateZapAmount(
zappedNote: Note,
onZapAmount: (String) -> Unit,
) {
if (zappedNote.zapPayments.isNotEmpty()) {
viewModelScope.launch(Dispatchers.IO) {
withContext(Dispatchers.IO) {
account.calculateZappedAmount(zappedNote) { onZapAmount(showAmount(it)) }
}
} else {
@ -243,28 +243,45 @@ class AccountViewModel(val account: Account, val settings: SettingsState) : View
}
}
fun calculateZapraiser(
suspend fun calculateZapraiser(
zappedNote: Note,
onZapraiserStatus: (ZapraiserStatus) -> Unit,
) {
viewModelScope.launch(Dispatchers.IO) {
val zapraiserAmount = zappedNote.event?.zapraiserAmount() ?: 0
account.calculateZappedAmount(zappedNote) { newZapAmount ->
var percentage = newZapAmount.div(zapraiserAmount.toBigDecimal()).toFloat()
val zapraiserAmount = zappedNote.event?.zapraiserAmount() ?: 0
if (zappedNote.zapPayments.isNotEmpty()) {
withContext(Dispatchers.IO) {
account.calculateZappedAmount(zappedNote) { newZapAmount ->
var percentage = newZapAmount.div(zapraiserAmount.toBigDecimal()).toFloat()
if (percentage > 1) {
percentage = 1f
}
val newZapraiserProgress = percentage
val newZapraiserLeft =
if (percentage > 0.99) {
"0"
} else {
showAmount((zapraiserAmount * (1 - percentage)).toBigDecimal())
if (percentage > 1) {
percentage = 1f
}
onZapraiserStatus(ZapraiserStatus(newZapraiserProgress, newZapraiserLeft))
val newZapraiserProgress = percentage
val newZapraiserLeft =
if (percentage > 0.99) {
"0"
} else {
showAmount((zapraiserAmount * (1 - percentage)).toBigDecimal())
}
onZapraiserStatus(ZapraiserStatus(newZapraiserProgress, newZapraiserLeft))
}
}
} else {
var percentage = zappedNote.zapsAmount.div(zapraiserAmount.toBigDecimal()).toFloat()
if (percentage > 1) {
percentage = 1f
}
val newZapraiserProgress = percentage
val newZapraiserLeft =
if (percentage > 0.99) {
"0"
} else {
showAmount((zapraiserAmount * (1 - percentage)).toBigDecimal())
}
onZapraiserStatus(ZapraiserStatus(newZapraiserProgress, newZapraiserLeft))
}
}
@ -776,15 +793,10 @@ class AccountViewModel(val account: Account, val settings: SettingsState) : View
viewModelScope.launch(Dispatchers.IO) { UrlCachedPreviewer.previewInfo(url, onResult) }
}
fun loadReactionTo(
note: Note?,
onNewReactionType: (String?) -> Unit,
) {
if (note == null) return
suspend fun loadReactionTo(note: Note?): String? {
if (note == null) return null
viewModelScope.launch(Dispatchers.Default) {
onNewReactionType(note.getReactionBy(userProfile()))
}
return note.getReactionBy(userProfile())
}
fun verifyNip05(