mirror of
https://github.com/bbara04/Purefin.git
synced 2026-07-22 17:41:39 +00:00
refactor: extract core-model into its own module
This commit is contained in:
@@ -10,7 +10,6 @@ import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.withFrameNanos
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
|
||||
@@ -20,7 +20,6 @@ import androidx.compose.foundation.layout.sizeIn
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
|
||||
@@ -52,6 +52,8 @@ kotlin {
|
||||
dependencies {
|
||||
implementation(project(":data"))
|
||||
implementation(project(":core"))
|
||||
//TODO: temporary hack fix it
|
||||
implementation(project(":core-model"))
|
||||
implementation(project(":core-ui"))
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||
|
||||
@@ -34,17 +34,16 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import hu.bbara.purefin.ui.common.media.MediaCastRow
|
||||
import hu.bbara.purefin.ui.common.media.MediaSynopsis
|
||||
import hu.bbara.purefin.ui.common.media.mediaPlaybackProgress
|
||||
import hu.bbara.purefin.ui.common.media.mediaPlayButtonText
|
||||
import hu.bbara.purefin.ui.common.button.GhostIconButton
|
||||
import hu.bbara.purefin.ui.common.button.MediaActionButton
|
||||
import hu.bbara.purefin.ui.common.media.MediaPlaybackSettings
|
||||
import hu.bbara.purefin.ui.common.button.MediaResumeButton
|
||||
import hu.bbara.purefin.download.DownloadState
|
||||
import hu.bbara.purefin.model.Episode
|
||||
import hu.bbara.purefin.player.PlayerActivity
|
||||
import hu.bbara.purefin.ui.common.button.GhostIconButton
|
||||
import hu.bbara.purefin.ui.common.button.MediaActionButton
|
||||
import hu.bbara.purefin.ui.common.button.MediaResumeButton
|
||||
import hu.bbara.purefin.ui.common.media.MediaPlaybackSettings
|
||||
import hu.bbara.purefin.ui.common.media.MediaSynopsis
|
||||
import hu.bbara.purefin.ui.common.media.mediaPlayButtonText
|
||||
import hu.bbara.purefin.ui.common.media.mediaPlaybackProgress
|
||||
|
||||
internal sealed interface EpisodeTopBarShortcut {
|
||||
val label: String
|
||||
@@ -182,9 +181,10 @@ internal fun EpisodeDetails(
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
MediaCastRow(
|
||||
cast = episode.cast
|
||||
)
|
||||
//TODO use it
|
||||
// MediaCastRow(
|
||||
// cast = episode.cast
|
||||
// )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,17 +29,16 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import hu.bbara.purefin.ui.common.media.MediaCastRow
|
||||
import hu.bbara.purefin.ui.common.media.MediaSynopsis
|
||||
import hu.bbara.purefin.ui.common.media.mediaPlaybackProgress
|
||||
import hu.bbara.purefin.ui.common.media.mediaPlayButtonText
|
||||
import hu.bbara.purefin.ui.common.button.GhostIconButton
|
||||
import hu.bbara.purefin.ui.common.button.MediaActionButton
|
||||
import hu.bbara.purefin.ui.common.media.MediaPlaybackSettings
|
||||
import hu.bbara.purefin.ui.common.button.MediaResumeButton
|
||||
import hu.bbara.purefin.download.DownloadState
|
||||
import hu.bbara.purefin.model.Movie
|
||||
import hu.bbara.purefin.player.PlayerActivity
|
||||
import hu.bbara.purefin.ui.common.button.GhostIconButton
|
||||
import hu.bbara.purefin.ui.common.button.MediaActionButton
|
||||
import hu.bbara.purefin.ui.common.button.MediaResumeButton
|
||||
import hu.bbara.purefin.ui.common.media.MediaPlaybackSettings
|
||||
import hu.bbara.purefin.ui.common.media.MediaSynopsis
|
||||
import hu.bbara.purefin.ui.common.media.mediaPlayButtonText
|
||||
import hu.bbara.purefin.ui.common.media.mediaPlaybackProgress
|
||||
|
||||
@Composable
|
||||
internal fun MovieTopBar(
|
||||
@@ -139,9 +138,10 @@ internal fun MovieDetails(
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
MediaCastRow(
|
||||
cast = movie.cast,
|
||||
)
|
||||
//TODO fix
|
||||
// MediaCastRow(
|
||||
// cast = movie.cast,
|
||||
// )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package hu.bbara.purefin.ui.screen.series
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@@ -15,32 +17,30 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import hu.bbara.purefin.ui.common.media.MediaSynopsis
|
||||
import hu.bbara.purefin.ui.screen.waiting.PurefinWaitingScreen
|
||||
import hu.bbara.purefin.ui.common.media.MediaHero
|
||||
import hu.bbara.purefin.download.DownloadState
|
||||
import hu.bbara.purefin.feature.content.series.SeriesViewModel
|
||||
import hu.bbara.purefin.image.ArtworkKind
|
||||
import hu.bbara.purefin.image.ImageUrlBuilder
|
||||
import hu.bbara.purefin.navigation.SeriesDto
|
||||
import hu.bbara.purefin.model.CastMember
|
||||
import hu.bbara.purefin.model.Episode
|
||||
import hu.bbara.purefin.model.Season
|
||||
import hu.bbara.purefin.model.Series
|
||||
import hu.bbara.purefin.feature.content.series.SeriesViewModel
|
||||
import hu.bbara.purefin.navigation.SeriesDto
|
||||
import hu.bbara.purefin.ui.common.media.MediaHero
|
||||
import hu.bbara.purefin.ui.common.media.MediaSynopsis
|
||||
import hu.bbara.purefin.ui.screen.series.components.CastRow
|
||||
import hu.bbara.purefin.ui.screen.series.components.EpisodeCarousel
|
||||
import hu.bbara.purefin.ui.screen.series.components.SeasonTabs
|
||||
@@ -48,8 +48,8 @@ import hu.bbara.purefin.ui.screen.series.components.SeriesActionButtons
|
||||
import hu.bbara.purefin.ui.screen.series.components.SeriesDownloadOption
|
||||
import hu.bbara.purefin.ui.screen.series.components.SeriesMetaChips
|
||||
import hu.bbara.purefin.ui.screen.series.components.SeriesTopBar
|
||||
import hu.bbara.purefin.ui.screen.waiting.PurefinWaitingScreen
|
||||
import hu.bbara.purefin.ui.theme.AppTheme
|
||||
import hu.bbara.purefin.image.ArtworkKind
|
||||
import java.util.UUID
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -55,28 +55,27 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import hu.bbara.purefin.ui.common.media.MediaCastRow
|
||||
import hu.bbara.purefin.ui.common.media.MediaMetadataFlowRow
|
||||
import hu.bbara.purefin.ui.common.media.mediaPlaybackProgress
|
||||
import hu.bbara.purefin.ui.common.media.mediaPlayButtonText
|
||||
import hu.bbara.purefin.ui.common.button.GhostIconButton
|
||||
import hu.bbara.purefin.ui.common.button.MediaActionButton
|
||||
import hu.bbara.purefin.ui.common.bar.MediaProgressBar
|
||||
import hu.bbara.purefin.ui.common.button.MediaResumeButton
|
||||
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
|
||||
import hu.bbara.purefin.ui.common.badge.WatchStateBadge
|
||||
import hu.bbara.purefin.download.DownloadState
|
||||
import hu.bbara.purefin.feature.content.series.SeriesViewModel
|
||||
import hu.bbara.purefin.image.ArtworkKind
|
||||
import hu.bbara.purefin.image.ImageUrlBuilder
|
||||
import hu.bbara.purefin.navigation.EpisodeDto
|
||||
import hu.bbara.purefin.navigation.LocalNavigationManager
|
||||
import hu.bbara.purefin.navigation.Route
|
||||
import hu.bbara.purefin.model.CastMember
|
||||
import hu.bbara.purefin.model.Episode
|
||||
import hu.bbara.purefin.model.Season
|
||||
import hu.bbara.purefin.model.Series
|
||||
import hu.bbara.purefin.feature.content.series.SeriesViewModel
|
||||
import hu.bbara.purefin.navigation.EpisodeDto
|
||||
import hu.bbara.purefin.navigation.LocalNavigationManager
|
||||
import hu.bbara.purefin.navigation.Route
|
||||
import hu.bbara.purefin.player.PlayerActivity
|
||||
import hu.bbara.purefin.image.ArtworkKind
|
||||
import hu.bbara.purefin.ui.common.badge.WatchStateBadge
|
||||
import hu.bbara.purefin.ui.common.bar.MediaProgressBar
|
||||
import hu.bbara.purefin.ui.common.button.GhostIconButton
|
||||
import hu.bbara.purefin.ui.common.button.MediaActionButton
|
||||
import hu.bbara.purefin.ui.common.button.MediaResumeButton
|
||||
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
|
||||
import hu.bbara.purefin.ui.common.media.MediaMetadataFlowRow
|
||||
import hu.bbara.purefin.ui.common.media.mediaPlayButtonText
|
||||
import hu.bbara.purefin.ui.common.media.mediaPlaybackProgress
|
||||
|
||||
@Composable
|
||||
internal fun SeriesTopBar(
|
||||
@@ -407,11 +406,12 @@ private fun EpisodeCard(
|
||||
|
||||
@Composable
|
||||
internal fun CastRow(cast: List<CastMember>, modifier: Modifier = Modifier) {
|
||||
MediaCastRow(
|
||||
cast = cast,
|
||||
modifier = modifier,
|
||||
cardWidth = 84.dp,
|
||||
nameSize = 11.sp,
|
||||
roleSize = 10.sp
|
||||
)
|
||||
//TODO fix
|
||||
// MediaCastRow(
|
||||
// cast = cast,
|
||||
// modifier = modifier,
|
||||
// cardWidth = 84.dp,
|
||||
// nameSize = 11.sp,
|
||||
// roleSize = 10.sp
|
||||
// )
|
||||
}
|
||||
|
||||
1
core-model/.gitignore
vendored
Normal file
1
core-model/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
13
core-model/build.gradle.kts
Normal file
13
core-model/build.gradle.kts
Normal file
@@ -0,0 +1,13 @@
|
||||
plugins {
|
||||
id("java-library")
|
||||
alias(libs.plugins.kotlin.jvm)
|
||||
}
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
|
||||
}
|
||||
}
|
||||
@@ -2,23 +2,11 @@ package hu.bbara.purefin.ui.common.media
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Person
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -26,15 +14,9 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.TextUnit
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import hu.bbara.purefin.model.CastMember
|
||||
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
|
||||
|
||||
@Composable
|
||||
fun MediaMetaChip(
|
||||
@@ -63,73 +45,74 @@ fun MediaMetaChip(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MediaCastRow(
|
||||
cast: List<CastMember>,
|
||||
modifier: Modifier = Modifier,
|
||||
cardWidth: Dp = 96.dp,
|
||||
nameSize: TextUnit = 12.sp,
|
||||
roleSize: TextUnit = 10.sp
|
||||
) {
|
||||
val scheme = MaterialTheme.colorScheme
|
||||
val mutedStrong = scheme.onSurfaceVariant.copy(alpha = 0.7f)
|
||||
|
||||
LazyRow(
|
||||
modifier = modifier,
|
||||
contentPadding = PaddingValues(horizontal = 4.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
items(
|
||||
items = cast,
|
||||
key = { member -> "${member.name}:${member.role}:${member.imageUrl.orEmpty()}" }
|
||||
) { member ->
|
||||
Column(modifier = Modifier.width(cardWidth)) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.aspectRatio(4f / 5f)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.background(scheme.surfaceVariant)
|
||||
) {
|
||||
if (member.imageUrl == null) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(scheme.surfaceVariant.copy(alpha = 0.6f)),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Person,
|
||||
contentDescription = null,
|
||||
tint = mutedStrong
|
||||
)
|
||||
}
|
||||
} else {
|
||||
PurefinAsyncImage(
|
||||
model = member.imageUrl,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentScale = ContentScale.Crop,
|
||||
fallbackIcon = null
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.height(6.dp))
|
||||
Text(
|
||||
text = member.name,
|
||||
color = scheme.onBackground,
|
||||
fontSize = nameSize,
|
||||
fontWeight = FontWeight.Bold,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
text = member.role,
|
||||
color = mutedStrong,
|
||||
fontSize = roleSize,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//TODO use CastMemberUiModel
|
||||
//@Composable
|
||||
//fun MediaCastRow(
|
||||
// cast: List<CastMember>,
|
||||
// modifier: Modifier = Modifier,
|
||||
// cardWidth: Dp = 96.dp,
|
||||
// nameSize: TextUnit = 12.sp,
|
||||
// roleSize: TextUnit = 10.sp
|
||||
//) {
|
||||
// val scheme = MaterialTheme.colorScheme
|
||||
// val mutedStrong = scheme.onSurfaceVariant.copy(alpha = 0.7f)
|
||||
//
|
||||
// LazyRow(
|
||||
// modifier = modifier,
|
||||
// contentPadding = PaddingValues(horizontal = 4.dp),
|
||||
// horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||
// ) {
|
||||
// items(
|
||||
// items = cast,
|
||||
// key = { member -> "${member.name}:${member.role}:${member.imageUrl.orEmpty()}" }
|
||||
// ) { member ->
|
||||
// Column(modifier = Modifier.width(cardWidth)) {
|
||||
// Box(
|
||||
// modifier = Modifier
|
||||
// .aspectRatio(4f / 5f)
|
||||
// .clip(RoundedCornerShape(12.dp))
|
||||
// .background(scheme.surfaceVariant)
|
||||
// ) {
|
||||
// if (member.imageUrl == null) {
|
||||
// Box(
|
||||
// modifier = Modifier
|
||||
// .fillMaxSize()
|
||||
// .background(scheme.surfaceVariant.copy(alpha = 0.6f)),
|
||||
// contentAlignment = Alignment.Center
|
||||
// ) {
|
||||
// Icon(
|
||||
// imageVector = Icons.Outlined.Person,
|
||||
// contentDescription = null,
|
||||
// tint = mutedStrong
|
||||
// )
|
||||
// }
|
||||
// } else {
|
||||
// PurefinAsyncImage(
|
||||
// model = member.imageUrl,
|
||||
// contentDescription = null,
|
||||
// modifier = Modifier.fillMaxSize(),
|
||||
// contentScale = ContentScale.Crop,
|
||||
// fallbackIcon = null
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// Spacer(modifier = Modifier.height(6.dp))
|
||||
// Text(
|
||||
// text = member.name,
|
||||
// color = scheme.onBackground,
|
||||
// fontSize = nameSize,
|
||||
// fontWeight = FontWeight.Bold,
|
||||
// maxLines = 1,
|
||||
// overflow = TextOverflow.Ellipsis
|
||||
// )
|
||||
// Text(
|
||||
// text = member.role,
|
||||
// color = mutedStrong,
|
||||
// fontSize = roleSize,
|
||||
// maxLines = 1,
|
||||
// overflow = TextOverflow.Ellipsis
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -30,6 +30,7 @@ kotlin {
|
||||
|
||||
dependencies {
|
||||
implementation(project(":data"))
|
||||
implementation(project(":core-model"))
|
||||
implementation(libs.hilt)
|
||||
ksp(libs.hilt.compiler)
|
||||
implementation(libs.androidx.lifecycle.viewmodel.ktx)
|
||||
|
||||
@@ -29,6 +29,7 @@ kotlin {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":core-model"))
|
||||
implementation(libs.media3.common)
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.jellyfin.core)
|
||||
|
||||
@@ -28,3 +28,4 @@ include(":app-tv")
|
||||
include(":data")
|
||||
include(":core")
|
||||
include(":core-ui")
|
||||
include(":core-model")
|
||||
|
||||
Reference in New Issue
Block a user