@@ -32,6 +32,7 @@ import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffo
3232import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteType
3333import androidx.compose.material3.rememberWideNavigationRailState
3434import androidx.compose.runtime.Composable
35+ import androidx.compose.runtime.CompositionLocalProvider
3536import androidx.compose.runtime.DisposableEffect
3637import androidx.compose.runtime.LaunchedEffect
3738import androidx.compose.runtime.derivedStateOf
@@ -131,22 +132,20 @@ internal fun HomeScreen(afterInit: () -> Unit) {
131132 tabs.all.firstOrNull { getDirection(it.tabItem) == currentRoute }?.tabItem
132133 }
133134 }
134-
135135 val accountTypeState by producePresenter(key = " home_account_type_${currentTab?.account} " ) {
136136 accountTypePresenter(currentTab?.account ? : AccountType .Active )
137137 }
138138 val layoutType =
139139 NavigationSuiteScaffoldDefaults .calculateFromAdaptiveInfo(
140140 currentWindowAdaptiveInfo(),
141141 )
142- val actualLayoutType = state.navigationState.type ? : layoutType
143142 Box {
144143 NavigationSuiteScaffold2 (
145144 wideNavigationRailState = wideNavigationRailState,
146145 modifier = Modifier .fillMaxSize(),
147146 bottomBarDividerEnabled = state.navigationState.bottomBarDividerEnabled,
148147 bottomBarAutoHideEnabled = state.navigationState.bottomBarAutoHideEnabled,
149- layoutType = actualLayoutType ,
148+ layoutType = layoutType ,
150149 navigationSuiteColors =
151150 NavigationSuiteDefaults .colors(
152151 navigationBarContainerColor = MaterialTheme .colorScheme.surface,
@@ -206,7 +205,7 @@ internal fun HomeScreen(afterInit: () -> Unit) {
206205 Modifier
207206 .padding(
208207 horizontal =
209- if (actualLayoutType ==
208+ if (layoutType ==
210209 NavigationSuiteType .NavigationBar
211210 ) {
212211 16 .dp
@@ -259,7 +258,7 @@ internal fun HomeScreen(afterInit: () -> Unit) {
259258 }
260259 }
261260 }
262- if (actualLayoutType == NavigationSuiteType .NavigationRail ) {
261+ if (layoutType == NavigationSuiteType .NavigationRail ) {
263262 AnimatedContent (
264263 wideNavigationRailState.currentValue,
265264 modifier = Modifier .padding(horizontal = 20 .dp),
@@ -332,12 +331,12 @@ internal fun HomeScreen(afterInit: () -> Unit) {
332331 }
333332 },
334333 navigationSuiteItems = {
335- tabs.primary.forEach { (tab, tabState, badgeState) ->
334+ tabs.primary.forEach { (tab, badgeState) ->
336335 item(
337336 selected = currentRoute == getDirection(tab),
338337 onClick = {
339338 if (currentRoute == getDirection(tab)) {
340- tabState.onClick ()
339+ state.scrollToTopRegistry.scrollToTop ()
341340 } else {
342341 navigate(getDirection(tab))
343342 }
@@ -383,12 +382,12 @@ internal fun HomeScreen(afterInit: () -> Unit) {
383382 }
384383 },
385384 secondaryItems = {
386- tabs.secondary.forEach { (tab, tabState ) ->
385+ tabs.secondary.forEach { (tab, badgeState ) ->
387386 item(
388387 selected = currentRoute == getDirection(tab),
389388 onClick = {
390389 if (currentRoute == getDirection(tab)) {
391- tabState.onClick ()
390+ state.scrollToTopRegistry.scrollToTop ()
392391 } else {
393392 navigate(getDirection(tab))
394393 }
@@ -406,6 +405,20 @@ internal fun HomeScreen(afterInit: () -> Unit) {
406405 title = tab.metaData.title,
407406 )
408407 },
408+ badge =
409+ if (badgeState.isSuccess) {
410+ {
411+ badgeState.onSuccess {
412+ if (it > 0 ) {
413+ Badge {
414+ Text (text = it.toString())
415+ }
416+ }
417+ }
418+ }
419+ } else {
420+ null
421+ },
409422 )
410423 }
411424 },
@@ -429,15 +442,19 @@ internal fun HomeScreen(afterInit: () -> Unit) {
429442 }
430443 },
431444 ) {
432- Router (
433- topLevelBackStack = topLevelBackStack,
434- navigationState = state.navigationState,
435- openDrawer = {
436- scope.launch {
437- wideNavigationRailState.toggle()
438- }
439- },
440- )
445+ CompositionLocalProvider (
446+ LocalScrollToTopRegistry provides state.scrollToTopRegistry,
447+ ) {
448+ Router (
449+ topLevelBackStack = topLevelBackStack,
450+ navigationState = state.navigationState,
451+ openDrawer = {
452+ scope.launch {
453+ wideNavigationRailState.toggle()
454+ }
455+ },
456+ )
457+ }
441458 }
442459 InAppNotificationComponent (
443460 modifier = Modifier .align(Alignment .TopCenter ),
@@ -494,9 +511,14 @@ private fun presenter(settingsRepository: SettingsRepository = koinInject()) =
494511 remember {
495512 HomeTabsPresenter (settingsRepository.tabSettings)
496513 }.invoke()
514+ val scrollToTopRegistry =
515+ remember {
516+ ScrollToTopRegistry ()
517+ }
497518 object {
498519 val tabs = tabs.tabs
499520 val navigationState = navigationState
521+ val scrollToTopRegistry = scrollToTopRegistry
500522 }
501523 }
502524
@@ -507,36 +529,13 @@ private fun accountTypePresenter(accountType: AccountType) =
507529 }
508530
509531internal class NavigationState {
510- private val state = mutableStateOf<NavigationSuiteType ?>(null )
511- private val drawerState = mutableStateOf(true )
512532 private val bottomBarAutoHideState = mutableStateOf(true )
513533 private val bottomBarDividerState = mutableStateOf(true )
514- val type: NavigationSuiteType ?
515- get() = state.value
516-
517- val drawerEnabled: Boolean
518- get() = drawerState.value
519534 val bottomBarAutoHideEnabled: Boolean
520535 get() = bottomBarAutoHideState.value
521536 val bottomBarDividerEnabled: Boolean
522537 get() = bottomBarDividerState.value
523538
524- fun hide () {
525- state.value = NavigationSuiteType .None
526- }
527-
528- fun show () {
529- state.value = null
530- }
531-
532- fun enableDrawer () {
533- drawerState.value = true
534- }
535-
536- fun disableDrawer () {
537- drawerState.value = false
538- }
539-
540539 fun enableBottomBarAutoHide () {
541540 bottomBarAutoHideState.value = true
542541 }
@@ -554,14 +553,30 @@ internal class NavigationState {
554553 }
555554}
556555
557- private val LocalTabState =
558- androidx.compose.runtime.staticCompositionLocalOf<HomeTabsPresenter .State .HomeTabState .HomeTabItem .TabState ?> {
556+ private class ScrollToTopRegistry {
557+ private val callbacks = mutableSetOf< () -> Unit > ()
558+
559+ fun registerCallback (callback : () -> Unit ) {
560+ callbacks.add(callback)
561+ }
562+
563+ fun unregisterCallback (callback : () -> Unit ) {
564+ callbacks.remove(callback)
565+ }
566+
567+ fun scrollToTop () {
568+ callbacks.forEach { it.invoke() }
569+ }
570+ }
571+
572+ private val LocalScrollToTopRegistry =
573+ androidx.compose.runtime.staticCompositionLocalOf<ScrollToTopRegistry ?> {
559574 null
560575 }
561576
562577@Composable
563578internal fun RegisterTabCallback (lazyListState : LazyStaggeredGridState ) {
564- val tabState = LocalTabState .current
579+ val tabState = LocalScrollToTopRegistry .current
565580 if (tabState != null ) {
566581 val scope = rememberCoroutineScope()
567582 val callback: () -> Unit =
0 commit comments