Remove longpreference

This commit is contained in:
Niels van Velzen
2020-06-04 21:40:38 +02:00
parent 1ff888f305
commit cc38559ed4
13 changed files with 72 additions and 126 deletions

View File

@@ -3,6 +3,7 @@ package org.jellyfin.androidtv.preferences
import android.content.SharedPreferences
typealias MigrationEditor = SharedPreferences.Editor
fun <T : Enum<T>> MigrationEditor.putEnum(key: String, value: T) {
putString(key, value.toString())
}

View File

@@ -3,9 +3,9 @@ package org.jellyfin.androidtv.preferences
import kotlin.reflect.KClass
data class Preference<T : Any>(
val key: String,
val defaultValue: T,
val type: KClass<T>
val key: String,
val defaultValue: T,
val type: KClass<T>
) {
companion object {
fun int(key: String, defaultValue: Int) = Preference(key, defaultValue, Int::class)

View File

@@ -62,14 +62,15 @@ abstract class SharedPreferenceStore(
}
// Enums
operator fun <T : Preference<V>, V: Enum<V>> get(preference: T): V {
operator fun <T : Preference<V>, V : Enum<V>> get(preference: T): V {
val stringValue = sharedPreferences.getString(preference.key, null)
return if (stringValue == null) preference.defaultValue
else preference.type.java.enumConstants?.find { it.name == stringValue } ?: preference.defaultValue
else preference.type.java.enumConstants?.find { it.name == stringValue }
?: preference.defaultValue
}
operator fun <T : Preference<V>, V: Enum<V>> set(preference: T, value: V) = transaction {
operator fun <T : Preference<V>, V : Enum<V>> set(preference: T, value: V) = transaction {
putString(preference.key, value.toString())
}

View File

@@ -9,7 +9,7 @@ import android.content.Context
* @param context Context to get the SharedPreferences from
*/
class SystemPreferences(context: Context) : SharedPreferenceStore(
sharedPreferences = context.getSharedPreferences("systemprefs", Context.MODE_PRIVATE)
sharedPreferences = context.getSharedPreferences("systemprefs", Context.MODE_PRIVATE)
) {
companion object {
// Warnings

View File

@@ -13,7 +13,7 @@ import org.jellyfin.androidtv.preferences.enums.*
* @param context Context to get the SharedPreferences from
*/
class UserPreferences(context: Context) : SharedPreferenceStore(
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
) {
companion object {
/* Authentication */
@@ -131,7 +131,7 @@ class UserPreferences(context: Context) : SharedPreferenceStore(
/**
* Default audio delay in milliseconds for libVLC
*/
var libVLCAudioDelay = Preference.long("libvlc_audio_delay", 0)
var libVLCAudioDelay = Preference.int("libvlc_audio_delay", 0)
/* Live TV */
/**
@@ -202,5 +202,9 @@ class UserPreferences(context: Context) : SharedPreferenceStore(
else -> PreferredVideoPlayer.AUTO
})
}
migration(toVersion = 4) {
putInt("libvlc_audio_delay", it.getLong("libvlc_audio_delay", 0).toInt())
}
}
}

View File

@@ -9,11 +9,9 @@ import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceScreen
import org.jellyfin.androidtv.R
import org.jellyfin.androidtv.TvApp
import org.jellyfin.androidtv.preferences.UserPreferences
import org.jellyfin.androidtv.preferences.ui.category.*
import org.jellyfin.androidtv.preferences.ui.preference.ButtonRemapDialogFragment
import org.jellyfin.androidtv.preferences.ui.preference.ButtonRemapPreference
import org.jellyfin.androidtv.preferences.ui.preference.EditLongPreference
class UserPreferencesFragment : LeanbackSettingsFragmentCompat() {
override fun onPreferenceStartInitialScreen() {
@@ -77,12 +75,12 @@ class UserPreferencesFragment : LeanbackSettingsFragmentCompat() {
}
private fun addCustomBehavior() {
findPreference<EditLongPreference>("libvlc_audio_delay")?.apply {
text = TvApp.getApplication().userPreferences[UserPreferences.libVLCAudioDelay].toString()
summaryProvider = Preference.SummaryProvider<EditLongPreference> {
"${it.text} ms"
}
}
// findPreference<EditLongPreference>("libvlc_audio_delay")?.apply {
// text = TvApp.getApplication().userPreferences[UserPreferences.libVLCAudioDelay].toString()
// summaryProvider = Preference.SummaryProvider<EditLongPreference> {
// "${it.text} ms"
// }
// }
}
}
}

View File

@@ -8,6 +8,7 @@ import org.jellyfin.androidtv.preferences.UserPreferences
import org.jellyfin.androidtv.preferences.enums.AudioBehavior
import org.jellyfin.androidtv.preferences.enums.PreferredVideoPlayer
import org.jellyfin.androidtv.preferences.ui.dsl.*
import org.jellyfin.androidtv.preferences.ui.preference.DurationSeekBarPreference
import org.jellyfin.androidtv.util.DeviceUtils
import org.jellyfin.androidtv.util.TimeUtils
@@ -23,9 +24,11 @@ fun PreferenceScreen.playbackCategory(
5.0, 3.0, 2.0, 1.5, 1.0, // 1 >=
0.72, 0.42 // 0 >=
).map {
val value = if (it == 0.0) activity.getString(R.string.bitrate_auto)
else if (it >= 1.0) activity.getString(R.string.bitrate_mbit, it)
else activity.getString(R.string.bitrate_kbit, it * 100.0)
val value = when {
it == 0.0 -> activity.getString(R.string.bitrate_auto)
it >= 1.0 -> activity.getString(R.string.bitrate_mbit, it)
else -> activity.getString(R.string.bitrate_kbit, it * 100.0)
}
it.toString().removeSuffix(".0") to value
}.toMap()
@@ -43,6 +46,14 @@ fun PreferenceScreen.playbackCategory(
it.toString() to value
}.toMap()
val secondsValueFormatter = object : DurationSeekBarPreference.ValueFormatter() {
override fun display(value: Int) = "${value / 1000}s"
}
val millisecondsValueFormatter = object : DurationSeekBarPreference.ValueFormatter() {
override fun display(value: Int) = "${value}ms"
}
listPreference(R.string.pref_max_bitrate_title, maxBitrateValues) {
bind(userPreferences, UserPreferences.maxBitrate)
}
@@ -53,7 +64,7 @@ fun PreferenceScreen.playbackCategory(
bind(userPreferences, UserPreferences.nextUpEnabled)
enabled { userPreferences[UserPreferences.mediaQueuingEnabled] }
}
seekbarPreference(R.string.pref_next_up_timeout_title, R.string.pref_next_up_timeout_summary, min = 3000, max = 30000, increment = 1000) {
seekbarPreference(R.string.pref_next_up_timeout_title, R.string.pref_next_up_timeout_summary, min = 3000, max = 30000, increment = 1000, valueFormatter = secondsValueFormatter) {
bind(userPreferences, UserPreferences.nextUpTimeout)
enabled { userPreferences[UserPreferences.mediaQueuingEnabled] && userPreferences[UserPreferences.nextUpEnabled] }
}
@@ -84,9 +95,7 @@ fun PreferenceScreen.playbackCategory(
visible { DeviceUtils.is60() }
enabled { userPreferences[UserPreferences.videoPlayer] != PreferredVideoPlayer.EXTERNAL }
}
//TODO Add summary
//TODO Set inputType to number only
longPreference(R.string.pref_libvlc_audio_delay_title) {
seekbarPreference(R.string.pref_libvlc_audio_delay_title, min = -5000, max = 5000, valueFormatter = millisecondsValueFormatter) {
bind(userPreferences, UserPreferences.libVLCAudioDelay)
}
checkboxPreference(R.string.pref_use_direct_path_title, R.string.pref_use_direct_path_summary) {

View File

@@ -4,7 +4,6 @@ import androidx.annotation.StringRes
import androidx.preference.*
import org.jellyfin.androidtv.preferences.ui.preference.ButtonRemapPreference
import org.jellyfin.androidtv.preferences.ui.preference.DurationSeekBarPreference
import org.jellyfin.androidtv.preferences.ui.preference.EditLongPreference
import java.util.*
@DslMarker
@@ -18,6 +17,9 @@ inline fun <T : Preference> PreferenceGroup.appendPreference(
preference.isPersistent = false
addPreference(preference)
// Use random UUID as key because we need something unique but don't actually save anything
preference.key = UUID.randomUUID().toString()
preference.init()
}
@@ -37,6 +39,7 @@ fun PreferenceGroup.seekbarPreference(
min: Int = 0,
max: Int = 100,
increment: Int = 1,
valueFormatter: DurationSeekBarPreference.ValueFormatter? = null,
storeInit: PreferenceOptions.Builder<Int>.() -> Unit
) = appendPreference(DurationSeekBarPreference(context)) {
val store = PreferenceOptions.Builder<Int>()
@@ -47,6 +50,8 @@ fun PreferenceGroup.seekbarPreference(
if (description != null) setSummary(description)
if (valueFormatter != null) this.valueFormatter = valueFormatter
setMin(min)
setMax(max)
seekBarIncrement = increment
@@ -64,33 +69,6 @@ fun PreferenceGroup.seekbarPreference(
}
}
@PreferenceDSL
fun PreferenceGroup.longPreference(
@StringRes title: Int,
storeInit: PreferenceOptions.Builder<Long>.() -> Unit
) = appendPreference(EditLongPreference(context, null)) {
val store = PreferenceOptions.Builder<Long>()
.apply { storeInit() }
.build()
setTitle(title)
// Use random UUID as key because we need something unique
// but don't actually save anything
key = UUID.randomUUID().toString()
value = store.get()
isEnabled = store.enabled()
isVisible = store.visible()
setOnPreferenceChangeListener { _, newValue ->
store.set(newValue as Long)
value = store.get()
// Always return false because we save it
false
}
}
@PreferenceDSL
fun PreferenceGroup.listPreference(
@StringRes title: Int,
@@ -103,10 +81,6 @@ fun PreferenceGroup.listPreference(
setTitle(title)
// Use random UUID as key because we need something unique
// but don't actually save anything
key = UUID.randomUUID().toString()
entryValues = entries.keys.toTypedArray()
setEntries(entries.values.toTypedArray())
summaryProvider = ListPreference.SimpleSummaryProvider.getInstance()
@@ -185,10 +159,6 @@ inline fun <reified T : Enum<T>> PreferenceGroup.enumPreference(
setTitle(title)
// Use random UUID as key because we need something unique
// but don't actually save anything
key = UUID.randomUUID().toString()
entryValues = values.keys.toTypedArray()
entries = values.values.toTypedArray()
summaryProvider = ListPreference.SimpleSummaryProvider.getInstance()
@@ -207,19 +177,15 @@ inline fun <reified T : Enum<T>> PreferenceGroup.enumPreference(
@PreferenceDSL
fun PreferenceGroup.shortcutPreference(
@StringRes title: Int,
storeInit: PreferenceOptions.Builder<Int>.() -> Unit
@StringRes title: Int,
storeInit: PreferenceOptions.Builder<Int>.() -> Unit
) = appendPreference(ButtonRemapPreference(context, null)) {
val store = PreferenceOptions.Builder<Int>()
.apply { storeInit() }
.build()
.apply { storeInit() }
.build()
setTitle(title)
// Use random UUID as key because we need something unique
// but don't actually save anything
key = UUID.randomUUID().toString()
summaryProvider = ButtonRemapPreference.ButtonRemapSummaryProvider.instance
setKeyCode(store.get())

View File

@@ -13,15 +13,15 @@ class ButtonRemapDialogFragment : LeanbackPreferenceDialogFragmentCompat() {
private var keyCode: Int = 0
private var originalKeyCode: Int = 0
private var ignoreKeys = listOf(
KeyEvent.KEYCODE_BACK,
KeyEvent.KEYCODE_HOME,
KeyEvent.KEYCODE_APP_SWITCH,
KeyEvent.KEYCODE_DPAD_CENTER,
KeyEvent.KEYCODE_DPAD_UP,
KeyEvent.KEYCODE_DPAD_DOWN,
KeyEvent.KEYCODE_DPAD_LEFT,
KeyEvent.KEYCODE_DPAD_RIGHT,
KeyEvent.KEYCODE_ENTER
KeyEvent.KEYCODE_BACK,
KeyEvent.KEYCODE_HOME,
KeyEvent.KEYCODE_APP_SWITCH,
KeyEvent.KEYCODE_DPAD_CENTER,
KeyEvent.KEYCODE_DPAD_UP,
KeyEvent.KEYCODE_DPAD_DOWN,
KeyEvent.KEYCODE_DPAD_LEFT,
KeyEvent.KEYCODE_DPAD_RIGHT,
KeyEvent.KEYCODE_ENTER
)
private var checkKeys: View.OnKeyListener = View.OnKeyListener { _, keyCode, _ ->
// ignore navigation buttons

View File

@@ -9,8 +9,8 @@ import org.jellyfin.androidtv.R
import java.util.*
class ButtonRemapPreference(
context: Context,
attrs: AttributeSet? = null
context: Context,
attrs: AttributeSet? = null
) : DialogPreference(context) {
override fun getDialogLayoutResource() = R.layout.button_remap_preference
@@ -49,12 +49,12 @@ class ButtonRemapPreference(
return if (keyCodeString.startsWith("KEYCODE")) {
keyCodeString
.removePrefix("KEYCODE_")
.toLowerCase(Locale.getDefault())
.split("_")
.joinToString(" ") {
it.capitalize()
}
.removePrefix("KEYCODE_")
.toLowerCase(Locale.getDefault())
.split("_")
.joinToString(" ") {
it.capitalize()
}
} else {
context.getString(R.string.lbl_unknown_key, keyCodeString)
}

View File

@@ -14,10 +14,7 @@ class DurationSeekBarPreference(
context: Context,
attrs: AttributeSet? = null
) : SeekBarPreference(context, attrs) {
init {
// Explicitly set the layout or it will crash
layoutResource = androidx.preference.R.layout.preference_widget_seekbar_material
}
var valueFormatter = ValueFormatter()
override fun onBindViewHolder(view: PreferenceViewHolder) {
super.onBindViewHolder(view)
@@ -28,8 +25,12 @@ class DurationSeekBarPreference(
override fun getTransformation(source: CharSequence?, view: View): CharSequence? {
val numberValue = source?.toString()?.toIntOrNull() ?: return source
return (numberValue / 1000).toString()
return valueFormatter.display(numberValue)
}
}
}
open class ValueFormatter {
open fun display(value: Int): String = value.toString()
}
}

View File

@@ -1,34 +0,0 @@
package org.jellyfin.androidtv.preferences.ui.preference
import android.content.Context
import android.text.InputType
import android.util.AttributeSet
import androidx.preference.EditTextPreference
import timber.log.Timber
class EditLongPreference(context: Context, attrs: AttributeSet?) : EditTextPreference(context, attrs) {
var value: Long
get() {
return getPersistedLong(-1)
}
set(value) {
persistLong(value)
}
init {
setOnBindEditTextListener { it.inputType = InputType.TYPE_CLASS_NUMBER and InputType.TYPE_NUMBER_FLAG_SIGNED }
}
override fun getPersistedString(defaultReturnValue: String?): String {
return getPersistedLong(-1).toString()
}
override fun persistString(value: String?): Boolean {
return try {
persistLong(value!!.toLong())
} catch (e: NumberFormatException) {
Timber.e(e)
false
}
}
}

View File

@@ -369,6 +369,6 @@
<string name="pref_button_remapping_description">Press any button on the TV remote to assign it</string>
<string name="lbl_Reset">Reset</string>
<string name="bitrate_auto">Auto</string>
<string name="bitrate_mbit">%s Mbit/s</string>
<string name="bitrate_kbit">%s Kbit/s</string>
<string name="bitrate_mbit">%1$,.0f Mbit/s</string>
<string name="bitrate_kbit">%1$,.0f Kbit/s</string>
</resources>