diff --git a/android/app/src/main/java/com/naviapp/home/compose/components/BottomBarWithFabButton.kt b/android/app/src/main/java/com/naviapp/home/compose/components/BottomBarWithFabButton.kt index fd85efe75c..9c9859ce13 100644 --- a/android/app/src/main/java/com/naviapp/home/compose/components/BottomBarWithFabButton.kt +++ b/android/app/src/main/java/com/naviapp/home/compose/components/BottomBarWithFabButton.kt @@ -53,6 +53,7 @@ fun BottomBarWithFabButton( val bottomStickyNudgeData by bottomNavBarVM.bottomStickyNudgeData.collectAsState() val showBottomBar by homeVM.showBottomBar.collectAsState() val showSnackBar by homeVM.showHomeScreenSnackBar.collectAsStateWithLifecycle() + val bottomNavBarState by sharedVM.bottomNavBarStateHolder.collectAsStateWithLifecycle() LaunchedEffect(key1 = expanded) { if (showBottomBar) { @@ -106,7 +107,8 @@ fun BottomBarWithFabButton( } AnimatedBottomBar( visible = expanded || selectedTabId != BottomBarTabType.HOME.name || showBottomBar, - selectedTabId = selectedTabId + selectedTabId = selectedTabId, + bottomNavBarState = bottomNavBarState ) { tabId -> onTabClick( selectedTabId = selectedTabId, diff --git a/android/app/src/main/java/com/naviapp/home/compose/components/HomePageBottomBar.kt b/android/app/src/main/java/com/naviapp/home/compose/components/HomePageBottomBar.kt index 4bf4ddf571..3e21cdcb39 100644 --- a/android/app/src/main/java/com/naviapp/home/compose/components/HomePageBottomBar.kt +++ b/android/app/src/main/java/com/naviapp/home/compose/components/HomePageBottomBar.kt @@ -12,12 +12,16 @@ import androidx.compose.animation.expandVertically import androidx.compose.animation.shrinkVertically import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOutVertically +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.BottomAppBar import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -26,6 +30,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.navi.pay.utils.noRippleClickable +import com.naviapp.home.model.BottomNavBarStateHolder import com.naviapp.home.utils.DrawIcon import com.naviapp.home.utils.TabText import com.naviapp.utils.BottomBarUtils @@ -34,19 +39,28 @@ import com.naviapp.utils.BottomBarUtils fun AnimatedBottomBar( visible: Boolean, selectedTabId: String, - onTabSelected: (String) -> Unit, + bottomNavBarState: BottomNavBarStateHolder, + onTabSelected: (String) -> Unit ) { AnimatedVisibility( visible = visible, enter = slideInVertically { it } + expandVertically(clip = false) { 0 }, exit = slideOutVertically { it } + shrinkVertically(clip = false) { 0 } ) { - BottomBar(selectedTabId = selectedTabId, onTabSelected = onTabSelected) + BottomBar( + selectedTabId = selectedTabId, + onTabSelected = onTabSelected, + bottomNavBarState = bottomNavBarState + ) } } @Composable -fun BottomBar(selectedTabId: String, onTabSelected: (String) -> Unit) { +fun BottomBar( + selectedTabId: String, + onTabSelected: (String) -> Unit, + bottomNavBarState: BottomNavBarStateHolder +) { BottomAppBar( modifier = Modifier.navigationBarsPadding(), backgroundColor = Color.White, @@ -58,33 +72,55 @@ fun BottomBar(selectedTabId: String, onTabSelected: (String) -> Unit) { modifier = Modifier.weight(1f), item = bottomTabItem, selectedTabId = selectedTabId, - onTabSelected = onTabSelected + onTabSelected = onTabSelected, + showRedDotBadge = isRedDotBadgeEnabled(bottomTabItem.tabId, bottomNavBarState) ) } } } +fun isRedDotBadgeEnabled(tabId: String, bottomNavRedDotState: BottomNavBarStateHolder): Boolean { + val item = bottomNavRedDotState.items[tabId] ?: return false + return if (item.isTabClicked) { + false + } else { + item.showRedDotBadge + } +} + @Composable private fun BottomBarItem( modifier: Modifier, item: NavigationItem, selectedTabId: String, onTabSelected: (String) -> Unit, + showRedDotBadge: Boolean ) { item.tabId.let { Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier.noRippleClickable { onTabSelected(it) } ) { - DrawIcon( - drawableIconId = - BottomBarUtils.fetchDefaultTabIconResourceId( - selectedTabId = selectedTabId, - tabId = it - ), - content = selectedTabId, - modifier = Modifier.size(24.dp) - ) + Box { + DrawIcon( + drawableIconId = + BottomBarUtils.fetchDefaultTabIconResourceId( + selectedTabId = selectedTabId, + tabId = it + ), + content = selectedTabId, + modifier = Modifier.size(24.dp) + ) + if (showRedDotBadge) { + Box( + modifier = + Modifier.size(8.dp) + .align(Alignment.TopEnd) + .offset(x = 4.dp, y = (-4).dp) + .background(Color.Red, shape = CircleShape) + ) + } + } Spacer(modifier = Modifier.height(4.dp)) TabText( selectedTabId = selectedTabId, diff --git a/android/app/src/main/java/com/naviapp/home/compose/components/NavigationItem.kt b/android/app/src/main/java/com/naviapp/home/compose/components/NavigationItem.kt index f167e6918d..c9d101edeb 100644 --- a/android/app/src/main/java/com/naviapp/home/compose/components/NavigationItem.kt +++ b/android/app/src/main/java/com/naviapp/home/compose/components/NavigationItem.kt @@ -30,3 +30,11 @@ fun getDefaultBottomTabsList() = NavigationItem.Loan, NavigationItem.Insurance ) + +fun getNavigationItemsList(): List = + listOf( + NavigationItem.Home.tabId, + NavigationItem.Investment.tabId, + NavigationItem.Loan.tabId, + NavigationItem.Insurance.tabId + ) diff --git a/android/app/src/main/java/com/naviapp/home/compose/homescreen/BottomBarFabInteractions.kt b/android/app/src/main/java/com/naviapp/home/compose/homescreen/BottomBarFabInteractions.kt index 5fb66a63ab..d0bfc680b8 100644 --- a/android/app/src/main/java/com/naviapp/home/compose/homescreen/BottomBarFabInteractions.kt +++ b/android/app/src/main/java/com/naviapp/home/compose/homescreen/BottomBarFabInteractions.kt @@ -46,5 +46,6 @@ fun onTabClick( restoreState = true } sharedVM.updateSelectedTabId(tabId) + sharedVM.updateBottomNavBarState(tabId = tabId, isTabClicked = true) } } diff --git a/android/app/src/main/java/com/naviapp/home/compose/homescreen/InitHomeScreenComponents.kt b/android/app/src/main/java/com/naviapp/home/compose/homescreen/InitHomeScreenComponents.kt index 98bd03e1f9..7ef6157462 100644 --- a/android/app/src/main/java/com/naviapp/home/compose/homescreen/InitHomeScreenComponents.kt +++ b/android/app/src/main/java/com/naviapp/home/compose/homescreen/InitHomeScreenComponents.kt @@ -158,6 +158,12 @@ fun InitHomeScreenComponents( activity, nowBottomSheetListener ) + extraData.bottomNavBarDetails?.entries?.forEach { (key, value) -> + sharedVM.updateBottomNavBarState( + tabId = key, + showRedDotBadge = value.showRedDot + ) + } } } } diff --git a/android/app/src/main/java/com/naviapp/home/model/BottomNavBarStateHolder.kt b/android/app/src/main/java/com/naviapp/home/model/BottomNavBarStateHolder.kt new file mode 100644 index 0000000000..a819f8aacc --- /dev/null +++ b/android/app/src/main/java/com/naviapp/home/model/BottomNavBarStateHolder.kt @@ -0,0 +1,15 @@ +/* + * + * * Copyright © 2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.naviapp.home.model + +data class BottomNavBarStateHolder(val items: Map = mapOf()) + +data class BottomNavBarItemData( + val isTabClicked: Boolean = false, + val showRedDotBadge: Boolean = false, +) diff --git a/android/app/src/main/java/com/naviapp/home/viewmodel/SharedVM.kt b/android/app/src/main/java/com/naviapp/home/viewmodel/SharedVM.kt index 1d8d9d95f8..81f82502fc 100644 --- a/android/app/src/main/java/com/naviapp/home/viewmodel/SharedVM.kt +++ b/android/app/src/main/java/com/naviapp/home/viewmodel/SharedVM.kt @@ -11,7 +11,10 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import com.navi.common.viewmodel.BaseVM import com.naviapp.common.model.UiTronActionHandler +import com.naviapp.home.compose.components.getNavigationItemsList import com.naviapp.home.model.BottomBarTabType +import com.naviapp.home.model.BottomNavBarItemData +import com.naviapp.home.model.BottomNavBarStateHolder import com.naviapp.utils.Constants import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @@ -37,6 +40,14 @@ class SharedVM @Inject constructor() : BaseVM() { private val _showBottomSheet = MutableStateFlow(false) val showBottomSheet = _showBottomSheet.asStateFlow() + private val _bottomNavBarStateHolder = + MutableStateFlow( + BottomNavBarStateHolder( + items = getNavigationItemsList().associateWith { BottomNavBarItemData() } + ) + ) + val bottomNavBarStateHolder = _bottomNavBarStateHolder.asStateFlow() + fun updateUiTronAction(uiTronActionHandler: UiTronActionHandler?) { _uiTronActionHandler.update { uiTronActionHandler } } @@ -56,4 +67,20 @@ class SharedVM @Inject constructor() : BaseVM() { fun setBottomSheetState(show: Boolean) { viewModelScope.launch { _showBottomSheet.emit(show) } } + + fun updateBottomNavBarState( + tabId: String, + isTabClicked: Boolean? = null, + showRedDotBadge: Boolean? = null + ) { + val currentState = _bottomNavBarStateHolder.value.items.toMutableMap() + currentState[tabId]?.let { + currentState[tabId] = + BottomNavBarItemData( + isTabClicked = isTabClicked ?: it.isTabClicked, + showRedDotBadge = showRedDotBadge ?: it.showRedDotBadge + ) + } + _bottomNavBarStateHolder.update { BottomNavBarStateHolder(currentState) } + } } diff --git a/android/navi-common/src/main/java/com/navi/common/model/common/WidgetResponse.kt b/android/navi-common/src/main/java/com/navi/common/model/common/WidgetResponse.kt index 79b7e69256..ac185b798d 100644 --- a/android/navi-common/src/main/java/com/navi/common/model/common/WidgetResponse.kt +++ b/android/navi-common/src/main/java/com/navi/common/model/common/WidgetResponse.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2023 by Navi Technologies Limited + * * Copyright © 2023-2024 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -95,8 +95,14 @@ data class ExtraDataDetails( @SerializedName("sipInfo") val sipInfo: SipInfo? = null, @SerializedName("loaderScreen") val loaderScreen: ActionCheckResponse? = null, @SerializedName("isUserInvested") val isUserInvested: Boolean? = null, + @SerializedName("bottomNavBarDetails") + val bottomNavBarDetails: Map? = null, ) : Parcelable +@Parcelize +data class BottomNavBarItemInfo(@SerializedName("showRedDot") val showRedDot: Boolean? = null) : + Parcelable + @Parcelize data class CacheConfig(val ttl: Long? = 0, val maxConsumptions: Int? = 0) : Parcelable @Parcelize