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.livedata.observeAsState
import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableFloatStateOf
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.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
@ -98,6 +99,7 @@ import coil.request.CachePolicy
import coil.request.ImageRequest import coil.request.ImageRequest
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.zap
import com.vitorpamplona.amethyst.service.ZapPaymentHandler import com.vitorpamplona.amethyst.service.ZapPaymentHandler
import com.vitorpamplona.amethyst.ui.actions.NewPostView import com.vitorpamplona.amethyst.ui.actions.NewPostView
import com.vitorpamplona.amethyst.ui.components.GenericLoadable import com.vitorpamplona.amethyst.ui.components.GenericLoadable
@ -663,11 +665,11 @@ fun TextCount(
@Composable @Composable
fun SlidingAnimationAmount( fun SlidingAnimationAmount(
amount: MutableState<String>, amount: String,
textColor: Color, textColor: Color,
) { ) {
AnimatedContent( AnimatedContent(
targetState = amount.value, targetState = amount,
transitionSpec = AnimatedContentTransitionScope<String>::transitionSpec, transitionSpec = AnimatedContentTransitionScope<String>::transitionSpec,
label = "SlidingAnimationAmount", label = "SlidingAnimationAmount",
) { count -> ) { count ->
@ -788,7 +790,7 @@ fun LikeReaction(
), ),
) { ) {
ObserveLikeIcon(baseNote, accountViewModel) { reactionType -> ObserveLikeIcon(baseNote, accountViewModel) { reactionType ->
Crossfade(targetState = reactionType.value, label = "LikeIcon") { Crossfade(targetState = reactionType, label = "LikeIcon") {
if (it != null) { if (it != null) {
RenderReactionType(it, heartSizeModifier, iconFontSize) RenderReactionType(it, heartSizeModifier, iconFontSize)
} else { } else {
@ -826,19 +828,17 @@ fun LikeReaction(
fun ObserveLikeIcon( fun ObserveLikeIcon(
baseNote: Note, baseNote: Note,
accountViewModel: AccountViewModel, 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() val reactionsState by baseNote.live().reactions.observeAsState()
LaunchedEffect(key1 = reactionsState) { val reactionType by
accountViewModel.loadReactionTo(reactionsState?.note) { newReactionType -> produceState(initialValue = null as String?, key1 = reactionsState) {
if (reactionType.value != newReactionType) { val newReactionType = accountViewModel.loadReactionTo(reactionsState?.note)
reactionType.value = newReactionType if (value != newReactionType) {
value = newReactionType
} }
} }
}
inner(reactionType) inner(reactionType)
} }
@ -1119,9 +1119,11 @@ fun ObserveZapIcon(
val zapsState by baseNote.live().zaps.observeAsState() val zapsState by baseNote.live().zaps.observeAsState()
LaunchedEffect(key1 = zapsState) { LaunchedEffect(key1 = zapsState) {
accountViewModel.calculateIfNoteWasZappedByAccount(baseNote) { newWasZapped -> if (zapsState?.note?.zapPayments?.isNotEmpty() == true || zapsState?.note?.zaps?.isNotEmpty() == true) {
if (wasZappedByLoggedInUser.value != newWasZapped) { accountViewModel.calculateIfNoteWasZappedByAccount(baseNote) { newWasZapped ->
wasZappedByLoggedInUser.value = newWasZapped if (wasZappedByLoggedInUser.value != newWasZapped) {
wasZappedByLoggedInUser.value = newWasZapped
}
} }
} }
} }
@ -1134,20 +1136,24 @@ fun ObserveZapIcon(
fun ObserveZapAmountText( fun ObserveZapAmountText(
baseNote: Note, baseNote: Note,
accountViewModel: AccountViewModel, 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() val zapsState by baseNote.live().zaps.observeAsState()
LaunchedEffect(key1 = zapsState) { if (zapsState?.note?.zapPayments?.isNotEmpty() == true) {
accountViewModel.calculateZapAmount(baseNote) { newZapAmount -> val zapAmountTxt by
if (zapAmountTxt.value != newZapAmount) { produceState(initialValue = showAmount(baseNote.zapsAmount), key1 = baseNote) {
zapAmountTxt.value = newZapAmount accountViewModel.calculateZapAmount(baseNote) { newZapAmount ->
if (value != newZapAmount) {
value = newZapAmount
}
}
} }
}
}
inner(zapAmountTxt) inner(zapAmountTxt)
} else {
inner(showAmount(zapsState?.note?.zapsAmount))
}
} }
@Composable @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)) } viewModelScope.launch(Dispatchers.IO) { account.delete(account.boostsTo(note)) }
} }
fun calculateIfNoteWasZappedByAccount( suspend fun calculateIfNoteWasZappedByAccount(
zappedNote: Note, zappedNote: Note,
onWasZapped: (Boolean) -> Unit, onWasZapped: (Boolean) -> Unit,
) { ) {
viewModelScope.launch(Dispatchers.Default) { withContext(Dispatchers.IO) {
account.calculateIfNoteWasZappedByAccount(zappedNote) { onWasZapped(true) } account.calculateIfNoteWasZappedByAccount(zappedNote) { onWasZapped(true) }
} }
} }
fun calculateZapAmount( suspend fun calculateZapAmount(
zappedNote: Note, zappedNote: Note,
onZapAmount: (String) -> Unit, onZapAmount: (String) -> Unit,
) { ) {
if (zappedNote.zapPayments.isNotEmpty()) { if (zappedNote.zapPayments.isNotEmpty()) {
viewModelScope.launch(Dispatchers.IO) { withContext(Dispatchers.IO) {
account.calculateZappedAmount(zappedNote) { onZapAmount(showAmount(it)) } account.calculateZappedAmount(zappedNote) { onZapAmount(showAmount(it)) }
} }
} else { } else {
@ -243,28 +243,45 @@ class AccountViewModel(val account: Account, val settings: SettingsState) : View
} }
} }
fun calculateZapraiser( suspend fun calculateZapraiser(
zappedNote: Note, zappedNote: Note,
onZapraiserStatus: (ZapraiserStatus) -> Unit, onZapraiserStatus: (ZapraiserStatus) -> Unit,
) { ) {
viewModelScope.launch(Dispatchers.IO) { val zapraiserAmount = zappedNote.event?.zapraiserAmount() ?: 0
val zapraiserAmount = zappedNote.event?.zapraiserAmount() ?: 0 if (zappedNote.zapPayments.isNotEmpty()) {
account.calculateZappedAmount(zappedNote) { newZapAmount -> withContext(Dispatchers.IO) {
var percentage = newZapAmount.div(zapraiserAmount.toBigDecimal()).toFloat() account.calculateZappedAmount(zappedNote) { newZapAmount ->
var percentage = newZapAmount.div(zapraiserAmount.toBigDecimal()).toFloat()
if (percentage > 1) { if (percentage > 1) {
percentage = 1f percentage = 1f
}
val newZapraiserProgress = percentage
val newZapraiserLeft =
if (percentage > 0.99) {
"0"
} else {
showAmount((zapraiserAmount * (1 - percentage)).toBigDecimal())
} }
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) } viewModelScope.launch(Dispatchers.IO) { UrlCachedPreviewer.previewInfo(url, onResult) }
} }
fun loadReactionTo( suspend fun loadReactionTo(note: Note?): String? {
note: Note?, if (note == null) return null
onNewReactionType: (String?) -> Unit,
) {
if (note == null) return
viewModelScope.launch(Dispatchers.Default) { return note.getReactionBy(userProfile())
onNewReactionType(note.getReactionBy(userProfile()))
}
} }
fun verifyNip05( fun verifyNip05(