Improvements to subtitle search & download (#1728)

## Description
Changes to searching & downloading subtitles:
- Activating newly downloaded subtitles more reliably
- Better audio index adjustment checks after downloading subtitles
- Sort subtitle downloadable options by whether the file hash matches
first
- Update the UI for subtitle downloadable options

Also, some improvements to the subtitle choice dialog:
- It now loops from top to bottom (and vice versa)
- It now focuses initially on current choice

### Dev notes
This PR now the selected tracks from `state.currentItemPlayback` to
`state.currentPlayback`. `currentItemPlayback` now only reflects the
user's choices saved in the database instead of a combination of DB and
"actual" state. `currentPlayback` stores the actual, resolved track
indexes regardless of how they were derived.

This means the indexes values in `state.currentItemPlayback` and
`state.currentPlayback` may be different. For example, if the user has
chosen "Only forced", `state.currentItemPlayback==-3` but
`state.currentPlayback` might be an actual forced track index.

### Related issues
Fixes #1549
Fixes #1718
Closes #1723
Fixes bug reported in
https://github.com/damontecres/Wholphin/issues/1498#issuecomment-5019965271

### Testing
Emulator

## Screenshots

Now shows SDH & hash matching

<img width="779" height="280" alt="image"
src="https://github.com/user-attachments/assets/4c33e5af-c9a1-4c9c-8217-6bc2ab3fcd27"
/>

## AI or LLM usage
None
This commit is contained in:
Damontecres 2026-07-23 13:30:43 -04:00 • committed by GitHub
parent 48005ce67a
commit 00490b14ec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 437 additions and 328 deletions

View file

@ -3,7 +3,6 @@ package com.github.damontecres.wholphin.util
import androidx.annotation.OptIn
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import com.github.damontecres.wholphin.data.model.ItemPlayback
import com.github.damontecres.wholphin.ui.launchIO
import com.github.damontecres.wholphin.ui.playback.CurrentPlayback
import kotlinx.coroutines.CoroutineScope
@ -177,12 +176,11 @@ data class PlaybackItemState(
) {
constructor(
playback: CurrentPlayback,
itemPlayback: ItemPlayback,
) : this(
itemId = itemPlayback.itemId,
itemId = playback.item.id,
playMethod = playback.playMethod,
audioStreamIndex = itemPlayback.audioIndex.takeIf { itemPlayback.audioIndexEnabled },
subtitleStreamIndex = itemPlayback.subtitleIndex.takeIf { itemPlayback.subtitleIndexEnabled },
audioStreamIndex = playback.audioIndex.takeIf { it >= 0 },
subtitleStreamIndex = playback.subtitleIndex.takeIf { it >= 0 },
playSessionId = playback.playSessionId,
liveStreamId = playback.liveStreamId,
)