feat: add DownloadsViewModel for managing offline media downloads

This commit is contained in:
2026-02-22 13:41:47 +01:00
parent ce126988d9
commit d5c0bbded6
3 changed files with 110 additions and 18 deletions

View File

@@ -1,23 +1,36 @@
package hu.bbara.purefin.app.home.ui package hu.bbara.purefin.app.home.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Download import androidx.compose.material.icons.outlined.Download
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.common.ui.PosterCard
import hu.bbara.purefin.feature.shared.download.DownloadsViewModel
@Composable @Composable
fun DownloadsContent( fun DownloadsContent(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
viewModel: DownloadsViewModel = hiltViewModel(),
) { ) {
val downloads = viewModel.downloads.collectAsState(emptyList())
if (downloads.value.isEmpty()) {
Column( Column(
modifier = modifier.fillMaxSize(), modifier = modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center, verticalArrangement = Arrangement.Center,
@@ -36,4 +49,23 @@ fun DownloadsContent(
modifier = Modifier modifier = Modifier
) )
} }
}
LazyVerticalGrid(
columns = GridCells.Adaptive(minSize = 120.dp),
contentPadding = PaddingValues(16.dp),
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = modifier.background(MaterialTheme.colorScheme.background)
) {
items(downloads.value) { item ->
PosterCard(
item = item,
onMovieSelected = viewModel::onMovieSelected,
onSeriesSelected = viewModel::onSeriesSelected,
onEpisodeSelected = { _, _, _ -> },
)
}
}
} }

View File

@@ -20,7 +20,7 @@ import hu.bbara.purefin.core.data.room.entity.SeriesEntity
SeasonEntity::class, SeasonEntity::class,
EpisodeEntity::class, EpisodeEntity::class,
], ],
version = 4, version = 5,
exportSchema = false exportSchema = false
) )
@TypeConverters(UuidConverters::class) @TypeConverters(UuidConverters::class)

View File

@@ -0,0 +1,60 @@
package hu.bbara.purefin.feature.shared.download
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import hu.bbara.purefin.core.data.OfflineMediaRepository
import hu.bbara.purefin.core.data.navigation.MovieDto
import hu.bbara.purefin.core.data.navigation.NavigationManager
import hu.bbara.purefin.core.data.navigation.Route
import hu.bbara.purefin.core.data.navigation.SeriesDto
import hu.bbara.purefin.feature.download.MediaDownloadManager
import hu.bbara.purefin.feature.shared.home.PosterItem
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.UUID
import org.jellyfin.sdk.model.api.BaseItemKind
import javax.inject.Inject
@HiltViewModel
class DownloadsViewModel @Inject constructor(
private val offlineMediaRepository: OfflineMediaRepository,
private val navigationManager: NavigationManager,
private val downloadManager: MediaDownloadManager
) : ViewModel() {
fun onMovieSelected(movieId: UUID) {
navigationManager.navigate(Route.MovieRoute(
MovieDto(
id = movieId,
)
))
}
fun onSeriesSelected(seriesId: UUID) {
viewModelScope.launch {
navigationManager.navigate(Route.SeriesRoute(
SeriesDto(
id = seriesId,
)
))
}
}
val downloads = combine(
offlineMediaRepository.movies,
offlineMediaRepository.series
) { movies, series ->
movies.values.map {
PosterItem(
type = BaseItemKind.MOVIE,
movie = it
)
} + series.values.map {
PosterItem(
type = BaseItemKind.SERIES,
series = it
)
}
}
}