TP-67659 | generic bottomsheet support in home page (#11105)

This commit is contained in:
Soumya Ranjan Patra
2024-05-31 19:13:46 +05:30
committed by GitHub
parent 7363d44de2
commit c878c5a261
4 changed files with 202 additions and 5 deletions

View File

@@ -40,6 +40,7 @@ import com.naviapp.dashboard.viewmodels.DashboardSharedVM
import com.naviapp.home.common.handler.InitActionsHandler
import com.naviapp.home.compose.components.BottomBarWithFabButton
import com.naviapp.home.compose.components.HomePageNavHost
import com.naviapp.home.compose.components.HomeScreenBottomSheet
import com.naviapp.home.compose.homescreen.onTabClick
import com.naviapp.home.compose.model.InitiatePaymentFromComposeData
import com.naviapp.home.compose.profile.ProfileScreen
@@ -155,6 +156,8 @@ private fun InitHomeActivityScreen(
}
}
HomeScreenBottomSheet(viewModel = sharedVM)
NaviModalNavigationDrawer(
drawerState = { drawerState },
modifier = Modifier.fillMaxSize(),

View File

@@ -0,0 +1,129 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.home.compose.components
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.BottomSheetDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.ModalBottomSheetProperties
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.SecureFlagPolicy
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.navi.alfred.AlfredManager
import com.navi.ap.utils.constants.BOTTOM_SHEET_VISIBILITY
import com.navi.base.utils.orTrue
import com.navi.common.utils.Constants.HIDE
import com.navi.common.utils.getStatusBarHeight
import com.navi.uitron.render.UiTronRenderer
import com.navi.uitron.utils.hexToComposeColor
import com.naviapp.home.model.HpBottomSheetContent
import com.naviapp.home.model.HpBottomSheetRenderType
import com.naviapp.home.model.HpBottomSheetState
import com.naviapp.home.viewmodel.SharedVM
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HomeScreenBottomSheet(viewModel: SharedVM) {
val bottomSheetStateHolder by viewModel.bottomSheetStateHolder.collectAsStateWithLifecycle()
val modalBottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
// Hide bottom sheet using UiTronAction UpdateStateHandleActionV2
LaunchedEffect(Unit) {
viewModel.handle.getStateFlow<String?>(BOTTOM_SHEET_VISIBILITY, null).collect {
if (it == HIDE) {
modalBottomSheetState.hide()
viewModel.updateBottomSheetState(state = HpBottomSheetState.Hidden)
viewModel.handle[BOTTOM_SHEET_VISIBILITY] = null
}
}
}
LaunchedEffect(key1 = bottomSheetStateHolder.state) {
when (bottomSheetStateHolder.state) {
HpBottomSheetState.Visible -> {
modalBottomSheetState.show()
}
HpBottomSheetState.Hidden -> {
if (modalBottomSheetState.isVisible) {
modalBottomSheetState.hide()
}
}
}
}
if (bottomSheetStateHolder.state != HpBottomSheetState.Hidden) {
bottomSheetStateHolder.let {
val statusBarHeight = with(LocalDensity.current) { getStatusBarHeight().toDp() }
ModalBottomSheet(
onDismissRequest = {
it.config?.onDismiss
viewModel.updateBottomSheetState(state = HpBottomSheetState.Hidden)
},
dragHandle = null,
sheetState = modalBottomSheetState,
containerColor = it.config?.contentColor?.hexToComposeColor ?: Color.White,
shape = RoundedCornerShape(topStart = 8.dp, topEnd = 8.dp),
scrimColor =
it.config?.scrimColor?.hexToComposeColor ?: BottomSheetDefaults.ScrimColor,
modifier = Modifier.padding(top = statusBarHeight),
properties =
ModalBottomSheetProperties(
shouldDismissOnBackPress = it.config?.isCancellable.orTrue(),
isFocusable = true,
securePolicy = SecureFlagPolicy.Inherit
),
windowInsets = WindowInsets(0, 0, 0, 0)
) {
AlfredManager.setBottomSheetView(LocalView.current.rootView)
Column(
modifier = Modifier.navigationBarsPadding().padding(bottom = statusBarHeight)
) {
BottomSheetContentRenderer(it.content, viewModel)
}
}
}
}
}
@Composable
private fun BottomSheetContentRenderer(content: HpBottomSheetContent?, viewModel: SharedVM) {
when (content?.renderType) {
HpBottomSheetRenderType.NATIVE -> {
// Native bottom sheet content
when (content.composableType) {
// Handle different composable types here using HpBottomSheetComposableType enum
else -> Unit
}
}
HpBottomSheetRenderType.UI_TRON -> {
content.uiTronContent?.forEach {
UiTronRenderer(
dataMap = it.widgetData?.data,
viewModel,
)
.Render(composeViews = it.widgetData?.parentComposeView ?: listOf())
}
}
else -> Unit
}
}

View File

@@ -0,0 +1,48 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.home.model
import androidx.compose.runtime.Stable
import com.navi.uitron.model.UiTronResponse
import com.naviapp.forge.model.WidgetModelDefinition
@Stable
data class HpBottomSheetStateHolder(
val state: HpBottomSheetState,
val config: HpBottomSheetConfig? = null,
val content: HpBottomSheetContent? = null,
)
@Stable
data class HpBottomSheetContent(
val composableType: HpBottomSheetComposableType? = null,
val renderType: HpBottomSheetRenderType? = null,
val uiTronContent: List<WidgetModelDefinition<UiTronResponse>>? = null,
)
@Stable
data class HpBottomSheetConfig(
val isCancellable: Boolean? = true,
val contentColor: String? = null,
val scrimColor: String? = null,
val onDismiss: () -> Unit = {},
)
enum class HpBottomSheetState {
Visible,
Hidden,
}
enum class HpBottomSheetRenderType {
UI_TRON,
NATIVE,
}
enum class HpBottomSheetComposableType {
// Add different composable types here according to your use case
}

View File

@@ -7,7 +7,6 @@
package com.naviapp.home.viewmodel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.navi.common.viewmodel.BaseVM
import com.naviapp.common.model.UiTronActionHandler
@@ -15,7 +14,10 @@ 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 com.naviapp.home.model.HpBottomSheetConfig
import com.naviapp.home.model.HpBottomSheetContent
import com.naviapp.home.model.HpBottomSheetState
import com.naviapp.home.model.HpBottomSheetStateHolder
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
@@ -26,12 +28,10 @@ import kotlinx.coroutines.launch
@HiltViewModel
class SharedVM @Inject constructor() : BaseVM() {
val homeStatusColor = MutableLiveData<String>(Constants.HOME_STATUS_BAR_COLOR)
private val _uiTronActionHandler = MutableStateFlow<UiTronActionHandler?>(null)
val uiTronActionHandler = _uiTronActionHandler.asStateFlow()
private val _insuranceTabFetchFlag = MutableStateFlow<Boolean>(false)
private val _insuranceTabFetchFlag = MutableStateFlow(false)
val insuranceTabFetchFlag = _insuranceTabFetchFlag.asStateFlow()
private val _selectedTabId = MutableStateFlow(BottomBarTabType.HOME.name)
@@ -48,6 +48,15 @@ class SharedVM @Inject constructor() : BaseVM() {
)
val bottomNavBarStateHolder = _bottomNavBarStateHolder.asStateFlow()
private val _bottomSheetStateHolder =
MutableStateFlow(
HpBottomSheetStateHolder(
state = HpBottomSheetState.Hidden,
)
)
val bottomSheetStateHolder = _bottomSheetStateHolder.asStateFlow()
fun updateUiTronAction(uiTronActionHandler: UiTronActionHandler?) {
_uiTronActionHandler.update { uiTronActionHandler }
}
@@ -83,4 +92,12 @@ class SharedVM @Inject constructor() : BaseVM() {
}
_bottomNavBarStateHolder.update { BottomNavBarStateHolder(currentState) }
}
fun updateBottomSheetState(
state: HpBottomSheetState,
config: HpBottomSheetConfig? = null,
content: HpBottomSheetContent? = null
) {
_bottomSheetStateHolder.update { HpBottomSheetStateHolder(state, config, content) }
}
}