From 43d03bc109337f52fafe3e0af4068a940d7ac51e Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 9 Nov 2023 14:26:11 -0500 Subject: [PATCH] Caching total Zaps --- .../vitorpamplona/amethyst/model/Account.kt | 2 +- .../com/vitorpamplona/amethyst/model/Note.kt | 81 ++++-- .../vitorpamplona/amethyst/ui/note/Icons.kt | 5 - .../amethyst/ui/note/ReactionsRow.kt | 269 +++++++----------- .../ui/screen/loggedIn/AccountViewModel.kt | 10 +- .../ui/screen/loggedIn/VideoScreen.kt | 2 +- 6 files changed, 173 insertions(+), 196 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index d8e69bb4e..b3ac9fb02 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -581,7 +581,7 @@ class Account( fun calculateZappedAmount(zappedNote: Note?): BigDecimal { val privKey = zapPaymentRequest?.secret?.hexToByteArray() ?: keyPair.privKey val pubKey = zapPaymentRequest?.pubKeyHex?.hexToByteArray() - return zappedNote?.zappedAmount(privKey, pubKey) ?: BigDecimal.ZERO + return zappedNote?.zappedAmountWithNWCPayments(privKey, pubKey) ?: BigDecimal.ZERO } fun sendZapPaymentRequestFor(bolt11: String, zappedNote: Note?, onResponse: (Response?) -> Unit) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt index 9f35872bf..1ae4df6f3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt @@ -86,6 +86,8 @@ open class Note(val idHex: String) { private set var zaps = mapOf() private set + var zapsAmount: BigDecimal = BigDecimal.ZERO + var zapPayments = mapOf() private set @@ -265,6 +267,7 @@ open class Note(val idHex: String) { reports = mapOf>() zaps = mapOf() zapPayments = mapOf() + zapsAmount = BigDecimal.ZERO relays = listOf() lastReactionsDownloadTime = emptyMap() @@ -311,9 +314,11 @@ open class Note(val idHex: String) { fun removeZap(note: Note) { if (zaps[note] != null) { zaps = zaps.minus(note) + updateZapTotal() liveSet?.innerZaps?.invalidateData() } else if (zaps.containsValue(note)) { zaps = zaps.filterValues { it != note } + updateZapTotal() liveSet?.innerZaps?.invalidateData() } } @@ -354,11 +359,13 @@ open class Note(val idHex: String) { if (zapRequest !in zaps.keys) { val inserted = innerAddZap(zapRequest, zap) if (inserted) { + updateZapTotal() liveSet?.innerZaps?.invalidateData() } } else if (zaps[zapRequest] == null) { val inserted = innerAddZap(zapRequest, zap) if (inserted) { + updateZapTotal() liveSet?.innerZaps?.invalidateData() } } @@ -478,44 +485,63 @@ open class Note(val idHex: String) { }.flatten() } - fun zappedAmount(privKey: ByteArray?, walletServicePubkey: ByteArray?): BigDecimal { - // Regular Zap Receipts - val completedZaps = zaps.asSequence() - .mapNotNull { it.value?.event } - .filterIsInstance() - .filter { it.amount != null } - .associate { - it.lnInvoice() to it.amount - } - .toMap() + private fun updateZapTotal() { + var sumOfAmounts = BigDecimal.ZERO + + // Regular Zap Receipts + zaps.values.forEach { + val noteEvent = it?.event + if (noteEvent is LnZapEvent) { + sumOfAmounts += noteEvent.amount ?: BigDecimal.ZERO + } + } + + zapsAmount = sumOfAmounts + } + + fun zappedAmountWithNWCPayments(privKey: ByteArray?, walletServicePubkey: ByteArray?): BigDecimal { + if (zapPayments.isEmpty()) return zapsAmount + + var sumOfAmounts = zapsAmount + + val invoiceSet = LinkedHashSet(zaps.size + zapPayments.size) + zaps.forEach { + (it.value as? LnZapEvent)?.lnInvoice()?.let { + invoiceSet.add(it) + } + } + + if (privKey != null && walletServicePubkey != null) { + zapPayments.forEach { + val noteEvent = (it.value?.event as? LnZapPaymentResponseEvent)?.response( + privKey, + walletServicePubkey + ) + if (noteEvent is PayInvoiceSuccessResponse) { + val invoice = (it.key.event as? LnZapPaymentRequestEvent)?.lnInvoice( + privKey, + walletServicePubkey + ) - val completedPayments = if (privKey != null && walletServicePubkey != null) { - // Payments confirmed by the User's Wallet - zapPayments - .asSequence() - .filter { - val response = (it.value?.event as? LnZapPaymentResponseEvent)?.response(privKey, walletServicePubkey) - response is PayInvoiceSuccessResponse - } - .associate { - val lnInvoice = (it.key.event as? LnZapPaymentRequestEvent)?.lnInvoice(privKey, walletServicePubkey) val amount = try { - if (lnInvoice == null) { + if (invoice == null) { null } else { - LnInvoiceUtil.getAmountInSats(lnInvoice) + LnInvoiceUtil.getAmountInSats(invoice) } } catch (e: java.lang.Exception) { null } - lnInvoice to amount + + if (invoice != null && amount != null && !invoiceSet.contains(invoice)) { + invoiceSet.add(invoice) + sumOfAmounts += amount + } } - .toMap() - } else { - emptyMap() + } } - return (completedZaps + completedPayments).values.filterNotNull().sumOf { it } + return sumOfAmounts } fun hasPledgeBy(user: User): Boolean { @@ -626,6 +652,7 @@ open class Note(val idHex: String) { boosts = emptyList() reports = emptyMap() zaps = emptyMap() + zapsAmount = BigDecimal.ZERO } fun clearEOSE() { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Icons.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Icons.kt index a5d9dada7..90473697a 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Icons.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Icons.kt @@ -205,11 +205,6 @@ fun CommentIcon(iconSize: Dp, tint: Color) { ) } -@Composable -fun ViewCountIcon(iconSize: Dp, tint: Color = Color.Unspecified) { - ViewCountIcon(remember { Modifier.size(iconSize) }, tint) -} - @Composable fun ViewCountIcon(modifier: Modifier, tint: Color = Color.Unspecified) { Icon( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt index b69dc2fcf..f6acaad33 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt @@ -12,6 +12,7 @@ import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOutVertically +import androidx.compose.animation.togetherWith import androidx.compose.animation.with import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.combinedClickable @@ -44,6 +45,7 @@ import androidx.compose.runtime.MutableState import androidx.compose.runtime.derivedStateOf 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.remember import androidx.compose.runtime.rememberCoroutineScope @@ -112,6 +114,7 @@ import kotlinx.collections.immutable.toImmutableMap import kotlinx.collections.immutable.toImmutableSet import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import java.math.BigDecimal import java.math.RoundingMode import java.text.DecimalFormat @@ -195,60 +198,35 @@ private fun GenericInnerReactionRow( six: @Composable () -> Unit ) { Row(verticalAlignment = CenterVertically, modifier = ReactionRowHeight) { + val fullWeight = remember { Modifier.weight(1f) } + if (showReactionDetail) { - Column( - verticalArrangement = Arrangement.Center, - modifier = ReactionRowExpandButton + Row( + verticalAlignment = CenterVertically, + modifier = remember { ReactionRowExpandButton.then(fullWeight) } ) { - Row(verticalAlignment = CenterVertically) { - one() - } + one() } } - Column( - verticalArrangement = Arrangement.Center, - modifier = remember { Modifier.weight(1f) } - ) { - Row(verticalAlignment = CenterVertically) { - two() - } + Row(verticalAlignment = CenterVertically, modifier = fullWeight) { + two() } - Column( - verticalArrangement = Arrangement.Center, - modifier = remember { Modifier.weight(1f) } - ) { - Row(verticalAlignment = CenterVertically) { - three() - } + Row(verticalAlignment = CenterVertically, modifier = fullWeight) { + three() } - Column( - verticalArrangement = Arrangement.Center, - modifier = remember { Modifier.weight(1f) } - ) { - Row(verticalAlignment = CenterVertically) { - four() - } + Row(verticalAlignment = CenterVertically, modifier = fullWeight) { + four() } - Column( - verticalArrangement = Arrangement.Center, - modifier = remember { Modifier.weight(1f) } - ) { - Row(verticalAlignment = CenterVertically) { - five() - } + Row(verticalAlignment = CenterVertically, modifier = fullWeight) { + five() } - Column( - verticalArrangement = Arrangement.Center, - modifier = remember { Modifier.weight(1f) } - ) { - Row(verticalAlignment = CenterVertically) { - six() - } + Row(verticalAlignment = CenterVertically, modifier = fullWeight) { + six() } } } @@ -590,17 +568,12 @@ fun ReplyCounter(baseNote: Note, textColor: Color) { SlidingAnimationCount(repliesState, textColor) } -@Composable -private fun SlidingAnimationCount(baseCount: MutableState, textColor: Color) { - SlidingAnimationCount(baseCount.value, textColor) -} - -@OptIn(ExperimentalAnimationApi::class) @Composable private fun SlidingAnimationCount(baseCount: Int, textColor: Color) { AnimatedContent( targetState = baseCount, - transitionSpec = AnimatedContentTransitionScope::transitionSpec + transitionSpec = AnimatedContentTransitionScope::transitionSpec, + label = "SlidingAnimationCount" ) { count -> TextCount(count, textColor) } @@ -612,11 +585,16 @@ private fun AnimatedContentTransitionScope.transitionSpec(): ContentTrans } @ExperimentalAnimationApi -val slideAnimation: ContentTransform = slideInVertically(animationSpec = tween(durationMillis = 100)) { height -> height } + fadeIn( - animationSpec = tween(durationMillis = 100) -) with slideOutVertically(animationSpec = tween(durationMillis = 100)) { height -> -height } + fadeOut( - animationSpec = tween(durationMillis = 100) -) +val slideAnimation: ContentTransform = + ( + slideInVertically(animationSpec = tween(durationMillis = 100)) { height -> height } + fadeIn( + animationSpec = tween(durationMillis = 100) + ) + ).togetherWith( + slideOutVertically(animationSpec = tween(durationMillis = 100)) { height -> -height } + fadeOut( + animationSpec = tween(durationMillis = 100) + ) + ) @Composable private fun TextCount(count: Int, textColor: Color) { @@ -630,11 +608,11 @@ private fun TextCount(count: Int, textColor: Color) { } @Composable -@OptIn(ExperimentalAnimationApi::class) private fun SlidingAnimationAmount(amount: MutableState, textColor: Color) { AnimatedContent( targetState = amount.value, - transitionSpec = AnimatedContentTransitionScope::transitionSpec + transitionSpec = AnimatedContentTransitionScope::transitionSpec, + label = "SlidingAnimationAmount" ) { count -> Text( text = count, @@ -667,7 +645,9 @@ fun BoostReaction( } } ) { - BoostIcon(baseNote, iconSize, grayTint, accountViewModel) + ObserveBoostIcon(baseNote, accountViewModel) { hasBoosted -> + RepostedIcon(iconButtonModifier, if (hasBoosted) Color.Unspecified else grayTint) + } if (wantsToBoost) { BoostTypeChoicePopup( @@ -692,20 +672,16 @@ fun BoostReaction( } @Composable -fun BoostIcon(baseNote: Note, iconSize: Dp = Size20dp, grayTint: Color, accountViewModel: AccountViewModel) { - val iconTint by remember(baseNote) { +fun ObserveBoostIcon(baseNote: Note, accountViewModel: AccountViewModel, inner: @Composable (Boolean) -> Unit) { + val hasBoosted by remember(baseNote) { baseNote.live().boosts.map { - if (it.note.isBoostedBy(accountViewModel.userProfile())) Color.Unspecified else grayTint + it.note.isBoostedBy(accountViewModel.userProfile()) }.distinctUntilChanged() }.observeAsState( - if (baseNote.isBoostedBy(accountViewModel.userProfile())) Color.Unspecified else grayTint + baseNote.isBoostedBy(accountViewModel.userProfile()) ) - val iconModifier = remember { - Modifier.size(iconSize) - } - - RepostedIcon(iconModifier, iconTint) + inner(hasBoosted) } @Composable @@ -760,10 +736,20 @@ fun LikeReaction( } ) ) { - LikeIcon(baseNote, iconFontSize, heartSize, grayTint, accountViewModel) + ObserveLikeIcon(baseNote, accountViewModel) { reactionType -> + Crossfade(targetState = reactionType.value, label = "LikeIcon") { + if (it != null) { + RenderReactionType(it, heartSize, iconFontSize) + } else { + LikeIcon(heartSize, grayTint) + } + } + } } - LikeText(baseNote, grayTint) + ObserveLikeText(baseNote) { reactionCount -> + SlidingAnimationCount(reactionCount, grayTint) + } if (wantsToChangeReactionSymbol) { UpdateReactionTypeDialog( @@ -790,44 +776,26 @@ fun LikeReaction( } @Composable -fun LikeIcon( +fun ObserveLikeIcon( baseNote: Note, - iconFontSize: TextUnit = Font14SP, - iconSize: Dp = Size20dp, - grayTint: Color, - accountViewModel: AccountViewModel + accountViewModel: AccountViewModel, + inner: @Composable (MutableState) -> Unit ) { val reactionType = remember(baseNote) { mutableStateOf(null) } - val scope = rememberCoroutineScope() + val reactionsState by baseNote.live().reactions.observeAsState() - WatchReactionTypeForNote(baseNote, accountViewModel) { newReactionType -> - if (reactionType.value != newReactionType) { - scope.launch(Dispatchers.Main) { + LaunchedEffect(key1 = reactionsState) { + accountViewModel.loadReactionTo(reactionsState?.note) { newReactionType -> + if (reactionType.value != newReactionType) { reactionType.value = newReactionType } } } - Crossfade(targetState = reactionType) { - val value = it.value - if (value != null) { - RenderReactionType(value, iconSize, iconFontSize) - } else { - LikeIcon(iconSize, grayTint) - } - } -} - -@Composable -private fun WatchReactionTypeForNote(baseNote: Note, accountViewModel: AccountViewModel, onNewReactionType: (String?) -> Unit) { - val reactionsState by baseNote.live().reactions.observeAsState() - - LaunchedEffect(key1 = reactionsState) { - accountViewModel.loadReactionTo(reactionsState?.note, onNewReactionType) - } + inner(reactionType) } @Composable @@ -863,10 +831,10 @@ private fun RenderReactionType( } @Composable -fun LikeText(baseNote: Note, grayTint: Color) { +fun ObserveLikeText(baseNote: Note, inner: @Composable (Int) -> Unit) { val reactionCount by baseNote.live().reactionCount.observeAsState(0) - SlidingAnimationCount(reactionCount, grayTint) + inner(reactionCount) } private fun likeClick( @@ -919,7 +887,7 @@ fun ZapReaction( val context = LocalContext.current val scope = rememberCoroutineScope() - var zappingProgress by remember { mutableStateOf(0f) } + var zappingProgress by remember { mutableFloatStateOf(0f) } Row( verticalAlignment = CenterVertically, @@ -942,7 +910,7 @@ fun ZapReaction( onMultipleChoices = { wantsToZap = true }, - onError = { title, message -> + onError = { _, message -> scope.launch { zappingProgress = 0f showErrorMessageDialog = message @@ -973,7 +941,7 @@ fun ZapReaction( wantsToZap = false wantsToChangeZapAmount = true }, - onError = { title, message -> + onError = { _, message -> scope.launch { zappingProgress = 0f showErrorMessageDialog = message @@ -1033,7 +1001,7 @@ fun ZapReaction( if (wantsToSetCustomZap) { ZapCustomDialog( onClose = { wantsToSetCustomZap = false }, - onError = { title, message -> + onError = { _, message -> scope.launch { zappingProgress = 0f showErrorMessageDialog = message @@ -1058,22 +1026,31 @@ fun ZapReaction( CircularProgressIndicator( progress = animateFloatAsState( targetValue = zappingProgress, - animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec + animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec, + label = "ZapIconIndicator" ).value, modifier = remember { Modifier.size(animationSize) }, strokeWidth = 2.dp ) } else { - ZapIcon( + ObserveZapIcon( baseNote, - iconSize, - grayTint, accountViewModel - ) + ) { wasZappedByLoggedInUser -> + Crossfade(targetState = wasZappedByLoggedInUser.value, label = "ZapIcon") { + if (it) { + ZappedIcon(iconSize) + } else { + ZapIcon(iconSize, grayTint) + } + } + } } } - ZapAmountText(baseNote, grayTint, accountViewModel) + ObserveZapAmountText(baseNote, accountViewModel) { zapAmountTxt -> + SlidingAnimationAmount(zapAmountTxt, grayTint) + } } private fun zapClick( @@ -1115,98 +1092,72 @@ private fun zapClick( } @Composable -private fun ZapIcon( +private fun ObserveZapIcon( baseNote: Note, - iconSize: Dp, - grayTint: Color, - accountViewModel: AccountViewModel + accountViewModel: AccountViewModel, + inner: @Composable (MutableState) -> Unit ) { val wasZappedByLoggedInUser = remember { mutableStateOf(false) } - val scope = rememberCoroutineScope() - if (!wasZappedByLoggedInUser.value) { - WatchZapsForNote(baseNote, accountViewModel) { newWasZapped -> - if (wasZappedByLoggedInUser.value != newWasZapped) { - scope.launch(Dispatchers.Main) { + val zapsState by baseNote.live().zaps.observeAsState() + + LaunchedEffect(key1 = zapsState) { + accountViewModel.calculateIfNoteWasZappedByAccount(baseNote) { newWasZapped -> + if (wasZappedByLoggedInUser.value != newWasZapped) { wasZappedByLoggedInUser.value = newWasZapped } } } } - Crossfade(targetState = wasZappedByLoggedInUser) { - if (it.value) { - ZappedIcon(iconSize) - } else { - ZapIcon(iconSize, grayTint) - } - } + inner(wasZappedByLoggedInUser) } @Composable -private fun WatchZapsForNote(baseNote: Note, accountViewModel: AccountViewModel, onWasZapped: (Boolean) -> Unit) { +private fun ObserveZapAmountText( + baseNote: Note, + accountViewModel: AccountViewModel, + inner: @Composable (MutableState) -> Unit +) { + val zapAmountTxt = remember(baseNote) { + mutableStateOf(showAmount(baseNote.zapsAmount)) + } val zapsState by baseNote.live().zaps.observeAsState() LaunchedEffect(key1 = zapsState) { - accountViewModel.calculateIfNoteWasZappedByAccount(baseNote, onWasZapped) - } -} - -@Composable -private fun ZapAmountText( - baseNote: Note, - grayTint: Color, - accountViewModel: AccountViewModel -) { - val zapAmountTxt = remember(baseNote) { mutableStateOf("") } - - val scope = rememberCoroutineScope() - - WatchZapAmountsForNote(baseNote, accountViewModel) { newZapAmount -> - if (zapAmountTxt.value != newZapAmount) { - scope.launch(Dispatchers.Main) { - zapAmountTxt.value = newZapAmount + accountViewModel.calculateZapAmount(baseNote) { newZapAmount -> + if (zapAmountTxt.value != newZapAmount) { + withContext(Dispatchers.Main) { + zapAmountTxt.value = newZapAmount + } } } } - SlidingAnimationAmount(zapAmountTxt, grayTint) -} - -@Composable -fun WatchZapAmountsForNote(baseNote: Note, accountViewModel: AccountViewModel, onZapAmount: (String) -> Unit) { - val zapsState by baseNote.live().zaps.observeAsState() - - LaunchedEffect(key1 = zapsState) { - accountViewModel.calculateZapAmount(baseNote, onZapAmount) - } + inner(zapAmountTxt) } @Composable fun ViewCountReaction( note: Note, grayTint: Color, - barChartSize: Dp = Size19dp, - numberSize: Dp = Size24dp, + barChartModifier: Modifier = Modifier.size(Size19dp), + numberSizeModifier: Modifier = Modifier.height(Size24dp), viewCountColorFilter: ColorFilter ) { - ViewCountIcon(barChartSize, grayTint) - DrawViewCount(note, numberSize, viewCountColorFilter) + ViewCountIcon(barChartModifier, grayTint) + DrawViewCount(note, numberSizeModifier, viewCountColorFilter) } @Composable private fun DrawViewCount( note: Note, - numberSize: Dp = Size24dp, + iconModifier: Modifier = Modifier, viewCountColorFilter: ColorFilter ) { val context = LocalContext.current - val iconModifier = remember { - Modifier.height(numberSize) - } - AsyncImage( model = remember(note) { ImageRequest.Builder(context) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index 29a153e39..d04db033e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -201,9 +201,13 @@ class AccountViewModel(val account: Account, val settings: SettingsState) : View return account.calculateZappedAmount(zappedNote) } - fun calculateZapAmount(zappedNote: Note, onZapAmount: (String) -> Unit) { - viewModelScope.launch(Dispatchers.IO) { - onZapAmount(showAmount(account.calculateZappedAmount(zappedNote))) + suspend fun calculateZapAmount(zappedNote: Note, onZapAmount: suspend (String) -> Unit) { + if (zappedNote.zapPayments.isNotEmpty()) { + viewModelScope.launch(Dispatchers.IO) { + onZapAmount(showAmount(account.calculateZappedAmount(zappedNote))) + } + } else { + onZapAmount(showAmount(zappedNote.zapsAmount)) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/VideoScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/VideoScreen.kt index a9b30fb01..9fc550f68 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/VideoScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/VideoScreen.kt @@ -437,6 +437,6 @@ fun ReactionsColumn(baseNote: Note, accountViewModel: AccountViewModel, nav: (St } LikeReaction(baseNote, grayTint = MaterialTheme.colorScheme.onBackground, accountViewModel, nav, iconSize = 40.dp, heartSize = Size35dp, 28.sp) ZapReaction(baseNote, grayTint = MaterialTheme.colorScheme.onBackground, accountViewModel, iconSize = 40.dp, animationSize = Size35dp, nav = nav) - ViewCountReaction(baseNote, grayTint = MaterialTheme.colorScheme.onBackground, barChartSize = 39.dp, viewCountColorFilter = MaterialTheme.colorScheme.onBackgroundColorFilter) + ViewCountReaction(baseNote, grayTint = MaterialTheme.colorScheme.onBackground, barChartModifier = Modifier.size(39.dp), viewCountColorFilter = MaterialTheme.colorScheme.onBackgroundColorFilter) } }