1 /* <lambda>null2 * Copyright 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.accompanist.navigation.material 18 19 import androidx.compose.foundation.layout.ColumnScope 20 import androidx.compose.material.ExperimentalMaterialApi 21 import androidx.compose.material.ModalBottomSheetState 22 import androidx.compose.runtime.Composable 23 import androidx.compose.runtime.LaunchedEffect 24 import androidx.compose.runtime.getValue 25 import androidx.compose.runtime.rememberUpdatedState 26 import androidx.compose.runtime.saveable.SaveableStateHolder 27 import androidx.compose.runtime.snapshotFlow 28 import androidx.navigation.NavBackStackEntry 29 import androidx.navigation.compose.LocalOwnersProvider 30 import kotlinx.coroutines.flow.distinctUntilChanged 31 import kotlinx.coroutines.flow.drop 32 33 /** 34 * Hosts a [BottomSheetNavigator.Destination]'s [NavBackStackEntry] and its 35 * [BottomSheetNavigator.Destination.content] and provides a [onSheetDismissed] callback. It also 36 * shows and hides the [ModalBottomSheetLayout] through the [sheetState] when the sheet content 37 * enters or leaves the composition. 38 * 39 * @param backStackEntry The [NavBackStackEntry] holding the [BottomSheetNavigator.Destination], 40 * or null if there is no [NavBackStackEntry] 41 * @param sheetState The [ModalBottomSheetState] used to observe and control the sheet visibility 42 * @param onSheetDismissed Callback when the sheet has been dismissed. Typically, you'll want to 43 * pop the back stack here. 44 */ 45 @ExperimentalMaterialNavigationApi 46 @OptIn(ExperimentalMaterialApi::class) 47 @Composable 48 internal fun ColumnScope.SheetContentHost( 49 backStackEntry: NavBackStackEntry?, 50 sheetState: ModalBottomSheetState, 51 saveableStateHolder: SaveableStateHolder, 52 onSheetShown: (entry: NavBackStackEntry) -> Unit, 53 onSheetDismissed: (entry: NavBackStackEntry) -> Unit, 54 ) { 55 if (backStackEntry != null) { 56 val currentOnSheetShown by rememberUpdatedState(onSheetShown) 57 val currentOnSheetDismissed by rememberUpdatedState(onSheetDismissed) 58 LaunchedEffect(sheetState, backStackEntry) { 59 snapshotFlow { sheetState.isVisible } 60 // We are only interested in changes in the sheet's visibility 61 .distinctUntilChanged() 62 // distinctUntilChanged emits the initial value which we don't need 63 .drop(1) 64 .collect { visible -> 65 if (visible) { 66 currentOnSheetShown(backStackEntry) 67 } else { 68 currentOnSheetDismissed(backStackEntry) 69 } 70 } 71 } 72 backStackEntry.LocalOwnersProvider(saveableStateHolder) { 73 val content = 74 (backStackEntry.destination as BottomSheetNavigator.Destination).content 75 content(backStackEntry) 76 } 77 } 78 } 79