mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-07-29 15:49:30 +00:00
Merge 5a8fe85b67 into 88d3cbdfac
This commit is contained in:
commit
8b551978c4
11 changed files with 229 additions and 2 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -1033,6 +1033,12 @@
|
|||
<string name="settings_playback_subtitle_vertical_offset">Vertical Offset</string>
|
||||
<string name="settings_playback_skip_intro_outro_recap">Skip Intro</string>
|
||||
<string name="settings_playback_skip_intro_outro_recap_description">Use introdb.app to detect intros and recaps.</string>
|
||||
<string name="settings_playback_auto_skip_intro">Auto-skip Intro / Opening</string>
|
||||
<string name="settings_playback_auto_skip_intro_description">Skip intros and anime openings automatically.</string>
|
||||
<string name="settings_playback_auto_skip_recap">Auto-skip Recap</string>
|
||||
<string name="settings_playback_auto_skip_recap_description">Skip recap segments automatically.</string>
|
||||
<string name="settings_playback_auto_skip_outro">Auto-skip Outro / Ending</string>
|
||||
<string name="settings_playback_auto_skip_outro_description">Skip outros and anime endings automatically.</string>
|
||||
<string name="settings_playback_source_scope">Auto-play Source Scope</string>
|
||||
<string name="settings_playback_source_scope_all_addons">All installed addons</string>
|
||||
<string name="settings_playback_source_scope_all_addons_description">Auto-play only considers streams coming from your installed addons.</string>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ internal class PlayerScreenRuntime(
|
|||
var skipIntervals by mutableStateOf<List<SkipInterval>>(emptyList())
|
||||
var activeSkipInterval by mutableStateOf<SkipInterval?>(null)
|
||||
var skipIntervalDismissed by mutableStateOf(false)
|
||||
var autoSkippedIntervals by mutableStateOf(setOf<SkipInterval>())
|
||||
var parentalWarnings by mutableStateOf<List<ParentalWarning>>(emptyList())
|
||||
var showParentalGuide by mutableStateOf(false)
|
||||
var parentalGuideHasShown by mutableStateOf(false)
|
||||
|
|
|
|||
|
|
@ -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 ->
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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)),
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue