Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
1b881322
Commit
1b881322
authored
Mar 17, 2020
by
Viktor De Pasquale
Committed by
John Wu
Mar 26, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated the app to use navigation components instead of custom solution
Welcome to mid 2018.
parent
922e36cf
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
262 additions
and
379 deletions
+262
-379
build.gradle
app/build.gradle
+8
-7
FlashActivity.kt
...n/java/com/topjohnwu/magisk/legacy/flash/FlashActivity.kt
+2
-3
SuRequestActivity.kt
...om/topjohnwu/magisk/legacy/surequest/SuRequestActivity.kt
+2
-3
MagiskNavigationEvent.kt
...opjohnwu/magisk/model/navigation/MagiskNavigationEvent.kt
+0
-94
Navigation.kt
.../java/com/topjohnwu/magisk/model/navigation/Navigation.kt
+0
-75
NavigationWrapper.kt
...om/topjohnwu/magisk/model/navigation/NavigationWrapper.kt
+18
-0
MainActivity.kt
app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt
+34
-41
BaseUIActivity.kt
.../main/java/com/topjohnwu/magisk/ui/base/BaseUIActivity.kt
+20
-16
BaseUIFragment.kt
.../main/java/com/topjohnwu/magisk/ui/base/BaseUIFragment.kt
+6
-1
BaseViewModel.kt
...c/main/java/com/topjohnwu/magisk/ui/base/BaseViewModel.kt
+6
-0
CompatNavigationDelegate.kt
.../com/topjohnwu/magisk/ui/base/CompatNavigationDelegate.kt
+0
-127
CompatView.kt
app/src/main/java/com/topjohnwu/magisk/ui/base/CompatView.kt
+2
-1
HomeFragment.kt
...rc/main/java/com/topjohnwu/magisk/ui/home/HomeFragment.kt
+2
-2
HomeViewModel.kt
...c/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt
+1
-2
SettingsViewModel.kt
...ava/com/topjohnwu/magisk/ui/settings/SettingsViewModel.kt
+1
-2
SuperuserViewModel.kt
...a/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt
+5
-3
activity_main_md2.xml
app/src/main/res/layout/activity_main_md2.xml
+5
-2
main.xml
app/src/main/res/navigation/main.xml
+148
-0
build.gradle
build.gradle
+2
-0
No files found.
app/build.gradle
View file @
1b881322
apply
plugin:
'com.android.application'
apply
plugin:
'kotlin-android'
apply
plugin:
'kotlin-android-extensions'
apply
plugin:
'kotlin-kapt'
plugins
{
id
(
"com.android.application"
)
id
(
"kotlin-android"
)
id
(
"kotlin-android-extensions"
)
id
(
"kotlin-kapt"
)
id
(
"androidx.navigation.safeargs.kotlin"
)
}
kapt
{
correctErrorTypes
=
true
...
...
@@ -22,7 +25,7 @@ android {
javaCompileOptions
{
annotationProcessorOptions
{
arguments
=
[
"room.incremental"
:
"true"
]
arguments
=
[
"room.incremental"
:
"true"
]
}
}
}
...
...
@@ -65,7 +68,6 @@ dependencies {
implementation
'com.github.topjohnwu:jtar:1.0.0'
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
'io.reactivex.rxjava2:rxjava:2.2.18'
...
...
@@ -116,7 +118,6 @@ dependencies {
implementation
"androidx.room:room-rxjava2:${vRoom}"
kapt
"androidx.room:room-compiler:${vRoom}"
def
vNav
=
'2.2.1'
implementation
"androidx.navigation:navigation-fragment-ktx:${vNav}"
implementation
"androidx.navigation:navigation-ui-ktx:${vNav}"
...
...
app/src/main/java/com/topjohnwu/magisk/legacy/flash/FlashActivity.kt
View file @
1b881322
...
...
@@ -6,6 +6,7 @@ import android.content.pm.ActivityInfo
import
android.net.Uri
import
android.os.Bundle
import
androidx.core.net.toUri
import
androidx.navigation.NavController
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.core.Const
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.ViewEvent
import
com.topjohnwu.magisk.ui.base.BaseUIActivity
import
com.topjohnwu.magisk.ui.base.CompatNavigationDelegate
import
org.koin.androidx.viewmodel.ext.android.viewModel
import
java.io.File
...
...
@@ -25,8 +25,7 @@ open class FlashActivity : BaseUIActivity<FlashViewModel, ActivityFlashBinding>(
override
val
layoutRes
:
Int
=
R
.
layout
.
activity_flash
override
val
viewModel
:
FlashViewModel
by
viewModel
()
override
val
navigation
:
CompatNavigationDelegate
<
BaseUIActivity
<
FlashViewModel
,
ActivityFlashBinding
>>?
=
null
override
val
navigation
:
NavController
?
=
null
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
requestedOrientation
=
ActivityInfo
.
SCREEN_ORIENTATION_NOSENSOR
...
...
app/src/main/java/com/topjohnwu/magisk/legacy/surequest/SuRequestActivity.kt
View file @
1b881322
...
...
@@ -7,6 +7,7 @@ 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.core.su.SuCallbackHandler
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.ViewEvent
import
com.topjohnwu.magisk.ui.base.BaseUIActivity
import
com.topjohnwu.magisk.ui.base.CompatNavigationDelegate
import
org.koin.androidx.viewmodel.ext.android.viewModel
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
viewModel
:
SuRequestViewModel
by
viewModel
()
override
val
navigation
:
CompatNavigationDelegate
<
BaseUIActivity
<
SuRequestViewModel
,
ActivityRequestBinding
>>?
=
null
override
val
navigation
:
NavController
?
=
null
override
fun
onBackPressed
()
{
viewModel
.
denyPressed
()
...
...
app/src/main/java/com/topjohnwu/magisk/model/navigation/MagiskNavigationEvent.kt
deleted
100644 → 0
View file @
922e36cf
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
}
app/src/main/java/com/topjohnwu/magisk/model/navigation/Navigation.kt
View file @
1b881322
...
...
@@ -6,80 +6,9 @@ import android.os.Build
import
com.topjohnwu.magisk.core.Const
import
com.topjohnwu.magisk.core.intent
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
{
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
)
{
context
.
intent
<
MainActivity
>()
.
putExtra
(
...
...
@@ -92,10 +21,6 @@ object Navigation {
.
also
{
context
.
startActivity
(
it
)
}
}
object
Main
{
const
val
OPEN_NAV
=
1
}
private
val
ACTION_APPLICATION_PREFERENCES
get
()
=
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
N
)
{
Intent
.
ACTION_APPLICATION_PREFERENCES
...
...
app/src/main/java/com/topjohnwu/magisk/model/navigation/NavigationWrapper.kt
0 → 100644
View file @
1b881322
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
()
}
}
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt
View file @
1b881322
...
...
@@ -7,47 +7,31 @@ import android.view.ViewTreeObserver
import
android.view.WindowManager
import
androidx.coordinatorlayout.widget.CoordinatorLayout
import
androidx.core.graphics.Insets
import
androidx.core.view.forEach
import
androidx.core.view.setPadding
import
androidx.core.view.updateLayoutParams
import
androidx.fragment.app.Fragment
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.core.Const
import
com.topjohnwu.magisk.core.Info
import
com.topjohnwu.magisk.databinding.ActivityMainMd2Binding
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.CompatNavigationDelegate
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.ui.home.HomeFragmentDirections
import
com.topjohnwu.magisk.utils.HideBottomViewOnScrollBehavior
import
com.topjohnwu.magisk.utils.HideTopViewOnScrollBehavior
import
com.topjohnwu.magisk.utils.HideableBehavior
import
com.topjohnwu.magisk.view.MagiskDialog
import
com.topjohnwu.superuser.Shell
import
org.koin.androidx.viewmodel.ext.android.viewModel
import
kotlin.reflect.KClass
open
class
MainActivity
:
BaseUIActivity
<
MainViewModel
,
ActivityMainMd2Binding
>(),
FragNavController
.
TransactionListener
{
open
class
MainActivity
:
BaseUIActivity
<
MainViewModel
,
ActivityMainMd2Binding
>()
{
override
val
layoutRes
=
R
.
layout
.
activity_main_md2
override
val
viewModel
by
viewModel
<
MainViewModel
>()
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
//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
...
...
@@ -56,6 +40,9 @@ open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>(
binding
.
mainNavigation
.
setPadding
(
0
)
}
protected
var
isRoot
=
true
private
set
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
...
...
@@ -70,6 +57,25 @@ open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>(
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
)
binding
.
mainToolbarWrapper
.
updateLayoutParams
<
CoordinatorLayout
.
LayoutParams
>
{
...
...
@@ -80,28 +86,26 @@ open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>(
}
binding
.
mainNavigation
.
setOnNavigationItemSelectedListener
{
when
(
it
.
itemId
)
{
R
.
id
.
homeFragment
->
Navigation
.
home
()
R
.
id
.
modulesFragment
->
Navigation
.
modules
()
R
.
id
.
superuserFragment
->
Navigation
.
superuser
()
R
.
id
.
logFragment
->
Navigation
.
log
()
R
.
id
.
homeFragment
->
MainDirections
.
actionHomeFragment
()
R
.
id
.
modulesFragment
->
MainDirections
.
actionModuleFragment
()
R
.
id
.
superuserFragment
->
MainDirections
.
actionSuperuserFragment
()
R
.
id
.
logFragment
->
MainDirections
.
actionLogFragment
()
else
->
throw
NotImplementedError
(
"Id ${it.itemId} is not defined as selectable"
)
}.
dispatchOnSelf
()
}.
navigate
()
true
}
binding
.
mainNavigation
.
setOnNavigationItemReselectedListener
{
navigation
.
onReselected
()
(
currentFragment
as
?
ReselectionTarget
)
?
.
onReselected
()
}
binding
.
mainNavigation
.
viewTreeObserver
.
addOnGlobalLayoutListener
(
navObserver
)
if
(
intent
.
getBooleanExtra
(
Const
.
Key
.
OPEN_SETTINGS
,
false
))
{
Navigation
.
settings
().
dispatchOnSelf
()
HomeFragmentDirections
.
actionHomeFragmentToSettingsFragment
().
navigate
()
}
if
(
savedInstanceState
!=
null
)
{
onTabTransaction
(
null
,
-
1
)
if
(!
navigation
.
isRoot
)
{
if
(!
isRoot
)
{
requestNavigationHidden
()
}
}
...
...
@@ -129,17 +133,6 @@ open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>(
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
)
{
viewModel
.
insets
.
value
=
insets
}
...
...
app/src/main/java/com/topjohnwu/magisk/ui/base/BaseUIActivity.kt
View file @
1b881322
...
...
@@ -9,7 +9,8 @@ import androidx.core.graphics.Insets
import
androidx.databinding.DataBindingUtil
import
androidx.databinding.OnRebindCallback
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.core.Config
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.ViewEvent
import
com.topjohnwu.magisk.ui.theme.Theme
import
kotlin.reflect.KClass
abstract
class
BaseUIActivity
<
ViewModel
:
BaseViewModel
,
Binding
:
ViewDataBinding
>
:
BaseActivity
(),
CompatView
<
ViewModel
>,
EventHandler
{
...
...
@@ -28,20 +28,30 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
protected
abstract
val
layoutRes
:
Int
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
navigation
by
lazy
{
CompatNavigationDelegate
(
this
)
as
CompatNavigationDelegate
?
}
override
val
navigation
by
lazy
{
kotlin
.
runCatching
{
findNavController
(
navHost
)
}.
getOrNull
()
}
private
val
delegate
by
lazy
{
CompatDelegate
(
this
)
}
open
val
navHost
:
Int
=
0
open
val
snackbarView
get
()
=
binding
.
root
open
val
baseFragments
=
listOf
<
KClass
<
out
Fragment
>>()
init
{
val
theme
=
Config
.
darkThemeExtended
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
?)
{
setTheme
(
themeRes
)
super
.
onCreate
(
savedInstanceState
)
...
...
@@ -61,12 +71,6 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
})
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
()
{
...
...
@@ -74,11 +78,6 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
delegate
.
onResume
()
}
override
fun
onSaveInstanceState
(
outState
:
Bundle
)
{
super
.
onSaveInstanceState
(
outState
)
navigation
?.
onSaveInstanceState
(
outState
)
}
override
fun
onEventDispatched
(
event
:
ViewEvent
)
{
delegate
.
onEventExecute
(
event
,
this
)
when
(
event
)
{
...
...
@@ -87,7 +86,7 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
}
override
fun
onBackPressed
()
{
if
(
navigation
==
null
||
navigation
?.
onBackPressed
()
?.
not
()
==
true
)
{
if
(
navigation
==
null
||
currentFragment
?.
onBackPressed
()
?.
not
()
==
true
)
{
super
.
onBackPressed
()
}
}
...
...
@@ -97,4 +96,9 @@ abstract class BaseUIActivity<ViewModel : BaseViewModel, Binding : ViewDataBindi
}
protected
fun
ViewEvent
.
dispatchOnSelf
()
=
onEventDispatched
(
this
)
fun
NavDirections
.
navigate
()
{
navigation
?.
navigate
(
this
)
}
}
app/src/main/java/com/topjohnwu/magisk/ui/base/BaseUIFragment.kt
View file @
1b881322
...
...
@@ -9,6 +9,7 @@ import androidx.databinding.DataBindingUtil
import
androidx.databinding.OnRebindCallback
import
androidx.databinding.ViewDataBinding
import
androidx.fragment.app.Fragment
import
androidx.navigation.NavDirections
import
com.topjohnwu.magisk.BR
import
com.topjohnwu.magisk.extensions.startAnimations
import
com.topjohnwu.magisk.model.events.EventHandler
...
...
@@ -22,7 +23,7 @@ abstract class BaseUIFragment<ViewModel : BaseViewModel, Binding : ViewDataBindi
protected
abstract
val
layoutRes
:
Int
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
)
}
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
)
fun
NavDirections
.
navigate
()
{
navigation
?.
navigate
(
this
)
}
}
app/src/main/java/com/topjohnwu/magisk/ui/base/BaseViewModel.kt
View file @
1b881322
...
...
@@ -7,11 +7,13 @@ import androidx.databinding.PropertyChangeRegistry
import
androidx.lifecycle.LiveData
import
androidx.lifecycle.MutableLiveData
import
androidx.lifecycle.ViewModel
import
androidx.navigation.NavDirections
import
com.topjohnwu.magisk.BR
import
com.topjohnwu.magisk.core.Info
import
com.topjohnwu.magisk.core.base.BaseActivity
import
com.topjohnwu.magisk.extensions.doOnSubscribeUi
import
com.topjohnwu.magisk.model.events.*
import
com.topjohnwu.magisk.model.navigation.NavigationWrapper
import
com.topjohnwu.magisk.model.observer.Observer
import
com.topjohnwu.magisk.utils.KObservableField
import
io.reactivex.*
...
...
@@ -99,6 +101,10 @@ abstract class BaseViewModel(
_viewEvents
.
postValue
(
SimpleViewEvent
(
this
))
}
fun
NavDirections
.
publish
()
{
_viewEvents
.
postValue
(
NavigationWrapper
(
this
))
}
fun
Disposable
.
add
()
{
disposables
.
add
(
this
)
}
...
...
app/src/main/java/com/topjohnwu/magisk/ui/base/CompatNavigationDelegate.kt
deleted
100644 → 0
View file @
922e36cf
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
)
}
}
app/src/main/java/com/topjohnwu/magisk/ui/base/CompatView.kt
View file @
1b881322
...
...
@@ -2,12 +2,13 @@ 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
:
CompatNavigationDelegate
<*>
?
val
navigation
:
NavController
?
fun
peekSystemWindowInsets
(
insets
:
Insets
)
=
Unit
fun
consumeSystemWindowInsets
(
insets
:
Insets
):
Insets
?
=
null
...
...
app/src/main/java/com/topjohnwu/magisk/ui/home/HomeFragment.kt
View file @
1b881322
...
...
@@ -5,7 +5,6 @@ import android.view.*
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
import
com.topjohnwu.magisk.model.events.RebootEvent
import
com.topjohnwu.magisk.model.navigation.Navigation
import
com.topjohnwu.magisk.ui.base.BaseUIFragment
import
com.topjohnwu.superuser.Shell
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
)
{
R
.
id
.
action_settings
->
Navigation
.
settings
().
dispatchOnSelf
()
R
.
id
.
action_settings
->
HomeFragmentDirections
.
actionHomeFragmentToSettingsFragment
()
.
navigate
()
R
.
id
.
action_reboot
->
RebootEvent
.
inflateMenu
(
activity
).
show
()
else
->
null
}
?.
let
{
true
}
?:
super
.
onOptionsItemSelected
(
item
)
...
...
app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt
View file @
1b881322
...
...
@@ -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.ManagerInstallDialog
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.itemBindingOf
import
com.topjohnwu.magisk.utils.KObservableField
...
...
@@ -114,7 +113,7 @@ class HomeViewModel(
Manifest
.
permission
.
READ_EXTERNAL_STORAGE
,
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
).
map
{
check
(
it
);
it
}
.
subscribeK
{
Navigation
.
install
().
publish
()
}
.
subscribeK
{
HomeFragmentDirections
.
actionHomeFragmentToInstallFragment
().
publish
()
}
.
add
()
fun
toggle
(
kof
:
KObservableField
<
Boolean
>)
=
kof
.
toggle
()
...
...
app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsViewModel.kt
View file @
1b881322
...
...
@@ -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.RecreateEvent
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.adapterOf
import
com.topjohnwu.magisk.ui.base.diffListOf
...
...
@@ -95,7 +94,7 @@ class SettingsViewModel(
override
fun
onItemChanged
(
view
:
View
,
item
:
SettingsItem
)
=
when
(
item
)
{
// use only instances you want, don't declare everything
is
Theme
->
Navigation
.
theme
().
publish
()
is
Theme
->
SettingsFragmentDirections
.
actionSettingsFragmentToThemeFragment
().
publish
()
is
Language
->
RecreateEvent
().
publish
()
is
UpdateChannel
->
openUrlIfNecessary
(
view
)
...
...
app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt
View file @
1b881322
...
...
@@ -20,7 +20,6 @@ import com.topjohnwu.magisk.model.events.PolicyUpdateEvent
import
com.topjohnwu.magisk.model.events.SnackbarEvent
import
com.topjohnwu.magisk.model.events.dialog.BiometricDialog
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.adapterOf
import
com.topjohnwu.magisk.ui.base.diffListOf
...
...
@@ -85,8 +84,11 @@ class SuperuserViewModel(
else
->
Unit
}
private
fun
safetynetPressed
()
=
Navigation
.
safetynet
().
publish
()
private
fun
hidePressed
()
=
Navigation
.
hide
().
publish
()
private
fun
safetynetPressed
()
=
SuperuserFragmentDirections
.
actionSuperuserFragmentToSafetynetFragment
().
publish
()
private
fun
hidePressed
()
=
SuperuserFragmentDirections
.
actionSuperuserFragmentToHideFragment
().
publish
()
fun
deletePressed
(
item
:
PolicyItem
)
{
fun
updateState
()
=
deletePolicy
(
item
.
item
)
...
...
app/src/main/res/layout/activity_main_md2.xml
View file @
1b881322
...
...
@@ -19,10 +19,13 @@
android:paddingRight=
"@{viewModel.insets.right}"
tools:ignore=
"RtlHardcoded"
>
<
androidx.fragment.app.FragmentContainerView
<
fragment
android:id=
"@+id/main_nav_host"
android:name=
"androidx.navigation.fragment.NavHostFragment"
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
android:id=
"@+id/main_toolbar_wrapper"
...
...
app/src/main/res/navigation/main.xml
0 → 100644
View file @
1b881322
<?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>
\ No newline at end of file
build.gradle
View file @
1b881322
...
...
@@ -8,6 +8,7 @@ if (configPath.exists())
buildscript
{
ext
.
vKotlin
=
'1.3.70'
ext
.
vNav
=
'2.3.0-alpha03'
repositories
{
google
()
...
...
@@ -18,6 +19,7 @@ buildscript {
dependencies
{
classpath
'com.android.tools.build:gradle:3.6.1'
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
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment