mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-27 20:15:29 +00:00
Cleaned up extensions and utilities in redesign
This commit is contained in:
parent
8a03c366b8
commit
c79b79b37e
@ -0,0 +1,43 @@
|
|||||||
|
package com.topjohnwu.magisk.redesign.compat
|
||||||
|
|
||||||
|
import androidx.databinding.ViewDataBinding
|
||||||
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
|
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||||
|
import com.topjohnwu.magisk.utils.FilterableDiffObservableList
|
||||||
|
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter
|
||||||
|
import me.tatarka.bindingcollectionadapter2.ItemBinding
|
||||||
|
import me.tatarka.bindingcollectionadapter2.OnItemBind
|
||||||
|
|
||||||
|
inline fun <T : ComparableRvItem<*>> diffListOf(
|
||||||
|
vararg newItems: T
|
||||||
|
) = DiffObservableList(object : DiffObservableList.Callback<T> {
|
||||||
|
override fun areItemsTheSame(oldItem: T, newItem: T) = oldItem.genericItemSameAs(newItem)
|
||||||
|
override fun areContentsTheSame(oldItem: T, newItem: T) = oldItem.genericContentSameAs(newItem)
|
||||||
|
}).also { it.update(newItems.toList()) }
|
||||||
|
|
||||||
|
inline fun <T : ComparableRvItem<*>> filterableListOf(
|
||||||
|
vararg newItems: T
|
||||||
|
) = FilterableDiffObservableList(object : DiffObservableList.Callback<T> {
|
||||||
|
override fun areItemsTheSame(oldItem: T, newItem: T) = oldItem.genericItemSameAs(newItem)
|
||||||
|
override fun areContentsTheSame(oldItem: T, newItem: T) = oldItem.genericContentSameAs(newItem)
|
||||||
|
}).also { it.update(newItems.toList()) }
|
||||||
|
|
||||||
|
fun <T : ComparableRvItem<*>> adapterOf() = object : BindingRecyclerViewAdapter<T>() {
|
||||||
|
override fun onBindBinding(
|
||||||
|
binding: ViewDataBinding,
|
||||||
|
variableId: Int,
|
||||||
|
layoutRes: Int,
|
||||||
|
position: Int,
|
||||||
|
item: T
|
||||||
|
) {
|
||||||
|
super.onBindBinding(binding, variableId, layoutRes, position, item)
|
||||||
|
item.onBindingBound(binding)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T : ComparableRvItem<*>> itemBindingOf(
|
||||||
|
crossinline body: (ItemBinding<*>) -> Unit = {}
|
||||||
|
) = OnItemBind<T> { itemBinding, _, item ->
|
||||||
|
item.bind(itemBinding)
|
||||||
|
body(itemBinding)
|
||||||
|
}
|
@ -1,8 +1,5 @@
|
|||||||
package com.topjohnwu.magisk.redesign.hide
|
package com.topjohnwu.magisk.redesign.hide
|
||||||
|
|
||||||
import android.animation.Animator
|
|
||||||
import android.animation.AnimatorSet
|
|
||||||
import android.animation.ObjectAnimator
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Insets
|
import android.graphics.Insets
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@ -10,23 +7,15 @@ import android.view.Menu
|
|||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.animation.addListener
|
|
||||||
import androidx.core.view.isInvisible
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.marginBottom
|
|
||||||
import androidx.core.view.marginEnd
|
|
||||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.android.material.circularreveal.CircularRevealCompat
|
|
||||||
import com.google.android.material.circularreveal.CircularRevealWidget
|
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.databinding.FragmentHideMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentHideMd2Binding
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatFragment
|
import com.topjohnwu.magisk.redesign.compat.CompatFragment
|
||||||
import com.topjohnwu.magisk.redesign.compat.hideKeyboard
|
import com.topjohnwu.magisk.redesign.compat.hideKeyboard
|
||||||
|
import com.topjohnwu.magisk.utils.MotionRevealHelper
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
import kotlin.math.hypot
|
|
||||||
|
|
||||||
class HideFragment : CompatFragment<HideViewModel, FragmentHideMd2Binding>() {
|
class HideFragment : CompatFragment<HideViewModel, FragmentHideMd2Binding>() {
|
||||||
|
|
||||||
@ -95,70 +84,3 @@ class HideFragment : CompatFragment<HideViewModel, FragmentHideMd2Binding>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object MotionRevealHelper {
|
|
||||||
|
|
||||||
fun <CV> withViews(
|
|
||||||
revealable: CV,
|
|
||||||
fab: FloatingActionButton,
|
|
||||||
expanded: Boolean
|
|
||||||
) where CV : CircularRevealWidget, CV : View {
|
|
||||||
revealable.revealInfo = revealable.createRevealInfo(!expanded)
|
|
||||||
|
|
||||||
val revealInfo = revealable.createRevealInfo(expanded)
|
|
||||||
val revealAnim = revealable.createRevealAnim(revealInfo)
|
|
||||||
val moveAnim = fab.createMoveAnim(revealInfo)
|
|
||||||
|
|
||||||
AnimatorSet().also {
|
|
||||||
if (expanded) {
|
|
||||||
it.play(revealAnim).after(moveAnim)
|
|
||||||
} else {
|
|
||||||
it.play(moveAnim).after(revealAnim)
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <CV> CV.createRevealAnim(
|
|
||||||
revealInfo: CircularRevealWidget.RevealInfo
|
|
||||||
): Animator where CV : CircularRevealWidget, CV : View =
|
|
||||||
CircularRevealCompat.createCircularReveal(
|
|
||||||
this,
|
|
||||||
revealInfo.centerX,
|
|
||||||
revealInfo.centerY,
|
|
||||||
revealInfo.radius
|
|
||||||
).apply {
|
|
||||||
addListener(onStart = {
|
|
||||||
isVisible = true
|
|
||||||
}, onEnd = {
|
|
||||||
if (revealInfo.radius == 0f) {
|
|
||||||
isInvisible = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FloatingActionButton.createMoveAnim(
|
|
||||||
revealInfo: CircularRevealWidget.RevealInfo
|
|
||||||
): Animator = AnimatorSet().also {
|
|
||||||
it.interpolator = FastOutSlowInInterpolator()
|
|
||||||
it.addListener(onStart = { show() }, onEnd = { if (revealInfo.radius != 0f) hide() })
|
|
||||||
|
|
||||||
val maxX = revealInfo.centerX - marginEnd - measuredWidth / 2f
|
|
||||||
val targetX = if (revealInfo.radius == 0f) 0f else -maxX
|
|
||||||
val moveX = ObjectAnimator.ofFloat(this, View.TRANSLATION_X, targetX)
|
|
||||||
|
|
||||||
val maxY = revealInfo.centerY - marginBottom - measuredHeight / 2f
|
|
||||||
val targetY = if (revealInfo.radius == 0f) 0f else -maxY
|
|
||||||
val moveY = ObjectAnimator.ofFloat(this, View.TRANSLATION_Y, targetY)
|
|
||||||
|
|
||||||
it.playTogether(moveX, moveY)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun View.createRevealInfo(expanded: Boolean): CircularRevealWidget.RevealInfo {
|
|
||||||
val cX = measuredWidth / 2f
|
|
||||||
val cY = measuredHeight / 2f - paddingBottom
|
|
||||||
return CircularRevealWidget.RevealInfo(cX, cY, if (expanded) hypot(cX, cY) else 0f)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import android.content.pm.ApplicationInfo
|
|||||||
import androidx.databinding.Bindable
|
import androidx.databinding.Bindable
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
|
||||||
import com.topjohnwu.magisk.extensions.subscribeK
|
import com.topjohnwu.magisk.extensions.subscribeK
|
||||||
import com.topjohnwu.magisk.extensions.toggle
|
import com.topjohnwu.magisk.extensions.toggle
|
||||||
import com.topjohnwu.magisk.model.entity.HideAppInfo
|
import com.topjohnwu.magisk.model.entity.HideAppInfo
|
||||||
@ -15,9 +14,8 @@ import com.topjohnwu.magisk.model.entity.recycler.HideItem
|
|||||||
import com.topjohnwu.magisk.model.entity.recycler.HideProcessItem
|
import com.topjohnwu.magisk.model.entity.recycler.HideProcessItem
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
||||||
import com.topjohnwu.magisk.redesign.compat.Queryable
|
import com.topjohnwu.magisk.redesign.compat.Queryable
|
||||||
import com.topjohnwu.magisk.redesign.home.itemBindingOf
|
import com.topjohnwu.magisk.redesign.compat.filterableListOf
|
||||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
import com.topjohnwu.magisk.redesign.compat.itemBindingOf
|
||||||
import com.topjohnwu.magisk.utils.FilterableDiffObservableList
|
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
import com.topjohnwu.magisk.utils.currentLocale
|
import com.topjohnwu.magisk.utils.currentLocale
|
||||||
|
|
||||||
@ -127,9 +125,3 @@ class HideViewModel(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T : ComparableRvItem<*>> filterableListOf(
|
|
||||||
vararg newItems: T
|
|
||||||
) = FilterableDiffObservableList(object : DiffObservableList.Callback<T> {
|
|
||||||
override fun areItemsTheSame(oldItem: T, newItem: T) = oldItem.genericItemSameAs(newItem)
|
|
||||||
override fun areContentsTheSame(oldItem: T, newItem: T) = oldItem.genericContentSameAs(newItem)
|
|
||||||
}).also { it.update(newItems.toList()) }
|
|
@ -7,7 +7,6 @@ import com.topjohnwu.magisk.Config
|
|||||||
import com.topjohnwu.magisk.Info
|
import com.topjohnwu.magisk.Info
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
|
||||||
import com.topjohnwu.magisk.extensions.*
|
import com.topjohnwu.magisk.extensions.*
|
||||||
import com.topjohnwu.magisk.model.download.RemoteFileService
|
import com.topjohnwu.magisk.model.download.RemoteFileService
|
||||||
import com.topjohnwu.magisk.model.entity.MagiskJson
|
import com.topjohnwu.magisk.model.entity.MagiskJson
|
||||||
@ -24,12 +23,11 @@ import com.topjohnwu.magisk.model.events.dialog.UninstallDialog
|
|||||||
import com.topjohnwu.magisk.model.navigation.Navigation
|
import com.topjohnwu.magisk.model.navigation.Navigation
|
||||||
import com.topjohnwu.magisk.model.observer.Observer
|
import com.topjohnwu.magisk.model.observer.Observer
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
||||||
|
import com.topjohnwu.magisk.redesign.compat.itemBindingOf
|
||||||
import com.topjohnwu.magisk.ui.home.MagiskState
|
import com.topjohnwu.magisk.ui.home.MagiskState
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import me.tatarka.bindingcollectionadapter2.BR
|
import me.tatarka.bindingcollectionadapter2.BR
|
||||||
import me.tatarka.bindingcollectionadapter2.ItemBinding
|
|
||||||
import me.tatarka.bindingcollectionadapter2.OnItemBind
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class HomeViewModel(
|
class HomeViewModel(
|
||||||
@ -179,6 +177,12 @@ class HomeViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun String.clipVersion(other: String = ""): String {
|
||||||
|
val thisVersion = substringBefore('-')
|
||||||
|
val otherVersion = other.substringBefore('-')
|
||||||
|
return if (thisVersion != otherVersion) thisVersion else substringAfter('-')
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@ -190,16 +194,3 @@ val ManagerJson.isUpdateChannelCorrect
|
|||||||
get() = versionCode > 0
|
get() = versionCode > 0
|
||||||
val ManagerJson.isObsolete
|
val ManagerJson.isObsolete
|
||||||
get() = BuildConfig.VERSION_CODE < versionCode
|
get() = BuildConfig.VERSION_CODE < versionCode
|
||||||
|
|
||||||
fun String.clipVersion(other: String = ""): String {
|
|
||||||
val thisVersion = substringBefore('-')
|
|
||||||
val otherVersion = other.substringBefore('-')
|
|
||||||
return if (thisVersion != otherVersion) thisVersion else substringAfter('-')
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <T : ComparableRvItem<*>> itemBindingOf(
|
|
||||||
crossinline body: (ItemBinding<*>) -> Unit = {}
|
|
||||||
) = OnItemBind<T> { itemBinding, _, item ->
|
|
||||||
item.bind(itemBinding)
|
|
||||||
body(itemBinding)
|
|
||||||
}
|
|
@ -11,7 +11,7 @@ import com.topjohnwu.magisk.R
|
|||||||
import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding
|
||||||
import com.topjohnwu.magisk.redesign.MainActivity
|
import com.topjohnwu.magisk.redesign.MainActivity
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatFragment
|
import com.topjohnwu.magisk.redesign.compat.CompatFragment
|
||||||
import com.topjohnwu.magisk.redesign.hide.MotionRevealHelper
|
import com.topjohnwu.magisk.utils.MotionRevealHelper
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
|
||||||
class LogFragment : CompatFragment<LogViewModel, FragmentLogMd2Binding>() {
|
class LogFragment : CompatFragment<LogViewModel, FragmentLogMd2Binding>() {
|
||||||
|
@ -12,8 +12,8 @@ import com.topjohnwu.magisk.model.entity.recycler.ConsoleItem
|
|||||||
import com.topjohnwu.magisk.model.entity.recycler.LogItem
|
import com.topjohnwu.magisk.model.entity.recycler.LogItem
|
||||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
||||||
import com.topjohnwu.magisk.redesign.home.itemBindingOf
|
import com.topjohnwu.magisk.redesign.compat.diffListOf
|
||||||
import com.topjohnwu.magisk.redesign.superuser.diffListOf
|
import com.topjohnwu.magisk.redesign.compat.itemBindingOf
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
@ -17,8 +17,8 @@ import com.topjohnwu.magisk.redesign.MainActivity
|
|||||||
import com.topjohnwu.magisk.redesign.ReselectionTarget
|
import com.topjohnwu.magisk.redesign.ReselectionTarget
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatFragment
|
import com.topjohnwu.magisk.redesign.compat.CompatFragment
|
||||||
import com.topjohnwu.magisk.redesign.compat.hideKeyboard
|
import com.topjohnwu.magisk.redesign.compat.hideKeyboard
|
||||||
import com.topjohnwu.magisk.redesign.hide.MotionRevealHelper
|
|
||||||
import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener
|
import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener
|
||||||
|
import com.topjohnwu.magisk.utils.MotionRevealHelper
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
|
||||||
class ModuleFragment : CompatFragment<ModuleViewModel, FragmentModuleMd2Binding>(),
|
class ModuleFragment : CompatFragment<ModuleViewModel, FragmentModuleMd2Binding>(),
|
||||||
|
@ -2,7 +2,6 @@ package com.topjohnwu.magisk.redesign.module
|
|||||||
|
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
import androidx.databinding.Bindable
|
import androidx.databinding.Bindable
|
||||||
import androidx.databinding.ViewDataBinding
|
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.Config
|
import com.topjohnwu.magisk.Config
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
@ -19,17 +18,13 @@ import com.topjohnwu.magisk.model.entity.recycler.*
|
|||||||
import com.topjohnwu.magisk.model.events.InstallExternalModuleEvent
|
import com.topjohnwu.magisk.model.events.InstallExternalModuleEvent
|
||||||
import com.topjohnwu.magisk.model.events.OpenChangelogEvent
|
import com.topjohnwu.magisk.model.events.OpenChangelogEvent
|
||||||
import com.topjohnwu.magisk.model.events.dialog.ModuleInstallDialog
|
import com.topjohnwu.magisk.model.events.dialog.ModuleInstallDialog
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
import com.topjohnwu.magisk.redesign.compat.*
|
||||||
import com.topjohnwu.magisk.redesign.compat.Queryable
|
|
||||||
import com.topjohnwu.magisk.redesign.home.itemBindingOf
|
|
||||||
import com.topjohnwu.magisk.redesign.superuser.diffListOf
|
|
||||||
import com.topjohnwu.magisk.tasks.RepoUpdater
|
import com.topjohnwu.magisk.tasks.RepoUpdater
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
import com.topjohnwu.magisk.utils.currentLocale
|
import com.topjohnwu.magisk.utils.currentLocale
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@ -294,16 +289,3 @@ class ModuleViewModel(
|
|||||||
prependIf(isNotEmpty(), item)
|
prependIf(isNotEmpty(), item)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : ComparableRvItem<*>> adapterOf() = object : BindingRecyclerViewAdapter<T>() {
|
|
||||||
override fun onBindBinding(
|
|
||||||
binding: ViewDataBinding,
|
|
||||||
variableId: Int,
|
|
||||||
layoutRes: Int,
|
|
||||||
position: Int,
|
|
||||||
item: T
|
|
||||||
) {
|
|
||||||
super.onBindBinding(binding, variableId, layoutRes, position, item)
|
|
||||||
item.onBindingBound(binding)
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,9 +17,9 @@ 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.model.navigation.Navigation
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
||||||
import com.topjohnwu.magisk.redesign.home.itemBindingOf
|
import com.topjohnwu.magisk.redesign.compat.adapterOf
|
||||||
import com.topjohnwu.magisk.redesign.module.adapterOf
|
import com.topjohnwu.magisk.redesign.compat.diffListOf
|
||||||
import com.topjohnwu.magisk.redesign.superuser.diffListOf
|
import com.topjohnwu.magisk.redesign.compat.itemBindingOf
|
||||||
import com.topjohnwu.magisk.utils.PatchAPK
|
import com.topjohnwu.magisk.utils.PatchAPK
|
||||||
import com.topjohnwu.magisk.utils.Utils
|
import com.topjohnwu.magisk.utils.Utils
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
|
@ -18,9 +18,9 @@ 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.model.navigation.Navigation
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
||||||
import com.topjohnwu.magisk.redesign.home.itemBindingOf
|
import com.topjohnwu.magisk.redesign.compat.diffListOf
|
||||||
|
import com.topjohnwu.magisk.redesign.compat.itemBindingOf
|
||||||
import com.topjohnwu.magisk.utils.BiometricHelper
|
import com.topjohnwu.magisk.utils.BiometricHelper
|
||||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
|
||||||
import com.topjohnwu.magisk.utils.currentLocale
|
import com.topjohnwu.magisk.utils.currentLocale
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
|
|
||||||
@ -143,10 +143,3 @@ class SuperuserViewModel(
|
|||||||
db.delete(policy.uid).andThen(Single.just(policy))
|
db.delete(policy.uid).andThen(Single.just(policy))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T : ComparableRvItem<*>> diffListOf(
|
|
||||||
vararg newItems: T
|
|
||||||
) = DiffObservableList(object : DiffObservableList.Callback<T> {
|
|
||||||
override fun areItemsTheSame(oldItem: T, newItem: T) = oldItem.genericItemSameAs(newItem)
|
|
||||||
override fun areContentsTheSame(oldItem: T, newItem: T) = oldItem.genericContentSameAs(newItem)
|
|
||||||
}).also { it.update(newItems.toList()) }
|
|
@ -1,19 +1,12 @@
|
|||||||
package com.topjohnwu.magisk.redesign.theme
|
package com.topjohnwu.magisk.redesign.theme
|
||||||
|
|
||||||
import com.topjohnwu.magisk.BR
|
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem
|
import com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.ThemeItem
|
|
||||||
import com.topjohnwu.magisk.model.events.RecreateEvent
|
import com.topjohnwu.magisk.model.events.RecreateEvent
|
||||||
import com.topjohnwu.magisk.model.events.dialog.DarkThemeDialog
|
import com.topjohnwu.magisk.model.events.dialog.DarkThemeDialog
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
||||||
import com.topjohnwu.magisk.redesign.home.itemBindingOf
|
|
||||||
import com.topjohnwu.magisk.redesign.superuser.diffListOf
|
|
||||||
|
|
||||||
class ThemeViewModel : CompatViewModel(), TappableHeadlineItem.Listener {
|
class ThemeViewModel : CompatViewModel(), TappableHeadlineItem.Listener {
|
||||||
|
|
||||||
val items = diffListOf(*Theme.values().map { ThemeItem(it) }.toTypedArray())
|
|
||||||
val itemBinding = itemBindingOf<ThemeItem> { it.bindExtra(BR.viewModel, this) }
|
|
||||||
|
|
||||||
val themeHeadline = TappableHeadlineItem.ThemeMode
|
val themeHeadline = TappableHeadlineItem.ThemeMode
|
||||||
|
|
||||||
override fun onItemPressed(item: TappableHeadlineItem) = when (item) {
|
override fun onItemPressed(item: TappableHeadlineItem) = when (item) {
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
package com.topjohnwu.magisk.utils
|
||||||
|
|
||||||
|
import android.animation.Animator
|
||||||
|
import android.animation.AnimatorSet
|
||||||
|
import android.animation.ObjectAnimator
|
||||||
|
import android.view.View
|
||||||
|
import androidx.core.animation.addListener
|
||||||
|
import androidx.core.view.isInvisible
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.core.view.marginBottom
|
||||||
|
import androidx.core.view.marginEnd
|
||||||
|
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
||||||
|
import com.google.android.material.circularreveal.CircularRevealCompat
|
||||||
|
import com.google.android.material.circularreveal.CircularRevealWidget
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
import kotlin.math.hypot
|
||||||
|
|
||||||
|
object MotionRevealHelper {
|
||||||
|
|
||||||
|
fun <CV> withViews(
|
||||||
|
revealable: CV,
|
||||||
|
fab: FloatingActionButton,
|
||||||
|
expanded: Boolean
|
||||||
|
) where CV : CircularRevealWidget, CV : View {
|
||||||
|
revealable.revealInfo = revealable.createRevealInfo(!expanded)
|
||||||
|
|
||||||
|
val revealInfo = revealable.createRevealInfo(expanded)
|
||||||
|
val revealAnim = revealable.createRevealAnim(revealInfo)
|
||||||
|
val moveAnim = fab.createMoveAnim(revealInfo)
|
||||||
|
|
||||||
|
AnimatorSet().also {
|
||||||
|
if (expanded) {
|
||||||
|
it.play(revealAnim).after(moveAnim)
|
||||||
|
} else {
|
||||||
|
it.play(moveAnim).after(revealAnim)
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <CV> CV.createRevealAnim(
|
||||||
|
revealInfo: CircularRevealWidget.RevealInfo
|
||||||
|
): Animator where CV : CircularRevealWidget, CV : View =
|
||||||
|
CircularRevealCompat.createCircularReveal(
|
||||||
|
this,
|
||||||
|
revealInfo.centerX,
|
||||||
|
revealInfo.centerY,
|
||||||
|
revealInfo.radius
|
||||||
|
).apply {
|
||||||
|
addListener(onStart = {
|
||||||
|
isVisible = true
|
||||||
|
}, onEnd = {
|
||||||
|
if (revealInfo.radius == 0f) {
|
||||||
|
isInvisible = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FloatingActionButton.createMoveAnim(
|
||||||
|
revealInfo: CircularRevealWidget.RevealInfo
|
||||||
|
): Animator = AnimatorSet().also {
|
||||||
|
it.interpolator = FastOutSlowInInterpolator()
|
||||||
|
it.addListener(onStart = { show() }, onEnd = { if (revealInfo.radius != 0f) hide() })
|
||||||
|
|
||||||
|
// fixme rtl
|
||||||
|
val maxX = revealInfo.centerX - marginEnd - measuredWidth / 2f
|
||||||
|
val targetX = if (revealInfo.radius == 0f) 0f else -maxX
|
||||||
|
val moveX = ObjectAnimator.ofFloat(this, View.TRANSLATION_X, targetX)
|
||||||
|
|
||||||
|
val maxY = revealInfo.centerY - marginBottom - measuredHeight / 2f
|
||||||
|
val targetY = if (revealInfo.radius == 0f) 0f else -maxY
|
||||||
|
val moveY = ObjectAnimator.ofFloat(this, View.TRANSLATION_Y, targetY)
|
||||||
|
|
||||||
|
it.playTogether(moveX, moveY)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun View.createRevealInfo(expanded: Boolean): CircularRevealWidget.RevealInfo {
|
||||||
|
val cX = measuredWidth / 2f
|
||||||
|
val cY = measuredHeight / 2f - paddingBottom
|
||||||
|
return CircularRevealWidget.RevealInfo(cX, cY, if (expanded) hypot(cX, cY) else 0f)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -19,7 +19,7 @@ import com.topjohnwu.magisk.BR
|
|||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
import com.topjohnwu.magisk.databinding.DialogMagiskBaseBinding
|
import com.topjohnwu.magisk.databinding.DialogMagiskBaseBinding
|
||||||
import com.topjohnwu.magisk.redesign.home.itemBindingOf
|
import com.topjohnwu.magisk.redesign.compat.itemBindingOf
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapters
|
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapters
|
||||||
import me.tatarka.bindingcollectionadapter2.ItemBinding
|
import me.tatarka.bindingcollectionadapter2.ItemBinding
|
||||||
|
Loading…
Reference in New Issue
Block a user