diff --git a/composeApp/src/androidMain/kotlin/com/nuvio/app/features/player/PlayerSettingsStorage.android.kt b/composeApp/src/androidMain/kotlin/com/nuvio/app/features/player/PlayerSettingsStorage.android.kt
index 74d31347..270f276c 100644
--- a/composeApp/src/androidMain/kotlin/com/nuvio/app/features/player/PlayerSettingsStorage.android.kt
+++ b/composeApp/src/androidMain/kotlin/com/nuvio/app/features/player/PlayerSettingsStorage.android.kt
@@ -60,6 +60,9 @@ actual object PlayerSettingsStorage {
private const val streamAutoPlayRegexKey = "stream_auto_play_regex"
private const val streamAutoPlayTimeoutSecondsKey = "stream_auto_play_timeout_seconds"
private const val skipIntroEnabledKey = "skip_intro_enabled"
+ private const val autoSkipIntroEnabledKey = "auto_skip_intro_enabled"
+ private const val autoSkipRecapEnabledKey = "auto_skip_recap_enabled"
+ private const val autoSkipOutroEnabledKey = "auto_skip_outro_enabled"
private const val animeSkipEnabledKey = "animeskip_enabled"
private const val animeSkipClientIdKey = "animeskip_client_id"
private const val introDbApiKeyKey = "introdb_api_key"
@@ -129,6 +132,9 @@ actual object PlayerSettingsStorage {
streamAutoPlayRegexKey,
streamAutoPlayTimeoutSecondsKey,
skipIntroEnabledKey,
+ autoSkipIntroEnabledKey,
+ autoSkipRecapEnabledKey,
+ autoSkipOutroEnabledKey,
animeSkipEnabledKey,
animeSkipClientIdKey,
streamAutoPlayNextEpisodeEnabledKey,
@@ -775,6 +781,57 @@ actual object PlayerSettingsStorage {
?.apply()
}
+ actual fun loadAutoSkipIntroEnabled(): Boolean? =
+ preferences?.let { sharedPreferences ->
+ val key = ProfileScopedKey.of(autoSkipIntroEnabledKey)
+ if (sharedPreferences.contains(key)) {
+ sharedPreferences.getBoolean(key, false)
+ } else {
+ null
+ }
+ }
+
+ actual fun saveAutoSkipIntroEnabled(enabled: Boolean) {
+ preferences
+ ?.edit()
+ ?.putBoolean(ProfileScopedKey.of(autoSkipIntroEnabledKey), enabled)
+ ?.apply()
+ }
+
+ actual fun loadAutoSkipRecapEnabled(): Boolean? =
+ preferences?.let { sharedPreferences ->
+ val key = ProfileScopedKey.of(autoSkipRecapEnabledKey)
+ if (sharedPreferences.contains(key)) {
+ sharedPreferences.getBoolean(key, false)
+ } else {
+ null
+ }
+ }
+
+ actual fun saveAutoSkipRecapEnabled(enabled: Boolean) {
+ preferences
+ ?.edit()
+ ?.putBoolean(ProfileScopedKey.of(autoSkipRecapEnabledKey), enabled)
+ ?.apply()
+ }
+
+ actual fun loadAutoSkipOutroEnabled(): Boolean? =
+ preferences?.let { sharedPreferences ->
+ val key = ProfileScopedKey.of(autoSkipOutroEnabledKey)
+ if (sharedPreferences.contains(key)) {
+ sharedPreferences.getBoolean(key, false)
+ } else {
+ null
+ }
+ }
+
+ actual fun saveAutoSkipOutroEnabled(enabled: Boolean) {
+ preferences
+ ?.edit()
+ ?.putBoolean(ProfileScopedKey.of(autoSkipOutroEnabledKey), enabled)
+ ?.apply()
+ }
+
actual fun loadAnimeSkipEnabled(): Boolean? =
preferences?.let { sharedPreferences ->
val key = ProfileScopedKey.of(animeSkipEnabledKey)
@@ -1116,6 +1173,9 @@ actual object PlayerSettingsStorage {
loadStreamAutoPlayRegex()?.let { put(streamAutoPlayRegexKey, encodeSyncString(it)) }
loadStreamAutoPlayTimeoutSeconds()?.let { put(streamAutoPlayTimeoutSecondsKey, encodeSyncInt(it)) }
loadSkipIntroEnabled()?.let { put(skipIntroEnabledKey, encodeSyncBoolean(it)) }
+ loadAutoSkipIntroEnabled()?.let { put(autoSkipIntroEnabledKey, encodeSyncBoolean(it)) }
+ loadAutoSkipRecapEnabled()?.let { put(autoSkipRecapEnabledKey, encodeSyncBoolean(it)) }
+ loadAutoSkipOutroEnabled()?.let { put(autoSkipOutroEnabledKey, encodeSyncBoolean(it)) }
loadAnimeSkipEnabled()?.let { put(animeSkipEnabledKey, encodeSyncBoolean(it)) }
loadAnimeSkipClientId()?.let { put(animeSkipClientIdKey, encodeSyncString(it)) }
loadStreamAutoPlayNextEpisodeEnabled()?.let { put(streamAutoPlayNextEpisodeEnabledKey, encodeSyncBoolean(it)) }
@@ -1190,6 +1250,9 @@ actual object PlayerSettingsStorage {
payload.decodeSyncString(streamAutoPlayRegexKey)?.let(::saveStreamAutoPlayRegex)
payload.decodeSyncInt(streamAutoPlayTimeoutSecondsKey)?.let(::saveStreamAutoPlayTimeoutSeconds)
payload.decodeSyncBoolean(skipIntroEnabledKey)?.let(::saveSkipIntroEnabled)
+ payload.decodeSyncBoolean(autoSkipIntroEnabledKey)?.let(::saveAutoSkipIntroEnabled)
+ payload.decodeSyncBoolean(autoSkipRecapEnabledKey)?.let(::saveAutoSkipRecapEnabled)
+ payload.decodeSyncBoolean(autoSkipOutroEnabledKey)?.let(::saveAutoSkipOutroEnabled)
payload.decodeSyncBoolean(animeSkipEnabledKey)?.let(::saveAnimeSkipEnabled)
payload.decodeSyncString(animeSkipClientIdKey)?.let(::saveAnimeSkipClientId)
payload.decodeSyncString(introDbApiKeyKey)?.let(::saveIntroDbApiKey)
diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
index affcc835..33e3bdbe 100644
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -1033,6 +1033,12 @@
Vertical Offset
Skip Intro
Use introdb.app to detect intros and recaps.
+ Auto-skip Intro / Opening
+ Skip intros and anime openings automatically.
+ Auto-skip Recap
+ Skip recap segments automatically.
+ Auto-skip Outro / Ending
+ Skip outros and anime endings automatically.
Auto-play Source Scope
All installed addons
Auto-play only considers streams coming from your installed addons.
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeEffects.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeEffects.kt
index 02df155a..49810a52 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeEffects.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeEffects.kt
@@ -10,6 +10,7 @@ import com.nuvio.app.features.p2p.P2pStreamingEngine
import com.nuvio.app.features.p2p.P2pStreamingState
import com.nuvio.app.features.player.skip.NextEpisodeInfo
import com.nuvio.app.features.player.skip.PlayerNextEpisodeRules
+import com.nuvio.app.features.player.skip.SkipInterval
import com.nuvio.app.features.player.skip.SkipIntroRepository
import com.nuvio.app.features.streams.BingeGroupCacheRepository
import com.nuvio.app.features.streams.StreamLinkCacheRepository
@@ -22,6 +23,15 @@ import kotlinx.coroutines.launch
import nuvio.composeapp.generated.resources.*
import org.jetbrains.compose.resources.getString
+/** Whether auto-skip is enabled for this segment's type (categorized by SkipIntroRepository). */
+internal fun PlayerSettingsUiState.autoSkips(interval: SkipInterval): Boolean =
+ when (SkipIntroRepository.segmentCategory(interval.type)) {
+ "opening" -> autoSkipIntroEnabled
+ "recap" -> autoSkipRecapEnabled
+ "ending" -> autoSkipOutroEnabled
+ else -> false
+ }
+
@Composable
internal fun PlayerScreenRuntime.BindPlayerRuntimeEffects() {
val currentFeedback = liveGestureFeedback ?: gestureFeedback
@@ -387,6 +397,7 @@ private fun PlayerScreenRuntime.BindPlayerMetadataAndSkipEffects() {
skipIntervals = emptyList()
activeSkipInterval = null
skipIntervalDismissed = false
+ autoSkippedIntervals = emptySet()
showNextEpisodeCard = false
nextEpisodeAutoPlayJob?.cancel()
nextEpisodeAutoPlaySearching = false
@@ -422,6 +433,21 @@ private fun PlayerScreenRuntime.BindPlayerMetadataAndSkipEffects() {
}
}
+ // Automatically skip the segment currently playing, once per segment.
+ LaunchedEffect(playbackSnapshot.positionMs, skipIntervals) {
+ if (!initialLoadCompleted || !initialSeekApplied || pausedOverlayVisible) return@LaunchedEffect
+ val positionSec = playbackSnapshot.positionMs / 1000.0
+ val current = skipIntervals.firstOrNull { interval ->
+ positionSec >= interval.startTime && positionSec < interval.endTime - 0.5
+ } ?: return@LaunchedEffect
+ if (current in autoSkippedIntervals) return@LaunchedEffect
+ if (!playerSettingsUiState.autoSkips(current)) return@LaunchedEffect
+ autoSkippedIntervals = autoSkippedIntervals + current
+ playerController?.seekTo((current.endTime * 1000).toLong())
+ scheduleProgressSyncAfterSeek()
+ skipIntervalDismissed = true
+ }
+
LaunchedEffect(playerMetaVideos, activeSeasonNumber, activeEpisodeNumber) {
if (!isSeries || playerMetaVideos.isEmpty()) {
nextEpisodeInfo = null
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeState.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeState.kt
index 43b4977a..f3dc11f2 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeState.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeState.kt
@@ -164,6 +164,7 @@ internal class PlayerScreenRuntime(
var skipIntervals by mutableStateOf>(emptyList())
var activeSkipInterval by mutableStateOf(null)
var skipIntervalDismissed by mutableStateOf(false)
+ var autoSkippedIntervals by mutableStateOf(setOf())
var parentalWarnings by mutableStateOf>(emptyList())
var showParentalGuide by mutableStateOf(false)
var parentalGuideHasShown by mutableStateOf(false)
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeUi.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeUi.kt
index d83c22fd..ddf352f1 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeUi.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeUi.kt
@@ -380,7 +380,9 @@ private fun BoxScope.RenderPlaybackOverlays(
renderedGestureFeedback = renderedGestureFeedback,
initialLoadCompleted = initialLoadCompleted,
pausedOverlayVisible = pausedOverlayVisible,
- activeSkipInterval = activeSkipInterval,
+ activeSkipInterval = activeSkipInterval?.takeUnless {
+ playerSettingsUiState.autoSkips(it) && (it !in autoSkippedIntervals || skipIntervalDismissed)
+ },
skipIntervalDismissed = skipIntervalDismissed,
controlsVisible = controlsVisible,
onSkipInterval = { interval ->
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerSettingsRepository.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerSettingsRepository.kt
index c0f4c429..90e16b1b 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerSettingsRepository.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerSettingsRepository.kt
@@ -64,6 +64,9 @@ data class PlayerSettingsUiState(
val streamAutoPlayRegex: String = "",
val streamAutoPlayTimeoutSeconds: Int = 3,
val skipIntroEnabled: Boolean = true,
+ val autoSkipIntroEnabled: Boolean = false,
+ val autoSkipRecapEnabled: Boolean = false,
+ val autoSkipOutroEnabled: Boolean = false,
val animeSkipEnabled: Boolean = false,
val animeSkipClientId: String = "",
val introDbApiKey: String = "",
@@ -130,6 +133,9 @@ object PlayerSettingsRepository {
private var streamAutoPlayRegex = ""
private var streamAutoPlayTimeoutSeconds = 3
private var skipIntroEnabled = true
+ private var autoSkipIntroEnabled = false
+ private var autoSkipRecapEnabled = false
+ private var autoSkipOutroEnabled = false
private var animeSkipEnabled = false
private var animeSkipClientId = ""
private var introDbApiKey = ""
@@ -201,6 +207,9 @@ object PlayerSettingsRepository {
streamAutoPlayRegex = ""
streamAutoPlayTimeoutSeconds = 3
skipIntroEnabled = true
+ autoSkipIntroEnabled = false
+ autoSkipRecapEnabled = false
+ autoSkipOutroEnabled = false
animeSkipEnabled = false
animeSkipClientId = ""
introDbApiKey = ""
@@ -324,6 +333,9 @@ object PlayerSettingsRepository {
PlayerSettingsStorage.saveStreamAutoPlayTimeoutSeconds(streamAutoPlayTimeoutSeconds)
}
skipIntroEnabled = PlayerSettingsStorage.loadSkipIntroEnabled() ?: true
+ autoSkipIntroEnabled = PlayerSettingsStorage.loadAutoSkipIntroEnabled() ?: false
+ autoSkipRecapEnabled = PlayerSettingsStorage.loadAutoSkipRecapEnabled() ?: false
+ autoSkipOutroEnabled = PlayerSettingsStorage.loadAutoSkipOutroEnabled() ?: false
animeSkipEnabled = PlayerSettingsStorage.loadAnimeSkipEnabled() ?: false
animeSkipClientId = PlayerSettingsStorage.loadAnimeSkipClientId() ?: ""
introDbApiKey = PlayerSettingsStorage.loadIntroDbApiKey() ?: ""
@@ -647,6 +659,30 @@ object PlayerSettingsRepository {
PlayerSettingsStorage.saveSkipIntroEnabled(enabled)
}
+ fun setAutoSkipIntroEnabled(enabled: Boolean) {
+ ensureLoaded()
+ if (autoSkipIntroEnabled == enabled) return
+ autoSkipIntroEnabled = enabled
+ publish()
+ PlayerSettingsStorage.saveAutoSkipIntroEnabled(enabled)
+ }
+
+ fun setAutoSkipRecapEnabled(enabled: Boolean) {
+ ensureLoaded()
+ if (autoSkipRecapEnabled == enabled) return
+ autoSkipRecapEnabled = enabled
+ publish()
+ PlayerSettingsStorage.saveAutoSkipRecapEnabled(enabled)
+ }
+
+ fun setAutoSkipOutroEnabled(enabled: Boolean) {
+ ensureLoaded()
+ if (autoSkipOutroEnabled == enabled) return
+ autoSkipOutroEnabled = enabled
+ publish()
+ PlayerSettingsStorage.saveAutoSkipOutroEnabled(enabled)
+ }
+
fun setAnimeSkipEnabled(enabled: Boolean) {
ensureLoaded()
if (animeSkipEnabled == enabled) return
@@ -942,6 +978,9 @@ object PlayerSettingsRepository {
streamAutoPlayRegex = streamAutoPlayRegex,
streamAutoPlayTimeoutSeconds = streamAutoPlayTimeoutSeconds,
skipIntroEnabled = skipIntroEnabled,
+ autoSkipIntroEnabled = autoSkipIntroEnabled,
+ autoSkipRecapEnabled = autoSkipRecapEnabled,
+ autoSkipOutroEnabled = autoSkipOutroEnabled,
animeSkipEnabled = animeSkipEnabled,
animeSkipClientId = animeSkipClientId,
introDbApiKey = introDbApiKey,
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerSettingsStorage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerSettingsStorage.kt
index 312a0764..c8856bef 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerSettingsStorage.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerSettingsStorage.kt
@@ -85,6 +85,12 @@ internal expect object PlayerSettingsStorage {
fun saveStreamAutoPlayTimeoutSeconds(seconds: Int)
fun loadSkipIntroEnabled(): Boolean?
fun saveSkipIntroEnabled(enabled: Boolean)
+ fun loadAutoSkipIntroEnabled(): Boolean?
+ fun saveAutoSkipIntroEnabled(enabled: Boolean)
+ fun loadAutoSkipRecapEnabled(): Boolean?
+ fun saveAutoSkipRecapEnabled(enabled: Boolean)
+ fun loadAutoSkipOutroEnabled(): Boolean?
+ fun saveAutoSkipOutroEnabled(enabled: Boolean)
fun loadAnimeSkipEnabled(): Boolean?
fun saveAnimeSkipEnabled(enabled: Boolean)
fun loadAnimeSkipClientId(): String?
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/skip/SkipIntroRepository.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/skip/SkipIntroRepository.kt
index d99dc978..7063b3fb 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/skip/SkipIntroRepository.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/skip/SkipIntroRepository.kt
@@ -151,7 +151,7 @@ object SkipIntroRepository {
return chosen.values.toList()
}
- private fun segmentCategory(type: String): String? = when (type.lowercase()) {
+ internal fun segmentCategory(type: String): String? = when (type.lowercase()) {
"intro", "op", "mixed-op" -> "opening"
"outro", "ed", "mixed-ed", "credits", "ending" -> "ending"
"recap" -> "recap"
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt
index 3dcf5a16..7a5e2308 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt
@@ -1028,6 +1028,33 @@ private fun PlaybackSettingsSection(
onCheckedChange = PlayerSettingsRepository::setSkipIntroEnabled,
)
SettingsGroupDivider(isTablet = isTablet)
+ SettingsSwitchRow(
+ title = stringResource(Res.string.settings_playback_auto_skip_intro),
+ description = stringResource(Res.string.settings_playback_auto_skip_intro_description),
+ checked = autoPlayPlayerSettings.autoSkipIntroEnabled,
+ enabled = autoPlayPlayerSettings.skipIntroEnabled,
+ isTablet = isTablet,
+ onCheckedChange = PlayerSettingsRepository::setAutoSkipIntroEnabled,
+ )
+ SettingsGroupDivider(isTablet = isTablet)
+ SettingsSwitchRow(
+ title = stringResource(Res.string.settings_playback_auto_skip_recap),
+ description = stringResource(Res.string.settings_playback_auto_skip_recap_description),
+ checked = autoPlayPlayerSettings.autoSkipRecapEnabled,
+ enabled = autoPlayPlayerSettings.skipIntroEnabled,
+ isTablet = isTablet,
+ onCheckedChange = PlayerSettingsRepository::setAutoSkipRecapEnabled,
+ )
+ SettingsGroupDivider(isTablet = isTablet)
+ SettingsSwitchRow(
+ title = stringResource(Res.string.settings_playback_auto_skip_outro),
+ description = stringResource(Res.string.settings_playback_auto_skip_outro_description),
+ checked = autoPlayPlayerSettings.autoSkipOutroEnabled,
+ enabled = autoPlayPlayerSettings.skipIntroEnabled,
+ isTablet = isTablet,
+ onCheckedChange = PlayerSettingsRepository::setAutoSkipOutroEnabled,
+ )
+ SettingsGroupDivider(isTablet = isTablet)
SettingsSwitchRow(
title = stringResource(Res.string.settings_playback_anime_skip),
description = stringResource(Res.string.settings_playback_anime_skip_description),
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsSearch.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsSearch.kt
index 9ed104d7..064b11f9 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsSearch.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsSearch.kt
@@ -637,6 +637,9 @@ internal fun settingsSearchEntries(
icon = Icons.Rounded.PlayArrow,
rows = listOf(
PlaybackSearchRow("skip-intro", stringResource(Res.string.settings_playback_skip_intro_outro_recap), stringResource(Res.string.settings_playback_skip_intro_outro_recap_description)),
+ PlaybackSearchRow("auto-skip-intro", stringResource(Res.string.settings_playback_auto_skip_intro), stringResource(Res.string.settings_playback_auto_skip_intro_description)),
+ PlaybackSearchRow("auto-skip-recap", stringResource(Res.string.settings_playback_auto_skip_recap), stringResource(Res.string.settings_playback_auto_skip_recap_description)),
+ PlaybackSearchRow("auto-skip-outro", stringResource(Res.string.settings_playback_auto_skip_outro), stringResource(Res.string.settings_playback_auto_skip_outro_description)),
PlaybackSearchRow("anime-skip", stringResource(Res.string.settings_playback_anime_skip), stringResource(Res.string.settings_playback_anime_skip_description)),
PlaybackSearchRow("anime-skip-client", stringResource(Res.string.settings_playback_anime_skip_client_id), stringResource(Res.string.settings_playback_anime_skip_client_id_description)),
PlaybackSearchRow("intro-submit", stringResource(Res.string.settings_playback_intro_submit_enabled), stringResource(Res.string.settings_playback_intro_submit_enabled_description)),
diff --git a/composeApp/src/iosMain/kotlin/com/nuvio/app/features/player/PlayerSettingsStorage.ios.kt b/composeApp/src/iosMain/kotlin/com/nuvio/app/features/player/PlayerSettingsStorage.ios.kt
index 4eeb657a..b9297674 100644
--- a/composeApp/src/iosMain/kotlin/com/nuvio/app/features/player/PlayerSettingsStorage.ios.kt
+++ b/composeApp/src/iosMain/kotlin/com/nuvio/app/features/player/PlayerSettingsStorage.ios.kt
@@ -58,6 +58,9 @@ actual object PlayerSettingsStorage {
private const val streamAutoPlayRegexKey = "stream_auto_play_regex"
private const val streamAutoPlayTimeoutSecondsKey = "stream_auto_play_timeout_seconds"
private const val skipIntroEnabledKey = "skip_intro_enabled"
+ private const val autoSkipIntroEnabledKey = "auto_skip_intro_enabled"
+ private const val autoSkipRecapEnabledKey = "auto_skip_recap_enabled"
+ private const val autoSkipOutroEnabledKey = "auto_skip_outro_enabled"
private const val animeSkipEnabledKey = "animeskip_enabled"
private const val animeSkipClientIdKey = "animeskip_client_id"
private const val introDbApiKeyKey = "introdb_api_key"
@@ -127,6 +130,9 @@ actual object PlayerSettingsStorage {
streamAutoPlayRegexKey,
streamAutoPlayTimeoutSecondsKey,
skipIntroEnabledKey,
+ autoSkipIntroEnabledKey,
+ autoSkipRecapEnabledKey,
+ autoSkipOutroEnabledKey,
animeSkipEnabledKey,
animeSkipClientIdKey,
streamAutoPlayNextEpisodeEnabledKey,
@@ -656,6 +662,48 @@ actual object PlayerSettingsStorage {
NSUserDefaults.standardUserDefaults.setBool(enabled, forKey = ProfileScopedKey.of(skipIntroEnabledKey))
}
+ actual fun loadAutoSkipIntroEnabled(): Boolean? {
+ val defaults = NSUserDefaults.standardUserDefaults
+ val key = ProfileScopedKey.of(autoSkipIntroEnabledKey)
+ return if (defaults.objectForKey(key) != null) {
+ defaults.boolForKey(key)
+ } else {
+ null
+ }
+ }
+
+ actual fun saveAutoSkipIntroEnabled(enabled: Boolean) {
+ NSUserDefaults.standardUserDefaults.setBool(enabled, forKey = ProfileScopedKey.of(autoSkipIntroEnabledKey))
+ }
+
+ actual fun loadAutoSkipRecapEnabled(): Boolean? {
+ val defaults = NSUserDefaults.standardUserDefaults
+ val key = ProfileScopedKey.of(autoSkipRecapEnabledKey)
+ return if (defaults.objectForKey(key) != null) {
+ defaults.boolForKey(key)
+ } else {
+ null
+ }
+ }
+
+ actual fun saveAutoSkipRecapEnabled(enabled: Boolean) {
+ NSUserDefaults.standardUserDefaults.setBool(enabled, forKey = ProfileScopedKey.of(autoSkipRecapEnabledKey))
+ }
+
+ actual fun loadAutoSkipOutroEnabled(): Boolean? {
+ val defaults = NSUserDefaults.standardUserDefaults
+ val key = ProfileScopedKey.of(autoSkipOutroEnabledKey)
+ return if (defaults.objectForKey(key) != null) {
+ defaults.boolForKey(key)
+ } else {
+ null
+ }
+ }
+
+ actual fun saveAutoSkipOutroEnabled(enabled: Boolean) {
+ NSUserDefaults.standardUserDefaults.setBool(enabled, forKey = ProfileScopedKey.of(autoSkipOutroEnabledKey))
+ }
+
actual fun loadAnimeSkipEnabled(): Boolean? {
val defaults = NSUserDefaults.standardUserDefaults
val key = ProfileScopedKey.of(animeSkipEnabledKey)
@@ -936,6 +984,9 @@ actual object PlayerSettingsStorage {
loadStreamAutoPlayRegex()?.let { put(streamAutoPlayRegexKey, encodeSyncString(it)) }
loadStreamAutoPlayTimeoutSeconds()?.let { put(streamAutoPlayTimeoutSecondsKey, encodeSyncInt(it)) }
loadSkipIntroEnabled()?.let { put(skipIntroEnabledKey, encodeSyncBoolean(it)) }
+ loadAutoSkipIntroEnabled()?.let { put(autoSkipIntroEnabledKey, encodeSyncBoolean(it)) }
+ loadAutoSkipRecapEnabled()?.let { put(autoSkipRecapEnabledKey, encodeSyncBoolean(it)) }
+ loadAutoSkipOutroEnabled()?.let { put(autoSkipOutroEnabledKey, encodeSyncBoolean(it)) }
loadAnimeSkipEnabled()?.let { put(animeSkipEnabledKey, encodeSyncBoolean(it)) }
loadAnimeSkipClientId()?.let { put(animeSkipClientIdKey, encodeSyncString(it)) }
loadStreamAutoPlayNextEpisodeEnabled()?.let { put(streamAutoPlayNextEpisodeEnabledKey, encodeSyncBoolean(it)) }
@@ -1009,6 +1060,9 @@ actual object PlayerSettingsStorage {
payload.decodeSyncString(streamAutoPlayRegexKey)?.let(::saveStreamAutoPlayRegex)
payload.decodeSyncInt(streamAutoPlayTimeoutSecondsKey)?.let(::saveStreamAutoPlayTimeoutSeconds)
payload.decodeSyncBoolean(skipIntroEnabledKey)?.let(::saveSkipIntroEnabled)
+ payload.decodeSyncBoolean(autoSkipIntroEnabledKey)?.let(::saveAutoSkipIntroEnabled)
+ payload.decodeSyncBoolean(autoSkipRecapEnabledKey)?.let(::saveAutoSkipRecapEnabled)
+ payload.decodeSyncBoolean(autoSkipOutroEnabledKey)?.let(::saveAutoSkipOutroEnabled)
payload.decodeSyncBoolean(animeSkipEnabledKey)?.let(::saveAnimeSkipEnabled)
payload.decodeSyncString(animeSkipClientIdKey)?.let(::saveAnimeSkipClientId)
payload.decodeSyncString(introDbApiKeyKey)?.let(::saveIntroDbApiKey)