Migrate hidden items panel to Jetpack Compose

This commit is contained in:
MM20 2022-02-18 23:35:41 +01:00
parent 6b59aa5118
commit 5e18d25335
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
3 changed files with 101 additions and 61 deletions

View File

@ -9,8 +9,10 @@ import android.view.View
import androidx.activity.viewModels
import androidx.core.view.*
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewTreeLifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.savedstate.ViewTreeSavedStateRegistryOwner
import com.afollestad.materialdialogs.LayoutMode
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
@ -107,22 +109,20 @@ class LauncherActivity : BaseActivity() {
}
}
var hiddenItemsDialog: MaterialDialog? = null
var hiddenItemsView: HiddenItemsView? = null
viewModel.isHiddenItemsShown.observe(this) {
if (it) {
val view = HiddenItemsView(this)
hiddenItemsDialog = MaterialDialog(this, BottomSheet(LayoutMode.MATCH_PARENT))
.show {
title(R.string.menu_hidden_items)
customView(view = view)
negativeButton(R.string.close) { dismiss() }
onDismiss {
viewModel.hideHiddenItems()
}
if (hiddenItemsView != null) return@observe
hiddenItemsView = HiddenItemsView(this).apply {
onDismiss = {
viewModel.hideHiddenItems()
}
}
binding.rootView.addView(hiddenItemsView)
} else {
hiddenItemsDialog?.dismiss()
hiddenItemsDialog = null
if (hiddenItemsView == null) return@observe
binding.rootView.removeView(hiddenItemsView)
hiddenItemsView = null
}
}

View File

@ -13,13 +13,5 @@ import org.koin.core.component.inject
class HiddenItemsVM: ViewModel(), KoinComponent {
private val repository: FavoritesRepository by inject()
val hiddenItems = MutableLiveData<List<Searchable>>(emptyList())
suspend fun onActive() {
withContext(Dispatchers.IO) {
repository.getHiddenItems().collectLatest {
hiddenItems.postValue(it)
}
}
}
val hiddenItems = repository.getHiddenItems()
}

View File

@ -2,56 +2,104 @@ package de.mm20.launcher2.ui.launcher.modals
import android.content.Context
import android.util.AttributeSet
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.setMargins
import androidx.core.widget.NestedScrollView
import de.mm20.launcher2.ktx.dp
import de.mm20.launcher2.ktx.lifecycleScope
import de.mm20.launcher2.ui.legacy.search.SearchGridView
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.slideIn
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
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.platform.ComposeView
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 de.mm20.launcher2.ui.MdcLauncherTheme
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.base.ProvideSettings
import de.mm20.launcher2.ui.launcher.search.common.SearchResultGrid
@OptIn(ExperimentalComposeUiApi::class)
class HiddenItemsView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : NestedScrollView(context, attrs) {
) : FrameLayout(context, attrs) {
private val viewModel: HiddenItemsVM by (context as AppCompatActivity).viewModels()
init {
clipChildren = false
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
val hiddenItemsGrid = SearchGridView(context)
hiddenItemsGrid.layoutParams = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
).apply {
setMargins((8 * dp).toInt())
val composeView = ComposeView(context)
composeView.setContent {
MdcLauncherTheme {
ProvideSettings {
Dialog(
properties = DialogProperties(usePlatformDefaultWidth = false),
onDismissRequest = { onDismiss() }) {
val animationState = remember {
MutableTransitionState(false).apply {
targetState = true
}
}
AnimatedVisibility(
animationState,
enter = slideIn { IntOffset(0, it.height) }
) {
Surface(modifier = Modifier.fillMaxSize()) {
Column(
modifier = Modifier
.fillMaxSize()
) {
Text(
stringResource(R.string.menu_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),
style = MaterialTheme.typography.labelLarge
)
}
}
}
}
}
}
}
}
}
val hiddenItems = viewModel.hiddenItems
hiddenItems.observe(context as AppCompatActivity) {
hiddenItemsGrid.submitItems(it)
}
addView(hiddenItemsGrid)
addView(composeView)
}
private var job: Job? = null
override fun onAttachedToWindow() {
super.onAttachedToWindow()
val job = Job()
this.job = job
lifecycleScope.launch(job) {
viewModel.onActive()
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
job?.cancel()
}
var onDismiss: () -> Unit = {}
}