mirror of
https://github.com/bbara04/Purefin.git
synced 2026-03-31 17:10:08 +02:00
feat: add Room database entities and DAOs for Episodes, Seasons, and Series
This commit is contained in:
@@ -73,6 +73,8 @@ dependencies {
|
||||
implementation(libs.medi3.ui.compose)
|
||||
implementation(libs.androidx.navigation3.runtime)
|
||||
implementation(libs.androidx.navigation3.ui)
|
||||
implementation(libs.androidx.room.runtime)
|
||||
implementation(libs.androidx.room.ktx)
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
@@ -81,4 +83,5 @@ dependencies {
|
||||
debugImplementation(libs.androidx.compose.ui.tooling)
|
||||
debugImplementation(libs.androidx.compose.ui.test.manifest)
|
||||
ksp(libs.hilt.compiler)
|
||||
ksp(libs.androidx.room.compiler)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package hu.bbara.purefin.data.local.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import androidx.room.Upsert
|
||||
import hu.bbara.purefin.data.local.entity.EpisodeEntity
|
||||
import java.util.UUID
|
||||
|
||||
@Dao
|
||||
interface EpisodeDao {
|
||||
|
||||
@Upsert
|
||||
suspend fun upsertEpisode(episode: EpisodeEntity)
|
||||
|
||||
@Upsert
|
||||
suspend fun upsertEpisodes(episodes: List<EpisodeEntity>)
|
||||
|
||||
@Query("DELETE FROM episodes WHERE id = :episodeId")
|
||||
suspend fun deleteEpisode(episodeId: UUID)
|
||||
|
||||
@Query("DELETE FROM episodes WHERE seasonId = :seasonId")
|
||||
suspend fun deleteEpisodesForSeason(seasonId: UUID)
|
||||
|
||||
@Query("DELETE FROM episodes WHERE seriesId = :seriesId")
|
||||
suspend fun deleteEpisodesForSeries(seriesId: UUID)
|
||||
|
||||
@Query("SELECT * FROM episodes WHERE id = :episodeId")
|
||||
suspend fun getEpisodeById(episodeId: UUID): EpisodeEntity?
|
||||
|
||||
@Query("SELECT * FROM episodes WHERE seasonId = :seasonId ORDER BY `index` ASC")
|
||||
suspend fun getEpisodesForSeason(seasonId: UUID): List<EpisodeEntity>
|
||||
|
||||
@Query("SELECT * FROM episodes WHERE seriesId = :seriesId ORDER BY seasonId, `index` ASC")
|
||||
suspend fun getEpisodesForSeries(seriesId: UUID): List<EpisodeEntity>
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package hu.bbara.purefin.data.local.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Upsert
|
||||
import hu.bbara.purefin.data.local.entity.SeasonEntity
|
||||
import hu.bbara.purefin.data.local.relations.SeasonWithEpisodes
|
||||
import java.util.UUID
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface SeasonDao {
|
||||
|
||||
@Upsert
|
||||
suspend fun upsertSeason(season: SeasonEntity)
|
||||
|
||||
@Upsert
|
||||
suspend fun upsertSeasons(seasons: List<SeasonEntity>)
|
||||
|
||||
@Query("DELETE FROM seasons WHERE id = :seasonId")
|
||||
suspend fun deleteSeason(seasonId: UUID)
|
||||
|
||||
@Query("DELETE FROM seasons WHERE seriesId = :seriesId")
|
||||
suspend fun deleteSeasonsForSeries(seriesId: UUID)
|
||||
|
||||
@Transaction
|
||||
@Query("SELECT * FROM seasons WHERE id = :seasonId")
|
||||
suspend fun getSeasonWithEpisodes(seasonId: UUID): SeasonWithEpisodes?
|
||||
|
||||
@Query("SELECT * FROM seasons WHERE id = :seasonId")
|
||||
suspend fun getSeasonById(seasonId: UUID): SeasonEntity?
|
||||
|
||||
@Query("SELECT * FROM seasons WHERE seriesId = :seriesId ORDER BY `index` ASC")
|
||||
suspend fun getSeasonsForSeries(seriesId: UUID): List<SeasonEntity>
|
||||
|
||||
@Transaction
|
||||
@Query("SELECT * FROM seasons WHERE seriesId = :seriesId ORDER BY `index` ASC")
|
||||
fun observeSeasonsWithEpisodes(seriesId: UUID): Flow<List<SeasonWithEpisodes>>
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package hu.bbara.purefin.data.local.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Upsert
|
||||
import hu.bbara.purefin.data.local.entity.SeriesEntity
|
||||
import hu.bbara.purefin.data.local.relations.SeriesWithSeasonsAndEpisodes
|
||||
import java.util.UUID
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface SeriesDao {
|
||||
|
||||
@Upsert
|
||||
suspend fun upsertSeries(series: SeriesEntity)
|
||||
|
||||
@Upsert
|
||||
suspend fun upsertSeries(series: List<SeriesEntity>)
|
||||
|
||||
@Query("DELETE FROM series WHERE id = :seriesId")
|
||||
suspend fun deleteSeries(seriesId: UUID)
|
||||
|
||||
@Transaction
|
||||
@Query("SELECT * FROM series WHERE id = :seriesId")
|
||||
suspend fun getSeriesWithContent(seriesId: UUID): SeriesWithSeasonsAndEpisodes?
|
||||
|
||||
@Transaction
|
||||
@Query("SELECT * FROM series WHERE id = :seriesId")
|
||||
fun observeSeriesWithContent(seriesId: UUID): Flow<SeriesWithSeasonsAndEpisodes?>
|
||||
|
||||
@Transaction
|
||||
@Query("SELECT * FROM series")
|
||||
fun observeAllSeriesWithContent(): Flow<List<SeriesWithSeasonsAndEpisodes>>
|
||||
|
||||
@Query("SELECT * FROM series WHERE id = :seriesId")
|
||||
suspend fun getSeriesById(seriesId: UUID): SeriesEntity?
|
||||
|
||||
@Query("SELECT * FROM series")
|
||||
fun observeSeriesEntities(): Flow<List<SeriesEntity>>
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package hu.bbara.purefin.data.local.db
|
||||
|
||||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverters
|
||||
import hu.bbara.purefin.data.local.dao.EpisodeDao
|
||||
import hu.bbara.purefin.data.local.dao.SeasonDao
|
||||
import hu.bbara.purefin.data.local.dao.SeriesDao
|
||||
import hu.bbara.purefin.data.local.entity.EpisodeEntity
|
||||
import hu.bbara.purefin.data.local.entity.SeasonEntity
|
||||
import hu.bbara.purefin.data.local.entity.SeriesEntity
|
||||
|
||||
@Database(
|
||||
entities = [SeriesEntity::class, SeasonEntity::class, EpisodeEntity::class],
|
||||
version = 1,
|
||||
exportSchema = false
|
||||
)
|
||||
@TypeConverters(PurefinTypeConverters::class)
|
||||
abstract class PurefinDatabase : RoomDatabase() {
|
||||
|
||||
abstract fun seriesDao(): SeriesDao
|
||||
|
||||
abstract fun seasonDao(): SeasonDao
|
||||
|
||||
abstract fun episodeDao(): EpisodeDao
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package hu.bbara.purefin.data.local.db
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import hu.bbara.purefin.data.local.entity.EpisodeCastMemberEntity
|
||||
import java.util.UUID
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
class PurefinTypeConverters {
|
||||
|
||||
@TypeConverter
|
||||
fun fromUuid(value: UUID?): String? = value?.toString()
|
||||
|
||||
@TypeConverter
|
||||
fun toUuid(value: String?): UUID? = value?.let(UUID::fromString)
|
||||
|
||||
@TypeConverter
|
||||
fun fromCastMembers(value: List<EpisodeCastMemberEntity>?): String? {
|
||||
if (value.isNullOrEmpty()) return null
|
||||
val jsonArray = JSONArray()
|
||||
value.forEach { member ->
|
||||
jsonArray.put(
|
||||
JSONObject().apply {
|
||||
put("name", member.name)
|
||||
put("role", member.role)
|
||||
put("imageUrl", member.imageUrl)
|
||||
}
|
||||
)
|
||||
}
|
||||
return jsonArray.toString()
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toCastMembers(value: String?): List<EpisodeCastMemberEntity> {
|
||||
if (value.isNullOrBlank()) return emptyList()
|
||||
val jsonArray = JSONArray(value)
|
||||
val members = mutableListOf<EpisodeCastMemberEntity>()
|
||||
for (index in 0 until jsonArray.length()) {
|
||||
val jsonObject = jsonArray.optJSONObject(index) ?: continue
|
||||
val imageUrl = when {
|
||||
jsonObject.has("imageUrl") && !jsonObject.isNull("imageUrl") -> jsonObject.optString("imageUrl")
|
||||
else -> null
|
||||
}
|
||||
members += EpisodeCastMemberEntity(
|
||||
name = jsonObject.optString("name"),
|
||||
role = jsonObject.optString("role"),
|
||||
imageUrl = imageUrl?.ifBlank { null }
|
||||
)
|
||||
}
|
||||
return members
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package hu.bbara.purefin.data.local.di
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Room
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import hu.bbara.purefin.data.local.dao.EpisodeDao
|
||||
import hu.bbara.purefin.data.local.dao.SeasonDao
|
||||
import hu.bbara.purefin.data.local.dao.SeriesDao
|
||||
import hu.bbara.purefin.data.local.db.PurefinDatabase
|
||||
import hu.bbara.purefin.data.local.repository.LocalMediaRepository
|
||||
import hu.bbara.purefin.data.local.repository.RoomLocalMediaRepository
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object DatabaseModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideDatabase(
|
||||
@ApplicationContext context: Context
|
||||
): PurefinDatabase {
|
||||
return Room.databaseBuilder(
|
||||
context,
|
||||
PurefinDatabase::class.java,
|
||||
"purefin.db"
|
||||
).build()
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideSeriesDao(database: PurefinDatabase): SeriesDao = database.seriesDao()
|
||||
|
||||
@Provides
|
||||
fun provideSeasonDao(database: PurefinDatabase): SeasonDao = database.seasonDao()
|
||||
|
||||
@Provides
|
||||
fun provideEpisodeDao(database: PurefinDatabase): EpisodeDao = database.episodeDao()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideLocalMediaRepository(
|
||||
seriesDao: SeriesDao,
|
||||
seasonDao: SeasonDao,
|
||||
episodeDao: EpisodeDao
|
||||
): LocalMediaRepository = RoomLocalMediaRepository(seriesDao, seasonDao, episodeDao)
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package hu.bbara.purefin.data.local.entity
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
import java.util.UUID
|
||||
|
||||
@Entity(
|
||||
tableName = "episodes",
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = SeriesEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["seriesId"],
|
||||
onDelete = ForeignKey.CASCADE,
|
||||
onUpdate = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = SeasonEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["seasonId"],
|
||||
onDelete = ForeignKey.CASCADE,
|
||||
onUpdate = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [Index(value = ["seriesId"]), Index(value = ["seasonId"])]
|
||||
)
|
||||
data class EpisodeEntity(
|
||||
@PrimaryKey val id: UUID,
|
||||
val seriesId: UUID,
|
||||
val seasonId: UUID,
|
||||
val title: String,
|
||||
val index: Int,
|
||||
val releaseDate: String,
|
||||
val rating: String,
|
||||
val runtime: String,
|
||||
val format: String,
|
||||
val synopsis: String,
|
||||
val heroImageUrl: String,
|
||||
val cast: List<EpisodeCastMemberEntity>
|
||||
)
|
||||
|
||||
data class EpisodeCastMemberEntity(
|
||||
val name: String,
|
||||
val role: String,
|
||||
val imageUrl: String?
|
||||
)
|
||||
@@ -0,0 +1,28 @@
|
||||
package hu.bbara.purefin.data.local.entity
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
import java.util.UUID
|
||||
|
||||
@Entity(
|
||||
tableName = "seasons",
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = SeriesEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["seriesId"],
|
||||
onDelete = ForeignKey.CASCADE,
|
||||
onUpdate = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [Index(value = ["seriesId"])]
|
||||
)
|
||||
data class SeasonEntity(
|
||||
@PrimaryKey val id: UUID,
|
||||
val seriesId: UUID,
|
||||
val name: String,
|
||||
val index: Int,
|
||||
val episodeCount: Int
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
package hu.bbara.purefin.data.local.entity
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import java.util.UUID
|
||||
|
||||
@Entity(tableName = "series")
|
||||
data class SeriesEntity(
|
||||
@PrimaryKey val id: UUID,
|
||||
val name: String,
|
||||
val synopsis: String,
|
||||
val year: String,
|
||||
val heroImageUrl: String,
|
||||
val seasonCount: Int
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
package hu.bbara.purefin.data.local.relations
|
||||
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Relation
|
||||
import hu.bbara.purefin.data.local.entity.EpisodeEntity
|
||||
import hu.bbara.purefin.data.local.entity.SeasonEntity
|
||||
|
||||
data class SeasonWithEpisodes(
|
||||
@Embedded val season: SeasonEntity,
|
||||
@Relation(
|
||||
parentColumn = "id",
|
||||
entityColumn = "seasonId"
|
||||
)
|
||||
val episodes: List<EpisodeEntity>
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
package hu.bbara.purefin.data.local.relations
|
||||
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Relation
|
||||
import hu.bbara.purefin.data.local.entity.SeasonEntity
|
||||
import hu.bbara.purefin.data.local.entity.SeriesEntity
|
||||
|
||||
data class SeriesWithSeasonsAndEpisodes(
|
||||
@Embedded val series: SeriesEntity,
|
||||
@Relation(
|
||||
entity = SeasonEntity::class,
|
||||
parentColumn = "id",
|
||||
entityColumn = "seriesId"
|
||||
)
|
||||
val seasons: List<SeasonWithEpisodes>
|
||||
)
|
||||
@@ -0,0 +1,40 @@
|
||||
package hu.bbara.purefin.data.local.repository
|
||||
|
||||
import hu.bbara.purefin.data.model.Episode
|
||||
import hu.bbara.purefin.data.model.Season
|
||||
import hu.bbara.purefin.data.model.Series
|
||||
import java.util.UUID
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface LocalMediaRepository {
|
||||
|
||||
suspend fun upsertSeries(series: Series)
|
||||
|
||||
suspend fun upsertSeries(seriesList: List<Series>)
|
||||
|
||||
suspend fun getSeries(seriesId: UUID, includeContent: Boolean = true): Series?
|
||||
|
||||
fun observeSeries(seriesId: UUID): Flow<Series?>
|
||||
|
||||
fun observeAllSeries(): Flow<List<Series>>
|
||||
|
||||
suspend fun deleteSeries(seriesId: UUID)
|
||||
|
||||
suspend fun upsertSeason(season: Season)
|
||||
|
||||
suspend fun upsertSeasons(seasons: List<Season>)
|
||||
|
||||
suspend fun getSeason(seasonId: UUID, includeEpisodes: Boolean = true): Season?
|
||||
|
||||
fun observeSeasons(seriesId: UUID): Flow<List<Season>>
|
||||
|
||||
suspend fun deleteSeason(seasonId: UUID)
|
||||
|
||||
suspend fun upsertEpisode(episode: Episode)
|
||||
|
||||
suspend fun upsertEpisodes(episodes: List<Episode>)
|
||||
|
||||
suspend fun getEpisode(episodeId: UUID): Episode?
|
||||
|
||||
suspend fun deleteEpisode(episodeId: UUID)
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
package hu.bbara.purefin.data.local.repository
|
||||
|
||||
import hu.bbara.purefin.app.content.episode.CastMember
|
||||
import hu.bbara.purefin.data.local.dao.EpisodeDao
|
||||
import hu.bbara.purefin.data.local.dao.SeasonDao
|
||||
import hu.bbara.purefin.data.local.dao.SeriesDao
|
||||
import hu.bbara.purefin.data.local.entity.EpisodeCastMemberEntity
|
||||
import hu.bbara.purefin.data.local.entity.EpisodeEntity
|
||||
import hu.bbara.purefin.data.local.entity.SeasonEntity
|
||||
import hu.bbara.purefin.data.local.entity.SeriesEntity
|
||||
import hu.bbara.purefin.data.local.relations.SeasonWithEpisodes
|
||||
import hu.bbara.purefin.data.local.relations.SeriesWithSeasonsAndEpisodes
|
||||
import hu.bbara.purefin.data.model.Episode
|
||||
import hu.bbara.purefin.data.model.Season
|
||||
import hu.bbara.purefin.data.model.Series
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class RoomLocalMediaRepository @Inject constructor(
|
||||
private val seriesDao: SeriesDao,
|
||||
private val seasonDao: SeasonDao,
|
||||
private val episodeDao: EpisodeDao
|
||||
) : LocalMediaRepository {
|
||||
|
||||
override suspend fun upsertSeries(series: Series) {
|
||||
withContext(Dispatchers.IO) {
|
||||
seriesDao.upsertSeries(series.toEntity())
|
||||
upsertSeasonsInternal(series.seasons)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun upsertSeries(seriesList: List<Series>) {
|
||||
if (seriesList.isEmpty()) return
|
||||
withContext(Dispatchers.IO) {
|
||||
seriesDao.upsertSeries(seriesList.map { it.toEntity() })
|
||||
val seasons = seriesList.flatMap { it.seasons }
|
||||
upsertSeasonsInternal(seasons)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getSeries(seriesId: UUID, includeContent: Boolean): Series? {
|
||||
return withContext(Dispatchers.IO) {
|
||||
if (includeContent) {
|
||||
seriesDao.getSeriesWithContent(seriesId)?.toDomain()
|
||||
} else {
|
||||
seriesDao.getSeriesById(seriesId)?.toDomain(emptyList())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun observeSeries(seriesId: UUID): Flow<Series?> {
|
||||
return seriesDao.observeSeriesWithContent(seriesId).map { relation ->
|
||||
relation?.toDomain()
|
||||
}
|
||||
}
|
||||
|
||||
override fun observeAllSeries(): Flow<List<Series>> {
|
||||
return seriesDao.observeAllSeriesWithContent().map { relations ->
|
||||
relations.map { it.toDomain() }
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun deleteSeries(seriesId: UUID) {
|
||||
withContext(Dispatchers.IO) {
|
||||
seriesDao.deleteSeries(seriesId)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun upsertSeason(season: Season) {
|
||||
withContext(Dispatchers.IO) {
|
||||
upsertSeasonsInternal(listOf(season))
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun upsertSeasons(seasons: List<Season>) {
|
||||
if (seasons.isEmpty()) return
|
||||
withContext(Dispatchers.IO) {
|
||||
upsertSeasonsInternal(seasons)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getSeason(seasonId: UUID, includeEpisodes: Boolean): Season? {
|
||||
return withContext(Dispatchers.IO) {
|
||||
if (includeEpisodes) {
|
||||
seasonDao.getSeasonWithEpisodes(seasonId)?.toDomain()
|
||||
} else {
|
||||
seasonDao.getSeasonById(seasonId)?.toDomain(emptyList())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun observeSeasons(seriesId: UUID): Flow<List<Season>> {
|
||||
return seasonDao.observeSeasonsWithEpisodes(seriesId).map { relations ->
|
||||
relations.map { it.toDomain() }
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun deleteSeason(seasonId: UUID) {
|
||||
withContext(Dispatchers.IO) {
|
||||
seasonDao.deleteSeason(seasonId)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun upsertEpisode(episode: Episode) {
|
||||
withContext(Dispatchers.IO) {
|
||||
episodeDao.upsertEpisode(episode.toEntity())
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun upsertEpisodes(episodes: List<Episode>) {
|
||||
if (episodes.isEmpty()) return
|
||||
withContext(Dispatchers.IO) {
|
||||
episodeDao.upsertEpisodes(episodes.map { it.toEntity() })
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getEpisode(episodeId: UUID): Episode? {
|
||||
return withContext(Dispatchers.IO) {
|
||||
episodeDao.getEpisodeById(episodeId)?.toDomain()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun deleteEpisode(episodeId: UUID) {
|
||||
withContext(Dispatchers.IO) {
|
||||
episodeDao.deleteEpisode(episodeId)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun upsertSeasonsInternal(seasons: List<Season>) {
|
||||
if (seasons.isEmpty()) return
|
||||
seasonDao.upsertSeasons(seasons.map { it.toEntity() })
|
||||
val episodes = seasons.flatMap { it.episodes }
|
||||
if (episodes.isNotEmpty()) {
|
||||
episodeDao.upsertEpisodes(episodes.map { it.toEntity() })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun SeriesEntity.toDomain(seasons: List<Season>): Series = Series(
|
||||
id = id,
|
||||
name = name,
|
||||
synopsis = synopsis,
|
||||
year = year,
|
||||
heroImageUrl = heroImageUrl,
|
||||
seasonCount = seasonCount,
|
||||
seasons = seasons
|
||||
)
|
||||
|
||||
private fun SeasonEntity.toDomain(episodes: List<Episode>): Season = Season(
|
||||
id = id,
|
||||
seriesId = seriesId,
|
||||
name = name,
|
||||
index = index,
|
||||
episodeCount = episodeCount,
|
||||
episodes = episodes
|
||||
)
|
||||
|
||||
private fun EpisodeEntity.toDomain(): Episode = Episode(
|
||||
id = id,
|
||||
seriesId = seriesId,
|
||||
seasonId = seasonId,
|
||||
title = title,
|
||||
index = index,
|
||||
releaseDate = releaseDate,
|
||||
rating = rating,
|
||||
runtime = runtime,
|
||||
format = format,
|
||||
synopsis = synopsis,
|
||||
heroImageUrl = heroImageUrl,
|
||||
cast = cast.map { it.toDomain() }
|
||||
)
|
||||
|
||||
private fun SeriesWithSeasonsAndEpisodes.toDomain(): Series =
|
||||
series.toDomain(seasons.map { it.toDomain() })
|
||||
|
||||
private fun SeasonWithEpisodes.toDomain(): Season =
|
||||
season.toDomain(episodes.map { it.toDomain() })
|
||||
|
||||
private fun Series.toEntity(): SeriesEntity = SeriesEntity(
|
||||
id = id,
|
||||
name = name,
|
||||
synopsis = synopsis,
|
||||
year = year,
|
||||
heroImageUrl = heroImageUrl,
|
||||
seasonCount = seasonCount
|
||||
)
|
||||
|
||||
private fun Season.toEntity(): SeasonEntity = SeasonEntity(
|
||||
id = id,
|
||||
seriesId = seriesId,
|
||||
name = name,
|
||||
index = index,
|
||||
episodeCount = episodeCount
|
||||
)
|
||||
|
||||
private fun Episode.toEntity(): EpisodeEntity = EpisodeEntity(
|
||||
id = id,
|
||||
seriesId = seriesId,
|
||||
seasonId = seasonId,
|
||||
title = title,
|
||||
index = index,
|
||||
releaseDate = releaseDate,
|
||||
rating = rating,
|
||||
runtime = runtime,
|
||||
format = format,
|
||||
synopsis = synopsis,
|
||||
heroImageUrl = heroImageUrl,
|
||||
cast = cast.map { it.toEntity() }
|
||||
)
|
||||
|
||||
private fun EpisodeCastMemberEntity.toDomain(): CastMember = CastMember(
|
||||
name = name,
|
||||
role = role,
|
||||
imageUrl = imageUrl
|
||||
)
|
||||
|
||||
private fun CastMember.toEntity(): EpisodeCastMemberEntity = EpisodeCastMemberEntity(
|
||||
name = name,
|
||||
role = role,
|
||||
imageUrl = imageUrl
|
||||
)
|
||||
@@ -5,6 +5,8 @@ import java.util.UUID
|
||||
|
||||
data class Episode(
|
||||
val id: UUID,
|
||||
val seriesId: UUID,
|
||||
val seasonId: UUID,
|
||||
val title: String,
|
||||
val index: Int,
|
||||
val releaseDate: String,
|
||||
@@ -13,6 +15,5 @@ data class Episode(
|
||||
val format: String,
|
||||
val synopsis: String,
|
||||
val heroImageUrl: String,
|
||||
val cast: List<CastMember>,
|
||||
val season: Season,
|
||||
val cast: List<CastMember>
|
||||
)
|
||||
|
||||
@@ -4,9 +4,9 @@ import java.util.UUID
|
||||
|
||||
data class Season(
|
||||
val id: UUID,
|
||||
val seriesId: UUID,
|
||||
val name: String,
|
||||
val index: Int,
|
||||
val episodeCount: Int,
|
||||
val episodes: List<Episode>,
|
||||
val series: Series
|
||||
)
|
||||
val episodes: List<Episode>
|
||||
)
|
||||
|
||||
@@ -19,6 +19,7 @@ foundation = "1.10.1"
|
||||
coil = "3.3.0"
|
||||
media3 = "1.9.0"
|
||||
nav3Core = "1.0.0"
|
||||
room = "2.6.1"
|
||||
|
||||
[libraries]
|
||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
@@ -54,6 +55,9 @@ medi3-ui = { group = "androidx.media3", name = "media3-ui", version.ref = "media
|
||||
medi3-ui-compose = { group = "androidx.media3", name = "media3-ui-compose-material3", version.ref = "media3"}
|
||||
androidx-navigation3-runtime = { module = "androidx.navigation3:navigation3-runtime", version.ref = "nav3Core" }
|
||||
androidx-navigation3-ui = { module = "androidx.navigation3:navigation3-ui", version.ref = "nav3Core" }
|
||||
androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
|
||||
androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
|
||||
androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
|
||||
|
||||
|
||||
[plugins]
|
||||
|
||||
Reference in New Issue
Block a user