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

View File

@ -30,7 +30,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavBackStackEntry
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@ -143,49 +142,45 @@ private fun RowScope.HasNewItemsIcon(
NavigationBarItem(
icon = {
ObserveNewItems(route, accountViewModel) { hasNewItems ->
NotifiableIcon(
route.icon,
route.notifSize,
route.iconSize,
selected,
hasNewItems
)
}
NotifiableIcon(
selected,
route,
accountViewModel
)
},
selected = 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
private fun NotifiableIcon(
icon: Int,
size: Dp,
iconSize: Dp,
selected: Boolean,
hasNewItems: State<Boolean>?
route: Route,
accountViewModel: AccountViewModel
) {
Box(remember { Modifier.size(size) }) {
Box(route.notifSize) {
Icon(
painter = painterResource(id = icon),
painter = painterResource(id = route.icon),
contentDescription = null,
modifier = remember { Modifier.size(iconSize) },
modifier = route.iconSize,
tint = if (selected) MaterialTheme.colorScheme.primary else Color.Unspecified
)
if (hasNewItems?.value == true) {
NotificationDotIcon(
Modifier.align(Alignment.TopEnd)
)
}
AddNotifIconIfNeeded(route, accountViewModel, 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)
}
}

View File

@ -1,11 +1,12 @@
package com.vitorpamplona.amethyst.ui.navigation
import android.os.Bundle
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.Modifier
import androidx.navigation.NamedNavArgument
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavDestination
@ -37,16 +38,16 @@ sealed class Route(
val route: String,
val base: String = route.substringBefore("?"),
val icon: Int,
val notifSize: Dp = Size23dp,
val iconSize: Dp = Size20dp,
val notifSize: Modifier = Modifier.size(Size23dp),
val iconSize: Modifier = Modifier.size(Size20dp),
val hasNewItems: (Account, Set<com.vitorpamplona.amethyst.model.Note>) -> Boolean = { _, _ -> false },
val arguments: ImmutableList<NamedNavArgument> = persistentListOf()
) {
object Home : Route(
route = "Home?nip47={nip47}",
icon = R.drawable.ic_home,
notifSize = Size25dp,
iconSize = Size24dp,
notifSize = Modifier.size(Size25dp),
iconSize = Modifier.size(Size24dp),
arguments = listOf(
navArgument("nip47") { type = NavType.StringType; nullable = true; defaultValue = null }
).toImmutableList(),