Add search only scaffold for assistant activity
This commit is contained in:
parent
2d60797830
commit
8be8875462
@ -0,0 +1,151 @@
|
||||
package de.mm20.launcher2.ui.assistant
|
||||
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.ui.launcher.LauncherScaffoldVM
|
||||
import de.mm20.launcher2.ui.launcher.search.SearchBar
|
||||
import de.mm20.launcher2.ui.launcher.search.SearchBarLevel
|
||||
import de.mm20.launcher2.ui.launcher.search.SearchColumn
|
||||
import de.mm20.launcher2.ui.launcher.search.SearchVM
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
@Composable
|
||||
fun AssistantScaffold(
|
||||
modifier: Modifier = Modifier,
|
||||
darkStatusBarIcons: Boolean = false,
|
||||
darkNavBarIcons: Boolean = false,
|
||||
) {
|
||||
val viewModel: LauncherScaffoldVM = viewModel()
|
||||
|
||||
val bottomSearchBar by remember {
|
||||
viewModel.dataStore.data.map { it.appearance.layout != Settings.AppearanceSettings.Layout.PullDown }
|
||||
}.collectAsState(null)
|
||||
|
||||
val reverseResults by remember {
|
||||
viewModel.dataStore.data.map { it.appearance.layout != Settings.AppearanceSettings.Layout.PullDown }
|
||||
}.collectAsState(null)
|
||||
|
||||
val searchBarFocused by viewModel.searchBarFocused.observeAsState(false)
|
||||
|
||||
val searchState = rememberLazyListState()
|
||||
|
||||
val isSearchAtStart by remember {
|
||||
derivedStateOf {
|
||||
searchState.firstVisibleItemIndex == 0 && searchState.firstVisibleItemScrollOffset == 0
|
||||
}
|
||||
}
|
||||
|
||||
val isSearchAtEnd by remember {
|
||||
derivedStateOf {
|
||||
val lastItem = searchState.layoutInfo.visibleItemsInfo.lastOrNull() ?: return@derivedStateOf true
|
||||
lastItem.offset + lastItem.size <= searchState.layoutInfo.viewportEndOffset - searchState.layoutInfo.afterContentPadding
|
||||
}
|
||||
}
|
||||
|
||||
if (reverseResults == null || bottomSearchBar == null) return
|
||||
|
||||
|
||||
val searchBarLevel by remember {
|
||||
derivedStateOf {
|
||||
when {
|
||||
reverseResults == bottomSearchBar && isSearchAtStart -> SearchBarLevel.Active
|
||||
reverseResults != bottomSearchBar && isSearchAtEnd -> SearchBarLevel.Active
|
||||
else -> SearchBarLevel.Raised
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val systemUiController = rememberSystemUiController()
|
||||
val showStatusBarScrim by remember {
|
||||
derivedStateOf {
|
||||
if (reverseResults == true) {
|
||||
!isSearchAtEnd
|
||||
} else {
|
||||
!isSearchAtStart
|
||||
}
|
||||
}
|
||||
}
|
||||
val showNavBarScrim by remember {
|
||||
derivedStateOf {
|
||||
if (reverseResults == true) {
|
||||
!isSearchAtStart
|
||||
} else {
|
||||
!isSearchAtEnd
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val colorSurface = MaterialTheme.colorScheme.surface
|
||||
LaunchedEffect(darkStatusBarIcons, colorSurface, showStatusBarScrim) {
|
||||
if (showStatusBarScrim) {
|
||||
systemUiController.setStatusBarColor(
|
||||
colorSurface.copy(0.7f),
|
||||
)
|
||||
} else {
|
||||
systemUiController.setStatusBarColor(
|
||||
Color.Transparent,
|
||||
darkIcons = darkStatusBarIcons
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(darkNavBarIcons, showNavBarScrim) {
|
||||
if (showNavBarScrim) {
|
||||
systemUiController.setNavigationBarColor(
|
||||
colorSurface.copy(0.7f),
|
||||
)
|
||||
} else {
|
||||
systemUiController.setNavigationBarColor(
|
||||
Color.Transparent,
|
||||
darkIcons = darkNavBarIcons,
|
||||
navigationBarContrastEnforced = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val searchVM: SearchVM = viewModel()
|
||||
val websearches by searchVM.websearchResults.observeAsState(emptyList())
|
||||
val webSearchPadding by animateDpAsState(
|
||||
if (websearches.isEmpty()) 0.dp else 48.dp
|
||||
)
|
||||
val windowInsets = WindowInsets.safeDrawing.asPaddingValues()
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
SearchColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
paddingValues = PaddingValues(
|
||||
top = (if (bottomSearchBar == true) 0.dp else 56.dp + webSearchPadding) + 4.dp + windowInsets.calculateTopPadding(),
|
||||
bottom = (if (bottomSearchBar == true) 56.dp + webSearchPadding else 0.dp) + 4.dp + windowInsets.calculateBottomPadding()
|
||||
),
|
||||
reverse = reverseResults == true,
|
||||
state = searchState
|
||||
)
|
||||
|
||||
SearchBar(
|
||||
level = { searchBarLevel },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight()
|
||||
.align(if (bottomSearchBar == true) Alignment.BottomCenter else Alignment.TopCenter)
|
||||
.windowInsetsPadding(WindowInsets.safeDrawing)
|
||||
.padding(8.dp),
|
||||
focused = searchBarFocused,
|
||||
onFocusChange = {
|
||||
if (it) viewModel.openSearch()
|
||||
viewModel.setSearchbarFocus(it)
|
||||
},
|
||||
reverse = bottomSearchBar == true
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -73,7 +73,7 @@ fun PagerScaffold(
|
||||
|
||||
val isSearchAtEnd by remember {
|
||||
derivedStateOf {
|
||||
val lastItem = searchState.layoutInfo.visibleItemsInfo.last()
|
||||
val lastItem = searchState.layoutInfo.visibleItemsInfo.lastOrNull() ?: return@derivedStateOf true
|
||||
lastItem.offset + lastItem.size <= searchState.layoutInfo.viewportEndOffset - searchState.layoutInfo.afterContentPadding
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ fun PullDownScaffold(
|
||||
|
||||
val isSearchAtEnd by remember {
|
||||
derivedStateOf {
|
||||
val lastItem = searchState.layoutInfo.visibleItemsInfo.last()
|
||||
val lastItem = searchState.layoutInfo.visibleItemsInfo.lastOrNull() ?: return@derivedStateOf true
|
||||
lastItem.offset + lastItem.size <= searchState.layoutInfo.viewportEndOffset - searchState.layoutInfo.afterContentPadding
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ import com.android.launcher3.GestureNavContract
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.assistant.AssistantScaffold
|
||||
import de.mm20.launcher2.ui.base.BaseActivity
|
||||
import de.mm20.launcher2.ui.base.ProvideCurrentTime
|
||||
import de.mm20.launcher2.ui.base.ProvideSettings
|
||||
@ -127,36 +128,45 @@ abstract class SharedLauncherActivity(
|
||||
contentAlignment = Alignment.BottomCenter
|
||||
) {
|
||||
NavBarEffects(modifier = Modifier.fillMaxSize())
|
||||
when (layout) {
|
||||
Settings.AppearanceSettings.Layout.PullDown -> {
|
||||
PullDownScaffold(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.graphicsLayer {
|
||||
scaleX = 0.5f + enterTransition.value * 0.5f
|
||||
scaleY = 0.5f + enterTransition.value * 0.5f
|
||||
alpha = enterTransition.value
|
||||
},
|
||||
darkStatusBarIcons = lightStatus,
|
||||
darkNavBarIcons = lightNav,
|
||||
)
|
||||
if (mode == LauncherActivityMode.Assistant) {
|
||||
AssistantScaffold(
|
||||
modifier = Modifier
|
||||
.fillMaxSize(),
|
||||
darkStatusBarIcons = lightStatus,
|
||||
darkNavBarIcons = lightNav,
|
||||
)
|
||||
} else {
|
||||
when (layout) {
|
||||
Settings.AppearanceSettings.Layout.PullDown -> {
|
||||
PullDownScaffold(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.graphicsLayer {
|
||||
scaleX = 0.5f + enterTransition.value * 0.5f
|
||||
scaleY = 0.5f + enterTransition.value * 0.5f
|
||||
alpha = enterTransition.value
|
||||
},
|
||||
darkStatusBarIcons = lightStatus,
|
||||
darkNavBarIcons = lightNav,
|
||||
)
|
||||
}
|
||||
Settings.AppearanceSettings.Layout.Pager,
|
||||
Settings.AppearanceSettings.Layout.PagerReversed -> {
|
||||
PagerScaffold(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.graphicsLayer {
|
||||
scaleX = enterTransition.value
|
||||
scaleY = enterTransition.value
|
||||
alpha = enterTransition.value
|
||||
},
|
||||
darkStatusBarIcons = lightStatus,
|
||||
darkNavBarIcons = lightNav,
|
||||
reverse = layout == Settings.AppearanceSettings.Layout.PagerReversed
|
||||
)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
Settings.AppearanceSettings.Layout.Pager,
|
||||
Settings.AppearanceSettings.Layout.PagerReversed -> {
|
||||
PagerScaffold(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.graphicsLayer {
|
||||
scaleX = enterTransition.value
|
||||
scaleY = enterTransition.value
|
||||
alpha = enterTransition.value
|
||||
},
|
||||
darkStatusBarIcons = lightStatus,
|
||||
darkNavBarIcons = lightNav,
|
||||
reverse = layout == Settings.AppearanceSettings.Layout.PagerReversed
|
||||
)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
SnackbarHost(
|
||||
snackbarHostState,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user