fix(player): enforce preferred-language subtitle filtering

This commit is contained in:
tapframe 2026-07-18 17:05:02 +05:30
parent a8d6d8d270
commit 079b3a7e97
3 changed files with 64 additions and 24 deletions

View file

@ -17,11 +17,10 @@ internal val PlayerScreenRuntime.visibleAddonSubtitles: List<AddonSubtitle>
get() = filterAddonSubtitlesForSettings(
subtitles = addonSubtitles,
settings = playerSettingsUiState,
selectedAddonSubtitleId = selectedAddonSubtitleId,
)
internal val PlayerScreenRuntime.selectedAddonSubtitle: AddonSubtitle?
get() = addonSubtitles.firstOrNull { subtitle ->
get() = visibleAddonSubtitles.firstOrNull { subtitle ->
subtitle.id == selectedAddonSubtitleId || subtitle.url == selectedAddonSubtitleId
}

View file

@ -97,40 +97,27 @@ internal fun findPreferredSubtitleTrackIndex(
internal fun filterAddonSubtitlesForSettings(
subtitles: List<AddonSubtitle>,
settings: PlayerSettingsUiState,
selectedAddonSubtitleId: String?,
): List<AddonSubtitle> {
val shouldFilter = settings.subtitleStyle.showOnlyPreferredLanguages ||
settings.addonSubtitleStartupMode == AddonSubtitleStartupMode.PREFERRED_ONLY
if (!shouldFilter) return subtitles
val targets = preferredSubtitleTargetsForSettings(settings)
if (targets.isEmpty()) {
return subtitles.filter { subtitle ->
subtitle.id == selectedAddonSubtitleId || subtitle.url == selectedAddonSubtitleId
if (targets.isEmpty()) return emptyList()
return subtitles.filter { subtitle ->
targets.any { target ->
languageMatchesPreference(
trackLanguage = subtitle.language,
targetLanguage = target,
)
}
}
val filtered = subtitles.filter { subtitle ->
subtitle.id == selectedAddonSubtitleId ||
subtitle.url == selectedAddonSubtitleId ||
targets.any { target ->
languageMatchesPreference(
trackLanguage = subtitle.language,
targetLanguage = target,
)
}
}
return filtered
}
internal fun preferredSubtitleTargetsForSettings(settings: PlayerSettingsUiState): List<String> {
val preferredLanguage = if (settings.subtitleStyle.useForcedSubtitles) {
SubtitleLanguageOption.FORCED
} else {
settings.preferredSubtitleLanguage
}
return resolvePreferredSubtitleLanguageTargets(
preferredSubtitleLanguage = preferredLanguage,
preferredSubtitleLanguage = settings.preferredSubtitleLanguage,
secondaryPreferredSubtitleLanguage = settings.secondaryPreferredSubtitleLanguage,
deviceLanguages = DeviceLanguagePreferences.preferredLanguageCodes(),
).filterNot { it == SubtitleLanguageOption.FORCED }

View file

@ -55,6 +55,49 @@ class PlayerTrackSelectionTest {
assertEquals(-1, selectedIndex)
}
@Test
fun preferredOnlyFilteringRemovesNonPreferredAddons() {
val subtitles = listOf(
addonSubtitle(id = "english", language = "en"),
addonSubtitle(id = "japanese", language = "ja"),
)
val settings = PlayerSettingsUiState(
preferredSubtitleLanguage = "en",
subtitleStyle = SubtitleStyleState.DEFAULT.copy(showOnlyPreferredLanguages = true),
)
val visibleSubtitles = filterAddonSubtitlesForSettings(
subtitles = subtitles,
settings = settings,
)
assertEquals(listOf("english"), visibleSubtitles.map { it.id })
}
@Test
fun forcedToggleKeepsPreferredLanguagesForAddonFiltering() {
val subtitles = listOf(
addonSubtitle(id = "japanese", language = "ja"),
addonSubtitle(id = "french", language = "fr"),
addonSubtitle(id = "english", language = "en"),
)
val settings = PlayerSettingsUiState(
preferredSubtitleLanguage = "en",
secondaryPreferredSubtitleLanguage = "fr",
subtitleStyle = SubtitleStyleState.DEFAULT.copy(
useForcedSubtitles = true,
showOnlyPreferredLanguages = true,
),
)
val visibleSubtitles = filterAddonSubtitlesForSettings(
subtitles = subtitles,
settings = settings,
)
assertEquals(listOf("french", "english"), visibleSubtitles.map { it.id })
}
private fun subtitleTrack(
index: Int,
language: String,
@ -66,4 +109,15 @@ class PlayerTrackSelectionTest {
language = language,
isForced = isForced,
)
private fun addonSubtitle(
id: String,
language: String,
) = AddonSubtitle(
id = id,
url = "https://example.com/$id.srt",
language = language,
display = id,
addonName = "Addon",
)
}