Add a setting to control the new timeout
This commit is contained in:
parent
0faaae406c
commit
68860f147b
9 changed files with 58 additions and 3 deletions
|
|
@ -184,6 +184,7 @@ data class PlayerSettings(
|
|||
val streamAutoPlayRegex: String = "",
|
||||
val streamAutoPlayNextEpisodeEnabled: Boolean = false,
|
||||
val streamAutoPlayPreferBingeGroupForNextEpisode: Boolean = true,
|
||||
val streamAutoPlayTimeoutSeconds: Int = 3,
|
||||
val nextEpisodeThresholdMode: NextEpisodeThresholdMode = NextEpisodeThresholdMode.PERCENTAGE,
|
||||
val nextEpisodeThresholdPercent: Float = 99f,
|
||||
val nextEpisodeThresholdMinutesBeforeEnd: Float = 2f,
|
||||
|
|
@ -289,6 +290,7 @@ class PlayerSettingsDataStore @Inject constructor(
|
|||
private val streamAutoPlayRegexKey = stringPreferencesKey("stream_auto_play_regex")
|
||||
private val streamAutoPlayNextEpisodeEnabledKey = booleanPreferencesKey("stream_auto_play_next_episode_enabled")
|
||||
private val streamAutoPlayPreferBingeGroupForNextEpisodeKey = booleanPreferencesKey("stream_auto_play_prefer_bingegroup_next_episode")
|
||||
private val streamAutoPlayTimeoutSecondsKey = intPreferencesKey("stream_auto_play_timeout_seconds")
|
||||
private val nextEpisodeThresholdModeKey = stringPreferencesKey("next_episode_threshold_mode")
|
||||
private val nextEpisodeThresholdPercentLegacyKey = intPreferencesKey("next_episode_threshold_percent")
|
||||
private val nextEpisodeThresholdMinutesBeforeEndLegacyKey = intPreferencesKey("next_episode_threshold_minutes_before_end")
|
||||
|
|
@ -437,6 +439,7 @@ class PlayerSettingsDataStore @Inject constructor(
|
|||
streamAutoPlayNextEpisodeEnabled = prefs[streamAutoPlayNextEpisodeEnabledKey] ?: false,
|
||||
streamAutoPlayPreferBingeGroupForNextEpisode =
|
||||
prefs[streamAutoPlayPreferBingeGroupForNextEpisodeKey] ?: true,
|
||||
streamAutoPlayTimeoutSeconds = (prefs[streamAutoPlayTimeoutSecondsKey] ?: 3).coerceIn(0, 10),
|
||||
nextEpisodeThresholdMode = prefs[nextEpisodeThresholdModeKey]?.let {
|
||||
runCatching { NextEpisodeThresholdMode.valueOf(it) }.getOrDefault(NextEpisodeThresholdMode.PERCENTAGE)
|
||||
} ?: NextEpisodeThresholdMode.PERCENTAGE,
|
||||
|
|
@ -641,6 +644,12 @@ class PlayerSettingsDataStore @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun setStreamAutoPlayTimeoutSeconds(seconds: Int) {
|
||||
store().edit { prefs ->
|
||||
prefs[streamAutoPlayTimeoutSecondsKey] = seconds.coerceIn(0, 10)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun setNextEpisodeThresholdMode(mode: NextEpisodeThresholdMode) {
|
||||
store().edit { prefs ->
|
||||
prefs[nextEpisodeThresholdModeKey] = mode.name
|
||||
|
|
|
|||
|
|
@ -822,7 +822,10 @@ internal fun PlayerRuntimeController.playNextEpisode() {
|
|||
}
|
||||
}
|
||||
|
||||
delay(5_000L)
|
||||
val timeoutMs = playerSettings.streamAutoPlayTimeoutSeconds * 1_000L
|
||||
if (timeoutMs > 0L) {
|
||||
delay(timeoutMs)
|
||||
}
|
||||
timeoutElapsed = true
|
||||
if (!autoSelectTriggered && lastSuccessData != null) {
|
||||
autoSelectTriggered = true
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import androidx.compose.material.icons.filled.Extension
|
|||
import androidx.compose.material.icons.filled.Language
|
||||
import androidx.compose.material.icons.filled.PlayArrow
|
||||
import androidx.compose.material.icons.filled.SkipNext
|
||||
import androidx.compose.material.icons.filled.Timer
|
||||
import androidx.compose.material.icons.filled.History
|
||||
import androidx.compose.material.icons.filled.Tune
|
||||
import androidx.compose.runtime.Composable
|
||||
|
|
@ -81,6 +82,7 @@ internal fun LazyListScope.autoPlaySettingsItems(
|
|||
onSetStreamAutoPlayPreferBingeGroupForNextEpisode: (Boolean) -> Unit,
|
||||
onSetNextEpisodeThresholdPercent: (Float) -> Unit,
|
||||
onSetNextEpisodeThresholdMinutesBeforeEnd: (Float) -> Unit,
|
||||
onSetStreamAutoPlayTimeoutSeconds: (Int) -> Unit,
|
||||
onSetReuseLastLinkEnabled: (Boolean) -> Unit,
|
||||
onItemFocused: () -> Unit = {}
|
||||
) {
|
||||
|
|
@ -122,6 +124,29 @@ internal fun LazyListScope.autoPlaySettingsItems(
|
|||
)
|
||||
}
|
||||
|
||||
if (playerSettings.streamAutoPlayMode != StreamAutoPlayMode.MANUAL) {
|
||||
item(key = "autoplay_stream_timeout") {
|
||||
val timeoutSec = playerSettings.streamAutoPlayTimeoutSeconds
|
||||
val valueText = if (timeoutSec == 0) {
|
||||
stringResource(R.string.autoplay_timeout_instant)
|
||||
} else {
|
||||
"${timeoutSec}s"
|
||||
}
|
||||
SliderSettingsItem(
|
||||
icon = Icons.Default.Timer,
|
||||
title = stringResource(R.string.autoplay_timeout_title),
|
||||
subtitle = stringResource(R.string.autoplay_timeout_sub),
|
||||
value = timeoutSec,
|
||||
valueText = valueText,
|
||||
minValue = 0,
|
||||
maxValue = 10,
|
||||
step = 1,
|
||||
onValueChange = { onSetStreamAutoPlayTimeoutSeconds(it) },
|
||||
onFocused = onItemFocused
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
item(key = "autoplay_next_episode") {
|
||||
ToggleSettingsItem(
|
||||
icon = Icons.Default.SkipNext,
|
||||
|
|
|
|||
|
|
@ -231,6 +231,9 @@ fun PlaybackSettingsContent(
|
|||
onSetNextEpisodeThresholdMinutesBeforeEnd = { minutes ->
|
||||
coroutineScope.launch { viewModel.setNextEpisodeThresholdMinutesBeforeEnd(minutes) }
|
||||
},
|
||||
onSetStreamAutoPlayTimeoutSeconds = { seconds ->
|
||||
coroutineScope.launch { viewModel.setStreamAutoPlayTimeoutSeconds(seconds) }
|
||||
},
|
||||
onSetReuseLastLinkEnabled = { enabled -> coroutineScope.launch { viewModel.setStreamReuseLastLinkEnabled(enabled) } },
|
||||
onSetLoadingOverlayEnabled = { enabled -> coroutineScope.launch { viewModel.setLoadingOverlayEnabled(enabled) } },
|
||||
onSetPauseOverlayEnabled = { enabled -> coroutineScope.launch { viewModel.setPauseOverlayEnabled(enabled) } },
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ internal fun PlaybackSettingsSections(
|
|||
onSetStreamAutoPlayPreferBingeGroupForNextEpisode: (Boolean) -> Unit,
|
||||
onSetNextEpisodeThresholdPercent: (Float) -> Unit,
|
||||
onSetNextEpisodeThresholdMinutesBeforeEnd: (Float) -> Unit,
|
||||
onSetStreamAutoPlayTimeoutSeconds: (Int) -> Unit,
|
||||
onSetReuseLastLinkEnabled: (Boolean) -> Unit,
|
||||
onSetLoadingOverlayEnabled: (Boolean) -> Unit,
|
||||
onSetPauseOverlayEnabled: (Boolean) -> Unit,
|
||||
|
|
@ -315,6 +316,7 @@ internal fun PlaybackSettingsSections(
|
|||
onSetStreamAutoPlayPreferBingeGroupForNextEpisode = onSetStreamAutoPlayPreferBingeGroupForNextEpisode,
|
||||
onSetNextEpisodeThresholdPercent = onSetNextEpisodeThresholdPercent,
|
||||
onSetNextEpisodeThresholdMinutesBeforeEnd = onSetNextEpisodeThresholdMinutesBeforeEnd,
|
||||
onSetStreamAutoPlayTimeoutSeconds = onSetStreamAutoPlayTimeoutSeconds,
|
||||
onSetReuseLastLinkEnabled = onSetReuseLastLinkEnabled,
|
||||
onItemFocused = { focusedSection = PlaybackSection.STREAM_SELECTION }
|
||||
)
|
||||
|
|
|
|||
|
|
@ -237,6 +237,10 @@ class PlaybackSettingsViewModel @Inject constructor(
|
|||
playerSettingsDataStore.setStreamAutoPlayPreferBingeGroupForNextEpisode(enabled)
|
||||
}
|
||||
|
||||
suspend fun setStreamAutoPlayTimeoutSeconds(seconds: Int) {
|
||||
playerSettingsDataStore.setStreamAutoPlayTimeoutSeconds(seconds)
|
||||
}
|
||||
|
||||
suspend fun setNextEpisodeThresholdMode(mode: NextEpisodeThresholdMode) {
|
||||
playerSettingsDataStore.setNextEpisodeThresholdMode(mode)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -399,8 +399,11 @@ class StreamScreenViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
// After 5s: if streams arrived, auto-select now; if not, wait for first result from inner job
|
||||
delay(5_000L)
|
||||
// After timeout: if streams arrived, auto-select now; if not, wait for first result from inner job
|
||||
val timeoutMs = playerSettings.streamAutoPlayTimeoutSeconds * 1_000L
|
||||
if (timeoutMs > 0L) {
|
||||
delay(timeoutMs)
|
||||
}
|
||||
timeoutElapsed = true
|
||||
if (!autoSelectTriggered && lastSuccessData != null) {
|
||||
autoSelectTriggered = true
|
||||
|
|
|
|||
|
|
@ -282,6 +282,9 @@
|
|||
<string name="autoplay_scope_addons">Tylko zainstalowane dodatki</string>
|
||||
<string name="autoplay_scope_plugins">Tylko włączone wtyczki</string>
|
||||
<string name="autoplay_scope">Zakres źródeł auto-play</string>
|
||||
<string name="autoplay_timeout_title">Limit czasu wyboru strumienia</string>
|
||||
<string name="autoplay_timeout_sub">Czas oczekiwania na dodatki przed wyborem. 0 = pierwszy wynik wygrywa.</string>
|
||||
<string name="autoplay_timeout_instant">Natychmiast</string>
|
||||
<string name="autoplay_allowed_addons">Dozwolone dodatki</string>
|
||||
<string name="autoplay_all_addons">Wszystkie zainstalowane dodatki</string>
|
||||
<string name="autoplay_allowed_plugins">Dozwolone wtyczki</string>
|
||||
|
|
|
|||
|
|
@ -351,6 +351,9 @@
|
|||
<string name="autoplay_scope_addons">Installed addons only</string>
|
||||
<string name="autoplay_scope_plugins">Enabled plugins only</string>
|
||||
<string name="autoplay_scope">Auto-play Source Scope</string>
|
||||
<string name="autoplay_timeout_title">Stream Selection Timeout</string>
|
||||
<string name="autoplay_timeout_sub">Wait time for addons before selecting. 0 = first result wins.</string>
|
||||
<string name="autoplay_timeout_instant">Instant</string>
|
||||
<string name="autoplay_allowed_addons">Allowed Addons</string>
|
||||
<string name="autoplay_all_addons">All installed addons</string>
|
||||
<string name="autoplay_allowed_plugins">Allowed Plugins</string>
|
||||
|
|
|
|||
Loading…
Reference in a new issue