mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-19 23:58:29 +00:00
Cleanup and move things around
This commit is contained in:
parent
3bcaf0ed5b
commit
683cfee88b
@ -1,8 +1,17 @@
|
|||||||
package com.topjohnwu.magisk.arch
|
package com.topjohnwu.magisk.arch
|
||||||
|
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.ViewModelStoreOwner
|
||||||
|
import com.topjohnwu.magisk.core.di.ServiceLocator
|
||||||
|
import com.topjohnwu.magisk.ui.home.HomeViewModel
|
||||||
|
import com.topjohnwu.magisk.ui.install.InstallViewModel
|
||||||
|
import com.topjohnwu.magisk.ui.log.LogViewModel
|
||||||
|
import com.topjohnwu.magisk.ui.superuser.SuperuserViewModel
|
||||||
|
import com.topjohnwu.magisk.ui.surequest.SuRequestViewModel
|
||||||
|
|
||||||
interface ViewModelHolder : LifecycleOwner {
|
interface ViewModelHolder : LifecycleOwner, ViewModelStoreOwner {
|
||||||
|
|
||||||
val viewModel: BaseViewModel
|
val viewModel: BaseViewModel
|
||||||
|
|
||||||
@ -17,3 +26,23 @@ interface ViewModelHolder : LifecycleOwner {
|
|||||||
*/
|
*/
|
||||||
fun onEventDispatched(event: ViewEvent) {}
|
fun onEventDispatched(event: ViewEvent) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object VMFactory : ViewModelProvider.Factory {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||||
|
return when (modelClass) {
|
||||||
|
HomeViewModel::class.java -> HomeViewModel(ServiceLocator.networkService)
|
||||||
|
LogViewModel::class.java -> LogViewModel(ServiceLocator.logRepo)
|
||||||
|
SuperuserViewModel::class.java -> SuperuserViewModel(ServiceLocator.policyDB)
|
||||||
|
InstallViewModel::class.java -> InstallViewModel(ServiceLocator.networkService)
|
||||||
|
SuRequestViewModel::class.java ->
|
||||||
|
SuRequestViewModel(ServiceLocator.policyDB, ServiceLocator.timeoutPrefs)
|
||||||
|
else -> modelClass.newInstance()
|
||||||
|
} as T
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified VM : ViewModel> ViewModelHolder.viewModel() =
|
||||||
|
lazy(LazyThreadSafetyMode.NONE) {
|
||||||
|
ViewModelProvider(this, VMFactory)[VM::class.java]
|
||||||
|
}
|
||||||
|
@ -3,9 +3,6 @@ package com.topjohnwu.magisk.core.di
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.text.method.LinkMovementMethod
|
import android.text.method.LinkMovementMethod
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
|
||||||
import androidx.lifecycle.ViewModelStoreOwner
|
|
||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import com.topjohnwu.magisk.core.Const
|
import com.topjohnwu.magisk.core.Const
|
||||||
import com.topjohnwu.magisk.core.data.SuLogDatabase
|
import com.topjohnwu.magisk.core.data.SuLogDatabase
|
||||||
@ -15,11 +12,6 @@ import com.topjohnwu.magisk.core.data.magiskdb.StringDao
|
|||||||
import com.topjohnwu.magisk.core.repository.LogRepository
|
import com.topjohnwu.magisk.core.repository.LogRepository
|
||||||
import com.topjohnwu.magisk.core.repository.NetworkService
|
import com.topjohnwu.magisk.core.repository.NetworkService
|
||||||
import com.topjohnwu.magisk.ktx.deviceProtectedContext
|
import com.topjohnwu.magisk.ktx.deviceProtectedContext
|
||||||
import com.topjohnwu.magisk.ui.home.HomeViewModel
|
|
||||||
import com.topjohnwu.magisk.ui.install.InstallViewModel
|
|
||||||
import com.topjohnwu.magisk.ui.log.LogViewModel
|
|
||||||
import com.topjohnwu.magisk.ui.superuser.SuperuserViewModel
|
|
||||||
import com.topjohnwu.magisk.ui.surequest.SuRequestViewModel
|
|
||||||
import io.noties.markwon.Markwon
|
import io.noties.markwon.Markwon
|
||||||
import io.noties.markwon.utils.NoCopySpannableFactory
|
import io.noties.markwon.utils.NoCopySpannableFactory
|
||||||
|
|
||||||
@ -50,27 +42,8 @@ object ServiceLocator {
|
|||||||
createApiService(retrofit, Const.Url.GITHUB_API_URL)
|
createApiService(retrofit, Const.Url.GITHUB_API_URL)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
object VMFactory : ViewModelProvider.Factory {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
|
||||||
return when (modelClass) {
|
|
||||||
HomeViewModel::class.java -> HomeViewModel(networkService)
|
|
||||||
LogViewModel::class.java -> LogViewModel(logRepo)
|
|
||||||
SuperuserViewModel::class.java -> SuperuserViewModel(policyDB)
|
|
||||||
InstallViewModel::class.java -> InstallViewModel(networkService)
|
|
||||||
SuRequestViewModel::class.java -> SuRequestViewModel(policyDB, timeoutPrefs)
|
|
||||||
else -> modelClass.newInstance()
|
|
||||||
} as T
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified VM : ViewModel> ViewModelStoreOwner.viewModel() =
|
|
||||||
lazy(LazyThreadSafetyMode.NONE) {
|
|
||||||
ViewModelProvider(this, ServiceLocator.VMFactory)[VM::class.java]
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createSuLogDatabase(context: Context) =
|
private fun createSuLogDatabase(context: Context) =
|
||||||
Room.databaseBuilder(context, SuLogDatabase::class.java, "sulogs.db")
|
Room.databaseBuilder(context, SuLogDatabase::class.java, "sulogs.db")
|
||||||
.fallbackToDestructiveMigration()
|
.fallbackToDestructiveMigration()
|
||||||
|
@ -30,6 +30,7 @@ import com.google.android.material.chip.Chip
|
|||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.core.di.ServiceLocator
|
import com.topjohnwu.magisk.core.di.ServiceLocator
|
||||||
|
import com.topjohnwu.magisk.utils.TextHolder
|
||||||
import com.topjohnwu.superuser.internal.UiThreadHandler
|
import com.topjohnwu.superuser.internal.UiThreadHandler
|
||||||
import com.topjohnwu.widget.IndeterminateCheckBox
|
import com.topjohnwu.widget.IndeterminateCheckBox
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
@ -289,3 +290,8 @@ fun TextView.setTextColorAttr(attr: Int) {
|
|||||||
context.theme.resolveAttribute(attr, tv, true)
|
context.theme.resolveAttribute(attr, tv, true)
|
||||||
setTextColor(tv.data)
|
setTextColor(tv.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BindingAdapter("android:text")
|
||||||
|
fun TextView.setText(text: TextHolder) {
|
||||||
|
this.text = text.getText(context.resources)
|
||||||
|
}
|
||||||
|
@ -11,7 +11,6 @@ import android.content.pm.PackageInfo
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.database.Cursor
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.drawable.AdaptiveIconDrawable
|
import android.graphics.drawable.AdaptiveIconDrawable
|
||||||
@ -22,12 +21,10 @@ import android.os.Build.VERSION.SDK_INT
|
|||||||
import android.os.Process
|
import android.os.Process
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewTreeObserver
|
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
||||||
import androidx.transition.AutoTransition
|
import androidx.transition.AutoTransition
|
||||||
import androidx.transition.TransitionManager
|
import androidx.transition.TransitionManager
|
||||||
@ -35,7 +32,6 @@ import com.topjohnwu.magisk.R
|
|||||||
import com.topjohnwu.magisk.core.Const
|
import com.topjohnwu.magisk.core.Const
|
||||||
import com.topjohnwu.magisk.core.utils.RootUtils
|
import com.topjohnwu.magisk.core.utils.RootUtils
|
||||||
import com.topjohnwu.magisk.core.utils.currentLocale
|
import com.topjohnwu.magisk.core.utils.currentLocale
|
||||||
import com.topjohnwu.magisk.utils.DynamicClassLoader
|
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.Array
|
import kotlin.Array
|
||||||
@ -172,12 +168,6 @@ fun Intent.toCommand(args: MutableList<String> = mutableListOf()): MutableList<S
|
|||||||
|
|
||||||
fun Context.cachedFile(name: String) = File(cacheDir, name)
|
fun Context.cachedFile(name: String) = File(cacheDir, name)
|
||||||
|
|
||||||
fun <Result> Cursor.toList(transformer: (Cursor) -> Result): List<Result> {
|
|
||||||
val out = mutableListOf<Result>()
|
|
||||||
while (moveToNext()) out.add(transformer(this))
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ApplicationInfo.getLabel(pm: PackageManager): String {
|
fun ApplicationInfo.getLabel(pm: PackageManager): String {
|
||||||
runCatching {
|
runCatching {
|
||||||
if (labelRes > 0) {
|
if (labelRes > 0) {
|
||||||
@ -192,9 +182,6 @@ fun ApplicationInfo.getLabel(pm: PackageManager): String {
|
|||||||
return loadLabel(pm).toString()
|
return loadLabel(pm).toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T> T.createClassLoader(apk: File) =
|
|
||||||
DynamicClassLoader(apk, T::class.java.classLoader)
|
|
||||||
|
|
||||||
fun Context.unwrap(): Context {
|
fun Context.unwrap(): Context {
|
||||||
var context = this
|
var context = this
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -217,21 +204,6 @@ fun Activity.hideKeyboard() {
|
|||||||
view.clearFocus()
|
view.clearFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Fragment.hideKeyboard() {
|
|
||||||
activity?.hideKeyboard()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun View.setOnViewReadyListener(callback: () -> Unit) = addOnGlobalLayoutListener(true, callback)
|
|
||||||
|
|
||||||
fun View.addOnGlobalLayoutListener(oneShot: Boolean = false, callback: () -> Unit) =
|
|
||||||
viewTreeObserver.addOnGlobalLayoutListener(object :
|
|
||||||
ViewTreeObserver.OnGlobalLayoutListener {
|
|
||||||
override fun onGlobalLayout() {
|
|
||||||
if (oneShot) viewTreeObserver.removeOnGlobalLayoutListener(this)
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
fun ViewGroup.startAnimations() {
|
fun ViewGroup.startAnimations() {
|
||||||
val transition = AutoTransition()
|
val transition = AutoTransition()
|
||||||
.setInterpolator(FastOutSlowInInterpolator())
|
.setInterpolator(FastOutSlowInInterpolator())
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.ktx
|
|
||||||
|
|
||||||
import androidx.databinding.ObservableList
|
|
||||||
|
|
||||||
fun <T> ObservableList<T>.addOnListChangedCallback(
|
|
||||||
onChanged: ((sender: ObservableList<T>) -> Unit)? = null,
|
|
||||||
onItemRangeRemoved: ((sender: ObservableList<T>, positionStart: Int, itemCount: Int) -> Unit)? = null,
|
|
||||||
onItemRangeMoved: ((sender: ObservableList<T>, fromPosition: Int, toPosition: Int, itemCount: Int) -> Unit)? = null,
|
|
||||||
onItemRangeInserted: ((sender: ObservableList<T>, positionStart: Int, itemCount: Int) -> Unit)? = null,
|
|
||||||
onItemRangeChanged: ((sender: ObservableList<T>, positionStart: Int, itemCount: Int) -> Unit)? = null
|
|
||||||
) = addOnListChangedCallback(object : ObservableList.OnListChangedCallback<ObservableList<T>>() {
|
|
||||||
override fun onChanged(sender: ObservableList<T>?) {
|
|
||||||
onChanged?.invoke(sender ?: return)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemRangeRemoved(
|
|
||||||
sender: ObservableList<T>?,
|
|
||||||
positionStart: Int,
|
|
||||||
itemCount: Int
|
|
||||||
) {
|
|
||||||
onItemRangeRemoved?.invoke(
|
|
||||||
sender ?: return,
|
|
||||||
positionStart,
|
|
||||||
itemCount
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemRangeMoved(
|
|
||||||
sender: ObservableList<T>?,
|
|
||||||
fromPosition: Int,
|
|
||||||
toPosition: Int,
|
|
||||||
itemCount: Int
|
|
||||||
) {
|
|
||||||
onItemRangeMoved?.invoke(
|
|
||||||
sender ?: return,
|
|
||||||
fromPosition,
|
|
||||||
toPosition,
|
|
||||||
itemCount
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemRangeInserted(
|
|
||||||
sender: ObservableList<T>?,
|
|
||||||
positionStart: Int,
|
|
||||||
itemCount: Int
|
|
||||||
) {
|
|
||||||
onItemRangeInserted?.invoke(
|
|
||||||
sender ?: return,
|
|
||||||
positionStart,
|
|
||||||
itemCount
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemRangeChanged(
|
|
||||||
sender: ObservableList<T>?,
|
|
||||||
positionStart: Int,
|
|
||||||
itemCount: Int
|
|
||||||
) {
|
|
||||||
onItemRangeChanged?.invoke(
|
|
||||||
sender ?: return,
|
|
||||||
positionStart,
|
|
||||||
itemCount
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
@ -1,11 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.ktx
|
|
||||||
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.flow.flatMapMerge
|
|
||||||
import kotlinx.coroutines.flow.flow
|
|
||||||
|
|
||||||
inline fun <T, R> Flow<T>.concurrentMap(crossinline transform: suspend (T) -> R): Flow<R> {
|
|
||||||
return flatMapMerge { value ->
|
|
||||||
flow { emit(transform(value)) }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +1,15 @@
|
|||||||
package com.topjohnwu.magisk.ktx
|
package com.topjohnwu.magisk.ktx
|
||||||
|
|
||||||
import androidx.collection.SparseArrayCompat
|
import androidx.collection.SparseArrayCompat
|
||||||
import timber.log.Timber
|
import com.topjohnwu.magisk.core.utils.currentLocale
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.flatMapMerge
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
|
import java.text.DateFormat
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
@ -45,8 +49,27 @@ fun <T> MutableSet<T>.synchronized(): MutableSet<T> = Collections.synchronizedSe
|
|||||||
|
|
||||||
fun <K, V> MutableMap<K, V>.synchronized(): MutableMap<K, V> = Collections.synchronizedMap(this)
|
fun <K, V> MutableMap<K, V>.synchronized(): MutableMap<K, V> = Collections.synchronizedMap(this)
|
||||||
|
|
||||||
fun SimpleDateFormat.parseOrNull(date: String) =
|
|
||||||
runCatching { parse(date) }.onFailure { Timber.e(it) }.getOrNull()
|
|
||||||
|
|
||||||
fun Class<*>.reflectField(name: String): Field =
|
fun Class<*>.reflectField(name: String): Field =
|
||||||
getDeclaredField(name).apply { isAccessible = true }
|
getDeclaredField(name).apply { isAccessible = true }
|
||||||
|
|
||||||
|
inline fun <T, R> Flow<T>.concurrentMap(crossinline transform: suspend (T) -> R): Flow<R> {
|
||||||
|
return flatMapMerge { value ->
|
||||||
|
flow { emit(transform(value)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Long.toTime(format: DateFormat) = format.format(this).orEmpty()
|
||||||
|
|
||||||
|
val timeFormatStandard by lazy {
|
||||||
|
SimpleDateFormat(
|
||||||
|
"yyyy-MM-dd'T'HH:mm:ss",
|
||||||
|
currentLocale
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val timeDateFormat: DateFormat by lazy {
|
||||||
|
DateFormat.getDateTimeInstance(
|
||||||
|
DateFormat.DEFAULT,
|
||||||
|
DateFormat.DEFAULT,
|
||||||
|
currentLocale
|
||||||
|
)
|
||||||
|
}
|
@ -1,21 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.ktx
|
|
||||||
|
|
||||||
import com.topjohnwu.magisk.core.utils.currentLocale
|
|
||||||
import java.text.DateFormat
|
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
|
|
||||||
val now get() = System.currentTimeMillis()
|
|
||||||
|
|
||||||
fun Long.toTime(format: DateFormat) = format.format(this).orEmpty()
|
|
||||||
|
|
||||||
val timeFormatStandard by lazy { SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss",
|
|
||||||
currentLocale
|
|
||||||
) }
|
|
||||||
|
|
||||||
val timeDateFormat: DateFormat by lazy {
|
|
||||||
DateFormat.getDateTimeInstance(
|
|
||||||
DateFormat.DEFAULT,
|
|
||||||
DateFormat.DEFAULT,
|
|
||||||
currentLocale
|
|
||||||
)
|
|
||||||
}
|
|
@ -15,10 +15,10 @@ import com.topjohnwu.magisk.MainDirections
|
|||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.BaseMainActivity
|
import com.topjohnwu.magisk.arch.BaseMainActivity
|
||||||
import com.topjohnwu.magisk.arch.BaseViewModel
|
import com.topjohnwu.magisk.arch.BaseViewModel
|
||||||
|
import com.topjohnwu.magisk.arch.viewModel
|
||||||
import com.topjohnwu.magisk.core.Config
|
import com.topjohnwu.magisk.core.Config
|
||||||
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.core.di.viewModel
|
|
||||||
import com.topjohnwu.magisk.core.isRunningAsStub
|
import com.topjohnwu.magisk.core.isRunningAsStub
|
||||||
import com.topjohnwu.magisk.databinding.ActivityMainMd2Binding
|
import com.topjohnwu.magisk.databinding.ActivityMainMd2Binding
|
||||||
import com.topjohnwu.magisk.ktx.startAnimations
|
import com.topjohnwu.magisk.ktx.startAnimations
|
||||||
|
@ -10,7 +10,7 @@ import androidx.appcompat.widget.SearchView
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.BaseFragment
|
import com.topjohnwu.magisk.arch.BaseFragment
|
||||||
import com.topjohnwu.magisk.core.di.viewModel
|
import com.topjohnwu.magisk.arch.viewModel
|
||||||
import com.topjohnwu.magisk.databinding.FragmentDenyMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentDenyMd2Binding
|
||||||
import com.topjohnwu.magisk.ktx.hideKeyboard
|
import com.topjohnwu.magisk.ktx.hideKeyboard
|
||||||
import rikka.recyclerview.addEdgeSpacing
|
import rikka.recyclerview.addEdgeSpacing
|
||||||
@ -35,7 +35,7 @@ class DenyListFragment : BaseFragment<FragmentDenyMd2Binding>() {
|
|||||||
|
|
||||||
binding.appList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
binding.appList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||||
if (newState != RecyclerView.SCROLL_STATE_IDLE) hideKeyboard()
|
if (newState != RecyclerView.SCROLL_STATE_IDLE) activity?.hideKeyboard()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -10,9 +10,9 @@ import androidx.navigation.NavDeepLinkBuilder
|
|||||||
import com.topjohnwu.magisk.MainDirections
|
import com.topjohnwu.magisk.MainDirections
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.BaseFragment
|
import com.topjohnwu.magisk.arch.BaseFragment
|
||||||
|
import com.topjohnwu.magisk.arch.viewModel
|
||||||
import com.topjohnwu.magisk.core.Const
|
import com.topjohnwu.magisk.core.Const
|
||||||
import com.topjohnwu.magisk.core.cmp
|
import com.topjohnwu.magisk.core.cmp
|
||||||
import com.topjohnwu.magisk.core.di.viewModel
|
|
||||||
import com.topjohnwu.magisk.databinding.FragmentFlashMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentFlashMd2Binding
|
||||||
import com.topjohnwu.magisk.ui.MainActivity
|
import com.topjohnwu.magisk.ui.MainActivity
|
||||||
|
|
||||||
|
@ -19,7 +19,10 @@ import com.topjohnwu.magisk.databinding.diffListOf
|
|||||||
import com.topjohnwu.magisk.databinding.itemBindingOf
|
import com.topjohnwu.magisk.databinding.itemBindingOf
|
||||||
import com.topjohnwu.magisk.databinding.set
|
import com.topjohnwu.magisk.databinding.set
|
||||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.ktx.*
|
import com.topjohnwu.magisk.ktx.reboot
|
||||||
|
import com.topjohnwu.magisk.ktx.synchronized
|
||||||
|
import com.topjohnwu.magisk.ktx.timeFormatStandard
|
||||||
|
import com.topjohnwu.magisk.ktx.toTime
|
||||||
import com.topjohnwu.superuser.CallbackList
|
import com.topjohnwu.superuser.CallbackList
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -100,7 +103,8 @@ class FlashViewModel : BaseViewModel() {
|
|||||||
|
|
||||||
private fun savePressed() = withExternalRW {
|
private fun savePressed() = withExternalRW {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
val name = "magisk_install_log_%s.log".format(now.toTime(timeFormatStandard))
|
val name = "magisk_install_log_%s.log".format(
|
||||||
|
System.currentTimeMillis().toTime(timeFormatStandard))
|
||||||
val file = MediaStoreUtils.getFile(name, true)
|
val file = MediaStoreUtils.getFile(name, true)
|
||||||
file.uri.outputStream().bufferedWriter().use { writer ->
|
file.uri.outputStream().bufferedWriter().use { writer ->
|
||||||
synchronized(logItems) {
|
synchronized(logItems) {
|
||||||
|
@ -6,8 +6,8 @@ import android.widget.ImageView
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.BaseFragment
|
import com.topjohnwu.magisk.arch.BaseFragment
|
||||||
|
import com.topjohnwu.magisk.arch.viewModel
|
||||||
import com.topjohnwu.magisk.core.Info
|
import com.topjohnwu.magisk.core.Info
|
||||||
import com.topjohnwu.magisk.core.di.viewModel
|
|
||||||
import com.topjohnwu.magisk.core.download.DownloadService
|
import com.topjohnwu.magisk.core.download.DownloadService
|
||||||
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
|
||||||
import com.topjohnwu.magisk.events.RebootEvent
|
import com.topjohnwu.magisk.events.RebootEvent
|
||||||
|
@ -2,7 +2,7 @@ package com.topjohnwu.magisk.ui.install
|
|||||||
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.BaseFragment
|
import com.topjohnwu.magisk.arch.BaseFragment
|
||||||
import com.topjohnwu.magisk.core.di.viewModel
|
import com.topjohnwu.magisk.arch.viewModel
|
||||||
import com.topjohnwu.magisk.databinding.FragmentInstallMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentInstallMd2Binding
|
||||||
|
|
||||||
class InstallFragment : BaseFragment<FragmentInstallMd2Binding>() {
|
class InstallFragment : BaseFragment<FragmentInstallMd2Binding>() {
|
||||||
|
@ -8,7 +8,7 @@ import android.view.View
|
|||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.BaseFragment
|
import com.topjohnwu.magisk.arch.BaseFragment
|
||||||
import com.topjohnwu.magisk.core.di.viewModel
|
import com.topjohnwu.magisk.arch.viewModel
|
||||||
import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding
|
||||||
import com.topjohnwu.magisk.ui.MainActivity
|
import com.topjohnwu.magisk.ui.MainActivity
|
||||||
import com.topjohnwu.magisk.utils.MotionRevealHelper
|
import com.topjohnwu.magisk.utils.MotionRevealHelper
|
||||||
|
@ -14,7 +14,6 @@ import com.topjohnwu.magisk.databinding.diffListOf
|
|||||||
import com.topjohnwu.magisk.databinding.itemBindingOf
|
import com.topjohnwu.magisk.databinding.itemBindingOf
|
||||||
import com.topjohnwu.magisk.databinding.set
|
import com.topjohnwu.magisk.databinding.set
|
||||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.ktx.now
|
|
||||||
import com.topjohnwu.magisk.ktx.timeFormatStandard
|
import com.topjohnwu.magisk.ktx.timeFormatStandard
|
||||||
import com.topjohnwu.magisk.ktx.toTime
|
import com.topjohnwu.magisk.ktx.toTime
|
||||||
import com.topjohnwu.magisk.view.TextItem
|
import com.topjohnwu.magisk.view.TextItem
|
||||||
@ -59,7 +58,8 @@ class LogViewModel(
|
|||||||
|
|
||||||
fun saveMagiskLog() = withExternalRW {
|
fun saveMagiskLog() = withExternalRW {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
val filename = "magisk_log_%s.log".format(now.toTime(timeFormatStandard))
|
val filename = "magisk_log_%s.log".format(
|
||||||
|
System.currentTimeMillis().toTime(timeFormatStandard))
|
||||||
val logFile = MediaStoreUtils.getFile(filename, true)
|
val logFile = MediaStoreUtils.getFile(filename, true)
|
||||||
logFile.uri.outputStream().bufferedWriter().use { file ->
|
logFile.uri.outputStream().bufferedWriter().use { file ->
|
||||||
file.write("---Detected Device Info---\n\n")
|
file.write("---Detected Device Info---\n\n")
|
||||||
|
@ -5,8 +5,8 @@ import android.view.View
|
|||||||
import com.topjohnwu.magisk.MainDirections
|
import com.topjohnwu.magisk.MainDirections
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.BaseFragment
|
import com.topjohnwu.magisk.arch.BaseFragment
|
||||||
|
import com.topjohnwu.magisk.arch.viewModel
|
||||||
import com.topjohnwu.magisk.core.Const
|
import com.topjohnwu.magisk.core.Const
|
||||||
import com.topjohnwu.magisk.core.di.viewModel
|
|
||||||
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
|
||||||
import com.topjohnwu.magisk.databinding.RvItem
|
import com.topjohnwu.magisk.databinding.RvItem
|
||||||
import com.topjohnwu.magisk.databinding.adapterOf
|
import com.topjohnwu.magisk.databinding.adapterOf
|
||||||
|
@ -4,7 +4,7 @@ import android.os.Bundle
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.BaseFragment
|
import com.topjohnwu.magisk.arch.BaseFragment
|
||||||
import com.topjohnwu.magisk.core.di.viewModel
|
import com.topjohnwu.magisk.arch.viewModel
|
||||||
import com.topjohnwu.magisk.databinding.FragmentSettingsMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentSettingsMd2Binding
|
||||||
import rikka.recyclerview.addEdgeSpacing
|
import rikka.recyclerview.addEdgeSpacing
|
||||||
import rikka.recyclerview.addItemSpacing
|
import rikka.recyclerview.addItemSpacing
|
||||||
|
@ -4,7 +4,7 @@ import android.os.Bundle
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.BaseFragment
|
import com.topjohnwu.magisk.arch.BaseFragment
|
||||||
import com.topjohnwu.magisk.core.di.viewModel
|
import com.topjohnwu.magisk.arch.viewModel
|
||||||
import com.topjohnwu.magisk.databinding.AnyDiffRvItem
|
import com.topjohnwu.magisk.databinding.AnyDiffRvItem
|
||||||
import com.topjohnwu.magisk.databinding.FragmentSuperuserMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentSuperuserMd2Binding
|
||||||
import com.topjohnwu.magisk.databinding.adapterOf
|
import com.topjohnwu.magisk.databinding.adapterOf
|
||||||
|
@ -10,7 +10,7 @@ import android.view.WindowManager
|
|||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.UIActivity
|
import com.topjohnwu.magisk.arch.UIActivity
|
||||||
import com.topjohnwu.magisk.core.di.viewModel
|
import com.topjohnwu.magisk.arch.viewModel
|
||||||
import com.topjohnwu.magisk.core.su.SuCallbackHandler
|
import com.topjohnwu.magisk.core.su.SuCallbackHandler
|
||||||
import com.topjohnwu.magisk.core.su.SuCallbackHandler.REQUEST
|
import com.topjohnwu.magisk.core.su.SuCallbackHandler.REQUEST
|
||||||
import com.topjohnwu.magisk.databinding.ActivityRequestBinding
|
import com.topjohnwu.magisk.databinding.ActivityRequestBinding
|
||||||
|
@ -9,7 +9,7 @@ import android.widget.FrameLayout
|
|||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.BaseFragment
|
import com.topjohnwu.magisk.arch.BaseFragment
|
||||||
import com.topjohnwu.magisk.core.di.viewModel
|
import com.topjohnwu.magisk.arch.viewModel
|
||||||
import com.topjohnwu.magisk.databinding.FragmentThemeMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentThemeMd2Binding
|
||||||
import com.topjohnwu.magisk.databinding.ItemThemeBindingImpl
|
import com.topjohnwu.magisk.databinding.ItemThemeBindingImpl
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package com.topjohnwu.magisk.utils
|
package com.topjohnwu.magisk.utils
|
||||||
|
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.databinding.BindingAdapter
|
|
||||||
|
|
||||||
abstract class TextHolder {
|
abstract class TextHolder {
|
||||||
|
|
||||||
@ -46,9 +44,3 @@ abstract class TextHolder {
|
|||||||
fun Int.asText(): TextHolder = TextHolder.Resource(this)
|
fun Int.asText(): TextHolder = TextHolder.Resource(this)
|
||||||
fun Int.asText(vararg params: Any): TextHolder = TextHolder.ResourceArgs(this, *params)
|
fun Int.asText(vararg params: Any): TextHolder = TextHolder.ResourceArgs(this, *params)
|
||||||
fun CharSequence.asText(): TextHolder = TextHolder.String(this)
|
fun CharSequence.asText(): TextHolder = TextHolder.String(this)
|
||||||
|
|
||||||
|
|
||||||
@BindingAdapter("android:text")
|
|
||||||
fun TextView.setText(text: TextHolder) {
|
|
||||||
this.text = text.getText(context.resources)
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user