From 592d6ab0369a790db86e7f7629d139288d5b18fb Mon Sep 17 00:00:00 2001 From: general-a <404aaronm@gmail.com> Date: Sat, 17 Jun 2023 00:21:47 -0500 Subject: [PATCH 01/11] Added ability to choose what categories are skipped automatically and manually --- .../libretube/constants/PreferenceKeys.kt | 1 - .../github/libretube/helpers/PlayerHelper.kt | 80 +++---------------- .../libretube/services/OnlinePlayerService.kt | 8 +- .../libretube/ui/fragments/PlayerFragment.kt | 10 +-- app/src/main/res/values/array.xml | 7 ++ app/src/main/res/values/strings.xml | 16 ++-- .../main/res/xml/sponsorblock_settings.xml | 66 +++++++++------ 7 files changed, 79 insertions(+), 109 deletions(-) diff --git a/app/src/main/java/com/github/libretube/constants/PreferenceKeys.kt b/app/src/main/java/com/github/libretube/constants/PreferenceKeys.kt index 0b8a113f3b..c7c07f4db4 100644 --- a/app/src/main/java/com/github/libretube/constants/PreferenceKeys.kt +++ b/app/src/main/java/com/github/libretube/constants/PreferenceKeys.kt @@ -81,7 +81,6 @@ object PreferenceKeys { const val SKIP_BUTTONS = "skip_buttons" const val PICTURE_IN_PICTURE = "picture_in_picture" const val PLAYER_RESIZE_MODE = "player_resize_mode" - const val SB_SKIP_MANUALLY = "sb_skip_manually_key" const val SB_SHOW_MARKERS = "sb_show_markers" const val ALTERNATIVE_PLAYER_LAYOUT = "alternative_player_layout" const val USE_HLS_OVER_DASH = "use_hls" diff --git a/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt b/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt index 53145c086b..1a571b8698 100644 --- a/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt @@ -23,11 +23,9 @@ import androidx.media3.exoplayer.ExoPlayer import androidx.media3.exoplayer.LoadControl import androidx.media3.ui.CaptionStyleCompat import com.github.libretube.R -import com.github.libretube.api.obj.PipedStream import com.github.libretube.api.obj.Segment import com.github.libretube.api.obj.Streams import com.github.libretube.constants.PreferenceKeys -import com.github.libretube.enums.AudioQuality import com.github.libretube.enums.PlayerEvent import kotlin.math.absoluteValue import kotlin.math.roundToInt @@ -35,6 +33,7 @@ import kotlin.math.roundToInt object PlayerHelper { private const val ACTION_MEDIA_CONTROL = "media_control" const val CONTROL_TYPE = "control_type" + private val SPONSOR_CATEGORIES: Array = arrayOf("intro", "selfpromo", "interaction", "sponsor", "outro", "filler", "music_offtopic", "preview") /** * Create a base64 encoded DASH stream manifest @@ -69,65 +68,18 @@ object PlayerHelper { /** * get the categories for sponsorBlock */ - fun getSponsorBlockCategories(): ArrayList { - val categories: ArrayList = arrayListOf() - if (PreferenceHelper.getBoolean( - "intro_category_key", - false, - ) - ) { - categories.add("intro") - } - if (PreferenceHelper.getBoolean( - "selfpromo_category_key", - false, - ) - ) { - categories.add("selfpromo") - } - if (PreferenceHelper.getBoolean( - "interaction_category_key", - false, - ) - ) { - categories.add("interaction") - } - if (PreferenceHelper.getBoolean( - "sponsors_category_key", - true, - ) - ) { - categories.add("sponsor") - } - if (PreferenceHelper.getBoolean( - "outro_category_key", - false, - ) - ) { - categories.add("outro") - } - if (PreferenceHelper.getBoolean( - "filler_category_key", - false, - ) - ) { - categories.add("filler") - } - if (PreferenceHelper.getBoolean( - "music_offtopic_category_key", - false, - ) - ) { - categories.add("music_offtopic") - } - if (PreferenceHelper.getBoolean( - "preview_category_key", - false, - ) - ) { - categories.add("preview") + //TODO: This should probably be done with Enums to avoid magic string anti pattern + fun getSponsorBlockCategories(): MutableMap { + val categories: MutableMap = mutableMapOf() + + for (cat in SPONSOR_CATEGORIES){ + val state = PreferenceHelper.getString(cat + "_category_key", "Off") + if (state != "Off"){ + categories[cat] = state + } } return categories + } fun getOrientation(videoWidth: Int, videoHeight: Int): Int { @@ -240,12 +192,6 @@ object PlayerHelper { true, ) - val skipSegmentsManually: Boolean - get() = PreferenceHelper.getBoolean( - PreferenceKeys.SB_SKIP_MANUALLY, - false, - ) - val autoPlayEnabled: Boolean get() = PreferenceHelper.getBoolean( PreferenceKeys.AUTO_PLAY, @@ -476,7 +422,7 @@ object PlayerHelper { fun ExoPlayer.checkForSegments( context: Context, segments: List, - skipManually: Boolean = false, + category_config: MutableMap, ): Long? { for (segment in segments) { val segmentStart = (segment.segment[0] * 1000f).toLong() @@ -486,7 +432,7 @@ object PlayerHelper { if ((duration - currentPosition).absoluteValue < 500) continue if (currentPosition in segmentStart until segmentEnd) { - if (!skipManually) { + if (category_config.get(segment.category) == "Automatic") { if (sponsorBlockNotifications) { runCatching { Toast.makeText(context, R.string.segment_skipped, Toast.LENGTH_SHORT) diff --git a/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt b/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt index 336c103476..36d60c5593 100644 --- a/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt +++ b/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt @@ -76,6 +76,7 @@ class OnlinePlayerService : LifecycleService() { * SponsorBlock Segment data */ private var segments: List = listOf() + private var catConfig: MutableMap = PlayerHelper.getSponsorBlockCategories() /** * [Notification] for the player @@ -321,11 +322,10 @@ class OnlinePlayerService : LifecycleService() { private fun fetchSponsorBlockSegments() { lifecycleScope.launch(Dispatchers.IO) { runCatching { - val categories = PlayerHelper.getSponsorBlockCategories() - if (categories.isEmpty()) return@runCatching + if (catConfig.isEmpty()) return@runCatching segments = RetrofitInstance.api.getSegments( videoId, - JsonHelper.json.encodeToString(categories), + JsonHelper.json.encodeToString(catConfig.keys), ).segments checkForSegments() } @@ -338,7 +338,7 @@ class OnlinePlayerService : LifecycleService() { private fun checkForSegments() { handler.postDelayed(this::checkForSegments, 100) - player?.checkForSegments(this, segments) + player?.checkForSegments(this, segments, catConfig) } private fun updateQueue() { diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index 109b6edabe..6768b31b03 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -181,6 +181,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { * SponsorBlock */ private var segments = listOf() + private var catConfig = PlayerHelper.getSponsorBlockCategories() private var sponsorBlockEnabled = PlayerHelper.sponsorBlockEnabled private val handler = Handler(Looper.getMainLooper()) @@ -663,16 +664,16 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { if (segments.isEmpty()) return - exoPlayer.checkForSegments(requireContext(), segments, PlayerHelper.skipSegmentsManually) + exoPlayer.checkForSegments(requireContext(), segments, catConfig) ?.let { segmentEnd -> binding.sbSkipBtn.visibility = View.VISIBLE binding.sbSkipBtn.setOnClickListener { exoPlayer.seekTo(segmentEnd) + binding.sbSkipBtn.visibility = View.GONE } return } - if (PlayerHelper.skipSegmentsManually) binding.sbSkipBtn.visibility = View.GONE } private fun playVideo() { @@ -773,12 +774,11 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { private fun fetchSponsorBlockSegments() { lifecycleScope.launch(Dispatchers.IO) { runCatching { - val categories = PlayerHelper.getSponsorBlockCategories() - if (categories.isEmpty()) return@runCatching + if (catConfig.isEmpty()) return@runCatching segments = RetrofitInstance.api.getSegments( videoId!!, - JsonHelper.json.encodeToString(categories), + JsonHelper.json.encodeToString(catConfig.keys), ).segments if (segments.isEmpty()) return@runCatching diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index 4c01c553e5..5f93698d81 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -422,4 +422,11 @@ playlists + + Off + Manual + Automatic + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2a2f61473e..359cfa5b1f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -85,21 +85,21 @@ Skipped segment Segments Sponsor - Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free genuine shoutouts to causes, creators, websites, and products. + Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free genuine shoutouts to causes, creators, websites, and products: %s Unpaid/Self Promotion - Similar to \"sponsor\" except for unpaid or self promotion. This includes sections about merchandise, donations, or info about who they collaborated with. + Similar to \"sponsor\" except for unpaid or self promotion. This includes sections about merchandise, donations, or info about who they collaborated with: %s Interaction reminder (like and subscribe) - When there is a short reminder to like, subscribe or follow in the middle of content. If long or about something specific, it should instead be self promotion. + When there is a short reminder to like, subscribe or follow in the middle of content. If long or about something specific, it should instead be self promotion: %s Intermission/Intro Animation - An interval without actual content. Could be a pause, static frame, repeating animation. Should not be used for transitions containing info. + An interval without actual content. Could be a pause, static frame, repeating animation. Should not be used for transitions containing info: %s End cards and credits - Info following the ending. Not for conclusions with info. + Info following the ending. Not for conclusions with info: %s Filler Tangent/Jokes - For tangential scenes added only for filler or humor not required to understand the main content of the video. + For tangential scenes added only for filler or humor not required to understand the main content of the video: %s Music: Non-Music Section - Only for use in music videos. It should cover parts of the video not part of official mixes. In the end, the video should resemble the Spotify or any other mixed version as closely as possible, or reduce talking or other distractions. + Only for use in music videos. It should cover parts of the video not part of official mixes. In the end, the video should resemble the Spotify or any other mixed version as closely as possible, or reduce talking or other distractions: %s Preview/Recap - For segments detailing future content without additional info. If it includes clips that only appear here, this is very likely the wrong category. + For segments detailing future content without additional info. If it includes clips that only appear here, this is very likely the wrong category: %s License Accents Resting red diff --git a/app/src/main/res/xml/sponsorblock_settings.xml b/app/src/main/res/xml/sponsorblock_settings.xml index d1f7b0a30e..279b507892 100644 --- a/app/src/main/res/xml/sponsorblock_settings.xml +++ b/app/src/main/res/xml/sponsorblock_settings.xml @@ -24,55 +24,73 @@ app:key="sb_show_markers" app:title="@string/sb_markers" /> - - + app:title="@string/category_sponsor" + app:entries="@array/category_sponsor_skip_choices" + app:entryValues="@array/category_sponsor_skip_choices" + app:defaultValue="Automatic"/> + - + app:title="@string/category_selfpromo" + app:entries="@array/category_sponsor_skip_choices" + app:entryValues="@array/category_sponsor_skip_choices" + app:defaultValue="Manual"/> - + app:title="@string/category_interaction" + app:entries="@array/category_sponsor_skip_choices" + app:entryValues="@array/category_sponsor_skip_choices" + app:defaultValue="Off"/> - + app:title="@string/category_intro" + app:entries="@array/category_sponsor_skip_choices" + app:entryValues="@array/category_sponsor_skip_choices" + app:defaultValue="Off"/> - + app:title="@string/category_outro" + app:entries="@array/category_sponsor_skip_choices" + app:entryValues="@array/category_sponsor_skip_choices" + app:defaultValue="Off"/> - + app:title="@string/category_filler" + app:entries="@array/category_sponsor_skip_choices" + app:entryValues="@array/category_sponsor_skip_choices" + app:defaultValue="Off"/> - + app:title="@string/category_music_offtopic" + app:entries="@array/category_sponsor_skip_choices" + app:entryValues="@array/category_sponsor_skip_choices" + app:defaultValue="Off"/> - + app:title="@string/category_preview" + app:entries="@array/category_sponsor_skip_choices" + app:entryValues="@array/category_sponsor_skip_choices" + app:defaultValue="Off"/> From 1ec85152779a4fb20aae564105509e09555d8cf7 Mon Sep 17 00:00:00 2001 From: general-a <404aaronm@gmail.com> Date: Sat, 17 Jun 2023 13:16:36 -0500 Subject: [PATCH 02/11] Added requested changes and implemented enums for state --- .../github/libretube/helpers/PlayerHelper.kt | 17 ++++--- .../libretube/services/OnlinePlayerService.kt | 9 ++-- .../libretube/ui/fragments/PlayerFragment.kt | 8 ++-- app/src/main/res/values/array.xml | 13 +++-- app/src/main/res/values/strings.xml | 3 ++ .../main/res/xml/sponsorblock_settings.xml | 48 +++++++++---------- 6 files changed, 53 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt b/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt index 1a571b8698..872ff00db4 100644 --- a/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt @@ -27,6 +27,7 @@ import com.github.libretube.api.obj.Segment import com.github.libretube.api.obj.Streams import com.github.libretube.constants.PreferenceKeys import com.github.libretube.enums.PlayerEvent +import com.github.libretube.enums.SbSkipOptions import kotlin.math.absoluteValue import kotlin.math.roundToInt @@ -68,18 +69,16 @@ object PlayerHelper { /** * get the categories for sponsorBlock */ - //TODO: This should probably be done with Enums to avoid magic string anti pattern - fun getSponsorBlockCategories(): MutableMap { - val categories: MutableMap = mutableMapOf() + fun getSponsorBlockCategories(): MutableMap { + val categories: MutableMap = mutableMapOf() for (cat in SPONSOR_CATEGORIES){ - val state = PreferenceHelper.getString(cat + "_category_key", "Off") - if (state != "Off"){ - categories[cat] = state + val state = PreferenceHelper.getString(cat + "_category_key", "off").uppercase() + if (SbSkipOptions.valueOf(state) != SbSkipOptions.OFF){ + categories[cat] = SbSkipOptions.valueOf(state) } } return categories - } fun getOrientation(videoWidth: Int, videoHeight: Int): Int { @@ -422,7 +421,7 @@ object PlayerHelper { fun ExoPlayer.checkForSegments( context: Context, segments: List, - category_config: MutableMap, + sponsorBlockConfig: MutableMap, ): Long? { for (segment in segments) { val segmentStart = (segment.segment[0] * 1000f).toLong() @@ -432,7 +431,7 @@ object PlayerHelper { if ((duration - currentPosition).absoluteValue < 500) continue if (currentPosition in segmentStart until segmentEnd) { - if (category_config.get(segment.category) == "Automatic") { + if (sponsorBlockConfig.get(segment.category) == SbSkipOptions.AUTOMATIC) { if (sponsorBlockNotifications) { runCatching { Toast.makeText(context, R.string.segment_skipped, Toast.LENGTH_SHORT) diff --git a/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt b/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt index 36d60c5593..2cc2779801 100644 --- a/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt +++ b/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt @@ -31,6 +31,7 @@ import com.github.libretube.db.obj.WatchPosition import com.github.libretube.extensions.TAG import com.github.libretube.extensions.setMetadata import com.github.libretube.extensions.toID +import com.github.libretube.enums.SbSkipOptions import com.github.libretube.helpers.PlayerHelper import com.github.libretube.helpers.PlayerHelper.checkForSegments import com.github.libretube.helpers.PlayerHelper.loadPlaybackParams @@ -76,7 +77,7 @@ class OnlinePlayerService : LifecycleService() { * SponsorBlock Segment data */ private var segments: List = listOf() - private var catConfig: MutableMap = PlayerHelper.getSponsorBlockCategories() + private var sponsorBlockConfig: MutableMap = PlayerHelper.getSponsorBlockCategories() /** * [Notification] for the player @@ -322,10 +323,10 @@ class OnlinePlayerService : LifecycleService() { private fun fetchSponsorBlockSegments() { lifecycleScope.launch(Dispatchers.IO) { runCatching { - if (catConfig.isEmpty()) return@runCatching + if (sponsorBlockConfig.isEmpty()) return@runCatching segments = RetrofitInstance.api.getSegments( videoId, - JsonHelper.json.encodeToString(catConfig.keys), + JsonHelper.json.encodeToString(sponsorBlockConfig.keys), ).segments checkForSegments() } @@ -338,7 +339,7 @@ class OnlinePlayerService : LifecycleService() { private fun checkForSegments() { handler.postDelayed(this::checkForSegments, 100) - player?.checkForSegments(this, segments, catConfig) + player?.checkForSegments(this, segments, sponsorBlockConfig) } private fun updateQueue() { diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index 6768b31b03..c364c62df7 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -181,8 +181,8 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { * SponsorBlock */ private var segments = listOf() - private var catConfig = PlayerHelper.getSponsorBlockCategories() private var sponsorBlockEnabled = PlayerHelper.sponsorBlockEnabled + private var sponsorBlockConfig = PlayerHelper.getSponsorBlockCategories() private val handler = Handler(Looper.getMainLooper()) private val mainActivity get() = activity as MainActivity @@ -664,7 +664,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { if (segments.isEmpty()) return - exoPlayer.checkForSegments(requireContext(), segments, catConfig) + exoPlayer.checkForSegments(requireContext(), segments, sponsorBlockConfig) ?.let { segmentEnd -> binding.sbSkipBtn.visibility = View.VISIBLE binding.sbSkipBtn.setOnClickListener { @@ -774,11 +774,11 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { private fun fetchSponsorBlockSegments() { lifecycleScope.launch(Dispatchers.IO) { runCatching { - if (catConfig.isEmpty()) return@runCatching + if (sponsorBlockConfig.isEmpty()) return@runCatching segments = RetrofitInstance.api.getSegments( videoId!!, - JsonHelper.json.encodeToString(catConfig.keys), + JsonHelper.json.encodeToString(sponsorBlockConfig.keys), ).segments if (segments.isEmpty()) return@runCatching diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index 5f93698d81..2e5ea2a81e 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -422,11 +422,16 @@ playlists - - Off - Manual - Automatic + + @string/off + @string/manual + @string/automatic + + off + manual + automatic + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 359cfa5b1f..d4493df668 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -419,6 +419,9 @@ Change playlist description Playlist description The playlist description can\'t be empty + Off + Manual + Automatic Import subscriptions from diff --git a/app/src/main/res/xml/sponsorblock_settings.xml b/app/src/main/res/xml/sponsorblock_settings.xml index 279b507892..6e74aa2ae8 100644 --- a/app/src/main/res/xml/sponsorblock_settings.xml +++ b/app/src/main/res/xml/sponsorblock_settings.xml @@ -31,66 +31,66 @@ app:key="sponsor_category_key" app:summary="@string/category_sponsor_description" app:title="@string/category_sponsor" - app:entries="@array/category_sponsor_skip_choices" - app:entryValues="@array/category_sponsor_skip_choices" - app:defaultValue="Automatic"/> + app:entries="@array/sb_skip_options" + app:entryValues="@array/sb_skip_options_values" + app:defaultValue="automatic"/> + app:entries="@array/sb_skip_options" + app:entryValues="@array/sb_skip_options_values" + app:defaultValue="manual"/> + app:entries="@array/sb_skip_options" + app:entryValues="@array/sb_skip_options_values" + app:defaultValue="off"/> + app:entries="@array/sb_skip_options" + app:entryValues="@array/sb_skip_options_values" + app:defaultValue="off"/> + app:entries="@array/sb_skip_options" + app:entryValues="@array/sb_skip_options_values" + app:defaultValue="off"/> + app:entries="@array/sb_skip_options" + app:entryValues="@array/sb_skip_options_values" + app:defaultValue="off"/> + app:entries="@array/sb_skip_options" + app:entryValues="@array/sb_skip_options_values" + app:defaultValue="off"/> + app:entries="@array/sb_skip_options" + app:entryValues="@array/sb_skip_options_values" + app:defaultValue="off"/> From f251d761e85bc4d49fd6004460bcf66aa52b811d Mon Sep 17 00:00:00 2001 From: general-a <404aaronm@gmail.com> Date: Sat, 17 Jun 2023 13:34:01 -0500 Subject: [PATCH 03/11] Enums file --- .../main/java/com/github/libretube/enums/SbSkipOptions.kt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/src/main/java/com/github/libretube/enums/SbSkipOptions.kt diff --git a/app/src/main/java/com/github/libretube/enums/SbSkipOptions.kt b/app/src/main/java/com/github/libretube/enums/SbSkipOptions.kt new file mode 100644 index 0000000000..dc13f9d8c0 --- /dev/null +++ b/app/src/main/java/com/github/libretube/enums/SbSkipOptions.kt @@ -0,0 +1,7 @@ +package com.github.libretube.enums + +enum class SbSkipOptions { + OFF, + MANUAL, + AUTOMATIC +} \ No newline at end of file From 95575ecbb419c7a38bd058e4a53d4882663787e4 Mon Sep 17 00:00:00 2001 From: general-a <404aaronm@gmail.com> Date: Sat, 17 Jun 2023 15:30:00 -0500 Subject: [PATCH 04/11] Reviewdog changes --- .../java/com/github/libretube/enums/SbSkipOptions.kt | 2 +- .../java/com/github/libretube/helpers/PlayerHelper.kt | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/github/libretube/enums/SbSkipOptions.kt b/app/src/main/java/com/github/libretube/enums/SbSkipOptions.kt index dc13f9d8c0..03b9ab2866 100644 --- a/app/src/main/java/com/github/libretube/enums/SbSkipOptions.kt +++ b/app/src/main/java/com/github/libretube/enums/SbSkipOptions.kt @@ -4,4 +4,4 @@ enum class SbSkipOptions { OFF, MANUAL, AUTOMATIC -} \ No newline at end of file +} diff --git a/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt b/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt index 872ff00db4..c80eaf3341 100644 --- a/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt @@ -34,7 +34,15 @@ import kotlin.math.roundToInt object PlayerHelper { private const val ACTION_MEDIA_CONTROL = "media_control" const val CONTROL_TYPE = "control_type" - private val SPONSOR_CATEGORIES: Array = arrayOf("intro", "selfpromo", "interaction", "sponsor", "outro", "filler", "music_offtopic", "preview") + private val SPONSOR_CATEGORIES: Array = + arrayOf("intro", + "selfpromo", + "interaction", + "sponsor", + "outro", + "filler", + "music_offtopic", + "preview") /** * Create a base64 encoded DASH stream manifest From 9ace571d63d305ba243f198116e211f6a6e3fbb0 Mon Sep 17 00:00:00 2001 From: general-a <404aaronm@gmail.com> Date: Sat, 17 Jun 2023 16:06:25 -0500 Subject: [PATCH 05/11] Reviewdog changes --- .../github/libretube/helpers/PlayerHelper.kt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt b/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt index c80eaf3341..a7906b1cb2 100644 --- a/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt +++ b/app/src/main/java/com/github/libretube/helpers/PlayerHelper.kt @@ -35,14 +35,15 @@ object PlayerHelper { private const val ACTION_MEDIA_CONTROL = "media_control" const val CONTROL_TYPE = "control_type" private val SPONSOR_CATEGORIES: Array = - arrayOf("intro", - "selfpromo", - "interaction", - "sponsor", - "outro", - "filler", - "music_offtopic", - "preview") + arrayOf( + "intro", + "selfpromo", + "interaction", + "sponsor", + "outro", + "filler", + "music_offtopic", + "preview") /** * Create a base64 encoded DASH stream manifest From 5e72d6d0c6d6e47383f7268b4019eec187d4b1e8 Mon Sep 17 00:00:00 2001 From: general-a <404aaronm@gmail.com> Date: Sat, 17 Jun 2023 17:22:27 -0500 Subject: [PATCH 06/11] Attempted to make custom preference --- .../libretube/ui/views/SpinnerPreference.kt | 17 +++++++++++ .../main/res/layout/spinner_preference.xml | 29 +++++++++++++++++++ .../main/res/xml/sponsorblock_settings.xml | 2 +- 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/github/libretube/ui/views/SpinnerPreference.kt create mode 100644 app/src/main/res/layout/spinner_preference.xml diff --git a/app/src/main/java/com/github/libretube/ui/views/SpinnerPreference.kt b/app/src/main/java/com/github/libretube/ui/views/SpinnerPreference.kt new file mode 100644 index 0000000000..052b7e185e --- /dev/null +++ b/app/src/main/java/com/github/libretube/ui/views/SpinnerPreference.kt @@ -0,0 +1,17 @@ +package com.github.libretube.ui.views +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.preference.DropDownPreference +import com.github.libretube.R + +class SpinnerPreference(context: Context, attrs: AttributeSet): DropDownPreference(context, attrs){ + + fun onCreate(parent: ViewGroup): View { + val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater + return inflater.inflate(R.layout.spinner_preference, parent, false) + } + +} diff --git a/app/src/main/res/layout/spinner_preference.xml b/app/src/main/res/layout/spinner_preference.xml new file mode 100644 index 0000000000..d0fbb6e13e --- /dev/null +++ b/app/src/main/res/layout/spinner_preference.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/sponsorblock_settings.xml b/app/src/main/res/xml/sponsorblock_settings.xml index 6e74aa2ae8..edf52153f9 100644 --- a/app/src/main/res/xml/sponsorblock_settings.xml +++ b/app/src/main/res/xml/sponsorblock_settings.xml @@ -27,7 +27,7 @@ - Date: Sun, 18 Jun 2023 15:25:38 -0500 Subject: [PATCH 07/11] Added custom spinner to settings --- .../libretube/ui/views/SpinnerPreference.kt | 71 +++++++++++++++++-- .../main/res/layout/spinner_preference.xml | 61 +++++++++++----- app/src/main/res/values/strings.xml | 18 ++--- .../main/res/xml/sponsorblock_settings.xml | 30 ++++---- 4 files changed, 130 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/com/github/libretube/ui/views/SpinnerPreference.kt b/app/src/main/java/com/github/libretube/ui/views/SpinnerPreference.kt index 052b7e185e..0d185b33cd 100644 --- a/app/src/main/java/com/github/libretube/ui/views/SpinnerPreference.kt +++ b/app/src/main/java/com/github/libretube/ui/views/SpinnerPreference.kt @@ -1,17 +1,74 @@ package com.github.libretube.ui.views + import android.content.Context +import android.content.res.TypedArray import android.util.AttributeSet -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup -import androidx.preference.DropDownPreference +import android.widget.AdapterView +import androidx.preference.Preference +import androidx.preference.PreferenceViewHolder +import android.widget.ArrayAdapter +import android.widget.Spinner +import android.widget.TextView import com.github.libretube.R -class SpinnerPreference(context: Context, attrs: AttributeSet): DropDownPreference(context, attrs){ +class SpinnerPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs) { + private lateinit var spinner: Spinner + private lateinit var adapter: ArrayAdapter + private var selectedItem: CharSequence? = null + + init { + layoutResource = R.layout.spinner_preference + } + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + spinner = holder.itemView.findViewById(R.id.spinner) + + val titleView = holder.itemView.findViewById(android.R.id.title) + titleView?.text = super.getTitle() + + val summaryView = holder.itemView.findViewById(android.R.id.summary) + summaryView?.text = super.getSummary() - fun onCreate(parent: ViewGroup): View { - val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater - return inflater.inflate(R.layout.spinner_preference, parent, false) + // Set the spinner adapter + adapter = ArrayAdapter.createFromResource( + context, + R.array.sb_skip_options, + android.R.layout.simple_spinner_item + ) + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + spinner.adapter = adapter + + // Set the initial selected item + if (selectedItem != null) { + val position = adapter.getPosition(selectedItem!!) + spinner.setSelection(position) + } + + // Set a listener to handle item selection + spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>, + view: View?, + position: Int, + id: Long + ) { + selectedItem = adapter.getItem(position) + persistString(selectedItem?.toString()) + } + + override fun onNothingSelected(parent: AdapterView<*>) {} + } } + override fun onGetDefaultValue(a: TypedArray, index: Int): Any { + // Get the default value from the XML attribute, if specified + return a.getString(index) ?: "" + } + + override fun onSetInitialValue(defaultValue: Any?) { + // Set the initial selected item from the persisted value, if available + selectedItem = getPersistedString(defaultValue?.toString()) + } } diff --git a/app/src/main/res/layout/spinner_preference.xml b/app/src/main/res/layout/spinner_preference.xml index d0fbb6e13e..e3021b06bc 100644 --- a/app/src/main/res/layout/spinner_preference.xml +++ b/app/src/main/res/layout/spinner_preference.xml @@ -1,29 +1,52 @@ - + android:layout_height="wrap_content" + android:layout_marginTop="20dp" + android:paddingStart="?android:attr/listPreferredItemPaddingStart" + android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"> - - + android:layout_alignParentStart="true" + android:layout_alignParentTop="true" + android:orientation="vertical"> - + + + + + - + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignTop="@android:id/title" + android:layout_alignBottom="@android:id/title" + android:layout_alignParentEnd="true" /> - \ No newline at end of file + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d4493df668..e86940bb83 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -85,21 +85,21 @@ Skipped segment Segments Sponsor - Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free genuine shoutouts to causes, creators, websites, and products: %s + Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free genuine shoutouts to causes, creators, websites, and products. Unpaid/Self Promotion - Similar to \"sponsor\" except for unpaid or self promotion. This includes sections about merchandise, donations, or info about who they collaborated with: %s - Interaction reminder (like and subscribe) - When there is a short reminder to like, subscribe or follow in the middle of content. If long or about something specific, it should instead be self promotion: %s + Similar to \"sponsor\" except for unpaid or self promotion. This includes sections about merchandise, donations, or info about who they collaborated with. + Interaction reminder + When there is a short reminder to like, subscribe or follow in the middle of content. If long or about something specific, it should instead be self promotion. Intermission/Intro Animation - An interval without actual content. Could be a pause, static frame, repeating animation. Should not be used for transitions containing info: %s + An interval without actual content. Could be a pause, static frame, repeating animation. Should not be used for transitions containing info. End cards and credits - Info following the ending. Not for conclusions with info: %s + Info following the ending. Not for conclusions with info. Filler Tangent/Jokes - For tangential scenes added only for filler or humor not required to understand the main content of the video: %s + For tangential scenes added only for filler or humor not required to understand the main content of the video. Music: Non-Music Section - Only for use in music videos. It should cover parts of the video not part of official mixes. In the end, the video should resemble the Spotify or any other mixed version as closely as possible, or reduce talking or other distractions: %s + Only for use in music videos. It should cover parts of the video not part of official mixes. In the end, the video should resemble the Spotify or any other mixed version as closely as possible, or reduce talking or other distractions. Preview/Recap - For segments detailing future content without additional info. If it includes clips that only appear here, this is very likely the wrong category: %s + For segments detailing future content without additional info. If it includes clips that only appear here, this is very likely the wrong category. License Accents Resting red diff --git a/app/src/main/res/xml/sponsorblock_settings.xml b/app/src/main/res/xml/sponsorblock_settings.xml index edf52153f9..612ab46652 100644 --- a/app/src/main/res/xml/sponsorblock_settings.xml +++ b/app/src/main/res/xml/sponsorblock_settings.xml @@ -33,64 +33,64 @@ app:title="@string/category_sponsor" app:entries="@array/sb_skip_options" app:entryValues="@array/sb_skip_options_values" - app:defaultValue="automatic"/> + app:defaultValue="@string/automatic"/> - + app:defaultValue="@string/manual"/> - + app:defaultValue="@string/off"/> - + app:defaultValue="@string/off"/> - + app:defaultValue="@string/off"/> - + app:defaultValue="@string/off"/> - + app:defaultValue="@string/off"/> - + app:defaultValue="@string/off"/> From f0b607e7791fdbc2d9ca1af95db640fbcc472b74 Mon Sep 17 00:00:00 2001 From: general-a <404aaronm@gmail.com> Date: Sun, 18 Jun 2023 17:31:47 -0500 Subject: [PATCH 08/11] rename and formatting --- ...erPreference.kt => SbSpinnerPreference.kt} | 3 +- .../main/res/layout/spinner_preference.xml | 10 ++++-- .../main/res/xml/sponsorblock_settings.xml | 36 ++++++------------- 3 files changed, 18 insertions(+), 31 deletions(-) rename app/src/main/java/com/github/libretube/ui/views/{SpinnerPreference.kt => SbSpinnerPreference.kt} (96%) diff --git a/app/src/main/java/com/github/libretube/ui/views/SpinnerPreference.kt b/app/src/main/java/com/github/libretube/ui/views/SbSpinnerPreference.kt similarity index 96% rename from app/src/main/java/com/github/libretube/ui/views/SpinnerPreference.kt rename to app/src/main/java/com/github/libretube/ui/views/SbSpinnerPreference.kt index 0d185b33cd..1c4a2fedfe 100644 --- a/app/src/main/java/com/github/libretube/ui/views/SpinnerPreference.kt +++ b/app/src/main/java/com/github/libretube/ui/views/SbSpinnerPreference.kt @@ -1,5 +1,4 @@ package com.github.libretube.ui.views - import android.content.Context import android.content.res.TypedArray import android.util.AttributeSet @@ -12,7 +11,7 @@ import android.widget.Spinner import android.widget.TextView import com.github.libretube.R -class SpinnerPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs) { +class SbSpinnerPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs) { private lateinit var spinner: Spinner private lateinit var adapter: ArrayAdapter private var selectedItem: CharSequence? = null diff --git a/app/src/main/res/layout/spinner_preference.xml b/app/src/main/res/layout/spinner_preference.xml index e3021b06bc..29228e92ce 100644 --- a/app/src/main/res/layout/spinner_preference.xml +++ b/app/src/main/res/layout/spinner_preference.xml @@ -2,7 +2,8 @@ @@ -10,21 +11,24 @@ android:id="@+id/left_container" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginLeft="55dp" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:orientation="vertical"> + android:textSize="14sp" + android:textStyle="bold" /> - + app:defaultValue="automatic"/> - + app:defaultValue="@string/automatic"/> - - - - - - From ff21dbfb8bf2b707d0ba213276f802d516cc1cdc Mon Sep 17 00:00:00 2001 From: general-a <404aaronm@gmail.com> Date: Sun, 18 Jun 2023 17:40:54 -0500 Subject: [PATCH 09/11] Merge conflict --- .../java/com/github/libretube/ui/fragments/PlayerFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index e3f20050f8..6097176a80 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -777,7 +777,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { if (sponsorBlockConfig.isEmpty()) return@runCatching segments = RetrofitInstance.api.getSegments( - videoId!!, + videoId, JsonHelper.json.encodeToString(sponsorBlockConfig.keys), ).segments if (segments.isEmpty()) return@runCatching From 36926401de40b7cbe1a8dab91c4cdcf7a734fec7 Mon Sep 17 00:00:00 2001 From: general-a <404aaronm@gmail.com> Date: Sun, 18 Jun 2023 17:53:05 -0500 Subject: [PATCH 10/11] default value fix --- app/src/main/res/xml/sponsorblock_settings.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/res/xml/sponsorblock_settings.xml b/app/src/main/res/xml/sponsorblock_settings.xml index b32d7835da..5d29330050 100644 --- a/app/src/main/res/xml/sponsorblock_settings.xml +++ b/app/src/main/res/xml/sponsorblock_settings.xml @@ -31,50 +31,50 @@ app:key="sponsor_category_key" app:summary="@string/category_sponsor_description" app:title="@string/category_sponsor" - app:defaultValue="automatic"/> + app:defaultValue="Automatic"/> + app:defaultValue="Manual"/> + app:defaultValue="Off"/> + app:defaultValue="Off"/> + app:defaultValue="Off"/> + app:defaultValue="Off"/> + app:defaultValue="Off"/> + app:defaultValue="Off"/> From 6b3c50d9cb7bb4eb15daf4e06db275baa3eb26d7 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Mon, 19 Jun 2023 12:39:10 +0200 Subject: [PATCH 11/11] Simplify the sponsorblock preference logic and store values independent from language --- .../libretube/ui/views/SbSpinnerPreference.kt | 25 ++++++++---------- .../main/res/layout/spinner_preference.xml | 26 ++++++++++++------- .../main/res/xml/sponsorblock_settings.xml | 16 ++++++------ 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/com/github/libretube/ui/views/SbSpinnerPreference.kt b/app/src/main/java/com/github/libretube/ui/views/SbSpinnerPreference.kt index 1c4a2fedfe..602b21fda9 100644 --- a/app/src/main/java/com/github/libretube/ui/views/SbSpinnerPreference.kt +++ b/app/src/main/java/com/github/libretube/ui/views/SbSpinnerPreference.kt @@ -12,7 +12,6 @@ import android.widget.TextView import com.github.libretube.R class SbSpinnerPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs) { - private lateinit var spinner: Spinner private lateinit var adapter: ArrayAdapter private var selectedItem: CharSequence? = null @@ -22,13 +21,10 @@ class SbSpinnerPreference(context: Context, attrs: AttributeSet) : Preference(co override fun onBindViewHolder(holder: PreferenceViewHolder) { super.onBindViewHolder(holder) - spinner = holder.itemView.findViewById(R.id.spinner) + val spinner: Spinner = holder.itemView.findViewById(R.id.spinner) - val titleView = holder.itemView.findViewById(android.R.id.title) - titleView?.text = super.getTitle() - - val summaryView = holder.itemView.findViewById(android.R.id.summary) - summaryView?.text = super.getSummary() + holder.itemView.findViewById(android.R.id.title)?.text = super.getTitle() + holder.itemView.findViewById(android.R.id.summary)?.text = super.getSummary() // Set the spinner adapter adapter = ArrayAdapter.createFromResource( @@ -40,8 +36,8 @@ class SbSpinnerPreference(context: Context, attrs: AttributeSet) : Preference(co spinner.adapter = adapter // Set the initial selected item - if (selectedItem != null) { - val position = adapter.getPosition(selectedItem!!) + selectedItem?.let { selectedItem -> + val position = getEntryValues().indexOf(selectedItem) spinner.setSelection(position) } @@ -53,21 +49,22 @@ class SbSpinnerPreference(context: Context, attrs: AttributeSet) : Preference(co position: Int, id: Long ) { - selectedItem = adapter.getItem(position) - persistString(selectedItem?.toString()) + persistString(getEntryValues()[position]) } - override fun onNothingSelected(parent: AdapterView<*>) {} + override fun onNothingSelected(parent: AdapterView<*>) = Unit } } - override fun onGetDefaultValue(a: TypedArray, index: Int): Any { + override fun onGetDefaultValue(ta: TypedArray, index: Int): Any { // Get the default value from the XML attribute, if specified - return a.getString(index) ?: "" + return ta.getString(index).orEmpty() } override fun onSetInitialValue(defaultValue: Any?) { // Set the initial selected item from the persisted value, if available selectedItem = getPersistedString(defaultValue?.toString()) } + + private fun getEntryValues() = context.resources.getStringArray(R.array.sb_skip_options_values) } diff --git a/app/src/main/res/layout/spinner_preference.xml b/app/src/main/res/layout/spinner_preference.xml index 29228e92ce..f1fa9bdecf 100644 --- a/app/src/main/res/layout/spinner_preference.xml +++ b/app/src/main/res/layout/spinner_preference.xml @@ -1,19 +1,20 @@ + android:paddingTop="10dp" + android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" + android:paddingBottom="10dp"> + android:textStyle="bold" + tools:text="Title" /> + android:textSize="14sp" + tools:text="Summary" /> @@ -51,6 +52,11 @@ android:layout_height="wrap_content" android:layout_alignTop="@android:id/title" android:layout_alignBottom="@android:id/title" - android:layout_alignParentEnd="true" /> + android:layout_alignParentEnd="true" + android:layout_marginTop="-2dp" + android:textAlignment="textEnd" + android:layout_marginEnd="-10dp" + android:paddingStart="0dp" + android:paddingEnd="35dp" /> diff --git a/app/src/main/res/xml/sponsorblock_settings.xml b/app/src/main/res/xml/sponsorblock_settings.xml index 5d29330050..b6b152e70d 100644 --- a/app/src/main/res/xml/sponsorblock_settings.xml +++ b/app/src/main/res/xml/sponsorblock_settings.xml @@ -31,50 +31,50 @@ app:key="sponsor_category_key" app:summary="@string/category_sponsor_description" app:title="@string/category_sponsor" - app:defaultValue="Automatic"/> + app:defaultValue="automatic"/> + app:defaultValue="automatic"/> + app:defaultValue="off"/> + app:defaultValue="off"/> + app:defaultValue="off"/> + app:defaultValue="off"/> + app:defaultValue="off"/> + app:defaultValue="off"/>