Updated the app to use navigation components instead of custom solution
Welcome to mid 2018.
This commit is contained in:
parent
922e36cfb0
commit
1b8813228b
@ -1,7 +1,10 @@
|
|||||||
apply plugin: 'com.android.application'
|
plugins {
|
||||||
apply plugin: 'kotlin-android'
|
id("com.android.application")
|
||||||
apply plugin: 'kotlin-android-extensions'
|
id("kotlin-android")
|
||||||
apply plugin: 'kotlin-kapt'
|
id("kotlin-android-extensions")
|
||||||
|
id("kotlin-kapt")
|
||||||
|
id("androidx.navigation.safeargs.kotlin")
|
||||||
|
}
|
||||||
|
|
||||||
kapt {
|
kapt {
|
||||||
correctErrorTypes = true
|
correctErrorTypes = true
|
||||||
@ -22,7 +25,7 @@ android {
|
|||||||
|
|
||||||
javaCompileOptions {
|
javaCompileOptions {
|
||||||
annotationProcessorOptions {
|
annotationProcessorOptions {
|
||||||
arguments = ["room.incremental":"true"]
|
arguments = ["room.incremental": "true"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,7 +68,6 @@ dependencies {
|
|||||||
|
|
||||||
implementation 'com.github.topjohnwu:jtar:1.0.0'
|
implementation 'com.github.topjohnwu:jtar:1.0.0'
|
||||||
implementation 'com.jakewharton.timber:timber:4.7.1'
|
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||||
implementation 'com.ncapdevi:frag-nav:3.2.0'
|
|
||||||
implementation 'com.github.pwittchen:reactivenetwork-rx2:3.0.6'
|
implementation 'com.github.pwittchen:reactivenetwork-rx2:3.0.6'
|
||||||
|
|
||||||
implementation 'io.reactivex.rxjava2:rxjava:2.2.18'
|
implementation 'io.reactivex.rxjava2:rxjava:2.2.18'
|
||||||
@ -116,7 +118,6 @@ dependencies {
|
|||||||
implementation "androidx.room:room-rxjava2:${vRoom}"
|
implementation "androidx.room:room-rxjava2:${vRoom}"
|
||||||
kapt "androidx.room:room-compiler:${vRoom}"
|
kapt "androidx.room:room-compiler:${vRoom}"
|
||||||
|
|
||||||
def vNav = '2.2.1'
|
|
||||||
implementation "androidx.navigation:navigation-fragment-ktx:${vNav}"
|
implementation "androidx.navigation:navigation-fragment-ktx:${vNav}"
|
||||||
implementation "androidx.navigation:navigation-ui-ktx:${vNav}"
|
implementation "androidx.navigation:navigation-ui-ktx:${vNav}"
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import android.content.pm.ActivityInfo
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
|
import androidx.navigation.NavController
|
||||||
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.intent
|
import com.topjohnwu.magisk.core.intent
|
||||||
@ -16,7 +17,6 @@ import com.topjohnwu.magisk.model.events.PermissionEvent
|
|||||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||||
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
||||||
import com.topjohnwu.magisk.ui.base.CompatNavigationDelegate
|
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@ -25,8 +25,7 @@ open class FlashActivity : BaseUIActivity<FlashViewModel, ActivityFlashBinding>(
|
|||||||
override val layoutRes: Int = R.layout.activity_flash
|
override val layoutRes: Int = R.layout.activity_flash
|
||||||
override val viewModel: FlashViewModel by viewModel()
|
override val viewModel: FlashViewModel by viewModel()
|
||||||
|
|
||||||
override val navigation: CompatNavigationDelegate<BaseUIActivity<FlashViewModel, ActivityFlashBinding>>? =
|
override val navigation: NavController? = null
|
||||||
null
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
|
||||||
|
@ -7,6 +7,7 @@ import android.os.Build
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
|
import androidx.navigation.NavController
|
||||||
import com.topjohnwu.magisk.R
|
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
|
||||||
@ -15,7 +16,6 @@ import com.topjohnwu.magisk.model.events.DieEvent
|
|||||||
import com.topjohnwu.magisk.model.events.ViewActionEvent
|
import com.topjohnwu.magisk.model.events.ViewActionEvent
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||||
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
||||||
import com.topjohnwu.magisk.ui.base.CompatNavigationDelegate
|
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
|
||||||
open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityRequestBinding>() {
|
open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityRequestBinding>() {
|
||||||
@ -23,8 +23,7 @@ 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: CompatNavigationDelegate<BaseUIActivity<SuRequestViewModel, ActivityRequestBinding>>? =
|
override val navigation: NavController? = null
|
||||||
null
|
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
viewModel.denyPressed()
|
viewModel.denyPressed()
|
||||||
|
@ -1,94 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.model.navigation
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.annotation.AnimRes
|
|
||||||
import androidx.annotation.AnimatorRes
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
|
||||||
import com.topjohnwu.magisk.model.events.ActivityExecutor
|
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
@DslMarker
|
|
||||||
annotation class NavigationDslMarker
|
|
||||||
|
|
||||||
class MagiskNavigationEvent(
|
|
||||||
val navDirections: MagiskNavDirectionsBuilder,
|
|
||||||
val navOptions: MagiskNavOptions,
|
|
||||||
val animOptions: MagiskAnimBuilder
|
|
||||||
) : ViewEvent(), ActivityExecutor {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
operator fun invoke(builder: Builder.() -> Unit) = Builder().apply(builder).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun invoke(activity: BaseActivity) {
|
|
||||||
if (activity !is BaseUIActivity<*, *>) return
|
|
||||||
activity.navigation?.navigateTo(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
@NavigationDslMarker
|
|
||||||
class Builder {
|
|
||||||
|
|
||||||
private var animOptions: MagiskAnimBuilder = MagiskAnimBuilder()
|
|
||||||
private var navOptions: MagiskNavOptions = MagiskNavOptions()
|
|
||||||
private val directionsBuilder = MagiskNavDirectionsBuilder()
|
|
||||||
|
|
||||||
fun args(builder: Bundle.() -> Unit) = directionsBuilder.args(builder)
|
|
||||||
|
|
||||||
fun navAnim(builder: MagiskAnimBuilder.() -> Unit) {
|
|
||||||
animOptions = MagiskAnimBuilder().apply(builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun navOptions(builder: MagiskNavOptions.() -> Unit) {
|
|
||||||
navOptions = MagiskNavOptions().apply(builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun navDirections(builder: MagiskNavDirectionsBuilder.() -> Unit) {
|
|
||||||
directionsBuilder.apply(builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun build() = MagiskNavigationEvent(directionsBuilder, navOptions, animOptions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NavigationDslMarker
|
|
||||||
class MagiskNavDirectionsBuilder {
|
|
||||||
|
|
||||||
var destination: KClass<out Fragment>? = null
|
|
||||||
var isActivity: Boolean = false
|
|
||||||
val args: Bundle = Bundle()
|
|
||||||
|
|
||||||
fun args(builder: Bundle.() -> Unit) = args.apply(builder)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@NavigationDslMarker
|
|
||||||
class MagiskNavOptions {
|
|
||||||
var popUpTo: KClass<*>? = null
|
|
||||||
var inclusive: Boolean = false
|
|
||||||
var clearTask: Boolean = false
|
|
||||||
var singleTop: Boolean = false
|
|
||||||
}
|
|
||||||
|
|
||||||
@NavigationDslMarker
|
|
||||||
class MagiskAnimBuilder {
|
|
||||||
@AnimRes
|
|
||||||
@AnimatorRes
|
|
||||||
var enter = 0
|
|
||||||
|
|
||||||
@AnimRes
|
|
||||||
@AnimatorRes
|
|
||||||
var exit = 0
|
|
||||||
|
|
||||||
@AnimRes
|
|
||||||
@AnimatorRes
|
|
||||||
var popEnter = 0
|
|
||||||
|
|
||||||
@AnimRes
|
|
||||||
@AnimatorRes
|
|
||||||
var popExit = 0
|
|
||||||
|
|
||||||
val anySet: Boolean get() = enter != 0 || exit != 0 || popEnter != 0 || popExit != 0
|
|
||||||
}
|
|
@ -6,80 +6,9 @@ import android.os.Build
|
|||||||
import com.topjohnwu.magisk.core.Const
|
import com.topjohnwu.magisk.core.Const
|
||||||
import com.topjohnwu.magisk.core.intent
|
import com.topjohnwu.magisk.core.intent
|
||||||
import com.topjohnwu.magisk.ui.MainActivity
|
import com.topjohnwu.magisk.ui.MainActivity
|
||||||
import com.topjohnwu.magisk.ui.hide.HideFragment
|
|
||||||
import com.topjohnwu.magisk.ui.home.HomeFragment
|
|
||||||
import com.topjohnwu.magisk.ui.install.InstallFragment
|
|
||||||
import com.topjohnwu.magisk.ui.log.LogFragment
|
|
||||||
import com.topjohnwu.magisk.ui.module.ModuleFragment
|
|
||||||
import com.topjohnwu.magisk.ui.safetynet.SafetynetFragment
|
|
||||||
import com.topjohnwu.magisk.ui.settings.SettingsFragment
|
|
||||||
import com.topjohnwu.magisk.ui.superuser.SuperuserFragment
|
|
||||||
import com.topjohnwu.magisk.ui.theme.ThemeFragment
|
|
||||||
|
|
||||||
object Navigation {
|
object Navigation {
|
||||||
|
|
||||||
fun home() = MagiskNavigationEvent {
|
|
||||||
navDirections {
|
|
||||||
destination = HomeFragment::class
|
|
||||||
}
|
|
||||||
navOptions {
|
|
||||||
popUpTo = HomeFragment::class
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun superuser() = MagiskNavigationEvent {
|
|
||||||
navDirections {
|
|
||||||
destination = SuperuserFragment::class
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun modules() = MagiskNavigationEvent {
|
|
||||||
navDirections {
|
|
||||||
destination = ModuleFragment::class
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun hide() = MagiskNavigationEvent {
|
|
||||||
navDirections {
|
|
||||||
destination = HideFragment::class
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun safetynet() = MagiskNavigationEvent {
|
|
||||||
navDirections { destination = SafetynetFragment::class }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun log() = MagiskNavigationEvent {
|
|
||||||
navDirections {
|
|
||||||
destination = LogFragment::class
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun settings() = MagiskNavigationEvent {
|
|
||||||
navDirections {
|
|
||||||
destination = SettingsFragment::class
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun install() = MagiskNavigationEvent {
|
|
||||||
navDirections { destination = InstallFragment::class }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun theme() = MagiskNavigationEvent {
|
|
||||||
navDirections { destination = ThemeFragment::class }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fromSection(section: String) = when (section) {
|
|
||||||
"superuser" -> superuser()
|
|
||||||
"modules" -> modules()
|
|
||||||
"magiskhide" -> hide()
|
|
||||||
"log" -> log()
|
|
||||||
"settings" -> settings()
|
|
||||||
else -> home()
|
|
||||||
}
|
|
||||||
|
|
||||||
// redesign starts here
|
|
||||||
|
|
||||||
fun start(launchIntent: Intent, context: Context) {
|
fun start(launchIntent: Intent, context: Context) {
|
||||||
context.intent<MainActivity>()
|
context.intent<MainActivity>()
|
||||||
.putExtra(
|
.putExtra(
|
||||||
@ -92,10 +21,6 @@ object Navigation {
|
|||||||
.also { context.startActivity(it) }
|
.also { context.startActivity(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
object Main {
|
|
||||||
const val OPEN_NAV = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
private val ACTION_APPLICATION_PREFERENCES
|
private val ACTION_APPLICATION_PREFERENCES
|
||||||
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
Intent.ACTION_APPLICATION_PREFERENCES
|
Intent.ACTION_APPLICATION_PREFERENCES
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.topjohnwu.magisk.model.navigation
|
||||||
|
|
||||||
|
import androidx.navigation.NavDirections
|
||||||
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
|
import com.topjohnwu.magisk.model.events.ActivityExecutor
|
||||||
|
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||||
|
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
||||||
|
|
||||||
|
class NavigationWrapper(
|
||||||
|
private val directions: NavDirections
|
||||||
|
) : ViewEvent(), ActivityExecutor {
|
||||||
|
override fun invoke(activity: BaseActivity) {
|
||||||
|
if (activity !is BaseUIActivity<*, *>) return
|
||||||
|
activity.apply {
|
||||||
|
directions.navigate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,47 +7,31 @@ import android.view.ViewTreeObserver
|
|||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.graphics.Insets
|
import androidx.core.graphics.Insets
|
||||||
|
import androidx.core.view.forEach
|
||||||
import androidx.core.view.setPadding
|
import androidx.core.view.setPadding
|
||||||
import androidx.core.view.updateLayoutParams
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import com.google.android.material.card.MaterialCardView
|
import com.google.android.material.card.MaterialCardView
|
||||||
import com.ncapdevi.fragnav.FragNavController
|
import com.topjohnwu.magisk.MainDirections
|
||||||
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.Info
|
import com.topjohnwu.magisk.core.Info
|
||||||
import com.topjohnwu.magisk.databinding.ActivityMainMd2Binding
|
import com.topjohnwu.magisk.databinding.ActivityMainMd2Binding
|
||||||
import com.topjohnwu.magisk.extensions.startAnimations
|
import com.topjohnwu.magisk.extensions.startAnimations
|
||||||
import com.topjohnwu.magisk.model.navigation.Navigation
|
|
||||||
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
import com.topjohnwu.magisk.ui.base.BaseUIActivity
|
||||||
import com.topjohnwu.magisk.ui.base.CompatNavigationDelegate
|
import com.topjohnwu.magisk.ui.home.HomeFragmentDirections
|
||||||
import com.topjohnwu.magisk.ui.home.HomeFragment
|
|
||||||
import com.topjohnwu.magisk.ui.log.LogFragment
|
|
||||||
import com.topjohnwu.magisk.ui.module.ModuleFragment
|
|
||||||
import com.topjohnwu.magisk.ui.superuser.SuperuserFragment
|
|
||||||
import com.topjohnwu.magisk.utils.HideBottomViewOnScrollBehavior
|
import com.topjohnwu.magisk.utils.HideBottomViewOnScrollBehavior
|
||||||
import com.topjohnwu.magisk.utils.HideTopViewOnScrollBehavior
|
import com.topjohnwu.magisk.utils.HideTopViewOnScrollBehavior
|
||||||
import com.topjohnwu.magisk.utils.HideableBehavior
|
import com.topjohnwu.magisk.utils.HideableBehavior
|
||||||
import com.topjohnwu.magisk.view.MagiskDialog
|
import com.topjohnwu.magisk.view.MagiskDialog
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>(),
|
open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>() {
|
||||||
FragNavController.TransactionListener {
|
|
||||||
|
|
||||||
override val layoutRes = R.layout.activity_main_md2
|
override val layoutRes = R.layout.activity_main_md2
|
||||||
override val viewModel by viewModel<MainViewModel>()
|
override val viewModel by viewModel<MainViewModel>()
|
||||||
override val navHost: Int = R.id.main_nav_host
|
override val navHost: Int = R.id.main_nav_host
|
||||||
|
|
||||||
override val navigation by lazy { CompatNavigationDelegate(this, this) }
|
|
||||||
|
|
||||||
override val baseFragments: List<KClass<out Fragment>> = listOf(
|
|
||||||
HomeFragment::class,
|
|
||||||
ModuleFragment::class,
|
|
||||||
SuperuserFragment::class,
|
|
||||||
LogFragment::class
|
|
||||||
)
|
|
||||||
|
|
||||||
//This temporarily fixes unwanted feature of BottomNavigationView - where the view applies
|
//This temporarily fixes unwanted feature of BottomNavigationView - where the view applies
|
||||||
//padding on itself given insets are not consumed beforehand. Unfortunately the listener
|
//padding on itself given insets are not consumed beforehand. Unfortunately the listener
|
||||||
//implementation doesn't favor us against the design library, so on re-create it's often given
|
//implementation doesn't favor us against the design library, so on re-create it's often given
|
||||||
@ -56,6 +40,9 @@ open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>(
|
|||||||
binding.mainNavigation.setPadding(0)
|
binding.mainNavigation.setPadding(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected var isRoot = true
|
||||||
|
private set
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
@ -70,6 +57,25 @@ open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>(
|
|||||||
|
|
||||||
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
|
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
|
||||||
|
|
||||||
|
navigation?.addOnDestinationChangedListener { controller, destination, arguments ->
|
||||||
|
isRoot = when (destination.id) {
|
||||||
|
R.id.homeFragment,
|
||||||
|
R.id.modulesFragment,
|
||||||
|
R.id.superuserFragment,
|
||||||
|
R.id.logFragment -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
setDisplayHomeAsUpEnabled(!isRoot)
|
||||||
|
requestNavigationHidden(!isRoot)
|
||||||
|
|
||||||
|
binding.mainNavigation.menu.forEach {
|
||||||
|
if (it.itemId == destination.id) {
|
||||||
|
it.isChecked = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setSupportActionBar(binding.mainToolbar)
|
setSupportActionBar(binding.mainToolbar)
|
||||||
|
|
||||||
binding.mainToolbarWrapper.updateLayoutParams<CoordinatorLayout.LayoutParams> {
|
binding.mainToolbarWrapper.updateLayoutParams<CoordinatorLayout.LayoutParams> {
|
||||||
@ -80,28 +86,26 @@ open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>(
|
|||||||
}
|
}
|
||||||
binding.mainNavigation.setOnNavigationItemSelectedListener {
|
binding.mainNavigation.setOnNavigationItemSelectedListener {
|
||||||
when (it.itemId) {
|
when (it.itemId) {
|
||||||
R.id.homeFragment -> Navigation.home()
|
R.id.homeFragment -> MainDirections.actionHomeFragment()
|
||||||
R.id.modulesFragment -> Navigation.modules()
|
R.id.modulesFragment -> MainDirections.actionModuleFragment()
|
||||||
R.id.superuserFragment -> Navigation.superuser()
|
R.id.superuserFragment -> MainDirections.actionSuperuserFragment()
|
||||||
R.id.logFragment -> Navigation.log()
|
R.id.logFragment -> MainDirections.actionLogFragment()
|
||||||
else -> throw NotImplementedError("Id ${it.itemId} is not defined as selectable")
|
else -> throw NotImplementedError("Id ${it.itemId} is not defined as selectable")
|
||||||
}.dispatchOnSelf()
|
}.navigate()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
binding.mainNavigation.setOnNavigationItemReselectedListener {
|
binding.mainNavigation.setOnNavigationItemReselectedListener {
|
||||||
navigation.onReselected()
|
(currentFragment as? ReselectionTarget)?.onReselected()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.mainNavigation.viewTreeObserver.addOnGlobalLayoutListener(navObserver)
|
binding.mainNavigation.viewTreeObserver.addOnGlobalLayoutListener(navObserver)
|
||||||
|
|
||||||
if (intent.getBooleanExtra(Const.Key.OPEN_SETTINGS, false)) {
|
if (intent.getBooleanExtra(Const.Key.OPEN_SETTINGS, false)) {
|
||||||
Navigation.settings().dispatchOnSelf()
|
HomeFragmentDirections.actionHomeFragmentToSettingsFragment().navigate()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
onTabTransaction(null, -1)
|
if (!isRoot) {
|
||||||
|
|
||||||
if (!navigation.isRoot) {
|
|
||||||
requestNavigationHidden()
|
requestNavigationHidden()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,17 +133,6 @@ open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTabTransaction(fragment: Fragment?, index: Int) =
|
|
||||||
onFragmentTransaction(fragment, FragNavController.TransactionType.PUSH)
|
|
||||||
|
|
||||||
override fun onFragmentTransaction(
|
|
||||||
fragment: Fragment?,
|
|
||||||
transactionType: FragNavController.TransactionType
|
|
||||||
) {
|
|
||||||
setDisplayHomeAsUpEnabled(!navigation.isRoot)
|
|
||||||
requestNavigationHidden(!navigation.isRoot)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun peekSystemWindowInsets(insets: Insets) {
|
override fun peekSystemWindowInsets(insets: Insets) {
|
||||||
viewModel.insets.value = insets
|
viewModel.insets.value = insets
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,8 @@ 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.fragment.app.Fragment
|
import androidx.navigation.NavDirections
|
||||||
|
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
|
||||||
@ -19,7 +20,6 @@ import com.topjohnwu.magisk.model.events.EventHandler
|
|||||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||||
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
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBinding> :
|
abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBinding> :
|
||||||
BaseActivity(), CompatView<ViewModel>, EventHandler {
|
BaseActivity(), CompatView<ViewModel>, EventHandler {
|
||||||
@ -28,20 +28,30 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
|
|||||||
protected abstract val layoutRes: Int
|
protected abstract val layoutRes: Int
|
||||||
protected open val themeRes: Int = Theme.selected.themeRes
|
protected open val themeRes: Int = Theme.selected.themeRes
|
||||||
|
|
||||||
|
private val navHostFragment get() = supportFragmentManager.findFragmentById(navHost)
|
||||||
|
private val topFragment get() = navHostFragment?.childFragmentManager?.fragments?.getOrNull(0)
|
||||||
|
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 { CompatNavigationDelegate(this) as CompatNavigationDelegate? }
|
override val navigation by lazy {
|
||||||
|
kotlin.runCatching { findNavController(navHost) }.getOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
private val delegate by lazy { CompatDelegate(this) }
|
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
|
||||||
open val baseFragments = listOf<KClass<out Fragment>>()
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val theme = Config.darkThemeExtended
|
val theme = Config.darkThemeExtended
|
||||||
AppCompatDelegate.setDefaultNightMode(theme)
|
AppCompatDelegate.setDefaultNightMode(theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
currentFragment?.onActivityResult(requestCode, resultCode, data)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setTheme(themeRes)
|
setTheme(themeRes)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -61,12 +71,6 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
|
|||||||
})
|
})
|
||||||
|
|
||||||
delegate.onCreate()
|
delegate.onCreate()
|
||||||
navigation?.onCreate(savedInstanceState)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
|
||||||
navigation?.onActivityResult(requestCode, resultCode, data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
@ -74,11 +78,6 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
|
|||||||
delegate.onResume()
|
delegate.onResume()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
|
||||||
super.onSaveInstanceState(outState)
|
|
||||||
navigation?.onSaveInstanceState(outState)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onEventDispatched(event: ViewEvent) {
|
override fun onEventDispatched(event: ViewEvent) {
|
||||||
delegate.onEventExecute(event, this)
|
delegate.onEventExecute(event, this)
|
||||||
when (event) {
|
when (event) {
|
||||||
@ -87,7 +86,7 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
if (navigation == null || navigation?.onBackPressed()?.not() == true) {
|
if (navigation == null || currentFragment?.onBackPressed()?.not() == true) {
|
||||||
super.onBackPressed()
|
super.onBackPressed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,4 +96,9 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected fun ViewEvent.dispatchOnSelf() = onEventDispatched(this)
|
protected fun ViewEvent.dispatchOnSelf() = onEventDispatched(this)
|
||||||
|
|
||||||
|
fun NavDirections.navigate() {
|
||||||
|
navigation?.navigate(this)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import androidx.databinding.DataBindingUtil
|
|||||||
import androidx.databinding.OnRebindCallback
|
import androidx.databinding.OnRebindCallback
|
||||||
import androidx.databinding.ViewDataBinding
|
import androidx.databinding.ViewDataBinding
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.navigation.NavDirections
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.extensions.startAnimations
|
import com.topjohnwu.magisk.extensions.startAnimations
|
||||||
import com.topjohnwu.magisk.model.events.EventHandler
|
import com.topjohnwu.magisk.model.events.EventHandler
|
||||||
@ -22,7 +23,7 @@ abstract class BaseUIFragment<ViewModel : BaseViewModel, Binding : ViewDataBindi
|
|||||||
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 by lazy { activity.navigation }
|
override val navigation get() = activity.navigation
|
||||||
private val delegate by lazy { CompatDelegate(this) }
|
private val delegate by lazy { CompatDelegate(this) }
|
||||||
|
|
||||||
override fun consumeSystemWindowInsets(insets: Insets) = insets
|
override fun consumeSystemWindowInsets(insets: Insets) = insets
|
||||||
@ -78,4 +79,8 @@ abstract class BaseUIFragment<ViewModel : BaseViewModel, Binding : ViewDataBindi
|
|||||||
|
|
||||||
protected fun ViewEvent.dispatchOnSelf() = delegate.onEventExecute(this, this@BaseUIFragment)
|
protected fun ViewEvent.dispatchOnSelf() = delegate.onEventExecute(this, this@BaseUIFragment)
|
||||||
|
|
||||||
|
fun NavDirections.navigate() {
|
||||||
|
navigation?.navigate(this)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,13 @@ import androidx.databinding.PropertyChangeRegistry
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.navigation.NavDirections
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.core.Info
|
import com.topjohnwu.magisk.core.Info
|
||||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||||
import com.topjohnwu.magisk.extensions.doOnSubscribeUi
|
import com.topjohnwu.magisk.extensions.doOnSubscribeUi
|
||||||
import com.topjohnwu.magisk.model.events.*
|
import com.topjohnwu.magisk.model.events.*
|
||||||
|
import com.topjohnwu.magisk.model.navigation.NavigationWrapper
|
||||||
import com.topjohnwu.magisk.model.observer.Observer
|
import com.topjohnwu.magisk.model.observer.Observer
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
import io.reactivex.*
|
import io.reactivex.*
|
||||||
@ -99,6 +101,10 @@ abstract class BaseViewModel(
|
|||||||
_viewEvents.postValue(SimpleViewEvent(this))
|
_viewEvents.postValue(SimpleViewEvent(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun NavDirections.publish() {
|
||||||
|
_viewEvents.postValue(NavigationWrapper(this))
|
||||||
|
}
|
||||||
|
|
||||||
fun Disposable.add() {
|
fun Disposable.add() {
|
||||||
disposables.add(this)
|
disposables.add(this)
|
||||||
}
|
}
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.ui.base
|
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
|
||||||
import com.ncapdevi.fragnav.FragNavController
|
|
||||||
import com.ncapdevi.fragnav.FragNavTransactionOptions
|
|
||||||
import com.topjohnwu.magisk.R
|
|
||||||
import com.topjohnwu.magisk.model.navigation.MagiskAnimBuilder
|
|
||||||
import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent
|
|
||||||
import com.topjohnwu.magisk.ui.ReselectionTarget
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
class CompatNavigationDelegate<out Source>(
|
|
||||||
private val source: Source,
|
|
||||||
private val listener: FragNavController.TransactionListener? = null
|
|
||||||
) : FragNavController.RootFragmentListener where Source : BaseUIActivity<*, *> {
|
|
||||||
|
|
||||||
private val controller by lazy {
|
|
||||||
check(source.navHost != 0) { "Did you forget to override \"navHostId\"?" }
|
|
||||||
FragNavController(source.supportFragmentManager, source.navHost)
|
|
||||||
}
|
|
||||||
|
|
||||||
val isRoot get() = controller.isRootFragment
|
|
||||||
|
|
||||||
|
|
||||||
//region Listener
|
|
||||||
override val numberOfRootFragments: Int
|
|
||||||
get() = source.baseFragments.size
|
|
||||||
|
|
||||||
override fun getRootFragment(index: Int) =
|
|
||||||
source.baseFragments[index].java.newInstance()
|
|
||||||
//endregion
|
|
||||||
|
|
||||||
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
||||||
controller.currentFrag?.onActivityResult(requestCode, resultCode, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onCreate(savedInstanceState: Bundle?) = controller.run {
|
|
||||||
rootFragmentListener = this@CompatNavigationDelegate
|
|
||||||
transactionListener = listener
|
|
||||||
initialize(0, savedInstanceState)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onSaveInstanceState(outState: Bundle) =
|
|
||||||
controller.onSaveInstanceState(outState)
|
|
||||||
|
|
||||||
fun onReselected() {
|
|
||||||
(controller.currentFrag as? ReselectionTarget)?.onReselected()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onBackPressed(): Boolean {
|
|
||||||
val fragment = controller.currentFrag as? BaseUIFragment<*, *>
|
|
||||||
|
|
||||||
if (fragment?.onBackPressed() == true) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return runCatching { controller.popFragment() }.fold({ true }, { false })
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---
|
|
||||||
|
|
||||||
fun navigateTo(event: MagiskNavigationEvent) {
|
|
||||||
val directions = event.navDirections
|
|
||||||
|
|
||||||
controller.defaultTransactionOptions = FragNavTransactionOptions.newBuilder()
|
|
||||||
.customAnimations(event.animOptions)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
controller.currentStack
|
|
||||||
?.indexOfFirst { it.javaClass == event.navOptions.popUpTo }
|
|
||||||
?.takeIf { it != -1 } // invalidate if class is not found
|
|
||||||
?.let { if (event.navOptions.inclusive) it + 1 else it }
|
|
||||||
?.let { controller.popFragments(it) }
|
|
||||||
|
|
||||||
when (directions.isActivity) {
|
|
||||||
true -> navigateToActivity(event)
|
|
||||||
else -> navigateToFragment(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun navigateToActivity(event: MagiskNavigationEvent) {
|
|
||||||
val destination = event.navDirections.destination?.java ?: let {
|
|
||||||
Timber.e("Cannot navigate to null destination")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val options = event.navOptions
|
|
||||||
|
|
||||||
Intent(source, destination)
|
|
||||||
.putExtras(event.navDirections.args)
|
|
||||||
.apply {
|
|
||||||
if (options.singleTop) addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
|
||||||
if (options.clearTask) addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
|
||||||
}
|
|
||||||
.let { source.startActivity(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun navigateToFragment(event: MagiskNavigationEvent) {
|
|
||||||
val destination = event.navDirections.destination ?: let {
|
|
||||||
Timber.e("Cannot navigate to null destination")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
source.baseFragments
|
|
||||||
.indexOfFirst { it == destination }
|
|
||||||
.takeIf { it >= 0 }
|
|
||||||
?.let { controller.switchTab(it) } ?: destination.java.newInstance()
|
|
||||||
.also { it.arguments = event.navDirections.args }
|
|
||||||
.let { controller.pushFragment(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FragNavTransactionOptions.Builder.customAnimations(options: MagiskAnimBuilder) =
|
|
||||||
apply {
|
|
||||||
if (!options.anySet) customAnimations(
|
|
||||||
R.anim.fragment_enter,
|
|
||||||
R.anim.fragment_exit,
|
|
||||||
R.anim.fragment_enter_pop,
|
|
||||||
R.anim.fragment_exit_pop
|
|
||||||
) else customAnimations(
|
|
||||||
options.enter,
|
|
||||||
options.exit,
|
|
||||||
options.popEnter,
|
|
||||||
options.popExit
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -2,12 +2,13 @@ package com.topjohnwu.magisk.ui.base
|
|||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.graphics.Insets
|
import androidx.core.graphics.Insets
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
|
||||||
internal interface CompatView<ViewModel : BaseViewModel> {
|
internal interface CompatView<ViewModel : BaseViewModel> {
|
||||||
|
|
||||||
val viewRoot: View
|
val viewRoot: View
|
||||||
val viewModel: ViewModel
|
val viewModel: ViewModel
|
||||||
val navigation: CompatNavigationDelegate<*>?
|
val navigation: NavController?
|
||||||
|
|
||||||
fun peekSystemWindowInsets(insets: Insets) = Unit
|
fun peekSystemWindowInsets(insets: Insets) = Unit
|
||||||
fun consumeSystemWindowInsets(insets: Insets): Insets? = null
|
fun consumeSystemWindowInsets(insets: Insets): Insets? = null
|
||||||
|
@ -5,7 +5,6 @@ import android.view.*
|
|||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
|
||||||
import com.topjohnwu.magisk.model.events.RebootEvent
|
import com.topjohnwu.magisk.model.events.RebootEvent
|
||||||
import com.topjohnwu.magisk.model.navigation.Navigation
|
|
||||||
import com.topjohnwu.magisk.ui.base.BaseUIFragment
|
import com.topjohnwu.magisk.ui.base.BaseUIFragment
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
@ -46,7 +45,8 @@ class HomeFragment : BaseUIFragment<HomeViewModel, FragmentHomeMd2Binding>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
|
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
|
||||||
R.id.action_settings -> Navigation.settings().dispatchOnSelf()
|
R.id.action_settings -> HomeFragmentDirections.actionHomeFragmentToSettingsFragment()
|
||||||
|
.navigate()
|
||||||
R.id.action_reboot -> RebootEvent.inflateMenu(activity).show()
|
R.id.action_reboot -> RebootEvent.inflateMenu(activity).show()
|
||||||
else -> null
|
else -> null
|
||||||
}?.let { true } ?: super.onOptionsItemSelected(item)
|
}?.let { true } ?: super.onOptionsItemSelected(item)
|
||||||
|
@ -22,7 +22,6 @@ import com.topjohnwu.magisk.model.events.ViewEvent
|
|||||||
import com.topjohnwu.magisk.model.events.dialog.EnvFixDialog
|
import com.topjohnwu.magisk.model.events.dialog.EnvFixDialog
|
||||||
import com.topjohnwu.magisk.model.events.dialog.ManagerInstallDialog
|
import com.topjohnwu.magisk.model.events.dialog.ManagerInstallDialog
|
||||||
import com.topjohnwu.magisk.model.events.dialog.UninstallDialog
|
import com.topjohnwu.magisk.model.events.dialog.UninstallDialog
|
||||||
import com.topjohnwu.magisk.model.navigation.Navigation
|
|
||||||
import com.topjohnwu.magisk.ui.base.BaseViewModel
|
import com.topjohnwu.magisk.ui.base.BaseViewModel
|
||||||
import com.topjohnwu.magisk.ui.base.itemBindingOf
|
import com.topjohnwu.magisk.ui.base.itemBindingOf
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
@ -114,7 +113,7 @@ class HomeViewModel(
|
|||||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
).map { check(it);it }
|
).map { check(it);it }
|
||||||
.subscribeK { Navigation.install().publish() }
|
.subscribeK { HomeFragmentDirections.actionHomeFragmentToInstallFragment().publish() }
|
||||||
.add()
|
.add()
|
||||||
|
|
||||||
fun toggle(kof: KObservableField<Boolean>) = kof.toggle()
|
fun toggle(kof: KObservableField<Boolean>) = kof.toggle()
|
||||||
|
@ -19,7 +19,6 @@ import com.topjohnwu.magisk.model.entity.recycler.SettingsItem
|
|||||||
import com.topjohnwu.magisk.model.events.PermissionEvent
|
import com.topjohnwu.magisk.model.events.PermissionEvent
|
||||||
import com.topjohnwu.magisk.model.events.RecreateEvent
|
import com.topjohnwu.magisk.model.events.RecreateEvent
|
||||||
import com.topjohnwu.magisk.model.events.dialog.BiometricDialog
|
import com.topjohnwu.magisk.model.events.dialog.BiometricDialog
|
||||||
import com.topjohnwu.magisk.model.navigation.Navigation
|
|
||||||
import com.topjohnwu.magisk.ui.base.BaseViewModel
|
import com.topjohnwu.magisk.ui.base.BaseViewModel
|
||||||
import com.topjohnwu.magisk.ui.base.adapterOf
|
import com.topjohnwu.magisk.ui.base.adapterOf
|
||||||
import com.topjohnwu.magisk.ui.base.diffListOf
|
import com.topjohnwu.magisk.ui.base.diffListOf
|
||||||
@ -95,7 +94,7 @@ class SettingsViewModel(
|
|||||||
|
|
||||||
override fun onItemChanged(view: View, item: SettingsItem) = when (item) {
|
override fun onItemChanged(view: View, item: SettingsItem) = when (item) {
|
||||||
// use only instances you want, don't declare everything
|
// use only instances you want, don't declare everything
|
||||||
is Theme -> Navigation.theme().publish()
|
is Theme -> SettingsFragmentDirections.actionSettingsFragmentToThemeFragment().publish()
|
||||||
is Language -> RecreateEvent().publish()
|
is Language -> RecreateEvent().publish()
|
||||||
|
|
||||||
is UpdateChannel -> openUrlIfNecessary(view)
|
is UpdateChannel -> openUrlIfNecessary(view)
|
||||||
|
@ -20,7 +20,6 @@ import com.topjohnwu.magisk.model.events.PolicyUpdateEvent
|
|||||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.model.events.dialog.BiometricDialog
|
import com.topjohnwu.magisk.model.events.dialog.BiometricDialog
|
||||||
import com.topjohnwu.magisk.model.events.dialog.SuperuserRevokeDialog
|
import com.topjohnwu.magisk.model.events.dialog.SuperuserRevokeDialog
|
||||||
import com.topjohnwu.magisk.model.navigation.Navigation
|
|
||||||
import com.topjohnwu.magisk.ui.base.BaseViewModel
|
import com.topjohnwu.magisk.ui.base.BaseViewModel
|
||||||
import com.topjohnwu.magisk.ui.base.adapterOf
|
import com.topjohnwu.magisk.ui.base.adapterOf
|
||||||
import com.topjohnwu.magisk.ui.base.diffListOf
|
import com.topjohnwu.magisk.ui.base.diffListOf
|
||||||
@ -85,8 +84,11 @@ class SuperuserViewModel(
|
|||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun safetynetPressed() = Navigation.safetynet().publish()
|
private fun safetynetPressed() =
|
||||||
private fun hidePressed() = Navigation.hide().publish()
|
SuperuserFragmentDirections.actionSuperuserFragmentToSafetynetFragment().publish()
|
||||||
|
|
||||||
|
private fun hidePressed() =
|
||||||
|
SuperuserFragmentDirections.actionSuperuserFragmentToHideFragment().publish()
|
||||||
|
|
||||||
fun deletePressed(item: PolicyItem) {
|
fun deletePressed(item: PolicyItem) {
|
||||||
fun updateState() = deletePolicy(item.item)
|
fun updateState() = deletePolicy(item.item)
|
||||||
|
@ -19,10 +19,13 @@
|
|||||||
android:paddingRight="@{viewModel.insets.right}"
|
android:paddingRight="@{viewModel.insets.right}"
|
||||||
tools:ignore="RtlHardcoded">
|
tools:ignore="RtlHardcoded">
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
<fragment
|
||||||
android:id="@+id/main_nav_host"
|
android:id="@+id/main_nav_host"
|
||||||
|
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent"
|
||||||
|
app:defaultNavHost="true"
|
||||||
|
app:navGraph="@navigation/main" />
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/main_toolbar_wrapper"
|
android:id="@+id/main_toolbar_wrapper"
|
||||||
|
148
app/src/main/res/navigation/main.xml
Normal file
148
app/src/main/res/navigation/main.xml
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/main"
|
||||||
|
app:startDestination="@id/homeFragment">
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/hideFragment"
|
||||||
|
android:name="com.topjohnwu.magisk.ui.hide.HideFragment"
|
||||||
|
android:label="HideFragment"
|
||||||
|
tools:layout="@layout/fragment_hide_md2" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/homeFragment"
|
||||||
|
android:name="com.topjohnwu.magisk.ui.home.HomeFragment"
|
||||||
|
android:label="HomeFragment"
|
||||||
|
tools:layout="@layout/fragment_home_md2">
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_homeFragment_to_settingsFragment"
|
||||||
|
app:destination="@id/settingsFragment"
|
||||||
|
app:enterAnim="@anim/fragment_enter"
|
||||||
|
app:exitAnim="@anim/fragment_exit"
|
||||||
|
app:popEnterAnim="@anim/fragment_enter_pop"
|
||||||
|
app:popExitAnim="@anim/fragment_exit_pop" />
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_homeFragment_to_installFragment"
|
||||||
|
app:destination="@id/installFragment"
|
||||||
|
app:enterAnim="@anim/fragment_enter"
|
||||||
|
app:exitAnim="@anim/fragment_exit"
|
||||||
|
app:popEnterAnim="@anim/fragment_enter_pop"
|
||||||
|
app:popExitAnim="@anim/fragment_exit_pop" />
|
||||||
|
|
||||||
|
</fragment>
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/installFragment"
|
||||||
|
android:name="com.topjohnwu.magisk.ui.install.InstallFragment"
|
||||||
|
android:label="InstallFragment"
|
||||||
|
tools:layout="@layout/fragment_install_md2" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/logFragment"
|
||||||
|
android:name="com.topjohnwu.magisk.ui.log.LogFragment"
|
||||||
|
android:label="LogFragment"
|
||||||
|
tools:layout="@layout/fragment_log_md2" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/modulesFragment"
|
||||||
|
android:name="com.topjohnwu.magisk.ui.module.ModuleFragment"
|
||||||
|
android:label="ModuleFragment"
|
||||||
|
tools:layout="@layout/fragment_module_md2" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/safetynetFragment"
|
||||||
|
android:name="com.topjohnwu.magisk.ui.safetynet.SafetynetFragment"
|
||||||
|
android:label="SafetynetFragment"
|
||||||
|
tools:layout="@layout/fragment_safetynet_md2" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/settingsFragment"
|
||||||
|
android:name="com.topjohnwu.magisk.ui.settings.SettingsFragment"
|
||||||
|
android:label="SettingsFragment"
|
||||||
|
tools:layout="@layout/fragment_settings_md2">
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_settingsFragment_to_themeFragment"
|
||||||
|
app:destination="@id/themeFragment"
|
||||||
|
app:enterAnim="@anim/fragment_enter"
|
||||||
|
app:exitAnim="@anim/fragment_exit"
|
||||||
|
app:popEnterAnim="@anim/fragment_enter_pop"
|
||||||
|
app:popExitAnim="@anim/fragment_exit_pop" />
|
||||||
|
|
||||||
|
</fragment>
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/superuserFragment"
|
||||||
|
android:name="com.topjohnwu.magisk.ui.superuser.SuperuserFragment"
|
||||||
|
android:label="SuperuserFragment"
|
||||||
|
tools:layout="@layout/fragment_superuser_md2">
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_superuserFragment_to_safetynetFragment"
|
||||||
|
app:destination="@id/safetynetFragment"
|
||||||
|
app:enterAnim="@anim/fragment_enter"
|
||||||
|
app:exitAnim="@anim/fragment_exit"
|
||||||
|
app:popEnterAnim="@anim/fragment_enter_pop"
|
||||||
|
app:popExitAnim="@anim/fragment_exit_pop" />
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_superuserFragment_to_hideFragment"
|
||||||
|
app:destination="@id/hideFragment"
|
||||||
|
app:enterAnim="@anim/fragment_enter"
|
||||||
|
app:exitAnim="@anim/fragment_exit"
|
||||||
|
app:popEnterAnim="@anim/fragment_enter_pop"
|
||||||
|
app:popExitAnim="@anim/fragment_exit_pop" />
|
||||||
|
|
||||||
|
</fragment>
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/themeFragment"
|
||||||
|
android:name="com.topjohnwu.magisk.ui.theme.ThemeFragment"
|
||||||
|
android:label="ThemeFragment"
|
||||||
|
tools:layout="@layout/fragment_theme_md2" />
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_homeFragment"
|
||||||
|
app:destination="@id/homeFragment"
|
||||||
|
app:enterAnim="@anim/fragment_enter"
|
||||||
|
app:exitAnim="@anim/fragment_exit"
|
||||||
|
app:popEnterAnim="@anim/fragment_enter_pop"
|
||||||
|
app:popExitAnim="@anim/fragment_exit_pop"
|
||||||
|
app:popUpTo="@id/homeFragment"
|
||||||
|
app:popUpToInclusive="true" />
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_superuserFragment"
|
||||||
|
app:destination="@id/superuserFragment"
|
||||||
|
app:enterAnim="@anim/fragment_enter"
|
||||||
|
app:exitAnim="@anim/fragment_exit"
|
||||||
|
app:popEnterAnim="@anim/fragment_enter_pop"
|
||||||
|
app:popExitAnim="@anim/fragment_exit_pop"
|
||||||
|
app:popUpTo="@id/superuserFragment"
|
||||||
|
app:popUpToInclusive="true" />
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_logFragment"
|
||||||
|
app:destination="@id/logFragment"
|
||||||
|
app:enterAnim="@anim/fragment_enter"
|
||||||
|
app:exitAnim="@anim/fragment_exit"
|
||||||
|
app:popEnterAnim="@anim/fragment_enter_pop"
|
||||||
|
app:popExitAnim="@anim/fragment_exit_pop"
|
||||||
|
app:popUpTo="@id/logFragment"
|
||||||
|
app:popUpToInclusive="true" />
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_moduleFragment"
|
||||||
|
app:destination="@id/modulesFragment"
|
||||||
|
app:enterAnim="@anim/fragment_enter"
|
||||||
|
app:exitAnim="@anim/fragment_exit"
|
||||||
|
app:popEnterAnim="@anim/fragment_enter_pop"
|
||||||
|
app:popExitAnim="@anim/fragment_exit_pop"
|
||||||
|
app:popUpTo="@id/modulesFragment"
|
||||||
|
app:popUpToInclusive="true" />
|
||||||
|
|
||||||
|
</navigation>
|
@ -8,6 +8,7 @@ if (configPath.exists())
|
|||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.vKotlin = '1.3.70'
|
ext.vKotlin = '1.3.70'
|
||||||
|
ext.vNav = '2.3.0-alpha03'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
@ -18,6 +19,7 @@ buildscript {
|
|||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.6.1'
|
classpath 'com.android.tools.build:gradle:3.6.1'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${vKotlin}"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${vKotlin}"
|
||||||
|
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$vNav"
|
||||||
|
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
Loading…
Reference in New Issue
Block a user