From dc1ff570c174205cdc63cf364194cddf84c1eb44 Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Sun, 5 Apr 2026 13:35:42 +0530 Subject: [PATCH 1/3] Trying Auto Skip --- .../cloudstream3/ui/player/GeneratorPlayer.kt | 86 +++++++++++++++++++ .../main/res/layout/player_custom_layout.xml | 5 +- .../res/layout/player_custom_layout_tv.xml | 5 +- .../res/values/donottranslate-strings.xml | 1 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/xml/settings_player.xml | 8 +- 6 files changed, 103 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt index ad7c8915f4b..7e0e00e4bb6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt @@ -138,6 +138,7 @@ class GeneratorPlayer : FullScreenPlayer() { const val NOTIFICATION_ID = 2326 const val CHANNEL_ID = 7340 const val STOP_ACTION = "stopcs3" + private const val SKIP_CHAPTER_AUTO_CLICK_COUNTDOWN_SECONDS = 5 private var lastUsedGenerator: IGenerator? = null fun newInstance(generator: IGenerator, syncData: HashMap? = null): Bundle { @@ -1996,12 +1997,91 @@ class GeneratorPlayer : FullScreenPlayer() { } override fun onDestroyView() { + clearSkipChapterAutoClick(resetText = false) binding = null super.onDestroyView() } var skipAnimator: ValueAnimator? = null var skipIndex = 0 + private var currentTimestamp: EpisodeSkip.SkipStamp? = null + private var skipAutoClickRunnable: Runnable? = null + private var skipAutoClickSecondsRemaining: Int? = null + private var skipAutoClickIndex: Int? = null + private var skipAutoClickTimestamp: EpisodeSkip.SkipStamp? = null + + private fun isAutoSkipPopupEnabled(): Boolean { + val ctx = context ?: return true + return PreferenceManager.getDefaultSharedPreferences(ctx).getBoolean( + ctx.getString(R.string.auto_skip_popup_key), + true + ) + } + + private fun updateSkipChapterButtonText() { + val text = currentTimestamp?.let { timestamp -> + if (isAutoSkipPopupEnabled()) { + skipAutoClickSecondsRemaining?.let { seconds -> + txt(R.string.skip_chapter_countdown_format, timestamp.uiText, seconds) + } ?: timestamp.uiText + } else { + timestamp.uiText + } + } + playerBinding?.skipChapterButton?.setText(text) + } + + private fun clearSkipChapterAutoClick(resetText: Boolean = true) { + skipAutoClickRunnable?.let { runnable -> + playerBinding?.skipChapterButton?.removeCallbacks(runnable) + } + skipAutoClickRunnable = null + skipAutoClickSecondsRemaining = null + skipAutoClickIndex = null + skipAutoClickTimestamp = null + if (resetText && currentTimestamp != null) { + updateSkipChapterButtonText() + } + } + + private fun startSkipChapterAutoClick(timestamp: EpisodeSkip.SkipStamp, currentIndex: Int) { + if ( + skipAutoClickRunnable != null && + skipAutoClickIndex == currentIndex && + skipAutoClickTimestamp == timestamp + ) return + + clearSkipChapterAutoClick(resetText = false) + if (!isAutoSkipPopupEnabled()) { + updateSkipChapterButtonText() + return + } + + skipAutoClickIndex = currentIndex + skipAutoClickTimestamp = timestamp + skipAutoClickSecondsRemaining = SKIP_CHAPTER_AUTO_CLICK_COUNTDOWN_SECONDS + updateSkipChapterButtonText() + + val runnable = object : Runnable { + override fun run() { + if (skipIndex != currentIndex || currentTimestamp != timestamp) return + + val nextSeconds = (skipAutoClickSecondsRemaining ?: return) - 1 + if (nextSeconds <= 0) { + clearSkipChapterAutoClick(resetText = false) + player.handleEvent(CSPlayerEvent.SkipCurrentChapter) + return + } + + skipAutoClickSecondsRemaining = nextSeconds + updateSkipChapterButtonText() + playerBinding?.skipChapterButton?.handler?.postDelayed(this, 1000) + } + } + + skipAutoClickRunnable = runnable + playerBinding?.skipChapterButton?.handler?.postDelayed(runnable, 1000) + } private fun displayTimeStamp(show: Boolean) { if (timestampShowState == show) return @@ -2053,11 +2133,14 @@ class GeneratorPlayer : FullScreenPlayer() { } override fun onTimestampSkipped(timestamp: EpisodeSkip.SkipStamp) { + currentTimestamp = null + clearSkipChapterAutoClick(resetText = false) displayTimeStamp(false) } override fun onTimestamp(timestamp: EpisodeSkip.SkipStamp?) { if (timestamp != null) { + currentTimestamp = timestamp playerBinding?.skipChapterButton?.setText(timestamp.uiText) displayTimeStamp(true) val currentIndex = skipIndex @@ -2065,7 +2148,10 @@ class GeneratorPlayer : FullScreenPlayer() { if (skipIndex == currentIndex) displayTimeStamp(false) }, 6000) + startSkipChapterAutoClick(timestamp, currentIndex) } else { + currentTimestamp = null + clearSkipChapterAutoClick(resetText = false) displayTimeStamp(false) } } diff --git a/app/src/main/res/layout/player_custom_layout.xml b/app/src/main/res/layout/player_custom_layout.xml index 72024a918d5..de6886b3d6c 100644 --- a/app/src/main/res/layout/player_custom_layout.xml +++ b/app/src/main/res/layout/player_custom_layout.xml @@ -620,11 +620,12 @@ - \ No newline at end of file + diff --git a/app/src/main/res/layout/player_custom_layout_tv.xml b/app/src/main/res/layout/player_custom_layout_tv.xml index ed06ef2b6a2..82c31dd3d6e 100644 --- a/app/src/main/res/layout/player_custom_layout_tv.xml +++ b/app/src/main/res/layout/player_custom_layout_tv.xml @@ -315,10 +315,11 @@ - \ No newline at end of file + diff --git a/app/src/main/res/values/donottranslate-strings.xml b/app/src/main/res/values/donottranslate-strings.xml index 0b7aab4cb7b..8c32243b68c 100644 --- a/app/src/main/res/values/donottranslate-strings.xml +++ b/app/src/main/res/values/donottranslate-strings.xml @@ -38,6 +38,7 @@ android_tv_interface_on_seek_key swipe_vertical_enabled_key autoplay_next_key + auto_skip_popup_key display_sub_key show_fillers_key show_player_metadata_key diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e9dd2748fc0..fe6a7dd042d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -156,6 +156,8 @@ Slide up or down on the left or right side to change brightness or volume Autoplay next episode Start the next episode when the current one ends + Auto-skip OP + Automatically SKIP OP after 5 seconds Double tap to seek Double tap to pause Player seek amount (Seconds) @@ -561,6 +563,7 @@ Mixed opening Credits Intro + %1$s (%2$d) Clear history History Show skip popups for opening/ending diff --git a/app/src/main/res/xml/settings_player.xml b/app/src/main/res/xml/settings_player.xml index 6e136747448..99d65719df4 100644 --- a/app/src/main/res/xml/settings_player.xml +++ b/app/src/main/res/xml/settings_player.xml @@ -98,6 +98,12 @@ android:title="@string/video_skip_op" app:defaultValue="true" app:key="@string/enable_skip_op_from_database" /> + - \ No newline at end of file + From a7a8dc11343eedff4fbcadd4675fd0373727cc8b Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Thu, 9 Apr 2026 09:23:59 +0530 Subject: [PATCH 2/3] Trying Auto Skip --- .../com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt index fffc32c1a9b..71eff245e01 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt @@ -2133,6 +2133,8 @@ class GeneratorPlayer : FullScreenPlayer() { } override fun onTimestampSkipped(timestamp: VideoSkipStamp) { + currentTimestamp = null + clearSkipChapterAutoClick(resetText = false) displayTimeStamp(false) } From 3b7ce95dae06d221ad25fd1b489c5b24ff511487 Mon Sep 17 00:00:00 2001 From: Phisher98 Date: Thu, 9 Apr 2026 09:51:03 +0530 Subject: [PATCH 3/3] Minor Fix --- .../cloudstream3/ui/player/GeneratorPlayer.kt | 31 +++++++++---------- app/src/main/res/xml/settings_player.xml | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt index 71eff245e01..08e8ca73a0f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt @@ -1997,24 +1997,24 @@ class GeneratorPlayer : FullScreenPlayer() { } override fun onDestroyView() { - clearSkipChapterAutoClick(resetText = false) + clearSkipChapterAutoClick() binding = null super.onDestroyView() } var skipAnimator: ValueAnimator? = null var skipIndex = 0 - private var currentTimestamp: EpisodeSkip.SkipStamp? = null + private var currentTimestamp: VideoSkipStamp? = null private var skipAutoClickRunnable: Runnable? = null private var skipAutoClickSecondsRemaining: Int? = null private var skipAutoClickIndex: Int? = null - private var skipAutoClickTimestamp: EpisodeSkip.SkipStamp? = null + private var skipAutoClickTimestamp: VideoSkipStamp? = null private fun isAutoSkipPopupEnabled(): Boolean { - val ctx = context ?: return true + val ctx = context ?: return false return PreferenceManager.getDefaultSharedPreferences(ctx).getBoolean( ctx.getString(R.string.auto_skip_popup_key), - true + false ) } @@ -2031,27 +2031,26 @@ class GeneratorPlayer : FullScreenPlayer() { playerBinding?.skipChapterButton?.setText(text) } - private fun clearSkipChapterAutoClick(resetText: Boolean = true) { + private fun clearSkipChapterAutoClick() { + val button = playerBinding?.skipChapterButton + skipAutoClickRunnable?.let { runnable -> - playerBinding?.skipChapterButton?.removeCallbacks(runnable) + button?.removeCallbacks(runnable) } + skipAutoClickRunnable = null skipAutoClickSecondsRemaining = null skipAutoClickIndex = null skipAutoClickTimestamp = null - if (resetText && currentTimestamp != null) { - updateSkipChapterButtonText() - } } - - private fun startSkipChapterAutoClick(timestamp: EpisodeSkip.SkipStamp, currentIndex: Int) { + private fun startSkipChapterAutoClick(timestamp: VideoSkipStamp, currentIndex: Int) { if ( skipAutoClickRunnable != null && skipAutoClickIndex == currentIndex && skipAutoClickTimestamp == timestamp ) return - clearSkipChapterAutoClick(resetText = false) + clearSkipChapterAutoClick() if (!isAutoSkipPopupEnabled()) { updateSkipChapterButtonText() return @@ -2068,7 +2067,7 @@ class GeneratorPlayer : FullScreenPlayer() { val nextSeconds = (skipAutoClickSecondsRemaining ?: return) - 1 if (nextSeconds <= 0) { - clearSkipChapterAutoClick(resetText = false) + clearSkipChapterAutoClick() player.handleEvent(CSPlayerEvent.SkipCurrentChapter) return } @@ -2134,7 +2133,7 @@ class GeneratorPlayer : FullScreenPlayer() { override fun onTimestampSkipped(timestamp: VideoSkipStamp) { currentTimestamp = null - clearSkipChapterAutoClick(resetText = false) + clearSkipChapterAutoClick() displayTimeStamp(false) } @@ -2151,7 +2150,7 @@ class GeneratorPlayer : FullScreenPlayer() { startSkipChapterAutoClick(timestamp, currentIndex) } else { currentTimestamp = null - clearSkipChapterAutoClick(resetText = false) + clearSkipChapterAutoClick() displayTimeStamp(false) } } diff --git a/app/src/main/res/xml/settings_player.xml b/app/src/main/res/xml/settings_player.xml index 99d65719df4..ac197eca7f3 100644 --- a/app/src/main/res/xml/settings_player.xml +++ b/app/src/main/res/xml/settings_player.xml @@ -102,7 +102,7 @@ android:icon="@drawable/ic_baseline_skip_next_24" android:summary="@string/auto_skip_popup_settings_des" android:title="@string/auto_skip_popup_settings" - app:defaultValue="true" + app:defaultValue="false" app:key="@string/auto_skip_popup_key" />