Don't hold resources in Settings objects
This commit is contained in:
parent
1418bc454d
commit
649b49ff45
@ -3,18 +3,14 @@ package com.topjohnwu.magisk.ui.settings
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.annotation.ArrayRes
|
|
||||||
import androidx.annotation.CallSuper
|
import androidx.annotation.CallSuper
|
||||||
import androidx.databinding.Bindable
|
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.ktx.get
|
|
||||||
import com.topjohnwu.magisk.utils.TextHolder
|
import com.topjohnwu.magisk.utils.TextHolder
|
||||||
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.component.KoinComponent
|
|
||||||
|
|
||||||
sealed class BaseSettingsItem : ObservableItem<BaseSettingsItem>() {
|
sealed class BaseSettingsItem : ObservableItem<BaseSettingsItem>() {
|
||||||
|
|
||||||
@ -141,34 +137,29 @@ sealed class BaseSettingsItem : ObservableItem<BaseSettingsItem>() {
|
|||||||
abstract fun getView(context: Context): View
|
abstract fun getView(context: Context): View
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Selector : Value<Int>(), KoinComponent {
|
abstract class Selector : Value<Int>() {
|
||||||
|
|
||||||
protected val resources get() = get<Resources>()
|
open val entryRes get() = -1
|
||||||
|
open val descriptionRes get() = entryRes
|
||||||
|
open fun entries(res: Resources) = res.getArrayOrEmpty(entryRes)
|
||||||
|
open fun descriptions(res: Resources) = res.getArrayOrEmpty(descriptionRes)
|
||||||
|
|
||||||
@ArrayRes open val entryRes = -1
|
override val description = object : TextHolder() {
|
||||||
@ArrayRes open val entryValRes = -1
|
override fun getText(resources: Resources): CharSequence {
|
||||||
|
return descriptions(resources).getOrElse(value) { "" }
|
||||||
open val entries get() = resources.getArrayOrEmpty(entryRes)
|
}
|
||||||
open val entryValues get() = resources.getArrayOrEmpty(entryValRes)
|
}
|
||||||
|
|
||||||
override val description: TextHolder
|
|
||||||
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())
|
||||||
|
|
||||||
override fun onPressed(view: View, callback: Callback) {
|
|
||||||
if (entries.isEmpty()) return
|
|
||||||
super.onPressed(view, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPressed(view: View) {
|
override fun onPressed(view: View) {
|
||||||
MagiskDialog(view.context)
|
MagiskDialog(view.context)
|
||||||
.applyTitle(title.getText(resources))
|
.applyTitle(title.getText(view.resources))
|
||||||
.applyButton(MagiskDialog.ButtonType.NEGATIVE) {
|
.applyButton(MagiskDialog.ButtonType.NEGATIVE) {
|
||||||
titleRes = android.R.string.cancel
|
titleRes = android.R.string.cancel
|
||||||
}
|
}
|
||||||
.applyAdapter(entries) {
|
.applyAdapter(entries(view.resources)) {
|
||||||
value = it
|
value = it
|
||||||
}
|
}
|
||||||
.reveal()
|
.reveal()
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package com.topjohnwu.magisk.ui.settings
|
package com.topjohnwu.magisk.ui.settings
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.res.Resources
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
import androidx.databinding.Bindable
|
import androidx.databinding.Bindable
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.BuildConfig
|
import com.topjohnwu.magisk.BuildConfig
|
||||||
@ -20,7 +22,6 @@ 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.TextHolder
|
|
||||||
import com.topjohnwu.magisk.utils.Utils
|
import com.topjohnwu.magisk.utils.Utils
|
||||||
import com.topjohnwu.magisk.utils.asText
|
import com.topjohnwu.magisk.utils.asText
|
||||||
import com.topjohnwu.magisk.utils.set
|
import com.topjohnwu.magisk.utils.set
|
||||||
@ -41,8 +42,17 @@ object Language : BaseSettingsItem.Selector() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val title = R.string.language.asText()
|
override val title = R.string.language.asText()
|
||||||
override var entries = emptyArray<String>()
|
|
||||||
override var entryValues = emptyArray<String>()
|
private var entries = emptyArray<String>()
|
||||||
|
private var entryValues = emptyArray<String>()
|
||||||
|
|
||||||
|
override fun entries(res: Resources) = entries
|
||||||
|
override fun descriptions(res: Resources) = entries
|
||||||
|
|
||||||
|
override fun onPressed(view: View, callback: Callback) {
|
||||||
|
if (entries.isEmpty()) return
|
||||||
|
super.onPressed(view, callback)
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun loadLanguages(scope: CoroutineScope) {
|
suspend fun loadLanguages(scope: CoroutineScope) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
@ -137,20 +147,22 @@ object DownloadPath : BaseSettingsItem.Input() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object UpdateChannel : BaseSettingsItem.Selector() {
|
object UpdateChannel : BaseSettingsItem.Selector() {
|
||||||
override var value = Config.updateChannel
|
override var value = Config.updateChannel.let { if (it < 0) 0 else it }
|
||||||
set(value) = setV(value, field, { field = it }) {
|
set(value) = setV(value, field, { field = it }) {
|
||||||
Config.updateChannel = it
|
Config.updateChannel = it
|
||||||
Info.remote = Info.EMPTY_REMOTE
|
Info.remote = Info.EMPTY_REMOTE
|
||||||
}
|
}
|
||||||
|
|
||||||
override val title = R.string.settings_update_channel_title.asText()
|
override val title = R.string.settings_update_channel_title.asText()
|
||||||
override val entries: Array<String> = resources.getStringArray(R.array.update_channel).let {
|
|
||||||
if (BuildConfig.VERSION_CODE % 100 == 0)
|
override val entryRes = R.array.update_channel
|
||||||
it.toMutableList().apply { removeAt(Config.Value.CANARY_CHANNEL) }.toTypedArray()
|
override fun entries(res: Resources): Array<String> {
|
||||||
else it
|
return super.entries(res).let {
|
||||||
|
if (!BuildConfig.DEBUG)
|
||||||
|
it.copyOfRange(0, Config.Value.CANARY_CHANNEL)
|
||||||
|
else it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
override val description
|
|
||||||
get() = entries.getOrNull(value)?.asText() ?: TextHolder.String(entries[0])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object UpdateChannelUrl : BaseSettingsItem.Input() {
|
object UpdateChannelUrl : BaseSettingsItem.Input() {
|
||||||
@ -272,15 +284,13 @@ object AccessMode : BaseSettingsItem.Selector() {
|
|||||||
object MultiuserMode : BaseSettingsItem.Selector() {
|
object MultiuserMode : BaseSettingsItem.Selector() {
|
||||||
override val title = R.string.multiuser_mode.asText()
|
override val title = R.string.multiuser_mode.asText()
|
||||||
override val entryRes = R.array.multiuser_mode
|
override val entryRes = R.array.multiuser_mode
|
||||||
|
override val descriptionRes = R.array.multiuser_summary
|
||||||
|
|
||||||
override var value = Config.suMultiuserMode
|
override var value = Config.suMultiuserMode
|
||||||
set(value) = setV(value, field, { field = it }) {
|
set(value) = setV(value, field, { field = it }) {
|
||||||
Config.suMultiuserMode = it
|
Config.suMultiuserMode = it
|
||||||
}
|
}
|
||||||
|
|
||||||
override val description
|
|
||||||
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
|
||||||
}
|
}
|
||||||
@ -289,14 +299,12 @@ object MultiuserMode : BaseSettingsItem.Selector() {
|
|||||||
object MountNamespaceMode : BaseSettingsItem.Selector() {
|
object MountNamespaceMode : BaseSettingsItem.Selector() {
|
||||||
override val title = R.string.mount_namespace_mode.asText()
|
override val title = R.string.mount_namespace_mode.asText()
|
||||||
override val entryRes = R.array.namespace
|
override val entryRes = R.array.namespace
|
||||||
|
override val descriptionRes = R.array.namespace_summary
|
||||||
|
|
||||||
override var value = Config.suMntNamespaceMode
|
override var value = Config.suMntNamespaceMode
|
||||||
set(value) = setV(value, field, { field = it }) {
|
set(value) = setV(value, field, { field = it }) {
|
||||||
Config.suMntNamespaceMode = it
|
Config.suMntNamespaceMode = it
|
||||||
}
|
}
|
||||||
|
|
||||||
override val description
|
|
||||||
get() = resources.getStringArray(R.array.namespace_summary)[value].asText()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object AutomaticResponse : BaseSettingsItem.Selector() {
|
object AutomaticResponse : BaseSettingsItem.Selector() {
|
||||||
@ -312,15 +320,15 @@ object AutomaticResponse : BaseSettingsItem.Selector() {
|
|||||||
object RequestTimeout : BaseSettingsItem.Selector() {
|
object RequestTimeout : BaseSettingsItem.Selector() {
|
||||||
override val title = R.string.request_timeout.asText()
|
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
|
|
||||||
|
|
||||||
|
private val entryValues = listOf(10, 15, 20, 30, 45, 60)
|
||||||
override var value = selected
|
override var value = selected
|
||||||
set(value) = setV(value, field, { field = it }) {
|
set(value) = setV(value, field, { field = it }) {
|
||||||
Config.suDefaultTimeout = entryValues[it].toInt()
|
Config.suDefaultTimeout = entryValues[it]
|
||||||
}
|
}
|
||||||
|
|
||||||
private val selected: Int
|
private val selected: Int
|
||||||
get() = entryValues.indexOfFirst { it.toInt() == Config.suDefaultTimeout }
|
get() = entryValues.indexOfFirst { it == Config.suDefaultTimeout }
|
||||||
}
|
}
|
||||||
|
|
||||||
object SUNotification : BaseSettingsItem.Selector() {
|
object SUNotification : BaseSettingsItem.Selector() {
|
||||||
|
@ -25,15 +25,6 @@
|
|||||||
<item>@string/settings_su_request_60</item>
|
<item>@string/settings_su_request_60</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="request_timeout_value">
|
|
||||||
<item>10</item>
|
|
||||||
<item>15</item>
|
|
||||||
<item>20</item>
|
|
||||||
<item>30</item>
|
|
||||||
<item>45</item>
|
|
||||||
<item>60</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<string-array name="auto_response">
|
<string-array name="auto_response">
|
||||||
<item>@string/prompt</item>
|
<item>@string/prompt</item>
|
||||||
<item>@string/deny</item>
|
<item>@string/deny</item>
|
||||||
|
Loading…
Reference in New Issue
Block a user