Cleanup arch classes

This commit is contained in:
topjohnwu 2022-01-22 14:42:34 -08:00
parent bf8b74e996
commit 8eac6c0b48
23 changed files with 85 additions and 86 deletions

View File

@ -13,14 +13,12 @@ import androidx.navigation.NavDirections
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.ktx.startAnimations
abstract class BaseUIFragment<VM : BaseViewModel, Binding : ViewDataBinding> :
Fragment(), BaseUIComponent<VM> {
abstract class BaseFragment<Binding : ViewDataBinding> : Fragment(), ViewModelHolder {
val activity get() = requireActivity() as BaseUIActivity<*, *>
val activity get() = requireActivity() as NavigationActivity<*>
protected lateinit var binding: Binding
protected abstract val layoutRes: Int
override val viewRoot: View get() = binding.root
private val navigation get() = activity.navigation
open val snackbarAnchorView: View? get() = null
@ -64,7 +62,7 @@ abstract class BaseUIFragment<VM : BaseViewModel, Binding : ViewDataBinding> :
super.onViewCreated(view, savedInstanceState)
binding.addOnRebindCallback(object : OnRebindCallback<Binding>() {
override fun onPreBind(binding: Binding): Boolean {
this@BaseUIFragment.onPreBind(binding)
this@BaseFragment.onPreBind(binding)
return true
}
})

View File

@ -21,8 +21,7 @@ import com.topjohnwu.superuser.Shell
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
abstract class BaseMainActivity<VM : BaseViewModel, Binding : ViewDataBinding>
: BaseUIActivity<VM, Binding>() {
abstract class BaseMainActivity<Binding : ViewDataBinding> : NavigationActivity<Binding>() {
companion object {
private var doPreload = true

View File

@ -0,0 +1,35 @@
package com.topjohnwu.magisk.arch
import android.view.KeyEvent
import androidx.databinding.ViewDataBinding
import androidx.navigation.NavController
import androidx.navigation.NavDirections
import androidx.navigation.fragment.NavHostFragment
abstract class NavigationActivity<Binding : ViewDataBinding> : UIActivity<Binding>() {
abstract val navHostId: Int
private val navHostFragment by lazy {
supportFragmentManager.findFragmentById(navHostId) as NavHostFragment
}
protected val currentFragment get() =
navHostFragment.childFragmentManager.fragments.getOrNull(0) as? BaseFragment<*>
val navigation: NavController get() = navHostFragment.navController
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
return currentFragment?.onKeyEvent(event) == true || super.dispatchKeyEvent(event)
}
override fun onBackPressed() {
if (currentFragment?.onBackPressed()?.not() == true) {
super.onBackPressed()
}
}
fun NavDirections.navigate() {
navigation.navigate(this)
}
}

View File

@ -4,37 +4,22 @@ import android.content.res.Resources
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.res.use
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.navigation.NavController
import androidx.navigation.NavDirections
import androidx.navigation.fragment.NavHostFragment
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.base.BaseActivity
import rikka.insets.WindowInsetsHelper
import rikka.layoutinflater.view.LayoutInflaterFactory
abstract class BaseUIActivity<VM : BaseViewModel, Binding : ViewDataBinding> :
BaseActivity(), BaseUIComponent<VM> {
abstract class UIActivity<Binding : ViewDataBinding> : BaseActivity(), ViewModelHolder {
protected lateinit var binding: Binding
protected abstract val layoutRes: Int
private val navHostFragment by lazy {
supportFragmentManager.findFragmentById(navHostId) as? NavHostFragment
}
private val topFragment get() = navHostFragment?.childFragmentManager?.fragments?.getOrNull(0)
protected val currentFragment get() = topFragment as? BaseUIFragment<*, *>
override val viewRoot: View get() = binding.root
open val navigation: NavController? get() = navHostFragment?.navController
open val navHostId: Int = 0
open val snackbarView get() = binding.root
open val snackbarAnchorView: View? get() = null
@ -89,7 +74,7 @@ abstract class BaseUIActivity<VM : BaseViewModel, Binding : ViewDataBinding> :
}
fun setAccessibilityDelegate(delegate: View.AccessibilityDelegate?) {
viewRoot.rootView.accessibilityDelegate = delegate
binding.root.rootView.accessibilityDelegate = delegate
}
override fun onResume() {
@ -97,23 +82,9 @@ abstract class BaseUIActivity<VM : BaseViewModel, Binding : ViewDataBinding> :
viewModel.requestRefresh()
}
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
return currentFragment?.onKeyEvent(event) == true || super.dispatchKeyEvent(event)
}
override fun onEventDispatched(event: ViewEvent) = when (event) {
is ContextExecutor -> event(this)
is ActivityExecutor -> event(this)
else -> Unit
}
override fun onBackPressed() {
if (navigation == null || currentFragment?.onBackPressed()?.not() == true) {
super.onBackPressed()
}
}
fun NavDirections.navigate() {
navigation?.navigate(this)
}
}

View File

@ -18,9 +18,9 @@ interface ContextExecutor {
}
interface ActivityExecutor {
operator fun invoke(activity: BaseUIActivity<*, *>)
operator fun invoke(activity: UIActivity<*>)
}
interface FragmentExecutor {
operator fun invoke(fragment: BaseUIFragment<*, *>)
operator fun invoke(fragment: BaseFragment<*>)
}

View File

@ -1,12 +1,10 @@
package com.topjohnwu.magisk.arch
import android.view.View
import androidx.lifecycle.LifecycleOwner
interface BaseUIComponent<VM : BaseViewModel> : LifecycleOwner {
interface ViewModelHolder : LifecycleOwner {
val viewRoot: View
val viewModel: VM
val viewModel: BaseViewModel
fun startObserveEvents() {
viewModel.viewEvents.observe(this) {

View File

@ -4,7 +4,7 @@ import android.view.View
import androidx.annotation.StringRes
import com.google.android.material.snackbar.Snackbar
import com.topjohnwu.magisk.arch.ActivityExecutor
import com.topjohnwu.magisk.arch.BaseUIActivity
import com.topjohnwu.magisk.arch.UIActivity
import com.topjohnwu.magisk.arch.ViewEvent
import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.magisk.utils.asText
@ -36,7 +36,7 @@ class SnackbarEvent constructor(
builder: Snackbar.() -> Unit
) = Snackbar.make(view, message, length).setAnchorView(anchor).apply(builder).show()
override fun invoke(activity: BaseUIActivity<*, *>) {
override fun invoke(activity: UIActivity<*>) {
snackbar(activity.snackbarView, activity.snackbarAnchorView,
msg.getText(activity.resources).toString(),
length, builder)

View File

@ -18,32 +18,32 @@ class PermissionEvent(
private val callback: (Boolean) -> Unit
) : ViewEvent(), ActivityExecutor {
override fun invoke(activity: BaseUIActivity<*, *>) =
override fun invoke(activity: UIActivity<*>) =
activity.withPermission(permission, callback)
}
class BackPressEvent : ViewEvent(), ActivityExecutor {
override fun invoke(activity: BaseUIActivity<*, *>) {
override fun invoke(activity: UIActivity<*>) {
activity.onBackPressed()
}
}
class DieEvent : ViewEvent(), ActivityExecutor {
override fun invoke(activity: BaseUIActivity<*, *>) {
override fun invoke(activity: UIActivity<*>) {
activity.finish()
}
}
class ShowUIEvent(private val delegate: View.AccessibilityDelegate?)
: ViewEvent(), ActivityExecutor {
override fun invoke(activity: BaseUIActivity<*, *>) {
override fun invoke(activity: UIActivity<*>) {
activity.setContentView()
activity.setAccessibilityDelegate(delegate)
}
}
class RecreateEvent : ViewEvent(), ActivityExecutor {
override fun invoke(activity: BaseUIActivity<*, *>) {
override fun invoke(activity: UIActivity<*>) {
activity.recreate()
}
}
@ -51,7 +51,7 @@ class RecreateEvent : ViewEvent(), ActivityExecutor {
class MagiskInstallFileEvent(
private val callback: (Uri) -> Unit
) : ViewEvent(), ActivityExecutor {
override fun invoke(activity: BaseUIActivity<*, *>) {
override fun invoke(activity: UIActivity<*>) {
try {
activity.getContent("*/*", callback)
Utils.toast(R.string.patch_file_msg, Toast.LENGTH_LONG)
@ -65,8 +65,8 @@ class NavigationEvent(
private val directions: NavDirections,
private val pop: Boolean
) : ViewEvent(), ActivityExecutor {
override fun invoke(activity: BaseUIActivity<*, *>) {
(activity as? BaseUIActivity<*, *>)?.apply {
override fun invoke(activity: UIActivity<*>) {
(activity as? NavigationActivity<*>)?.apply {
if (pop) navigation?.popBackStack()
directions.navigate()
}
@ -80,7 +80,7 @@ class AddHomeIconEvent : ViewEvent(), ContextExecutor {
}
class SelectModuleEvent : ViewEvent(), FragmentExecutor {
override fun invoke(fragment: BaseUIFragment<*, *>) {
override fun invoke(fragment: BaseFragment<*>) {
try {
fragment.apply {
activity.getContent("application/zip") {

View File

@ -1,7 +1,7 @@
package com.topjohnwu.magisk.events.dialog
import com.topjohnwu.magisk.arch.ActivityExecutor
import com.topjohnwu.magisk.arch.BaseUIActivity
import com.topjohnwu.magisk.arch.UIActivity
import com.topjohnwu.magisk.arch.ViewEvent
import com.topjohnwu.magisk.core.utils.BiometricHelper
@ -16,7 +16,7 @@ class BiometricEvent(
builder(Builder())
}
override fun invoke(activity: BaseUIActivity<*, *>) {
override fun invoke(activity: UIActivity<*>) {
BiometricHelper.authenticate(
activity,
onError = listenerOnFailure,

View File

@ -1,13 +1,13 @@
package com.topjohnwu.magisk.events.dialog
import com.topjohnwu.magisk.arch.ActivityExecutor
import com.topjohnwu.magisk.arch.BaseUIActivity
import com.topjohnwu.magisk.arch.UIActivity
import com.topjohnwu.magisk.arch.ViewEvent
import com.topjohnwu.magisk.view.MagiskDialog
abstract class DialogEvent : ViewEvent(), ActivityExecutor {
override fun invoke(activity: BaseUIActivity<*, *>) {
override fun invoke(activity: UIActivity<*>) {
MagiskDialog(activity)
.apply { setOwnerActivity(activity) }
.apply(this::build).show()

View File

@ -4,7 +4,7 @@ import android.app.ProgressDialog
import android.content.Context
import android.widget.Toast
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIActivity
import com.topjohnwu.magisk.arch.NavigationActivity
import com.topjohnwu.magisk.ui.flash.FlashFragment
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.view.MagiskDialog
@ -45,8 +45,8 @@ class UninstallDialog : DialogEvent() {
}
private fun completeUninstall(dialog: MagiskDialog) {
(dialog.ownerActivity as BaseUIActivity<*, *>)
.navigation?.navigate(FlashFragment.uninstall())
(dialog.ownerActivity as NavigationActivity<*>)
.navigation.navigate(FlashFragment.uninstall())
}
}

View File

@ -27,7 +27,7 @@ import java.io.File
class MainViewModel : BaseViewModel()
class MainActivity : BaseMainActivity<MainViewModel, ActivityMainMd2Binding>() {
class MainActivity : BaseMainActivity<ActivityMainMd2Binding>() {
override val layoutRes = R.layout.activity_main_md2
override val viewModel by viewModel<MainViewModel>()

View File

@ -9,7 +9,7 @@ import android.view.View
import androidx.appcompat.widget.SearchView
import androidx.recyclerview.widget.RecyclerView
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.databinding.FragmentDenyMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.ktx.hideKeyboard
@ -17,7 +17,7 @@ import rikka.recyclerview.addEdgeSpacing
import rikka.recyclerview.addItemSpacing
import rikka.recyclerview.fixEdgeEffect
class DenyListFragment : BaseUIFragment<DenyListViewModel, FragmentDenyMd2Binding>() {
class DenyListFragment : BaseFragment<FragmentDenyMd2Binding>() {
override val layoutRes = R.layout.fragment_deny_md2
override val viewModel by viewModel<DenyListViewModel>()

View File

@ -9,14 +9,14 @@ import android.view.*
import androidx.navigation.NavDeepLinkBuilder
import com.topjohnwu.magisk.MainDirections
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.cmp
import com.topjohnwu.magisk.databinding.FragmentFlashMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.ui.MainActivity
class FlashFragment : BaseUIFragment<FlashViewModel, FragmentFlashMd2Binding>() {
class FlashFragment : BaseFragment<FragmentFlashMd2Binding>() {
override val layoutRes = R.layout.fragment_flash_md2
override val viewModel by viewModel<FlashViewModel>()

View File

@ -5,14 +5,14 @@ import android.view.*
import android.widget.ImageView
import android.widget.TextView
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.events.RebootEvent
import com.topjohnwu.superuser.Shell
class HomeFragment : BaseUIFragment<HomeViewModel, FragmentHomeMd2Binding>() {
class HomeFragment : BaseFragment<FragmentHomeMd2Binding>() {
override val layoutRes = R.layout.fragment_home_md2
override val viewModel by viewModel<HomeViewModel>()

View File

@ -106,7 +106,7 @@ class HomeViewModel(
val showTest = false
fun onTestPressed() = object : ViewEvent(), ActivityExecutor {
override fun invoke(activity: BaseUIActivity<*, *>) {
override fun invoke(activity: UIActivity<*>) {
/* Entry point to trigger test events within the app */
}
}.publish()

View File

@ -5,11 +5,11 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.databinding.FragmentInstallMd2Binding
import com.topjohnwu.magisk.di.viewModel
class InstallFragment : BaseUIFragment<InstallViewModel, FragmentInstallMd2Binding>() {
class InstallFragment : BaseFragment<FragmentInstallMd2Binding>() {
override val layoutRes = R.layout.fragment_install_md2
override val viewModel by viewModel<InstallViewModel>()

View File

@ -7,7 +7,7 @@ import android.view.MenuItem
import android.view.View
import androidx.core.view.isVisible
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.ui.MainActivity
@ -16,7 +16,7 @@ import rikka.recyclerview.addEdgeSpacing
import rikka.recyclerview.addItemSpacing
import rikka.recyclerview.fixEdgeEffect
class LogFragment : BaseUIFragment<LogViewModel, FragmentLogMd2Binding>() {
class LogFragment : BaseFragment<FragmentLogMd2Binding>() {
override val layoutRes = R.layout.fragment_log_md2
override val viewModel by viewModel<LogViewModel>()

View File

@ -3,7 +3,7 @@ package com.topjohnwu.magisk.ui.module
import android.os.Bundle
import android.view.View
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
import com.topjohnwu.magisk.di.viewModel
import rikka.recyclerview.addEdgeSpacing
@ -11,7 +11,7 @@ import rikka.recyclerview.addInvalidateItemDecorationsObserver
import rikka.recyclerview.addItemSpacing
import rikka.recyclerview.fixEdgeEffect
class ModuleFragment : BaseUIFragment<ModuleViewModel, FragmentModuleMd2Binding>() {
class ModuleFragment : BaseFragment<FragmentModuleMd2Binding>() {
override val layoutRes = R.layout.fragment_module_md2
override val viewModel by viewModel<ModuleViewModel>()

View File

@ -3,14 +3,14 @@ package com.topjohnwu.magisk.ui.settings
import android.os.Bundle
import android.view.View
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.databinding.FragmentSettingsMd2Binding
import com.topjohnwu.magisk.di.viewModel
import rikka.recyclerview.addEdgeSpacing
import rikka.recyclerview.addItemSpacing
import rikka.recyclerview.fixEdgeEffect
class SettingsFragment : BaseUIFragment<SettingsViewModel, FragmentSettingsMd2Binding>() {
class SettingsFragment : BaseFragment<FragmentSettingsMd2Binding>() {
override val layoutRes = R.layout.fragment_settings_md2
override val viewModel by viewModel<SettingsViewModel>()

View File

@ -3,14 +3,14 @@ package com.topjohnwu.magisk.ui.superuser
import android.os.Bundle
import android.view.View
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.databinding.FragmentSuperuserMd2Binding
import com.topjohnwu.magisk.di.viewModel
import rikka.recyclerview.addEdgeSpacing
import rikka.recyclerview.addItemSpacing
import rikka.recyclerview.fixEdgeEffect
class SuperuserFragment : BaseUIFragment<SuperuserViewModel, FragmentSuperuserMd2Binding>() {
class SuperuserFragment : BaseFragment<FragmentSuperuserMd2Binding>() {
override val layoutRes = R.layout.fragment_superuser_md2
override val viewModel by viewModel<SuperuserViewModel>()

View File

@ -7,20 +7,18 @@ import android.os.Build
import android.os.Bundle
import android.view.Window
import android.view.WindowManager
import androidx.navigation.NavController
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIActivity
import com.topjohnwu.magisk.arch.UIActivity
import com.topjohnwu.magisk.core.su.SuCallbackHandler
import com.topjohnwu.magisk.core.su.SuCallbackHandler.REQUEST
import com.topjohnwu.magisk.databinding.ActivityRequestBinding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.ui.theme.Theme
open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityRequestBinding>() {
open class SuRequestActivity : UIActivity<ActivityRequestBinding>() {
override val layoutRes: Int = R.layout.activity_request
override val viewModel: SuRequestViewModel by viewModel()
override val navigation: NavController? = null
override fun onBackPressed() {
viewModel.denyPressed()

View File

@ -8,12 +8,12 @@ import android.view.ViewGroup
import android.widget.FrameLayout
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.databinding.FragmentThemeMd2Binding
import com.topjohnwu.magisk.databinding.ItemThemeBindingImpl
import com.topjohnwu.magisk.di.viewModel
class ThemeFragment : BaseUIFragment<ThemeViewModel, FragmentThemeMd2Binding>() {
class ThemeFragment : BaseFragment<FragmentThemeMd2Binding>() {
override val layoutRes = R.layout.fragment_theme_md2
override val viewModel by viewModel<ThemeViewModel>()