mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-12-31 10:07:17 +00:00
Updated hide fragment with more robust filtering UI
This commit is contained in:
@@ -2,9 +2,8 @@ package com.topjohnwu.magisk.redesign.hide
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Insets
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.FragmentHideMd2Binding
|
||||
import com.topjohnwu.magisk.redesign.compat.CompatFragment
|
||||
@@ -20,16 +19,14 @@ class HideFragment : CompatFragment<HideViewModel, FragmentHideMd2Binding>() {
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
activity.setTitle(R.string.magiskhide)
|
||||
setHasOptionsMenu(true)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_hide_md2, menu)
|
||||
menu.findItem(R.id.action_show_system)?.isChecked = viewModel.isShowSystem
|
||||
}
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return viewModel.menuItemPressed(item)
|
||||
binding.hideActionScrollUp.setOnClickListener {
|
||||
binding.hideScrollContainer.fullScroll(View.FOCUS_UP)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
package com.topjohnwu.magisk.redesign.hide
|
||||
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.view.MenuItem
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import androidx.databinding.Bindable
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.subscribeK
|
||||
import com.topjohnwu.magisk.extensions.toggle
|
||||
import com.topjohnwu.magisk.model.entity.HideAppInfo
|
||||
import com.topjohnwu.magisk.model.entity.HideTarget
|
||||
import com.topjohnwu.magisk.model.entity.ProcessHideApp
|
||||
@@ -19,18 +21,31 @@ import com.topjohnwu.magisk.utils.DiffObservableList
|
||||
import com.topjohnwu.magisk.utils.FilterableDiffObservableList
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
import com.topjohnwu.magisk.utils.currentLocale
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
|
||||
class HideViewModel(
|
||||
private val magiskRepo: MagiskRepository
|
||||
) : CompatViewModel() {
|
||||
|
||||
private val queryHandler = Handler(Looper.getMainLooper())
|
||||
private val queryRunnable = Runnable { query() }
|
||||
|
||||
var isShowSystem = false
|
||||
@Bindable get
|
||||
set(value) {
|
||||
field = value
|
||||
notifyPropertyChanged(BR.showSystem)
|
||||
query()
|
||||
}
|
||||
|
||||
val query = KObservableField("")
|
||||
var query = ""
|
||||
@Bindable get
|
||||
set(value) {
|
||||
field = value
|
||||
notifyPropertyChanged(BR.query)
|
||||
submitQuery()
|
||||
}
|
||||
val items = filterableListOf<HideItem>()
|
||||
val itemBinding = itemBindingOf<HideItem> {
|
||||
it.bindExtra(BR.viewModel, this)
|
||||
@@ -39,6 +54,8 @@ class HideViewModel(
|
||||
it.bindExtra(BR.viewModel, this)
|
||||
}
|
||||
|
||||
val isFilterExpanded = KObservableField(false)
|
||||
|
||||
override fun refresh() = magiskRepo.fetchApps()
|
||||
.map { it to magiskRepo.fetchHideTargets().blockingGet() }
|
||||
.map { pair -> pair.first.map { mergeAppTargets(it, pair.second) } }
|
||||
@@ -70,8 +87,13 @@ class HideViewModel(
|
||||
|
||||
// ---
|
||||
|
||||
private fun submitQuery() {
|
||||
queryHandler.removeCallbacks(queryRunnable)
|
||||
queryHandler.postDelayed(queryRunnable, 1000)
|
||||
}
|
||||
|
||||
private fun query(
|
||||
query: String = this.query.value,
|
||||
query: String = this.query,
|
||||
showSystem: Boolean = isShowSystem
|
||||
) = items.filter {
|
||||
fun filterSystem(): Boolean {
|
||||
@@ -90,18 +112,22 @@ class HideViewModel(
|
||||
|
||||
// ---
|
||||
|
||||
fun menuItemPressed(menuItem: MenuItem) = when (menuItem.itemId) {
|
||||
R.id.action_show_system -> isShowSystem = (!menuItem.isChecked)
|
||||
.also { menuItem.isChecked = it }
|
||||
else -> null
|
||||
}?.let { true } ?: false
|
||||
|
||||
fun toggleItem(item: HideProcessItem) = magiskRepo
|
||||
.toggleHide(item.isHidden.value, item.item.packageName, item.item.name)
|
||||
// might wanna reorder the list to display the item at the top
|
||||
.subscribeK()
|
||||
.add()
|
||||
|
||||
fun toggle(item: KObservableField<Boolean>) = item.toggle()
|
||||
|
||||
fun resetQuery() {
|
||||
query = ""
|
||||
}
|
||||
|
||||
fun hideFilter() {
|
||||
isFilterExpanded.value = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline fun <T : ComparableRvItem<T>> filterableListOf(
|
||||
|
||||
@@ -15,6 +15,7 @@ import androidx.appcompat.widget.AppCompatImageView
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.animation.doOnEnd
|
||||
import androidx.core.view.*
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.databinding.BindingAdapter
|
||||
import androidx.databinding.InverseBindingAdapter
|
||||
import androidx.databinding.InverseBindingListener
|
||||
@@ -26,6 +27,7 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.google.android.material.navigation.NavigationView
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
@@ -410,4 +412,21 @@ fun Toolbar.setOnMenuClickListener(listener: Toolbar.OnMenuItemClickListener) {
|
||||
@BindingAdapter("tooltipText")
|
||||
fun View.setTooltipTextCompat(text: String) {
|
||||
ViewCompat.setTooltipText(this, text)
|
||||
}
|
||||
|
||||
@BindingAdapter("onCloseClicked")
|
||||
fun Chip.setOnCloseClickedListenerBinding(listener: View.OnClickListener) {
|
||||
setOnCloseIconClickListener(listener)
|
||||
}
|
||||
|
||||
@BindingAdapter("onScrollStateChanged")
|
||||
fun NestedScrollView.setOnScrollStateChangeListener(listener: Runnable) {
|
||||
setOnScrollChangeListener { _: NestedScrollView?, _: Int, _: Int, _: Int, _: Int ->
|
||||
if (!handler.hasCallbacks(listener)) {
|
||||
listener.run()
|
||||
} else {
|
||||
handler.removeCallbacksAndMessages(null)
|
||||
}
|
||||
handler.postDelayed(listener, 1000)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user