feat(android): Change match from a library tile's long press

The tile menu now offers the same provider search as the title page, so
a title wearing the wrong poster can be fixed from the grid that shows
it, without opening the title first.
This commit is contained in:
nvrl committed 2026-10-03 13:15:59 +02:00
1 parent 6c2ec83cb1
commit 4ff8ae303c
3 files changed
+21 -1

No files matched your search

@@ -23,6 +23,7 @@ import java.time.LocalDate
import androidx.compose.foundation.combinedClickable
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Download
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.RemoveCircleOutline
@@ -102,11 +103,14 @@ internal fun LibraryScreen(
onSetTitleWatched: (TitleRecord, Boolean) -> Unit,
onForgetPosition: (TitleRecord, EpisodeRecord) -> Unit,
padding: PaddingValues,
onMatchChanged: () -> Unit = {},
onError: (Throwable) -> Unit = {},
) {
val context = LocalContext.current
// What a long press opened a menu for: a title, or a Continue watching card.
var menuFor by remember { mutableStateOf<TitleRecord?>(null) }
var menuResume by remember { mutableStateOf<Resumable?>(null) }
var matching by remember { mutableStateOf<TitleRecord?>(null) }
// Most recently played first, one episode per show: a shelf that lists four
// episodes of the same series is a shelf with room for nothing else.
val resumable = remember(state.titles) {
@@ -189,8 +193,22 @@ internal fun LibraryScreen(
if (allWatched) Icons.Outlined.CheckCircle else Icons.Default.CheckCircle,
if (allWatched) "Mark unwatched" else "Mark watched",
) { onSetTitleWatched(title, !allWatched) }
// The same search the title page offers, for the tile that is
// plainly wrong — the wrong poster is what the grid shows.
MenuRow(Icons.Default.Edit, "Change match") { matching = title }
}
}
matching?.let { title ->
ChangeMatchDialog(
title = title,
onDismiss = { matching = null },
onChanged = {
matching = null
onMatchChanged()
},
onError = onError,
)
}
menuResume?.let { entry ->
TileMenu(
entry.title.canonicalName ?: entry.title.name,
@@ -201,6 +201,8 @@ fun ProtonStreamApp(
model::setTitleWatched,
model::forgetPosition,
body,
onMatchChanged = model::reloadAfterMetadataChange,
onError = model::reportError,
)
} else {
TitleScreen(
@@ -488,7 +488,7 @@ private fun EpisodeRow(
}
@Composable
private fun ChangeMatchDialog(
internal fun ChangeMatchDialog(
title: TitleRecord,
onDismiss: () -> Unit,
onChanged: () -> Unit,