Refining recompositions of Route.

This commit is contained in:
Vitor Pamplona
2023-12-15 22:21:43 -05:00
parent fe3a0568f2
commit 26846fa91a
2 changed files with 30 additions and 34 deletions
@@ -30,7 +30,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavBackStackEntry import androidx.navigation.NavBackStackEntry
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@@ -143,49 +142,45 @@ private fun RowScope.HasNewItemsIcon(
NavigationBarItem( NavigationBarItem(
icon = { icon = {
ObserveNewItems(route, accountViewModel) { hasNewItems -> NotifiableIcon(
NotifiableIcon( selected,
route.icon, route,
route.notifSize, accountViewModel
route.iconSize, )
selected,
hasNewItems
)
}
}, },
selected = selected, selected = selected,
onClick = { nav(route, selected) } onClick = { nav(route, selected) }
) )
} }
@Composable
fun ObserveNewItems(route: Route, accountViewModel: AccountViewModel, inner: @Composable (hasNewItems: State<Boolean>?) -> Unit) {
val hasNewItems = accountViewModel.notificationDots.hasNewItems[route]?.collectAsStateWithLifecycle()
inner(hasNewItems)
}
@Composable @Composable
private fun NotifiableIcon( private fun NotifiableIcon(
icon: Int,
size: Dp,
iconSize: Dp,
selected: Boolean, selected: Boolean,
hasNewItems: State<Boolean>? route: Route,
accountViewModel: AccountViewModel
) { ) {
Box(remember { Modifier.size(size) }) { Box(route.notifSize) {
Icon( Icon(
painter = painterResource(id = icon), painter = painterResource(id = route.icon),
contentDescription = null, contentDescription = null,
modifier = remember { Modifier.size(iconSize) }, modifier = route.iconSize,
tint = if (selected) MaterialTheme.colorScheme.primary else Color.Unspecified tint = if (selected) MaterialTheme.colorScheme.primary else Color.Unspecified
) )
if (hasNewItems?.value == true) { AddNotifIconIfNeeded(route, accountViewModel, Modifier.align(Alignment.TopEnd))
NotificationDotIcon( }
Modifier.align(Alignment.TopEnd) }
)
} @Composable
fun AddNotifIconIfNeeded(
route: Route,
accountViewModel: AccountViewModel,
modifier: Modifier
) {
val flow = accountViewModel.notificationDots.hasNewItems[route] ?: return
val hasNewItems by flow.collectAsStateWithLifecycle()
if (hasNewItems) {
NotificationDotIcon(modifier)
} }
} }
@@ -1,11 +1,12 @@
package com.vitorpamplona.amethyst.ui.navigation package com.vitorpamplona.amethyst.ui.navigation
import android.os.Bundle import android.os.Bundle
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.unit.Dp import androidx.compose.ui.Modifier
import androidx.navigation.NamedNavArgument import androidx.navigation.NamedNavArgument
import androidx.navigation.NavBackStackEntry import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavDestination import androidx.navigation.NavDestination
@@ -37,16 +38,16 @@ sealed class Route(
val route: String, val route: String,
val base: String = route.substringBefore("?"), val base: String = route.substringBefore("?"),
val icon: Int, val icon: Int,
val notifSize: Dp = Size23dp, val notifSize: Modifier = Modifier.size(Size23dp),
val iconSize: Dp = Size20dp, val iconSize: Modifier = Modifier.size(Size20dp),
val hasNewItems: (Account, Set<com.vitorpamplona.amethyst.model.Note>) -> Boolean = { _, _ -> false }, val hasNewItems: (Account, Set<com.vitorpamplona.amethyst.model.Note>) -> Boolean = { _, _ -> false },
val arguments: ImmutableList<NamedNavArgument> = persistentListOf() val arguments: ImmutableList<NamedNavArgument> = persistentListOf()
) { ) {
object Home : Route( object Home : Route(
route = "Home?nip47={nip47}", route = "Home?nip47={nip47}",
icon = R.drawable.ic_home, icon = R.drawable.ic_home,
notifSize = Size25dp, notifSize = Modifier.size(Size25dp),
iconSize = Size24dp, iconSize = Modifier.size(Size24dp),
arguments = listOf( arguments = listOf(
navArgument("nip47") { type = NavType.StringType; nullable = true; defaultValue = null } navArgument("nip47") { type = NavType.StringType; nullable = true; defaultValue = null }
).toImmutableList(), ).toImmutableList(),