From 9bdac79b209e603e509435c1362a5e0120e228d5 Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Sun, 29 May 2022 20:05:39 +0200 Subject: [PATCH] Bring back hidden items bottom sheet --- .../launcher2/ui/launcher/LauncherActivity.kt | 8 ++ .../ui/launcher/LauncherActivityVM.kt | 9 ++ .../ui/launcher/modals/HiddenItemsSheet.kt | 116 ++++++++++++++++++ .../ui/launcher/modals/HiddenItemsSheetVM.kt | 17 +++ .../ui/launcher/search/SearchColumn.kt | 25 +--- 5 files changed, 153 insertions(+), 22 deletions(-) create mode 100644 ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/HiddenItemsSheet.kt create mode 100644 ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/HiddenItemsSheetVM.kt diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivity.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivity.kt index 20107989..45a332cd 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivity.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivity.kt @@ -36,6 +36,7 @@ import de.mm20.launcher2.ui.base.ProvideSettings import de.mm20.launcher2.ui.component.NavBarEffects import de.mm20.launcher2.ui.ktx.animateTo import de.mm20.launcher2.ui.launcher.modals.EditFavoritesView +import de.mm20.launcher2.ui.launcher.modals.HiddenItemsSheet import de.mm20.launcher2.ui.launcher.transitions.HomeTransitionManager import de.mm20.launcher2.ui.launcher.transitions.LocalHomeTransitionManager import de.mm20.launcher2.ui.locals.LocalSnackbarHostState @@ -142,6 +143,13 @@ class LauncherActivity : BaseActivity() { .navigationBarsPadding() .imePadding() ) + + val showHiddenItems by viewModel.isHiddenItemsShown.observeAsState(false) + if (showHiddenItems) { + HiddenItemsSheet(onDismiss = { + viewModel.hideHiddenItems() + }) + } } } } diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivityVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivityVM.kt index 3be824c1..16b6ae0a 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivityVM.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivityVM.kt @@ -13,6 +13,7 @@ import org.koin.core.component.inject class LauncherActivityVM : ViewModel(), KoinComponent { private val dataStore: LauncherDataStore by inject() + val isHiddenItemsShown = MutableLiveData(false) val isEditFavoritesShown = MutableLiveData(false) private var isDarkInMode = MutableStateFlow(false) @@ -54,5 +55,13 @@ class LauncherActivityVM : ViewModel(), KoinComponent { isEditFavoritesShown.value = false } + fun showHiddenItems() { + isHiddenItemsShown.value = true + } + + fun hideHiddenItems() { + isHiddenItemsShown.value = false + } + val layout = dataStore.data.map { it.appearance.layout }.asLiveData() } \ No newline at end of file diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/HiddenItemsSheet.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/HiddenItemsSheet.kt new file mode 100644 index 00000000..077af104 --- /dev/null +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/HiddenItemsSheet.kt @@ -0,0 +1,116 @@ +package de.mm20.launcher2.ui.launcher.modals + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.MutableTransitionState +import androidx.compose.animation.slideIn +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.FractionalThreshold +import androidx.compose.material.rememberSwipeableState +import androidx.compose.material.swipeable +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import androidx.lifecycle.viewmodel.compose.viewModel +import de.mm20.launcher2.ui.R +import de.mm20.launcher2.ui.ktx.toPixels +import de.mm20.launcher2.ui.launcher.search.common.grid.SearchResultGrid +import kotlin.math.roundToInt + +@OptIn(ExperimentalComposeUiApi::class, ExperimentalMaterialApi::class) +@Composable +fun HiddenItemsSheet( + onDismiss: () -> Unit +) { + val viewModel: HiddenItemsSheetVM = viewModel() + + Dialog( + properties = DialogProperties(usePlatformDefaultWidth = false), + onDismissRequest = { onDismiss() }) { + val animationState = remember { + MutableTransitionState(false).apply { + targetState = true + } + } + + AnimatedVisibility( + animationState, + enter = slideIn { IntOffset(0, it.height) } + ) { + val swipeState = + rememberSwipeableState(initialValue = SwipeState.Default) { + if (it == SwipeState.Dismiss) onDismiss() + return@rememberSwipeableState true + } + Surface( + modifier = Modifier + .fillMaxSize() + .swipeable( + swipeState, + mapOf( + 0f to SwipeState.Default, + 600.dp.toPixels() to SwipeState.Dismiss + ), + orientation = Orientation.Vertical, + thresholds = { _, _ -> FractionalThreshold(0.5f) }, + ) + .offset { IntOffset(0, swipeState.offset.value.roundToInt()) } + + ) { + Column( + modifier = Modifier + .fillMaxSize() + ) { + Text( + stringResource(R.string.preference_hidden_items), + style = MaterialTheme.typography.titleLarge, + modifier = Modifier.padding(24.dp) + + ) + val items by viewModel.hiddenItems.collectAsState(emptyList()) + SearchResultGrid( + items, + modifier = Modifier + .weight(1f) + .padding(8.dp) + .verticalScroll(rememberScrollState()) + ) + Box( + modifier = Modifier + .fillMaxWidth() + .padding(12.dp), + contentAlignment = Alignment.CenterEnd + ) { + TextButton(onClick = { onDismiss() }) { + Text( + stringResource(id = R.string.close), + ) + } + } + } + } + } + + } + +} + +private enum class SwipeState { + Default, Dismiss +} \ No newline at end of file diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/HiddenItemsSheetVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/HiddenItemsSheetVM.kt new file mode 100644 index 00000000..6f56e7dc --- /dev/null +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/HiddenItemsSheetVM.kt @@ -0,0 +1,17 @@ +package de.mm20.launcher2.ui.launcher.modals + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import de.mm20.launcher2.favorites.FavoritesRepository +import de.mm20.launcher2.search.data.Searchable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.withContext +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject + +class HiddenItemsSheetVM: ViewModel(), KoinComponent { + private val repository: FavoritesRepository by inject() + + val hiddenItems = repository.getHiddenItems() +} \ No newline at end of file diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt index 5716fd30..691c6571 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt @@ -1,10 +1,8 @@ package de.mm20.launcher2.ui.launcher.search -import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Settings import androidx.compose.material.icons.rounded.VisibilityOff import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon @@ -16,6 +14,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel +import de.mm20.launcher2.ui.launcher.LauncherActivityVM import de.mm20.launcher2.ui.launcher.search.apps.AppResults import de.mm20.launcher2.ui.launcher.search.appshortcuts.AppShortcutResults import de.mm20.launcher2.ui.launcher.search.calculator.CalculatorResults @@ -55,14 +54,14 @@ fun SearchColumn( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.End ) { - val viewModel: SearchVM = viewModel() + val viewModel: LauncherActivityVM = viewModel() val context = LocalContext.current Surface( shadowElevation = 2.dp, color = MaterialTheme.colorScheme.secondaryContainer, contentColor = MaterialTheme.colorScheme.onSecondaryContainer, shape = CircleShape, - onClick = { viewModel.showHiddenItems(context) } + onClick = { viewModel.showHiddenItems() } ) { Box( modifier = Modifier.padding(12.dp), @@ -74,24 +73,6 @@ fun SearchColumn( } } - Spacer(modifier = Modifier.width(16.dp)) - Surface( - shadowElevation = 2.dp, - color = MaterialTheme.colorScheme.secondaryContainer, - contentColor = MaterialTheme.colorScheme.onSecondaryContainer, - shape = CircleShape, - onClick = { viewModel.openSearchSettings(context) } - ) { - Box( - modifier = Modifier.padding(12.dp), - ) { - Icon( - imageVector = Icons.Rounded.Settings, - contentDescription = null, - ) - } - - } } } } \ No newline at end of file