Tp-67619 showing red dot on nav bar tabs super app (#10996)
Co-authored-by: abhinavgupta <abhinav.g@navi.com>
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -30,3 +30,11 @@ fun getDefaultBottomTabsList() =
|
||||
NavigationItem.Loan,
|
||||
NavigationItem.Insurance
|
||||
)
|
||||
|
||||
fun getNavigationItemsList(): List<String> =
|
||||
listOf(
|
||||
NavigationItem.Home.tabId,
|
||||
NavigationItem.Investment.tabId,
|
||||
NavigationItem.Loan.tabId,
|
||||
NavigationItem.Insurance.tabId
|
||||
)
|
||||
|
||||
@@ -46,5 +46,6 @@ fun onTabClick(
|
||||
restoreState = true
|
||||
}
|
||||
sharedVM.updateSelectedTabId(tabId)
|
||||
sharedVM.updateBottomNavBarState(tabId = tabId, isTabClicked = true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,6 +158,12 @@ fun InitHomeScreenComponents(
|
||||
activity,
|
||||
nowBottomSheetListener
|
||||
)
|
||||
extraData.bottomNavBarDetails?.entries?.forEach { (key, value) ->
|
||||
sharedVM.updateBottomNavBarState(
|
||||
tabId = key,
|
||||
showRedDotBadge = value.showRedDot
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String, BottomNavBarItemData> = mapOf())
|
||||
|
||||
data class BottomNavBarItemData(
|
||||
val isTabClicked: Boolean = false,
|
||||
val showRedDotBadge: Boolean = false,
|
||||
)
|
||||
@@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String, BottomNavBarItemInfo>? = 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
|
||||
|
||||
Reference in New Issue
Block a user