mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-25 22:47:23 +00:00
Remove unnecessary abstractions
This commit is contained in:
parent
b2bece9ef6
commit
a86d5b3e61
@ -66,7 +66,7 @@ abstract class BaseActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
resultCallbacks[requestCode]?.also {
|
resultCallbacks[requestCode]?.also {
|
||||||
resultCallbacks.remove(requestCode)
|
resultCallbacks.remove(requestCode)
|
||||||
it(this@BaseActivity, if (success) 1 else -1, null)
|
it(this, if (success) 1 else -1, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ abstract class BaseActivity : AppCompatActivity() {
|
|||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
resultCallbacks[requestCode]?.also {
|
resultCallbacks[requestCode]?.also {
|
||||||
resultCallbacks.remove(requestCode)
|
resultCallbacks.remove(requestCode)
|
||||||
it(this@BaseActivity, resultCode, data)
|
it(this, resultCode, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.model.events
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
|
||||||
|
|
||||||
interface ContextExecutor {
|
|
||||||
|
|
||||||
operator fun invoke(context: Context)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ActivityExecutor {
|
|
||||||
|
|
||||||
operator fun invoke(activity: BaseActivity)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FragmentExecutor {
|
|
||||||
|
|
||||||
operator fun invoke(fragment: Fragment)
|
|
||||||
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.model.events
|
|
||||||
|
|
||||||
internal interface EventHandler {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called for all [ViewEvent]s published by associated viewModel.
|
|
||||||
* For [SimpleViewEvent]s, both this and [onSimpleEventDispatched]
|
|
||||||
* methods are called - you can choose the way how you handle them.
|
|
||||||
*/
|
|
||||||
fun onEventDispatched(event: ViewEvent) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called for all [SimpleViewEvent]s published by associated viewModel.
|
|
||||||
* Both this and [onEventDispatched] methods are called - you can choose
|
|
||||||
* the way how you handle them.
|
|
||||||
*/
|
|
||||||
fun onSimpleEventDispatched(event: Int) {}
|
|
||||||
|
|
||||||
val viewEventObserver get() = ViewEventObserver {
|
|
||||||
onEventDispatched(it)
|
|
||||||
if (it is SimpleViewEvent) {
|
|
||||||
onSimpleEventDispatched(it.event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.model.events
|
|
||||||
|
|
||||||
class SimpleViewEvent(
|
|
||||||
val event: Int
|
|
||||||
) : ViewEvent()
|
|
@ -3,6 +3,7 @@ package com.topjohnwu.magisk.model.events
|
|||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.core.Const
|
import com.topjohnwu.magisk.core.Const
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
@ -32,7 +33,6 @@ import java.lang.reflect.InvocationHandler
|
|||||||
* Use [ViewEventObserver] for observing these events
|
* Use [ViewEventObserver] for observing these events
|
||||||
*/
|
*/
|
||||||
abstract class ViewEvent {
|
abstract class ViewEvent {
|
||||||
|
|
||||||
var handled = false
|
var handled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +40,18 @@ abstract class ViewEventsWithScope: ViewEvent() {
|
|||||||
lateinit var scope: CoroutineScope
|
lateinit var scope: CoroutineScope
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ContextExecutor {
|
||||||
|
operator fun invoke(context: Context)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ActivityExecutor {
|
||||||
|
operator fun invoke(activity: BaseActivity)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FragmentExecutor {
|
||||||
|
operator fun invoke(fragment: Fragment)
|
||||||
|
}
|
||||||
|
|
||||||
class CheckSafetyNetEvent(
|
class CheckSafetyNetEvent(
|
||||||
private val callback: (SafetyNetResult) -> Unit = {}
|
private val callback: (SafetyNetResult) -> Unit = {}
|
||||||
) : ViewEventsWithScope(), ContextExecutor, KoinComponent, SafetyNetHelper.Callback {
|
) : ViewEventsWithScope(), ContextExecutor, KoinComponent, SafetyNetHelper.Callback {
|
||||||
@ -146,7 +158,7 @@ class CheckSafetyNetEvent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ViewActionEvent(val action: BaseActivity.() -> Unit) : ViewEvent(), ActivityExecutor {
|
class ViewActionEvent(val action: BaseActivity.() -> Unit) : ViewEvent(), ActivityExecutor {
|
||||||
override fun invoke(activity: BaseActivity) = activity.run(action)
|
override fun invoke(activity: BaseActivity) = action(activity)
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpenChangelogEvent(val item: Repo) : ViewEventsWithScope(), ContextExecutor {
|
class OpenChangelogEvent(val item: Repo) : ViewEventsWithScope(), ContextExecutor {
|
||||||
|
@ -7,26 +7,23 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.core.content.res.use
|
import androidx.core.content.res.use
|
||||||
import androidx.core.graphics.Insets
|
|
||||||
import androidx.databinding.DataBindingUtil
|
import androidx.databinding.DataBindingUtil
|
||||||
import androidx.databinding.OnRebindCallback
|
import androidx.databinding.OnRebindCallback
|
||||||
import androidx.databinding.ViewDataBinding
|
import androidx.databinding.ViewDataBinding
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.Observer
|
|
||||||
import androidx.navigation.NavDirections
|
import androidx.navigation.NavDirections
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.core.Config
|
import com.topjohnwu.magisk.core.Config
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
import com.topjohnwu.magisk.ktx.snackbar
|
|
||||||
import com.topjohnwu.magisk.ktx.startAnimations
|
import com.topjohnwu.magisk.ktx.startAnimations
|
||||||
import com.topjohnwu.magisk.model.events.EventHandler
|
import com.topjohnwu.magisk.model.events.ActivityExecutor
|
||||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
import com.topjohnwu.magisk.model.events.ContextExecutor
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||||
import com.topjohnwu.magisk.ui.theme.Theme
|
import com.topjohnwu.magisk.ui.theme.Theme
|
||||||
|
|
||||||
abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBinding> :
|
abstract class BaseUIActivity<VM : BaseViewModel, Binding : ViewDataBinding> :
|
||||||
BaseActivity(), CompatView<ViewModel>, EventHandler {
|
BaseActivity(), BaseUIComponent<VM> {
|
||||||
|
|
||||||
protected lateinit var binding: Binding
|
protected lateinit var binding: Binding
|
||||||
protected abstract val layoutRes: Int
|
protected abstract val layoutRes: Int
|
||||||
@ -37,12 +34,10 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
|
|||||||
protected val currentFragment get() = topFragment as? BaseUIFragment<*, *>
|
protected val currentFragment get() = topFragment as? BaseUIFragment<*, *>
|
||||||
|
|
||||||
override val viewRoot: View get() = binding.root
|
override val viewRoot: View get() = binding.root
|
||||||
override val navigation by lazy {
|
open val navigation by lazy {
|
||||||
kotlin.runCatching { findNavController(navHost) }.getOrNull()
|
runCatching { findNavController(navHost) }.getOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val delegate by lazy { CompatDelegate(this) }
|
|
||||||
|
|
||||||
open val navHost: Int = 0
|
open val navHost: Int = 0
|
||||||
open val snackbarView get() = binding.root
|
open val snackbarView get() = binding.root
|
||||||
|
|
||||||
@ -66,35 +61,33 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
|
|||||||
.also { window.setBackgroundDrawable(it) }
|
.also { window.setBackgroundDrawable(it) }
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
startObserveEvents()
|
||||||
|
|
||||||
viewModel.viewEvents.observe(this, viewEventObserver)
|
binding = DataBindingUtil.setContentView<Binding>(this, layoutRes).also {
|
||||||
|
it.setVariable(BR.viewModel, viewModel)
|
||||||
binding = DataBindingUtil.setContentView<Binding>(this, layoutRes).apply {
|
it.lifecycleOwner = this
|
||||||
setVariable(BR.viewModel, viewModel)
|
it.addOnRebindCallback(object : OnRebindCallback<Binding>() {
|
||||||
lifecycleOwner = this@BaseUIActivity
|
override fun onPreBind(binding: Binding): Boolean {
|
||||||
|
(binding.root as? ViewGroup)?.startAnimations()
|
||||||
|
return super.onPreBind(binding)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.addOnRebindCallback(object : OnRebindCallback<Binding>() {
|
ensureInsets()
|
||||||
override fun onPreBind(binding: Binding): Boolean {
|
|
||||||
(binding.root as? ViewGroup)?.startAnimations()
|
|
||||||
return super.onPreBind(binding)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
delegate.onCreate()
|
directionsDispatcher.observe(this) {
|
||||||
|
|
||||||
directionsDispatcher.observe(this, Observer {
|
|
||||||
it?.navigate()
|
it?.navigate()
|
||||||
// we don't want the directions to be re-dispatched, so we preemptively set them to null
|
// we don't want the directions to be re-dispatched, so we preemptively set them to null
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
directionsDispatcher.value = null
|
directionsDispatcher.value = null
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
delegate.onResume()
|
viewModel.requestRefresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||||
@ -102,10 +95,8 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onEventDispatched(event: ViewEvent) {
|
override fun onEventDispatched(event: ViewEvent) {
|
||||||
delegate.onEventExecute(event, this)
|
(event as? ContextExecutor)?.invoke(this)
|
||||||
when (event) {
|
(event as? ActivityExecutor)?.invoke(this)
|
||||||
is SnackbarEvent -> snackbar(snackbarView, event.message(this), event.length, event.f)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
@ -114,12 +105,6 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun peekSystemWindowInsets(insets: Insets) {
|
|
||||||
viewModel.insets = insets
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun ViewEvent.dispatchOnSelf() = onEventDispatched(this)
|
|
||||||
|
|
||||||
fun NavDirections.navigate() {
|
fun NavDirections.navigate() {
|
||||||
navigation?.navigate(this)
|
navigation?.navigate(this)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.topjohnwu.magisk.ui.base
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.core.graphics.Insets
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.lifecycle.LifecycleOwner
|
||||||
|
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||||
|
|
||||||
|
interface BaseUIComponent<VM : BaseViewModel>: LifecycleOwner {
|
||||||
|
|
||||||
|
val viewRoot: View
|
||||||
|
val viewModel: VM
|
||||||
|
|
||||||
|
fun startObserveEvents() {
|
||||||
|
viewModel.viewEvents.observe(this) {
|
||||||
|
onEventDispatched(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun consumeSystemWindowInsets(insets: Insets): Insets? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called for all [ViewEvent]s published by associated viewModel.
|
||||||
|
*/
|
||||||
|
fun onEventDispatched(event: ViewEvent) {}
|
||||||
|
|
||||||
|
fun ensureInsets() {
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(viewRoot) { _, insets ->
|
||||||
|
insets.asInsets()
|
||||||
|
.also { viewModel.insets = it }
|
||||||
|
.let { consumeSystemWindowInsets(it) }
|
||||||
|
?.subtractBy(insets) ?: insets
|
||||||
|
}
|
||||||
|
if (ViewCompat.isAttachedToWindow(viewRoot)) {
|
||||||
|
ViewCompat.requestApplyInsets(viewRoot)
|
||||||
|
} else {
|
||||||
|
viewRoot.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
|
||||||
|
override fun onViewDetachedFromWindow(v: View) = Unit
|
||||||
|
override fun onViewAttachedToWindow(v: View) {
|
||||||
|
ViewCompat.requestApplyInsets(v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun WindowInsetsCompat.asInsets() = Insets.of(
|
||||||
|
systemWindowInsetLeft,
|
||||||
|
systemWindowInsetTop,
|
||||||
|
systemWindowInsetRight,
|
||||||
|
systemWindowInsetBottom
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun Insets.subtractBy(insets: WindowInsetsCompat) =
|
||||||
|
WindowInsetsCompat.Builder(insets).setSystemWindowInsets(
|
||||||
|
Insets.of(
|
||||||
|
insets.systemWindowInsetLeft - left,
|
||||||
|
insets.systemWindowInsetTop - top,
|
||||||
|
insets.systemWindowInsetRight - right,
|
||||||
|
insets.systemWindowInsetBottom - bottom
|
||||||
|
)
|
||||||
|
).build()
|
||||||
|
|
||||||
|
}
|
@ -13,25 +13,26 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.navigation.NavDirections
|
import androidx.navigation.NavDirections
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.ktx.startAnimations
|
import com.topjohnwu.magisk.ktx.startAnimations
|
||||||
import com.topjohnwu.magisk.model.events.EventHandler
|
import com.topjohnwu.magisk.model.events.ActivityExecutor
|
||||||
|
import com.topjohnwu.magisk.model.events.ContextExecutor
|
||||||
|
import com.topjohnwu.magisk.model.events.FragmentExecutor
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||||
|
|
||||||
abstract class BaseUIFragment<ViewModel : BaseViewModel, Binding : ViewDataBinding> :
|
abstract class BaseUIFragment<VM : BaseViewModel, Binding : ViewDataBinding> :
|
||||||
Fragment(), CompatView<ViewModel>, EventHandler {
|
Fragment(), BaseUIComponent<VM> {
|
||||||
|
|
||||||
protected val activity get() = requireActivity() as BaseUIActivity<*, *>
|
protected val activity get() = requireActivity() as BaseUIActivity<*, *>
|
||||||
protected lateinit var binding: Binding
|
protected lateinit var binding: Binding
|
||||||
protected abstract val layoutRes: Int
|
protected abstract val layoutRes: Int
|
||||||
|
|
||||||
override val viewRoot: View get() = binding.root
|
override val viewRoot: View get() = binding.root
|
||||||
override val navigation get() = activity.navigation
|
private val navigation get() = activity.navigation
|
||||||
private val delegate by lazy { CompatDelegate(this) }
|
|
||||||
|
|
||||||
override fun consumeSystemWindowInsets(insets: Insets) = insets
|
override fun consumeSystemWindowInsets(insets: Insets) = insets
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
viewModel.viewEvents.observe(this, viewEventObserver)
|
startObserveEvents()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
@ -39,17 +40,17 @@ abstract class BaseUIFragment<ViewModel : BaseViewModel, Binding : ViewDataBindi
|
|||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = DataBindingUtil.inflate<Binding>(inflater, layoutRes, container, false).apply {
|
binding = DataBindingUtil.inflate<Binding>(inflater, layoutRes, container, false).also {
|
||||||
setVariable(BR.viewModel, viewModel)
|
it.setVariable(BR.viewModel, viewModel)
|
||||||
lifecycleOwner = this@BaseUIFragment
|
it.lifecycleOwner = this
|
||||||
}
|
}
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEventDispatched(event: ViewEvent) {
|
override fun onEventDispatched(event: ViewEvent) {
|
||||||
super.onEventDispatched(event)
|
(event as? ContextExecutor)?.invoke(requireContext())
|
||||||
delegate.onEventExecute(event, this)
|
(event as? FragmentExecutor)?.invoke(this)
|
||||||
|
(event as? ActivityExecutor)?.invoke(activity)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun onKeyEvent(event: KeyEvent): Boolean {
|
open fun onKeyEvent(event: KeyEvent): Boolean {
|
||||||
@ -61,29 +62,24 @@ abstract class BaseUIFragment<ViewModel : BaseViewModel, Binding : ViewDataBindi
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
binding.addOnRebindCallback(object : OnRebindCallback<Binding>() {
|
binding.addOnRebindCallback(object : OnRebindCallback<Binding>() {
|
||||||
override fun onPreBind(binding: Binding): Boolean {
|
override fun onPreBind(binding: Binding): Boolean {
|
||||||
this@BaseUIFragment.onPreBind(binding)
|
this@BaseUIFragment.onPreBind(binding)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
ensureInsets()
|
||||||
delegate.onCreate()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
viewModel.requestRefresh()
|
||||||
delegate.onResume()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun onPreBind(binding: Binding) {
|
protected open fun onPreBind(binding: Binding) {
|
||||||
(binding.root as? ViewGroup)?.startAnimations()
|
(binding.root as? ViewGroup)?.startAnimations()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun ViewEvent.dispatchOnSelf() = delegate.onEventExecute(this, this@BaseUIFragment)
|
|
||||||
|
|
||||||
fun NavDirections.navigate() {
|
fun NavDirections.navigate() {
|
||||||
navigation?.navigate(this)
|
navigation?.navigate(this)
|
||||||
}
|
}
|
||||||
|
@ -107,10 +107,6 @@ abstract class BaseViewModel(
|
|||||||
_viewEvents.postValue(this)
|
_viewEvents.postValue(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Int.publish() {
|
|
||||||
_viewEvents.postValue(SimpleViewEvent(this))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun NavDirections.publish() {
|
fun NavDirections.publish() {
|
||||||
_viewEvents.postValue(NavigationWrapper(this))
|
_viewEvents.postValue(NavigationWrapper(this))
|
||||||
}
|
}
|
||||||
|
@ -1,75 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.ui.base
|
|
||||||
|
|
||||||
import android.view.View
|
|
||||||
import androidx.core.graphics.Insets
|
|
||||||
import androidx.core.view.ViewCompat
|
|
||||||
import androidx.core.view.WindowInsetsCompat
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import com.topjohnwu.magisk.model.events.ActivityExecutor
|
|
||||||
import com.topjohnwu.magisk.model.events.ContextExecutor
|
|
||||||
import com.topjohnwu.magisk.model.events.FragmentExecutor
|
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
|
|
||||||
class CompatDelegate internal constructor(
|
|
||||||
private val view: CompatView<*>
|
|
||||||
) {
|
|
||||||
|
|
||||||
fun onCreate() {
|
|
||||||
ensureInsets()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onResume() {
|
|
||||||
view.viewModel.requestRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onEventExecute(event: ViewEvent, activity: BaseUIActivity<*, *>) {
|
|
||||||
(event as? ContextExecutor)?.invoke(activity)
|
|
||||||
(event as? ActivityExecutor)?.invoke(activity)
|
|
||||||
(event as? FragmentExecutor)?.let {
|
|
||||||
Timber.e("Cannot run ${FragmentExecutor::class.java.simpleName} in Activity. Consider adding ${ContextExecutor::class.java.simpleName} as fallback.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onEventExecute(event: ViewEvent, fragment: Fragment) {
|
|
||||||
(event as? ContextExecutor)?.invoke(fragment.requireContext())
|
|
||||||
(event as? FragmentExecutor)?.invoke(fragment)
|
|
||||||
(event as? ActivityExecutor)?.invoke(fragment.requireActivity() as BaseUIActivity<*, *>)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ensureInsets() {
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(view.viewRoot) { _, insets ->
|
|
||||||
insets.asInsets()
|
|
||||||
.also { view.peekSystemWindowInsets(it) }
|
|
||||||
.let { view.consumeSystemWindowInsets(it) }
|
|
||||||
?.also { view.viewModel.insets = it }
|
|
||||||
?.subtractBy(insets) ?: insets
|
|
||||||
}
|
|
||||||
if (ViewCompat.isAttachedToWindow(view.viewRoot)) {
|
|
||||||
ViewCompat.requestApplyInsets(view.viewRoot)
|
|
||||||
} else {
|
|
||||||
view.viewRoot.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
|
|
||||||
override fun onViewDetachedFromWindow(v: View) = Unit
|
|
||||||
override fun onViewAttachedToWindow(v: View) {
|
|
||||||
ViewCompat.requestApplyInsets(v)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun WindowInsetsCompat.asInsets() = Insets.of(
|
|
||||||
systemWindowInsetLeft,
|
|
||||||
systemWindowInsetTop,
|
|
||||||
systemWindowInsetRight,
|
|
||||||
systemWindowInsetBottom
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun Insets.subtractBy(insets: WindowInsetsCompat) = insets.replaceSystemWindowInsets(
|
|
||||||
insets.systemWindowInsetLeft - left,
|
|
||||||
insets.systemWindowInsetTop - top,
|
|
||||||
insets.systemWindowInsetRight - right,
|
|
||||||
insets.systemWindowInsetBottom - bottom
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.ui.base
|
|
||||||
|
|
||||||
import android.view.View
|
|
||||||
import androidx.core.graphics.Insets
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
|
|
||||||
internal interface CompatView<ViewModel : BaseViewModel> {
|
|
||||||
|
|
||||||
val viewRoot: View
|
|
||||||
val viewModel: ViewModel
|
|
||||||
val navigation: NavController?
|
|
||||||
|
|
||||||
fun peekSystemWindowInsets(insets: Insets) = Unit
|
|
||||||
fun consumeSystemWindowInsets(insets: Insets): Insets? = null
|
|
||||||
|
|
||||||
}
|
|
@ -12,9 +12,6 @@ import com.topjohnwu.magisk.R
|
|||||||
import com.topjohnwu.magisk.core.su.SuCallbackHandler
|
import com.topjohnwu.magisk.core.su.SuCallbackHandler
|
||||||
import com.topjohnwu.magisk.core.su.SuCallbackHandler.REQUEST
|
import com.topjohnwu.magisk.core.su.SuCallbackHandler.REQUEST
|
||||||
import com.topjohnwu.magisk.databinding.ActivityRequestBinding
|
import com.topjohnwu.magisk.databinding.ActivityRequestBinding
|
||||||
import com.topjohnwu.magisk.model.events.DieEvent
|
|
||||||
import com.topjohnwu.magisk.model.events.ViewActionEvent
|
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
|
||||||
@ -22,7 +19,6 @@ open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityReques
|
|||||||
|
|
||||||
override val layoutRes: Int = R.layout.activity_request
|
override val layoutRes: Int = R.layout.activity_request
|
||||||
override val viewModel: SuRequestViewModel by viewModel()
|
override val viewModel: SuRequestViewModel by viewModel()
|
||||||
|
|
||||||
override val navigation: NavController? = null
|
override val navigation: NavController? = null
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
@ -65,14 +61,6 @@ open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityReques
|
|||||||
return theme
|
return theme
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEventDispatched(event: ViewEvent) {
|
|
||||||
super.onEventDispatched(event)
|
|
||||||
when (event) {
|
|
||||||
is ViewActionEvent -> event.action(this)
|
|
||||||
is DieEvent -> finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun lockOrientation() {
|
private fun lockOrientation() {
|
||||||
requestedOrientation = if (Build.VERSION.SDK_INT < 18)
|
requestedOrientation = if (Build.VERSION.SDK_INT < 18)
|
||||||
resources.configuration.orientation
|
resources.configuration.orientation
|
||||||
|
Loading…
x
Reference in New Issue
Block a user