mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-09 08:01:20 +02:00
Suport passout protection (#41)
Adds a setting to configure pass out protection which, when enabled, will stop auto playing next up episodes if the user hasn't interacted with the app within the configurable 1-3 hours.
This commit is contained in:
parent
c3cc284238
commit
8904360fb5
7 changed files with 56 additions and 7 deletions
|
|
@ -8,6 +8,7 @@ import com.github.damontecres.wholphin.ui.nav.Destination
|
|||
import com.github.damontecres.wholphin.ui.preferences.PreferenceGroup
|
||||
import com.github.damontecres.wholphin.ui.preferences.PreferenceScreenOption
|
||||
import com.github.damontecres.wholphin.ui.preferences.PreferenceValidation
|
||||
import kotlin.time.Duration.Companion.hours
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
|
@ -267,6 +268,28 @@ sealed interface AppPreference<T> {
|
|||
},
|
||||
)
|
||||
|
||||
val PassOutProtection =
|
||||
AppSliderPreference(
|
||||
title = R.string.pass_out_protection,
|
||||
defaultValue = 2,
|
||||
min = 0,
|
||||
max = 3,
|
||||
interval = 1,
|
||||
getter = { it.playbackPreferences.passOutProtectionMs.milliseconds.inWholeHours },
|
||||
setter = { prefs, value ->
|
||||
prefs.updatePlaybackPreferences {
|
||||
passOutProtectionMs = value.hours.inWholeMilliseconds
|
||||
}
|
||||
},
|
||||
summarizer = { value ->
|
||||
if (value == 0L) {
|
||||
"Disabled"
|
||||
} else {
|
||||
"$value hours"
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
private const val MEGA_BIT = 1024 * 1024L
|
||||
const val DEFAULT_BITRATE = 20 * MEGA_BIT
|
||||
private val bitrateValues =
|
||||
|
|
@ -529,6 +552,7 @@ val basicPreferences =
|
|||
AppPreference.ControllerTimeout,
|
||||
AppPreference.AutoPlayNextUp,
|
||||
AppPreference.AutoPlayNextDelay,
|
||||
AppPreference.PassOutProtection,
|
||||
AppPreference.SkipBackOnResume,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import java.io.InputStream
|
|||
import java.io.OutputStream
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Duration.Companion.hours
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
class AppPreferencesSerializer
|
||||
|
|
@ -42,6 +43,8 @@ class AppPreferencesSerializer
|
|||
skipCommercials = AppPreference.SkipCommercials.defaultValue
|
||||
skipPreviews = AppPreference.SkipPreviews.defaultValue
|
||||
skipRecaps = AppPreference.SkipRecaps.defaultValue
|
||||
passOutProtectionMs =
|
||||
AppPreference.PassOutProtection.defaultValue.hours.inWholeMilliseconds
|
||||
|
||||
overrides =
|
||||
PlaybackOverrides
|
||||
|
|
|
|||
|
|
@ -23,8 +23,11 @@ class PlaybackKeyHandler(
|
|||
private val controllerViewState: ControllerViewState,
|
||||
private val updateSkipIndicator: (Long) -> Unit,
|
||||
private val skipBackOnResume: Duration?,
|
||||
private val onInteraction: () -> Unit,
|
||||
) {
|
||||
fun onKeyEvent(it: KeyEvent): Boolean {
|
||||
if (it.type == KeyEventType.KeyUp) onInteraction.invoke()
|
||||
|
||||
var result = true
|
||||
if (!controlsEnabled) {
|
||||
result = false
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ fun PlaybackPage(
|
|||
controllerViewState = controllerViewState,
|
||||
updateSkipIndicator = updateSkipIndicator,
|
||||
skipBackOnResume = preferences.appPreferences.playbackPreferences.skipBackOnResume,
|
||||
onInteraction = viewModel::reportInteraction,
|
||||
)
|
||||
|
||||
val showSegment =
|
||||
|
|
@ -413,12 +414,7 @@ fun PlaybackPage(
|
|||
.align(Alignment.BottomCenter),
|
||||
) {
|
||||
nextUp?.let {
|
||||
var autoPlayEnabled by
|
||||
remember {
|
||||
mutableStateOf(
|
||||
preferences.appPreferences.playbackPreferences.autoPlayNext,
|
||||
)
|
||||
}
|
||||
var autoPlayEnabled by remember { mutableStateOf(viewModel.shouldAutoPlayNextUp()) }
|
||||
var timeLeft by remember {
|
||||
mutableLongStateOf(
|
||||
preferences.appPreferences.playbackPreferences.autoPlayNextDelaySeconds,
|
||||
|
|
@ -452,7 +448,10 @@ fun PlaybackPage(
|
|||
description = it.data.overview,
|
||||
imageUrl = it.imageUrl,
|
||||
aspectRatio = it.data.primaryImageAspectRatio?.toFloat() ?: (16f / 9),
|
||||
onClick = { viewModel.playUpNextUp() },
|
||||
onClick = {
|
||||
viewModel.reportInteraction()
|
||||
viewModel.playUpNextUp()
|
||||
},
|
||||
timeLeft = if (autoPlayEnabled) timeLeft.seconds else null,
|
||||
modifier =
|
||||
Modifier
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ import org.jellyfin.sdk.model.extensions.inWholeTicks
|
|||
import org.jellyfin.sdk.model.extensions.ticks
|
||||
import org.jellyfin.sdk.model.serializer.toUUIDOrNull
|
||||
import timber.log.Timber
|
||||
import java.util.Date
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Duration
|
||||
|
|
@ -649,6 +650,23 @@ class PlaybackViewModel
|
|||
}
|
||||
}
|
||||
|
||||
private var lastInteractionDate: Date = Date()
|
||||
|
||||
fun reportInteraction() {
|
||||
Timber.v("reportInteraction")
|
||||
lastInteractionDate = Date()
|
||||
}
|
||||
|
||||
fun shouldAutoPlayNextUp(): Boolean =
|
||||
preferences.appPreferences.playbackPreferences.let {
|
||||
it.autoPlayNext &&
|
||||
if (it.passOutProtectionMs > 0) {
|
||||
(Date().time - lastInteractionDate.time) < it.passOutProtectionMs
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fun playUpNextUp() {
|
||||
playlist.value?.let {
|
||||
if (it.hasNext()) {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ message PlaybackPreferences {
|
|||
SkipSegmentBehavior skip_previews = 14;
|
||||
|
||||
PlaybackOverrides overrides = 15;
|
||||
int64 pass_out_protection_ms = 16;
|
||||
}
|
||||
|
||||
message HomePagePreferences{
|
||||
|
|
|
|||
|
|
@ -83,5 +83,6 @@
|
|||
<string name="direct_play_ass">Direct play ASS subtitles</string>
|
||||
<string name="direct_play_pgs">Direct play PGS subtitles</string>
|
||||
<string name="trailers">Trailers</string>
|
||||
<string name="pass_out_protection">Passout Protection</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue