From 899e3decc2b8dcee6a058a02713596abe723db9e Mon Sep 17 00:00:00 2001 From: Damontecres Date: Tue, 23 Jun 2026 17:23:37 -0400 Subject: [PATCH] Prefer non-forced when subtitle preference is always on (#1618) ## Description If subtitles preferences are "Always", this PR will prefer non-forced tracks even if any forced ones are default tracks. This is in-line with the web UI from my testing and another review of the code. ### Related issues Fixes https://github.com/damontecres/Wholphin/issues/790#issuecomment-4708705576 ### Testing Unit tests ## Screenshots N/A ## AI or LLM usage None --- .../wholphin/services/StreamChoiceService.kt | 10 ++-- .../services/StreamChoiceServiceTest.kt | 53 ++++++++++++++++++- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/StreamChoiceService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/StreamChoiceService.kt index 3a3a3e9c..c0a9465e 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/StreamChoiceService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/StreamChoiceService.kt @@ -277,11 +277,13 @@ class StreamChoiceService SubtitlePlaybackMode.ALWAYS -> { if (subtitleLanguage.isNotNullOrBlank()) { candidates.firstOrNull { - it.language.equals(subtitleLanguage, true) || - it.language.isUnknown + // Prefer non-forced first + !it.isForced && it.language.equalsLangOrUnknown(subtitleLanguage) + } ?: candidates.firstOrNull { + it.language.equalsLangOrUnknown(subtitleLanguage) } } else { - candidates.firstOrNull() + candidates.firstOrNull { !it.isForced } ?: candidates.firstOrNull() } } @@ -371,3 +373,5 @@ private val String?.isUnknown: Boolean this.equals("undetermined", true) || this.equals("mul", true) || this.equals("zxx", true) + +private fun String?.equalsLangOrUnknown(lang: String): Boolean = equals(lang, ignoreCase = true) || this.isUnknown diff --git a/app/src/test/java/com/github/damontecres/wholphin/services/StreamChoiceServiceTest.kt b/app/src/test/java/com/github/damontecres/wholphin/services/StreamChoiceServiceTest.kt index e16bc4e5..61f0f136 100644 --- a/app/src/test/java/com/github/damontecres/wholphin/services/StreamChoiceServiceTest.kt +++ b/app/src/test/java/com/github/damontecres/wholphin/services/StreamChoiceServiceTest.kt @@ -102,6 +102,56 @@ class StreamChoiceServiceTest( ), itemPlayback = itemPlayback(subtitleIndex = TrackIndex.UNSPECIFIED), ), + TestInput( + 1, + SubtitlePlaybackMode.ALWAYS, + userSubtitleLang = "eng", + subtitles = + listOf( + subtitle(0, "eng", default = true, forced = true), + subtitle(1, "eng", default = false, forced = false), + ), + ), + TestInput( + 1, + SubtitlePlaybackMode.ALWAYS, + userSubtitleLang = null, + subtitles = + listOf( + subtitle(0, "eng", default = true, forced = true), + subtitle(1, "eng", default = false, forced = false), + ), + ), + TestInput( + 0, + SubtitlePlaybackMode.SMART, + userSubtitleLang = "eng", + subtitles = + listOf( + subtitle(0, "eng", default = true, forced = true), + subtitle(1, "eng", default = false, forced = false), + ), + ), + TestInput( + 0, + SubtitlePlaybackMode.ONLY_FORCED, + userSubtitleLang = "eng", + subtitles = + listOf( + subtitle(0, "eng", default = true, forced = true), + subtitle(1, "eng", default = false, forced = false), + ), + ), + TestInput( + null, + SubtitlePlaybackMode.NONE, + userSubtitleLang = "eng", + subtitles = + listOf( + subtitle(0, "eng", default = true, forced = true), + subtitle(1, "eng", default = false, forced = false), + ), + ), ) } } @@ -277,6 +327,7 @@ class TestStreamChoiceServiceSmart( TestInput( 0, SubtitlePlaybackMode.SMART, + userSubtitleLang = "eng", subtitles = listOf( subtitle(0, "eng", false), @@ -488,7 +539,7 @@ class TestStreamChoiceServiceMultipleChoices( fun data(): Collection = listOf( TestInput( - 0, + 1, SubtitlePlaybackMode.ALWAYS, subtitles = listOf(