Rename TransitiveText

This commit is contained in:
topjohnwu 2021-04-09 01:32:37 -07:00
parent 0f95a7babe
commit 706d53065b
9 changed files with 112 additions and 121 deletions

View File

@ -5,7 +5,6 @@ import android.view.KeyEvent
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.graphics.Insets
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.databinding.OnRebindCallback import androidx.databinding.OnRebindCallback
import androidx.databinding.ViewDataBinding import androidx.databinding.ViewDataBinding

View File

@ -6,11 +6,11 @@ import com.google.android.material.snackbar.Snackbar
import com.topjohnwu.magisk.arch.ActivityExecutor import com.topjohnwu.magisk.arch.ActivityExecutor
import com.topjohnwu.magisk.arch.BaseUIActivity import com.topjohnwu.magisk.arch.BaseUIActivity
import com.topjohnwu.magisk.arch.ViewEvent import com.topjohnwu.magisk.arch.ViewEvent
import com.topjohnwu.magisk.utils.TransitiveText import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.magisk.utils.asTransitive import com.topjohnwu.magisk.utils.asText
class SnackbarEvent constructor( class SnackbarEvent constructor(
private val msg: TransitiveText, private val msg: TextHolder,
private val length: Int = Snackbar.LENGTH_SHORT, private val length: Int = Snackbar.LENGTH_SHORT,
private val builder: Snackbar.() -> Unit = {} private val builder: Snackbar.() -> Unit = {}
) : ViewEvent(), ActivityExecutor { ) : ViewEvent(), ActivityExecutor {
@ -19,13 +19,13 @@ class SnackbarEvent constructor(
@StringRes res: Int, @StringRes res: Int,
length: Int = Snackbar.LENGTH_SHORT, length: Int = Snackbar.LENGTH_SHORT,
builder: Snackbar.() -> Unit = {} builder: Snackbar.() -> Unit = {}
) : this(res.asTransitive(), length, builder) ) : this(res.asText(), length, builder)
constructor( constructor(
msg: String, msg: String,
length: Int = Snackbar.LENGTH_SHORT, length: Int = Snackbar.LENGTH_SHORT,
builder: Snackbar.() -> Unit = {} builder: Snackbar.() -> Unit = {}
) : this(msg.asTransitive(), length, builder) ) : this(msg.asText(), length, builder)
private fun snackbar( private fun snackbar(

View File

@ -16,7 +16,7 @@ import com.topjohnwu.magisk.events.dialog.EnvFixDialog
import com.topjohnwu.magisk.events.dialog.ManagerInstallDialog import com.topjohnwu.magisk.events.dialog.ManagerInstallDialog
import com.topjohnwu.magisk.events.dialog.UninstallDialog import com.topjohnwu.magisk.events.dialog.UninstallDialog
import com.topjohnwu.magisk.ktx.await import com.topjohnwu.magisk.ktx.await
import com.topjohnwu.magisk.utils.asTransitive import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.utils.set import com.topjohnwu.magisk.utils.set
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -54,13 +54,13 @@ class HomeViewModel(
val magiskInstalledVersion get() = Info.env.run { val magiskInstalledVersion get() = Info.env.run {
if (isActive) if (isActive)
"$magiskVersionString ($magiskVersionCode)".asTransitive() "$magiskVersionString ($magiskVersionCode)".asText()
else else
R.string.not_available.asTransitive() R.string.not_available.asText()
} }
@get:Bindable @get:Bindable
var managerRemoteVersion = R.string.loading.asTransitive() var managerRemoteVersion = R.string.loading.asText()
set(value) = set(value, field, { field = it }, BR.managerRemoteVersion) set(value) = set(value, field, { field = it }, BR.managerRemoteVersion)
val managerInstalledVersion = Info.stub?.let { val managerInstalledVersion = Info.stub?.let {
@ -92,14 +92,14 @@ class HomeViewModel(
} }
managerRemoteVersion = managerRemoteVersion =
"${magisk.version} (${magisk.versionCode}) (${stub.versionCode})".asTransitive() "${magisk.version} (${magisk.versionCode}) (${stub.versionCode})".asText()
launch { launch {
ensureEnv() ensureEnv()
} }
} ?: { } ?: {
state = State.LOADING_FAILED state = State.LOADING_FAILED
managerRemoteVersion = R.string.not_available.asTransitive() managerRemoteVersion = R.string.not_available.asText()
}() }()
} }

View File

@ -9,8 +9,8 @@ import androidx.databinding.Bindable
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.databinding.ObservableItem import com.topjohnwu.magisk.databinding.ObservableItem
import com.topjohnwu.magisk.utils.TransitiveText import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.magisk.utils.asTransitive import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.utils.set import com.topjohnwu.magisk.utils.set
import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.magisk.view.MagiskDialog
import org.koin.core.KoinComponent import org.koin.core.KoinComponent
@ -21,9 +21,9 @@ sealed class BaseSettingsItem : ObservableItem<BaseSettingsItem>() {
override val layoutRes get() = R.layout.item_settings override val layoutRes get() = R.layout.item_settings
open val icon: Int get() = 0 open val icon: Int get() = 0
open val title: TransitiveText get() = TransitiveText.EMPTY open val title: TextHolder get() = TextHolder.EMPTY
@get:Bindable @get:Bindable
open val description: TransitiveText get() = TransitiveText.EMPTY open val description: TextHolder get() = TextHolder.EMPTY
// --- // ---
@ -151,8 +151,8 @@ sealed class BaseSettingsItem : ObservableItem<BaseSettingsItem>() {
open val entries get() = resources.getArrayOrEmpty(entryRes) open val entries get() = resources.getArrayOrEmpty(entryRes)
open val entryValues get() = resources.getArrayOrEmpty(entryValRes) open val entryValues get() = resources.getArrayOrEmpty(entryValRes)
override val description: TransitiveText override val description: TextHolder
get() = entries.getOrNull(value)?.asTransitive() ?: TransitiveText.EMPTY get() = entries.getOrNull(value)?.asText() ?: TextHolder.EMPTY
private fun Resources.getArrayOrEmpty(id: Int): Array<String> = private fun Resources.getArrayOrEmpty(id: Int): Array<String> =
runCatching { getStringArray(id) }.getOrDefault(emptyArray()) runCatching { getStringArray(id) }.getOrDefault(emptyArray())

View File

@ -20,9 +20,9 @@ import com.topjohnwu.magisk.databinding.DialogSettingsAppNameBinding
import com.topjohnwu.magisk.databinding.DialogSettingsDownloadPathBinding import com.topjohnwu.magisk.databinding.DialogSettingsDownloadPathBinding
import com.topjohnwu.magisk.databinding.DialogSettingsUpdateChannelBinding import com.topjohnwu.magisk.databinding.DialogSettingsUpdateChannelBinding
import com.topjohnwu.magisk.ktx.get import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.utils.TransitiveText import com.topjohnwu.magisk.utils.TextHolder
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.asTransitive import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.utils.set import com.topjohnwu.magisk.utils.set
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -31,7 +31,7 @@ import kotlinx.coroutines.launch
// --- Customization // --- Customization
object Customization : BaseSettingsItem.Section() { object Customization : BaseSettingsItem.Section() {
override val title = R.string.settings_customization.asTransitive() override val title = R.string.settings_customization.asText()
} }
object Language : BaseSettingsItem.Selector() { object Language : BaseSettingsItem.Selector() {
@ -40,7 +40,7 @@ object Language : BaseSettingsItem.Selector() {
Config.locale = entryValues[it] Config.locale = entryValues[it]
} }
override val title = R.string.language.asTransitive() override val title = R.string.language.asText()
override var entries = emptyArray<String>() override var entries = emptyArray<String>()
override var entryValues = emptyArray<String>() override var entryValues = emptyArray<String>()
@ -58,18 +58,18 @@ object Language : BaseSettingsItem.Selector() {
object Theme : BaseSettingsItem.Blank() { object Theme : BaseSettingsItem.Blank() {
override val icon = R.drawable.ic_paint override val icon = R.drawable.ic_paint
override val title = R.string.section_theme.asTransitive() override val title = R.string.section_theme.asText()
} }
// --- App // --- App
object AppSettings : BaseSettingsItem.Section() { object AppSettings : BaseSettingsItem.Section() {
override val title = R.string.home_app_title.asTransitive() override val title = R.string.home_app_title.asText()
} }
object ClearRepoCache : BaseSettingsItem.Blank() { object ClearRepoCache : BaseSettingsItem.Blank() {
override val title = R.string.settings_clear_cache_title.asTransitive() override val title = R.string.settings_clear_cache_title.asText()
override val description = R.string.settings_clear_cache_summary.asTransitive() override val description = R.string.settings_clear_cache_summary.asText()
override fun refresh() { override fun refresh() {
isEnabled = Info.env.isActive isEnabled = Info.env.isActive
@ -77,8 +77,8 @@ object ClearRepoCache : BaseSettingsItem.Blank() {
} }
object Hide : BaseSettingsItem.Input() { object Hide : BaseSettingsItem.Input() {
override val title = R.string.settings_hide_app_title.asTransitive() override val title = R.string.settings_hide_app_title.asText()
override val description = R.string.settings_hide_app_summary.asTransitive() override val description = R.string.settings_hide_app_summary.asText()
override var value = "" override var value = ""
set(value) = setV(value, field, { field = it }) set(value) = setV(value, field, { field = it })
@ -106,21 +106,21 @@ object Hide : BaseSettingsItem.Input() {
} }
object Restore : BaseSettingsItem.Blank() { object Restore : BaseSettingsItem.Blank() {
override val title = R.string.settings_restore_app_title.asTransitive() override val title = R.string.settings_restore_app_title.asText()
override val description = R.string.settings_restore_app_summary.asTransitive() override val description = R.string.settings_restore_app_summary.asText()
} }
object AddShortcut : BaseSettingsItem.Blank() { object AddShortcut : BaseSettingsItem.Blank() {
override val title = R.string.add_shortcut_title.asTransitive() override val title = R.string.add_shortcut_title.asText()
override val description = R.string.setting_add_shortcut_summary.asTransitive() override val description = R.string.setting_add_shortcut_summary.asText()
} }
object DownloadPath : BaseSettingsItem.Input() { object DownloadPath : BaseSettingsItem.Input() {
override var value = Config.downloadDir override var value = Config.downloadDir
set(value) = setV(value, field, { field = it }) { Config.downloadDir = it } set(value) = setV(value, field, { field = it }) { Config.downloadDir = it }
override val title = R.string.settings_download_path_title.asTransitive() override val title = R.string.settings_download_path_title.asText()
override val description get() = path.asTransitive() override val description get() = path.asText()
override val inputResult: String get() = result override val inputResult: String get() = result
@ -143,24 +143,24 @@ object UpdateChannel : BaseSettingsItem.Selector() {
Info.remote = Info.EMPTY_REMOTE Info.remote = Info.EMPTY_REMOTE
} }
override val title = R.string.settings_update_channel_title.asTransitive() override val title = R.string.settings_update_channel_title.asText()
override val entries: Array<String> = resources.getStringArray(R.array.update_channel).let { override val entries: Array<String> = resources.getStringArray(R.array.update_channel).let {
if (BuildConfig.VERSION_CODE % 100 == 0) if (BuildConfig.VERSION_CODE % 100 == 0)
it.toMutableList().apply { removeAt(Config.Value.CANARY_CHANNEL) }.toTypedArray() it.toMutableList().apply { removeAt(Config.Value.CANARY_CHANNEL) }.toTypedArray()
else it else it
} }
override val description override val description
get() = entries.getOrNull(value)?.asTransitive() ?: TransitiveText.String(entries[0]) get() = entries.getOrNull(value)?.asText() ?: TextHolder.String(entries[0])
} }
object UpdateChannelUrl : BaseSettingsItem.Input() { object UpdateChannelUrl : BaseSettingsItem.Input() {
override val title = R.string.settings_update_custom.asTransitive() override val title = R.string.settings_update_custom.asText()
override var value = Config.customChannelUrl override var value = Config.customChannelUrl
set(value) = setV(value, field, { field = it }) { set(value) = setV(value, field, { field = it }) {
Config.customChannelUrl = it Config.customChannelUrl = it
Info.remote = Info.EMPTY_REMOTE Info.remote = Info.EMPTY_REMOTE
} }
override val description get() = value.asTransitive() override val description get() = value.asText()
override val inputResult get() = result override val inputResult get() = result
@ -177,8 +177,8 @@ object UpdateChannelUrl : BaseSettingsItem.Input() {
} }
object UpdateChecker : BaseSettingsItem.Toggle() { object UpdateChecker : BaseSettingsItem.Toggle() {
override val title = R.string.settings_check_update_title.asTransitive() override val title = R.string.settings_check_update_title.asText()
override val description = R.string.settings_check_update_summary.asTransitive() override val description = R.string.settings_check_update_summary.asText()
override var value = Config.checkUpdate override var value = Config.checkUpdate
set(value) = setV(value, field, { field = it }) { set(value) = setV(value, field, { field = it }) {
Config.checkUpdate = it Config.checkUpdate = it
@ -187,8 +187,8 @@ object UpdateChecker : BaseSettingsItem.Toggle() {
} }
object DoHToggle : BaseSettingsItem.Toggle() { object DoHToggle : BaseSettingsItem.Toggle() {
override val title = R.string.settings_doh_title.asTransitive() override val title = R.string.settings_doh_title.asText()
override val description = R.string.settings_doh_description.asTransitive() override val description = R.string.settings_doh_description.asText()
override var value = Config.doh override var value = Config.doh
set(value) = setV(value, field, { field = it }) { set(value) = setV(value, field, { field = it }) {
Config.doh = it Config.doh = it
@ -197,35 +197,35 @@ object DoHToggle : BaseSettingsItem.Toggle() {
// check whether is module already installed beforehand? // check whether is module already installed beforehand?
object SystemlessHosts : BaseSettingsItem.Blank() { object SystemlessHosts : BaseSettingsItem.Blank() {
override val title = R.string.settings_hosts_title.asTransitive() override val title = R.string.settings_hosts_title.asText()
override val description = R.string.settings_hosts_summary.asTransitive() override val description = R.string.settings_hosts_summary.asText()
} }
object Tapjack : BaseSettingsItem.Toggle() { object Tapjack : BaseSettingsItem.Toggle() {
override val title = R.string.settings_su_tapjack_title.asTransitive() override val title = R.string.settings_su_tapjack_title.asText()
override var description = R.string.settings_su_tapjack_summary.asTransitive() override var description = R.string.settings_su_tapjack_summary.asText()
override var value = Config.suTapjack override var value = Config.suTapjack
set(value) = setV(value, field, { field = it }) { Config.suTapjack = it } set(value) = setV(value, field, { field = it }) { Config.suTapjack = it }
} }
object Biometrics : BaseSettingsItem.Toggle() { object Biometrics : BaseSettingsItem.Toggle() {
override val title = R.string.settings_su_biometric_title.asTransitive() override val title = R.string.settings_su_biometric_title.asText()
override var value = Config.suBiometric override var value = Config.suBiometric
set(value) = setV(value, field, { field = it }) { Config.suBiometric = it } set(value) = setV(value, field, { field = it }) { Config.suBiometric = it }
override var description = R.string.settings_su_biometric_summary.asTransitive() override var description = R.string.settings_su_biometric_summary.asText()
override fun refresh() { override fun refresh() {
isEnabled = BiometricHelper.isSupported isEnabled = BiometricHelper.isSupported
if (!isEnabled) { if (!isEnabled) {
value = false value = false
description = R.string.no_biometric.asTransitive() description = R.string.no_biometric.asText()
} }
} }
} }
object Reauthenticate : BaseSettingsItem.Toggle() { object Reauthenticate : BaseSettingsItem.Toggle() {
override val title = R.string.settings_su_reauth_title.asTransitive() override val title = R.string.settings_su_reauth_title.asText()
override val description = R.string.settings_su_reauth_summary.asTransitive() override val description = R.string.settings_su_reauth_summary.asText()
override var value = Config.suReAuth override var value = Config.suReAuth
set(value) = setV(value, field, { field = it }) { Config.suReAuth = it } set(value) = setV(value, field, { field = it }) { Config.suReAuth = it }
@ -237,12 +237,12 @@ object Reauthenticate : BaseSettingsItem.Toggle() {
// --- Magisk // --- Magisk
object Magisk : BaseSettingsItem.Section() { object Magisk : BaseSettingsItem.Section() {
override val title = R.string.magisk.asTransitive() override val title = R.string.magisk.asText()
} }
object MagiskHide : BaseSettingsItem.Toggle() { object MagiskHide : BaseSettingsItem.Toggle() {
override val title = R.string.magiskhide.asTransitive() override val title = R.string.magiskhide.asText()
override val description = R.string.settings_magiskhide_summary.asTransitive() override val description = R.string.settings_magiskhide_summary.asText()
override var value = Config.magiskHide override var value = Config.magiskHide
set(value) = setV(value, field, { field = it }) { set(value) = setV(value, field, { field = it }) {
val cmd = if (it) "enable" else "disable" val cmd = if (it) "enable" else "disable"
@ -256,11 +256,11 @@ object MagiskHide : BaseSettingsItem.Toggle() {
// --- Superuser // --- Superuser
object Superuser : BaseSettingsItem.Section() { object Superuser : BaseSettingsItem.Section() {
override val title = R.string.superuser.asTransitive() override val title = R.string.superuser.asText()
} }
object AccessMode : BaseSettingsItem.Selector() { object AccessMode : BaseSettingsItem.Selector() {
override val title = R.string.superuser_access.asTransitive() override val title = R.string.superuser_access.asText()
override val entryRes = R.array.su_access override val entryRes = R.array.su_access
override var value = Config.rootMode override var value = Config.rootMode
@ -270,7 +270,7 @@ object AccessMode : BaseSettingsItem.Selector() {
} }
object MultiuserMode : BaseSettingsItem.Selector() { object MultiuserMode : BaseSettingsItem.Selector() {
override val title = R.string.multiuser_mode.asTransitive() override val title = R.string.multiuser_mode.asText()
override val entryRes = R.array.multiuser_mode override val entryRes = R.array.multiuser_mode
override var value = Config.suMultiuserMode override var value = Config.suMultiuserMode
@ -279,7 +279,7 @@ object MultiuserMode : BaseSettingsItem.Selector() {
} }
override val description override val description
get() = resources.getStringArray(R.array.multiuser_summary)[value].asTransitive() get() = resources.getStringArray(R.array.multiuser_summary)[value].asText()
override fun refresh() { override fun refresh() {
isEnabled = Const.USER_ID == 0 isEnabled = Const.USER_ID == 0
@ -287,7 +287,7 @@ object MultiuserMode : BaseSettingsItem.Selector() {
} }
object MountNamespaceMode : BaseSettingsItem.Selector() { object MountNamespaceMode : BaseSettingsItem.Selector() {
override val title = R.string.mount_namespace_mode.asTransitive() override val title = R.string.mount_namespace_mode.asText()
override val entryRes = R.array.namespace override val entryRes = R.array.namespace
override var value = Config.suMntNamespaceMode override var value = Config.suMntNamespaceMode
@ -296,11 +296,11 @@ object MountNamespaceMode : BaseSettingsItem.Selector() {
} }
override val description override val description
get() = resources.getStringArray(R.array.namespace_summary)[value].asTransitive() get() = resources.getStringArray(R.array.namespace_summary)[value].asText()
} }
object AutomaticResponse : BaseSettingsItem.Selector() { object AutomaticResponse : BaseSettingsItem.Selector() {
override val title = R.string.auto_response.asTransitive() override val title = R.string.auto_response.asText()
override val entryRes = R.array.auto_response override val entryRes = R.array.auto_response
override var value = Config.suAutoResponse override var value = Config.suAutoResponse
@ -310,7 +310,7 @@ object AutomaticResponse : BaseSettingsItem.Selector() {
} }
object RequestTimeout : BaseSettingsItem.Selector() { object RequestTimeout : BaseSettingsItem.Selector() {
override val title = R.string.request_timeout.asTransitive() override val title = R.string.request_timeout.asText()
override val entryRes = R.array.request_timeout override val entryRes = R.array.request_timeout
override val entryValRes = R.array.request_timeout_value override val entryValRes = R.array.request_timeout_value
@ -324,7 +324,7 @@ object RequestTimeout : BaseSettingsItem.Selector() {
} }
object SUNotification : BaseSettingsItem.Selector() { object SUNotification : BaseSettingsItem.Selector() {
override val title = R.string.superuser_notification.asTransitive() override val title = R.string.superuser_notification.asText()
override val entryRes = R.array.su_notification override val entryRes = R.array.su_notification
override var value = Config.suNotification override var value = Config.suNotification

View File

@ -18,7 +18,7 @@ import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.events.dialog.BiometricEvent import com.topjohnwu.magisk.events.dialog.BiometricEvent
import com.topjohnwu.magisk.events.dialog.SuperuserRevokeDialog import com.topjohnwu.magisk.events.dialog.SuperuserRevokeDialog
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.asTransitive import com.topjohnwu.magisk.utils.asText
import com.topjohnwu.magisk.view.TappableHeadlineItem import com.topjohnwu.magisk.view.TappableHeadlineItem
import com.topjohnwu.magisk.view.TextItem import com.topjohnwu.magisk.view.TextItem
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -116,7 +116,7 @@ class SuperuserViewModel(
else -> R.string.su_snack_notif_off else -> R.string.su_snack_notif_off
} }
} }
SnackbarEvent(res.asTransitive(policy.appName)).publish() SnackbarEvent(res.asText(policy.appName)).publish()
} }
fun togglePolicy(item: PolicyRvItem, enable: Boolean) { fun togglePolicy(item: PolicyRvItem, enable: Boolean) {
@ -130,7 +130,7 @@ class SuperuserViewModel(
db.update(app) db.update(app)
val res = if (app.policy == SuPolicy.ALLOW) R.string.su_snack_grant val res = if (app.policy == SuPolicy.ALLOW) R.string.su_snack_grant
else R.string.su_snack_deny else R.string.su_snack_deny
SnackbarEvent(res.asTransitive(item.item.appName)).publish() SnackbarEvent(res.asText(item.item.appName)).publish()
} }
} }

View File

@ -0,0 +1,47 @@
package com.topjohnwu.magisk.utils
import android.content.res.Resources
import android.widget.TextView
import androidx.databinding.BindingAdapter
sealed class TextHolder {
abstract val isEmpty: Boolean
abstract fun getText(resources: Resources): CharSequence
// ---
class String(
private val value: CharSequence
) : TextHolder() {
override val isEmpty get() = value.isEmpty()
override fun getText(resources: Resources) = value
}
class Resource(
private val value: Int,
private vararg val params: Any
) : TextHolder() {
override val isEmpty get() = value == 0
override fun getText(resources: Resources) = resources.getString(value, *params)
}
// ---
companion object {
val EMPTY = String("")
}
}
fun Int.asText(vararg params: Any): TextHolder = TextHolder.Resource(this, *params)
fun CharSequence.asText(): TextHolder = TextHolder.String(this)
@BindingAdapter("android:text")
fun TextView.setText(text: TextHolder) {
this.text = text.getText(context.resources)
}

View File

@ -1,53 +0,0 @@
package com.topjohnwu.magisk.utils
import android.content.res.Resources
import android.widget.TextView
import androidx.databinding.BindingAdapter
import androidx.databinding.InverseBindingAdapter
sealed class TransitiveText {
abstract val isEmpty: Boolean
abstract fun getText(resources: Resources): CharSequence
// ---
class String(
private val value: CharSequence
) : TransitiveText() {
override val isEmpty = value.isEmpty()
override fun getText(resources: Resources) = value
}
class Res(
private val value: Int,
private vararg val params: Any
) : TransitiveText() {
override val isEmpty = value == 0
override fun getText(resources: Resources) =
resources.getString(value, *params)
}
// ---
companion object {
val EMPTY = String("")
}
}
fun Int.asTransitive(vararg params: Any): TransitiveText = TransitiveText.Res(this, *params)
fun CharSequence.asTransitive(): TransitiveText = TransitiveText.String(this)
@BindingAdapter("android:text")
fun TextView.setText(text: TransitiveText) {
this.text = text.getText(context.resources)
}
@InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged")
fun TextView.getTransitiveText() = text.asTransitive()

View File

@ -10,7 +10,6 @@ import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator; import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.CMSTypedData; import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
@ -31,7 +30,6 @@ import java.security.InvalidKeyException;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.Security;
import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.ArrayList; import java.util.ArrayList;