Добавляем в бейдж каталога статусы загрузки и готовности видео на очки

This commit is contained in:
2026-09-02 19:53:21 +03:00
parent b2e2d2697d
commit 1b28760c6e
2 changed files with 28 additions and 4 deletions
@@ -43,6 +43,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import pw.binom.viewmate.core.media.JellyfinItem
import pw.binom.viewmate.core.media.MirrorJob
import pw.binom.viewmate.core.protocol.DownloadPhase
import pw.binom.viewmate.phone.PhoneApp
/** Вкладки каталога: Фильмы / Сериалы / Папки. */
@@ -247,6 +248,10 @@ fun CatalogScreen(
}
val downloaded by app.state.downloadedFlow.collectAsState()
val localDownloaded by app.downloadManager.downloadedIds.collectAsState()
// Статус видео на очках: скачанные itemId (свежий GlassesStatus) + живой прогресс
// DownloadProgress (видео очки качают сами, звук — телефон).
val glassesDownloadedIds by app.server.hub.downloadedItemIds.collectAsState()
val glassesDownloads by app.server.hub.glassesDownloads.collectAsState()
// подтянуть список, когда появился пользователь Jellyfin
LaunchedEffect(userId) {
@@ -271,6 +276,7 @@ fun CatalogScreen(
modifier = Modifier.fillMaxSize(),
) {
items(state.items, key = { it.Id }) { item ->
val videoProgress = glassesDownloads[item.Id]?.get("video.mkv")
ItemCard(
item = item,
posterUrl = posterUrlOrNull(app, item),
@@ -279,6 +285,9 @@ fun CatalogScreen(
job = state.mirrors[item.Id],
downloaded = downloaded,
localDownloaded = localDownloaded,
glassesDownloading = videoProgress?.phase == DownloadPhase.DOWNLOADING,
glassesDownloadingPercent = videoProgress?.percent,
glassesDownloaded = item.Id in glassesDownloadedIds,
),
onClick = {
when {
@@ -77,11 +77,13 @@ fun BottomNavBar(current: Screen, onSelect: (Screen) -> Unit) {
data class MirrorBadge(val text: String, val bg: Color, val fg: Color)
/**
* Статус зеркала элемента:
* Статус зеркала элемента (коротко для бейджа каталога):
* - ⟳ N% — конвертируется;
* - ↓ часть — что-то скачано локально (телефон) или на очки;
* - ✓ — зеркало готово;
* - ✗ — ошибка;
* - ✗ — ошибка конвертации;
* - ↓ N% — видео скачивается на очки;
* - ▶ — можно смотреть (видео уже на очках);
* - ✓ — зеркало готово (ещё не на очках);
* - ↓ часть — скачано что-то локально (телефон) или на очки;
* - нет — ничего нет.
*/
fun mirrorBadge(
@@ -89,6 +91,9 @@ fun mirrorBadge(
job: MirrorJob?,
downloaded: Map<String, String>,
localDownloaded: Set<String>,
glassesDownloading: Boolean = false,
glassesDownloadingPercent: Int? = null,
glassesDownloaded: Boolean = false,
): MirrorBadge {
val status = job?.status
val hasLocal = localDownloaded.contains(itemId)
@@ -102,6 +107,16 @@ fun mirrorBadge(
status == "failed" || status == "error" -> MirrorBadge("✗", PhoneRed, Color.White)
// Видео уже летит на очки — конкретнее «✓ готово»
glassesDownloading -> MirrorBadge(
"↓ ${glassesDownloadingPercent ?: 0}%",
PhoneBlue,
PhoneBlueText,
)
// Видео на очках — можно смотреть
glassesDownloaded -> MirrorBadge("▶", PhoneGreen, PhoneGreenText)
status == "done" -> MirrorBadge("✓", PhoneGreen, PhoneGreenText)
hasLocal || hasAny -> MirrorBadge("↓ часть", PhoneBlue, PhoneBlueText)