Remove longpreference
This commit is contained in:
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user