Improve settings item code

This commit is contained in:
topjohnwu 2020-01-18 01:34:46 +08:00
parent b95cf9b9a3
commit cae43b26f4
2 changed files with 61 additions and 118 deletions

View File

@ -28,7 +28,7 @@ sealed class SettingsItem : ObservableItem<SettingsItem>() {
@get:Bindable @get:Bindable
var isEnabled by bindable(true, BR.enabled) var isEnabled by bindable(true, BR.enabled)
protected open val isFullSpan: Boolean = false protected open val isFullSpan get() = false
@CallSuper @CallSuper
open fun onPressed(view: View, callback: Callback) { open fun onPressed(view: View, callback: Callback) {
@ -145,28 +145,13 @@ sealed class SettingsItem : ObservableItem<SettingsItem>() {
protected val resources get() = get<Resources>() protected val resources get() = get<Resources>()
var entries: Array<out CharSequence> = arrayOf() abstract val entries: Array<out CharSequence>
private set abstract val entryValues: Array<out CharSequence>
var entryValues: Array<out CharSequence> = arrayOf()
private set
@get:Bindable @get:Bindable
val selectedEntry val selectedEntry
get() = entries.getOrNull(value) get() = entries.getOrNull(value)
fun setValues(
entries: Array<out CharSequence>,
values: Array<out CharSequence>
) {
check(entries.size <= values.size) { "List sizes must match" }
this.entries = entries
this.entryValues = values
notifyChange(BR.selectedEntry)
}
override fun onPressed(view: View, callback: Callback) { override fun onPressed(view: View, callback: Callback) {
if (entries.isEmpty() || entryValues.isEmpty()) return if (entries.isEmpty() || entryValues.isEmpty()) return
callback.onItemPressed(view, this) callback.onItemPressed(view, this)
@ -199,7 +184,7 @@ sealed class SettingsItem : ObservableItem<SettingsItem>() {
abstract class Section : SettingsItem() { abstract class Section : SettingsItem() {
override val layoutRes = R.layout.item_settings_section override val layoutRes = R.layout.item_settings_section
override val isFullSpan = true override val isFullSpan get() = true
} }

View File

@ -33,19 +33,21 @@ object Customization : SettingsItem.Section() {
object Language : SettingsItem.Selector() { object Language : SettingsItem.Selector() {
override var value by bindableValue(0) { override var value by bindableValue(0) {
Config.locale = entryValues.getOrNull(it)?.toString() ?: return@bindableValue Config.locale = entryValues[it]
refreshLocale() refreshLocale()
} }
override val title = R.string.language.asTransitive() override val title = R.string.language.asTransitive()
override var entries = arrayOf<String>()
override var entryValues = arrayOf<String>()
init { init {
availableLocales.subscribeK { (names, values) -> availableLocales.subscribeK { (names, values) ->
setValues(names, values) entries = names
val selectedLocale = currentLocale.getDisplayName( entryValues = values
currentLocale val selectedLocale = currentLocale.getDisplayName(currentLocale)
)
value = names.indexOfFirst { it == selectedLocale }.let { if (it == -1) 0 else it } value = names.indexOfFirst { it == selectedLocale }.let { if (it == -1) 0 else it }
notifyChange(BR.selectedEntry)
} }
} }
} }
@ -80,8 +82,9 @@ object Hide : SettingsItem.Input() {
notifyChange(BR.value) notifyChange(BR.value)
notifyChange(BR.error) notifyChange(BR.error)
} }
val isError
@Bindable get() = value.length > 14 || value.isBlank() @get:Bindable
val isError get() = value.length > 14 || value.isBlank()
override val intermediate: String? override val intermediate: String?
get() = if (isError) null else value get() = if (isError) null else value
@ -108,18 +111,18 @@ object DownloadPath : SettingsItem.Input() {
override val title = R.string.settings_download_path_title.asTransitive() override val title = R.string.settings_download_path_title.asTransitive()
override val intermediate: String? override val intermediate: String?
get() = if (Utils.ensureDownloadPath(result) != null) result else null get() = if (Utils.ensureDownloadPath(result) != null) result else null
@get:Bindable
var result = value var result = value
@Bindable get
set(value) { set(value) {
field = value field = value
notifyChange(BR.result) notifyChange(BR.result)
notifyChange(BR.path) notifyChange(BR.path)
} }
@get:Bindable
val path val path
@Bindable get() = File( get() = File(Environment.getExternalStorageDirectory(), result).absolutePath.orEmpty()
Environment.getExternalStorageDirectory(),
result
).absolutePath.orEmpty()
override fun getView(context: Context) = DialogSettingsDownloadPathBinding override fun getView(context: Context) = DialogSettingsDownloadPathBinding
.inflate(LayoutInflater.from(context)).also { it.data = this }.root .inflate(LayoutInflater.from(context)).also { it.data = this }.root
@ -132,40 +135,28 @@ object GridSize : SettingsItem.Selector() {
override val title = R.string.settings_grid_span_count_title.asTransitive() override val title = R.string.settings_grid_span_count_title.asTransitive()
override val description = R.string.settings_grid_span_count_summary.asTransitive() override val description = R.string.settings_grid_span_count_summary.asTransitive()
override val entries = resources.getStringArray(R.array.span_count)
init { override val entryValues = resources.getStringArray(R.array.value_array)
setValues(
resources.getStringArray(R.array.span_count),
resources.getStringArray(R.array.value_array)
)
}
} }
object UpdateChannel : SettingsItem.Selector() { object UpdateChannel : SettingsItem.Selector() {
override var value by bindableValue(Config.updateChannel) { Config.updateChannel = it } override var value by bindableValue(Config.updateChannel) { Config.updateChannel = it }
override val title = R.string.settings_update_channel_title.asTransitive()
init { override val title = R.string.settings_update_channel_title.asTransitive()
val entries = resources.getStringArray(R.array.update_channel).let { override val entries = resources.getStringArray(R.array.update_channel).let {
if (!Utils.isCanary && Config.updateChannel < Config.Value.CANARY_CHANNEL) if (!Utils.isCanary && Config.updateChannel < Config.Value.CANARY_CHANNEL)
it.take(it.size - 2).toTypedArray() else it it.take(it.size - 2).toTypedArray() else it
}
setValues(
entries,
resources.getStringArray(R.array.value_array)
)
} }
override val entryValues = resources.getStringArray(R.array.value_array)
} }
object UpdateChannelUrl : SettingsItem.Input() { object UpdateChannelUrl : SettingsItem.Input() {
override val title = R.string.settings_update_custom.asTransitive() override val title = R.string.settings_update_custom.asTransitive()
override var value: String by bindableValue(Config.customChannelUrl) { override var value by bindableValue(Config.customChannelUrl) { Config.customChannelUrl = it }
Config.customChannelUrl = it
}
override val intermediate: String? get() = result override val intermediate: String? get() = result
@get:Bindable
var result = value var result = value
@Bindable get
set(value) { set(value) {
field = value field = value
notifyChange(BR.result) notifyChange(BR.result)
@ -271,17 +262,11 @@ object Superuser : SettingsItem.Section() {
object AccessMode : SettingsItem.Selector() { object AccessMode : SettingsItem.Selector() {
override val title = R.string.superuser_access.asTransitive() override val title = R.string.superuser_access.asTransitive()
override var value by bindableValue(Config.rootMode) { override val entries = resources.getStringArray(R.array.su_access)
Config.rootMode = entryValues.getOrNull(it) override val entryValues = resources.getStringArray(R.array.value_array)
?.toString()
?.toInt() ?: return@bindableValue
}
init { override var value by bindableValue(Config.rootMode) {
setValues( Config.rootMode = entryValues[it].toInt()
resources.getStringArray(R.array.su_access),
resources.getStringArray(R.array.value_array)
)
} }
override fun refresh() { override fun refresh() {
@ -291,22 +276,17 @@ object AccessMode : SettingsItem.Selector() {
object MultiuserMode : SettingsItem.Selector() { object MultiuserMode : SettingsItem.Selector() {
override val title = R.string.multiuser_mode.asTransitive() override val title = R.string.multiuser_mode.asTransitive()
override var value by bindableValue(Config.suMultiuserMode) { override val entries = resources.getStringArray(R.array.multiuser_mode)
Config.suMultiuserMode = entryValues.getOrNull(it) override val entryValues = resources.getStringArray(R.array.value_array)
?.toString()
?.toInt() ?: return@bindableValue
}
private val descArray = resources.getStringArray(R.array.multiuser_summary) private val descArray = resources.getStringArray(R.array.multiuser_summary)
override var value by bindableValue(Config.suMultiuserMode) {
Config.suMultiuserMode = entryValues[it].toInt()
}
override val description override val description
get() = descArray[value].asTransitive() get() = descArray[value].asTransitive()
init {
setValues(
resources.getStringArray(R.array.multiuser_mode),
resources.getStringArray(R.array.value_array)
)
}
override fun refresh() { override fun refresh() {
isEnabled = Const.USER_ID <= 0 && Utils.showSuperUser() isEnabled = Const.USER_ID <= 0 && Utils.showSuperUser()
} }
@ -314,22 +294,17 @@ object MultiuserMode : SettingsItem.Selector() {
object MountNamespaceMode : SettingsItem.Selector() { object MountNamespaceMode : SettingsItem.Selector() {
override val title = R.string.mount_namespace_mode.asTransitive() override val title = R.string.mount_namespace_mode.asTransitive()
override var value by bindableValue(Config.suMntNamespaceMode) { override val entries = resources.getStringArray(R.array.namespace)
Config.suMntNamespaceMode = entryValues.getOrNull(it) override val entryValues = resources.getStringArray(R.array.value_array)
?.toString()
?.toInt() ?: return@bindableValue
}
private val descArray = resources.getStringArray(R.array.namespace_summary) private val descArray = resources.getStringArray(R.array.namespace_summary)
override var value by bindableValue(Config.suMntNamespaceMode) {
Config.suMntNamespaceMode = entryValues[it].toInt()
}
override val description override val description
get() = descArray[value].asTransitive() get() = descArray[value].asTransitive()
init {
setValues(
resources.getStringArray(R.array.namespace),
resources.getStringArray(R.array.value_array)
)
}
override fun refresh() { override fun refresh() {
isEnabled = Utils.showSuperUser() isEnabled = Utils.showSuperUser()
} }
@ -337,17 +312,11 @@ object MountNamespaceMode : SettingsItem.Selector() {
object AutomaticResponse : SettingsItem.Selector() { object AutomaticResponse : SettingsItem.Selector() {
override val title = R.string.auto_response.asTransitive() override val title = R.string.auto_response.asTransitive()
override var value by bindableValue(Config.suAutoReponse) { override val entries = resources.getStringArray(R.array.auto_response)
Config.suAutoReponse = entryValues.getOrNull(it) override val entryValues = resources.getStringArray(R.array.value_array)
?.toString()
?.toInt() ?: return@bindableValue
}
init { override var value by bindableValue(Config.suAutoReponse) {
setValues( Config.suAutoReponse = entryValues[it].toInt()
resources.getStringArray(R.array.auto_response),
resources.getStringArray(R.array.value_array)
)
} }
override fun refresh() { override fun refresh() {
@ -357,20 +326,15 @@ object AutomaticResponse : SettingsItem.Selector() {
object RequestTimeout : SettingsItem.Selector() { object RequestTimeout : SettingsItem.Selector() {
override val title = R.string.request_timeout.asTransitive() override val title = R.string.request_timeout.asTransitive()
override var value by bindableValue(-1) { override val entries = resources.getStringArray(R.array.request_timeout)
Config.suDefaultTimeout = entryValues.getOrNull(it) override val entryValues = resources.getStringArray(R.array.request_timeout_value)
?.toString()
?.toInt() ?: return@bindableValue override var value by bindableValue(selected) {
Config.suDefaultTimeout = entryValues[it].toInt()
} }
init { private val selected: Int
setValues( get() = entryValues.indexOfFirst { it.toInt() == Config.suDefaultTimeout }
resources.getStringArray(R.array.request_timeout),
resources.getStringArray(R.array.request_timeout_value)
)
val currentValue = Config.suDefaultTimeout.toString()
value = entryValues.indexOfFirst { it == currentValue }
}
override fun refresh() { override fun refresh() {
isEnabled = Utils.showSuperUser() isEnabled = Utils.showSuperUser()
@ -379,17 +343,11 @@ object RequestTimeout : SettingsItem.Selector() {
object SUNotification : SettingsItem.Selector() { object SUNotification : SettingsItem.Selector() {
override val title = R.string.superuser_notification.asTransitive() override val title = R.string.superuser_notification.asTransitive()
override var value by bindableValue(Config.suNotification) { override val entries = resources.getStringArray(R.array.su_notification)
Config.suNotification = entryValues.getOrNull(it) override val entryValues = resources.getStringArray(R.array.value_array)
?.toString()
?.toInt() ?: return@bindableValue
}
init { override var value by bindableValue(Config.suNotification) {
setValues( Config.suNotification = entryValues[it].toInt()
resources.getStringArray(R.array.su_notification),
resources.getStringArray(R.array.value_array)
)
} }
override fun refresh() { override fun refresh() {