Compare commits

...

3 Commits

203 changed files with 1283 additions and 1454 deletions

View File

@@ -21,9 +21,9 @@ import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle
import hu.bbara.purefin.common.ui.components.TvMediaDetailBodyBox
import hu.bbara.purefin.common.ui.components.TvMediaDetailScaffold
import hu.bbara.purefin.core.data.image.JellyfinImageHelper
import hu.bbara.purefin.core.data.navigation.EpisodeDto
import hu.bbara.purefin.core.data.navigation.LocalNavigationManager
import hu.bbara.purefin.core.data.navigation.Route
import hu.bbara.purefin.feature.shared.navigation.EpisodeDto
import hu.bbara.purefin.tv.navigation.LocalNavigationManager
import hu.bbara.purefin.feature.shared.navigation.Route
import hu.bbara.purefin.core.model.Episode
import hu.bbara.purefin.feature.shared.content.episode.EpisodeScreenViewModel
import org.jellyfin.sdk.model.api.ImageType

View File

@@ -21,7 +21,7 @@ import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle
import hu.bbara.purefin.common.ui.components.TvMediaDetailBodyBox
import hu.bbara.purefin.common.ui.components.TvMediaDetailScaffold
import hu.bbara.purefin.common.ui.components.tvMediaDetailBackgroundImageUrl
import hu.bbara.purefin.core.data.navigation.MovieDto
import hu.bbara.purefin.feature.shared.navigation.MovieDto
import hu.bbara.purefin.core.model.Movie
import hu.bbara.purefin.feature.shared.content.movie.MovieScreenViewModel

View File

@@ -22,11 +22,11 @@ import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle
import hu.bbara.purefin.common.ui.components.TvMediaDetailBodyBox
import hu.bbara.purefin.common.ui.components.TvMediaDetailScaffold
import hu.bbara.purefin.common.ui.components.tvMediaDetailBackgroundImageUrl
import hu.bbara.purefin.core.data.navigation.SeriesDto
import hu.bbara.purefin.feature.shared.navigation.SeriesDto
import hu.bbara.purefin.core.model.Season
import hu.bbara.purefin.core.model.Series
import hu.bbara.purefin.feature.shared.content.series.SeriesViewModel
import org.jellyfin.sdk.model.UUID
import java.util.UUID
@Composable
fun TvSeriesScreen(

View File

@@ -34,8 +34,8 @@ import hu.bbara.purefin.common.ui.components.UnwatchedEpisodeIndicator
import hu.bbara.purefin.common.ui.components.WatchStateIndicator
import hu.bbara.purefin.feature.shared.home.FocusableItem
import hu.bbara.purefin.feature.shared.home.PosterItem
import org.jellyfin.sdk.model.UUID
import org.jellyfin.sdk.model.api.BaseItemKind
import java.util.UUID
import hu.bbara.purefin.core.model.MediaKind
@Composable
fun PosterCard(
@@ -57,9 +57,9 @@ fun PosterCard(
fun openItem(posterItem: PosterItem) {
when (posterItem.type) {
BaseItemKind.MOVIE -> onMovieSelected(posterItem.id)
BaseItemKind.SERIES -> onSeriesSelected(posterItem.id)
BaseItemKind.EPISODE -> {
MediaKind.MOVIE -> onMovieSelected(posterItem.id)
MediaKind.SERIES -> onSeriesSelected(posterItem.id)
MediaKind.EPISODE -> {
val ep = posterItem.episode!!
onEpisodeSelected(ep.seriesId, ep.seasonId, ep.id)
}
@@ -99,7 +99,7 @@ fun PosterCard(
contentScale = ContentScale.Crop
)
when (item.type) {
BaseItemKind.MOVIE -> {
MediaKind.MOVIE -> {
val m = item.movie!!
WatchStateIndicator(
size = indicatorSize,
@@ -109,7 +109,7 @@ fun PosterCard(
started = (m.progress ?: 0.0) > 0
)
}
BaseItemKind.EPISODE -> {
MediaKind.EPISODE -> {
val ep = item.episode!!
WatchStateIndicator(
size = indicatorSize,
@@ -119,7 +119,7 @@ fun PosterCard(
started = (ep.progress ?: 0.0) > 0
)
}
BaseItemKind.SERIES -> UnwatchedEpisodeIndicator(
MediaKind.SERIES -> UnwatchedEpisodeIndicator(
size = indicatorSize,
modifier = Modifier.align(Alignment.TopEnd)
.padding(indicatorPadding),

View File

@@ -39,13 +39,13 @@ import dagger.hilt.android.AndroidEntryPoint
import hu.bbara.purefin.common.ui.PurefinWaitingScreen
import hu.bbara.purefin.core.data.client.JellyfinApiClient
import hu.bbara.purefin.core.data.client.JellyfinAuthInterceptor
import hu.bbara.purefin.core.data.navigation.LocalNavigationBackStack
import hu.bbara.purefin.core.data.navigation.LocalNavigationManager
import hu.bbara.purefin.core.data.navigation.NavigationCommand
import hu.bbara.purefin.core.data.navigation.NavigationManager
import hu.bbara.purefin.core.data.navigation.Route
import hu.bbara.purefin.core.data.session.UserSessionRepository
import hu.bbara.purefin.feature.shared.navigation.NavigationCommand
import hu.bbara.purefin.feature.shared.navigation.NavigationManager
import hu.bbara.purefin.feature.shared.navigation.Route
import hu.bbara.purefin.login.ui.LoginScreen
import hu.bbara.purefin.tv.navigation.LocalNavigationBackStack
import hu.bbara.purefin.tv.navigation.LocalNavigationManager
import hu.bbara.purefin.ui.theme.AppTheme
import hu.bbara.purefin.ui.theme.backgroundDark
import kotlinx.coroutines.launch

View File

@@ -21,7 +21,7 @@ import hu.bbara.purefin.tv.home.ui.TvDrawerDestination
import hu.bbara.purefin.tv.home.ui.TvDrawerDestinationItem
import hu.bbara.purefin.tv.home.ui.TvNavigationDrawer
import hu.bbara.purefin.tv.library.ui.TvLibrariesOverviewScreen
import org.jellyfin.sdk.model.api.CollectionType
import hu.bbara.purefin.core.model.LibraryKind
@Composable
fun TvAppScreen(
@@ -48,8 +48,8 @@ fun TvAppScreen(
destination = TvDrawerDestination.LIBRARIES,
label = "Libraries",
icon = when {
libraries.any { it.type == CollectionType.MOVIES } -> Icons.Outlined.Movie
libraries.any { it.type == CollectionType.TVSHOWS } -> Icons.Outlined.Tv
libraries.any { it.type == LibraryKind.MOVIES } -> Icons.Outlined.Movie
libraries.any { it.type == LibraryKind.SERIES } -> Icons.Outlined.Tv
else -> Icons.Outlined.Collections
},
selected = selectedDestination == TvDrawerDestination.LIBRARIES

View File

@@ -11,7 +11,7 @@ import hu.bbara.purefin.core.data.download.MediaDownloadController
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import org.jellyfin.sdk.model.UUID
import java.util.UUID
import javax.inject.Singleton
@Module

View File

@@ -16,7 +16,7 @@ import hu.bbara.purefin.feature.shared.home.PosterItem
import hu.bbara.purefin.tv.home.ui.TvFocusedItemHero
import hu.bbara.purefin.tv.home.ui.TvHomeContent
import hu.bbara.purefin.tv.home.ui.rememberTvHomeHeroState
import org.jellyfin.sdk.model.UUID
import java.util.UUID
private const val TvHomeHeroHeightFraction = 0.32f
private val TvHomeMinHeroHeight = 160.dp

View File

@@ -8,8 +8,8 @@ import hu.bbara.purefin.feature.shared.home.ContinueWatchingItem
import hu.bbara.purefin.feature.shared.home.FocusableItem
import hu.bbara.purefin.feature.shared.home.NextUpItem
import hu.bbara.purefin.feature.shared.home.PosterItem
import org.jellyfin.sdk.model.UUID
import org.jellyfin.sdk.model.api.BaseItemKind
import java.util.UUID
import hu.bbara.purefin.core.model.MediaKind
import org.jellyfin.sdk.model.api.ImageType
import kotlin.math.roundToInt
@@ -26,16 +26,16 @@ internal data class TvFocusedHeroModel(
internal fun FocusableItem.toTvFocusedHeroModel(): TvFocusedHeroModel {
return when (this) {
is ContinueWatchingItem -> when (type) {
BaseItemKind.MOVIE -> movie!!.toTvFocusedHeroModel()
BaseItemKind.EPISODE -> episode!!.toTvFocusedHeroModel()
MediaKind.MOVIE -> movie!!.toTvFocusedHeroModel()
MediaKind.EPISODE -> episode!!.toTvFocusedHeroModel()
else -> unsupportedType(type)
}
is NextUpItem -> episode.toTvFocusedHeroModel()
is PosterItem -> when (type) {
BaseItemKind.MOVIE -> movie!!.toTvFocusedHeroModel()
BaseItemKind.EPISODE -> episode!!.toTvFocusedHeroModel()
BaseItemKind.SERIES -> series!!.toTvFocusedHeroModel()
MediaKind.MOVIE -> movie!!.toTvFocusedHeroModel()
MediaKind.EPISODE -> episode!!.toTvFocusedHeroModel()
MediaKind.SERIES -> series!!.toTvFocusedHeroModel()
else -> unsupportedType(type)
}
}
@@ -117,6 +117,6 @@ private fun seasonLabel(seasonCount: Int): String {
return if (seasonCount == 1) "1 season" else "$seasonCount seasons"
}
private fun unsupportedType(type: BaseItemKind): Nothing {
private fun unsupportedType(type: MediaKind): Nothing {
throw UnsupportedOperationException("Unsupported item type: $type")
}

View File

@@ -29,7 +29,7 @@ import hu.bbara.purefin.feature.shared.home.FocusableItem
import hu.bbara.purefin.feature.shared.home.LibraryItem
import hu.bbara.purefin.feature.shared.home.NextUpItem
import hu.bbara.purefin.feature.shared.home.PosterItem
import org.jellyfin.sdk.model.UUID
import java.util.UUID
internal const val TvHomeInitialFocusTag = "tv-home-initial-focus-item"
internal const val TvHomeContentViewportTag = "tv-home-content-viewport"

View File

@@ -10,7 +10,7 @@ import hu.bbara.purefin.feature.shared.home.FocusableItem
import hu.bbara.purefin.feature.shared.home.LibraryItem
import hu.bbara.purefin.feature.shared.home.NextUpItem
import hu.bbara.purefin.feature.shared.home.PosterItem
import org.jellyfin.sdk.model.UUID
import java.util.UUID
internal data class TvHomeItemRegistry(
val visibleLibraries: List<LibraryItem>,

View File

@@ -52,8 +52,8 @@ import hu.bbara.purefin.feature.shared.home.ContinueWatchingItem
import hu.bbara.purefin.feature.shared.home.FocusableItem
import hu.bbara.purefin.feature.shared.home.NextUpItem
import hu.bbara.purefin.feature.shared.home.PosterItem
import org.jellyfin.sdk.model.UUID
import org.jellyfin.sdk.model.api.BaseItemKind
import java.util.UUID
import hu.bbara.purefin.core.model.MediaKind
import org.jellyfin.sdk.model.api.ImageType
private val TvHomeSectionsThumbShape = RoundedCornerShape(20.dp)
@@ -93,12 +93,12 @@ fun TvContinueWatchingSection(
title = item.primaryText,
supporting = item.secondaryText,
imageUrl = when (item.type) {
BaseItemKind.MOVIE -> JellyfinImageHelper.finishImageUrl(
MediaKind.MOVIE -> JellyfinImageHelper.finishImageUrl(
prefixImageUrl = item.movie?.imageUrlPrefix,
imageType = ImageType.PRIMARY
)
BaseItemKind.EPISODE -> JellyfinImageHelper.finishImageUrl(
MediaKind.EPISODE -> JellyfinImageHelper.finishImageUrl(
prefixImageUrl = item.episode?.imageUrlPrefix,
imageType = ImageType.PRIMARY
)
@@ -124,8 +124,8 @@ fun TvContinueWatchingSection(
onFocusedItem = { onFocusedItem(item) },
onClick = {
when (item.type) {
BaseItemKind.MOVIE -> onMovieSelected(item.movie!!.id)
BaseItemKind.EPISODE -> {
MediaKind.MOVIE -> onMovieSelected(item.movie!!.id)
MediaKind.EPISODE -> {
val episode = item.episode!!
onEpisodeSelected(episode.seriesId, episode.seasonId, episode.id)
}

View File

@@ -45,7 +45,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import hu.bbara.purefin.common.ui.components.PurefinAsyncImage
import hu.bbara.purefin.feature.shared.home.LibraryItem
import org.jellyfin.sdk.model.api.CollectionType
import hu.bbara.purefin.core.model.LibraryKind
internal const val TvLibrariesOverviewItemTagPrefix = "tv-libraries-overview-item-"
@@ -161,9 +161,8 @@ private fun TvLibraryOverviewCard(
} else {
Icon(
imageVector = when (item.type) {
CollectionType.MOVIES -> Icons.Outlined.Movie
CollectionType.TVSHOWS -> Icons.Outlined.Tv
else -> Icons.Outlined.Collections
LibraryKind.MOVIES -> Icons.Outlined.Movie
LibraryKind.SERIES -> Icons.Outlined.Tv
},
contentDescription = null,
tint = scheme.onSurfaceVariant,

View File

@@ -24,10 +24,10 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.common.ui.PosterCard
import hu.bbara.purefin.common.ui.components.PurefinIconButton
import hu.bbara.purefin.core.data.navigation.LibraryDto
import hu.bbara.purefin.feature.shared.navigation.LibraryDto
import hu.bbara.purefin.feature.shared.home.PosterItem
import hu.bbara.purefin.feature.shared.library.LibraryViewModel
import org.jellyfin.sdk.model.UUID
import java.util.UUID
@Composable
fun TvLibraryScreen(

View File

@@ -0,0 +1,12 @@
package hu.bbara.purefin.tv.navigation
import androidx.compose.runtime.ProvidableCompositionLocal
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.staticCompositionLocalOf
import hu.bbara.purefin.feature.shared.navigation.NavigationManager
import hu.bbara.purefin.feature.shared.navigation.Route
val LocalNavigationManager: ProvidableCompositionLocal<NavigationManager> =
staticCompositionLocalOf { error("NavigationManager not provided") }
val LocalNavigationBackStack = compositionLocalOf<List<Route>> { emptyList() }

View File

@@ -6,7 +6,7 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityRetainedComponent
import dagger.multibindings.IntoSet
import hu.bbara.purefin.core.data.navigation.Route
import hu.bbara.purefin.feature.shared.navigation.Route
@Module
@InstallIn(ActivityRetainedComponent::class)

View File

@@ -4,8 +4,7 @@ import androidx.navigation3.runtime.EntryProviderScope
import hu.bbara.purefin.app.content.episode.TvEpisodeScreen
import hu.bbara.purefin.app.content.movie.TvMovieScreen
import hu.bbara.purefin.app.content.series.TvSeriesScreen
import hu.bbara.purefin.core.data.navigation.LocalNavigationManager
import hu.bbara.purefin.core.data.navigation.Route
import hu.bbara.purefin.feature.shared.navigation.Route
import hu.bbara.purefin.login.ui.LoginScreen
import hu.bbara.purefin.tv.TvAppScreen
import hu.bbara.purefin.tv.library.ui.TvLibraryScreen

View File

@@ -1,74 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z"/>
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/purefin_logo_background"/>
<background android:drawable="@color/purefin_logo_background"/>
<foreground android:drawable="@mipmap/purefin_logo_foreground"/>
<monochrome android:drawable="@mipmap/purefin_logo_foreground"/>
</adaptive-icon>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/purefin_logo_background"/>
<background android:drawable="@color/purefin_logo_background"/>
<foreground android:drawable="@mipmap/purefin_logo_foreground"/>
<monochrome android:drawable="@mipmap/purefin_logo_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purefin_logo_background">#201337</color>
</resources>

View File

@@ -12,9 +12,9 @@
android:screenOrientation="portrait"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/purefin_logo_2"
android:icon="@mipmap/purefin_logo"
android:label="@string/app_name"
android:roundIcon="@mipmap/purefin_logo_2_round"
android:roundIcon="@mipmap/purefin_logo_round"
android:supportsRtl="true"
android:theme="@style/Theme.Purefin">
<activity

View File

@@ -36,16 +36,16 @@ import coil3.network.okhttp.OkHttpNetworkFetcherFactory
import coil3.request.crossfade
import coil3.util.DebugLogger
import dagger.hilt.android.AndroidEntryPoint
import hu.bbara.purefin.common.ui.PurefinWaitingScreen
import hu.bbara.purefin.ui.screen.waiting.PurefinWaitingScreen
import hu.bbara.purefin.core.data.client.JellyfinApiClient
import hu.bbara.purefin.core.data.client.JellyfinAuthInterceptor
import hu.bbara.purefin.core.data.navigation.LocalNavigationBackStack
import hu.bbara.purefin.core.data.navigation.LocalNavigationManager
import hu.bbara.purefin.core.data.navigation.NavigationCommand
import hu.bbara.purefin.core.data.navigation.NavigationManager
import hu.bbara.purefin.core.data.navigation.Route
import hu.bbara.purefin.core.data.session.UserSessionRepository
import hu.bbara.purefin.login.ui.LoginScreen
import hu.bbara.purefin.feature.shared.navigation.NavigationCommand
import hu.bbara.purefin.feature.shared.navigation.NavigationManager
import hu.bbara.purefin.feature.shared.navigation.Route
import hu.bbara.purefin.navigation.LocalNavigationBackStack
import hu.bbara.purefin.navigation.LocalNavigationManager
import hu.bbara.purefin.ui.screen.login.LoginScreen
import hu.bbara.purefin.ui.theme.AppTheme
import hu.bbara.purefin.ui.theme.backgroundDark
import kotlinx.coroutines.launch

View File

@@ -1,13 +0,0 @@
package hu.bbara.purefin.app.home
import androidx.navigation3.runtime.EntryProviderScope
import hu.bbara.purefin.core.data.navigation.Route
/**
* Navigation 3 entry definition for the Home section.
*/
fun EntryProviderScope<Route>.homeSection() {
entry<Route.Home> {
AppScreen()
}
}

View File

@@ -1,111 +0,0 @@
package hu.bbara.purefin.common.ui.components
import androidx.compose.foundation.background
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.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SearchBar
import androidx.compose.material3.SearchBarDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.semantics.isTraversalGroup
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.traversalIndex
import androidx.compose.ui.unit.dp
import hu.bbara.purefin.core.model.SearchResult
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PurefinSearchBar(
onQueryChange: (String) -> Unit,
onSearch: (String) -> Unit,
searchResults: List<SearchResult>,
onExpandedChange: (Boolean) -> Unit = {},
modifier: Modifier = Modifier
) {
var query by remember { mutableStateOf("") }
var expanded by rememberSaveable { mutableStateOf(false) }
val setExpanded: (Boolean) -> Unit = {
expanded = it
onExpandedChange(it)
}
Box(
modifier
.fillMaxWidth()
.semantics { isTraversalGroup = true }
) {
SearchBar(
modifier = Modifier
.align(Alignment.TopCenter)
.fillMaxWidth()
.semantics { traversalIndex = 0f },
inputField = {
SearchBarDefaults.InputField(
query = query,
onQueryChange = {
query = it
onQueryChange(it)
},
onSearch = {
onSearch(query)
setExpanded(false)
},
expanded = expanded,
onExpandedChange = setExpanded,
placeholder = { Text("Search") }
)
},
expanded = expanded,
onExpandedChange = setExpanded,
) {
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(searchResults) { item ->
SearchResultCard(item)
}
}
}
}
}
@Composable
private fun SearchResultCard(
item: SearchResult,
modifier: Modifier = Modifier
) {
Column(modifier = modifier) {
PurefinAsyncImage(
model = item.posterUrl,
contentDescription = item.title,
modifier = Modifier.height(150.dp),
contentScale = ContentScale.Fit
)
Text(
text = item.title,
modifier = Modifier.padding(horizontal = 8.dp)
)
}
}

View File

@@ -1,56 +0,0 @@
package hu.bbara.purefin.common.ui.components
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
@Composable
fun SearchField(
value: String,
onValueChange: (String) -> Unit,
placeholder: String,
backgroundColor: Color = Color.Unspecified,
textColor: Color = Color.Unspecified,
cursorColor: Color = Color.Unspecified,
modifier: Modifier = Modifier,
) {
val scheme = MaterialTheme.colorScheme
val resolvedBackgroundColor =
if (backgroundColor == Color.Unspecified) scheme.surfaceVariant else backgroundColor
val resolvedTextColor = if (textColor == Color.Unspecified) scheme.onSurface else textColor
val resolvedCursorColor = if (cursorColor == Color.Unspecified) scheme.primary else cursorColor
TextField(
value = value,
onValueChange = onValueChange,
modifier = modifier
.fillMaxWidth()
.clip(RoundedCornerShape(12.dp)),
singleLine = true,
placeholder = { Text(placeholder) },
leadingIcon = { Icon(imageVector = Icons.Outlined.Search, contentDescription = null) },
colors = TextFieldDefaults.colors(
focusedContainerColor = resolvedBackgroundColor,
unfocusedContainerColor = resolvedBackgroundColor,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
cursorColor = resolvedCursorColor,
focusedTextColor = resolvedTextColor,
unfocusedTextColor = resolvedTextColor,
focusedLeadingIconColor = scheme.onSurfaceVariant,
unfocusedLeadingIconColor = scheme.onSurfaceVariant,
focusedPlaceholderColor = scheme.onSurfaceVariant,
unfocusedPlaceholderColor = scheme.onSurfaceVariant,
))
}

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.navigation
package hu.bbara.purefin.modules
import androidx.navigation3.runtime.EntryProviderScope
import dagger.Module
@@ -6,7 +6,8 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityRetainedComponent
import dagger.multibindings.IntoSet
import hu.bbara.purefin.core.data.navigation.Route
import hu.bbara.purefin.feature.shared.navigation.Route
import hu.bbara.purefin.navigation.appRouteEntryBuilder
@Module
@InstallIn(ActivityRetainedComponent::class)

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.di
package hu.bbara.purefin.modules
import dagger.Module
import dagger.Provides

View File

@@ -0,0 +1,12 @@
package hu.bbara.purefin.navigation
import androidx.compose.runtime.ProvidableCompositionLocal
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.staticCompositionLocalOf
import hu.bbara.purefin.feature.shared.navigation.NavigationManager
import hu.bbara.purefin.feature.shared.navigation.Route
val LocalNavigationManager: ProvidableCompositionLocal<NavigationManager> =
staticCompositionLocalOf { error("NavigationManager not provided") }
val LocalNavigationBackStack = compositionLocalOf<List<Route>> { emptyList() }

View File

@@ -1,13 +1,13 @@
package hu.bbara.purefin.navigation
import androidx.navigation3.runtime.EntryProviderScope
import hu.bbara.purefin.app.content.episode.EpisodeScreen
import hu.bbara.purefin.app.content.movie.MovieScreen
import hu.bbara.purefin.app.content.series.SeriesScreen
import hu.bbara.purefin.app.home.AppScreen
import hu.bbara.purefin.app.library.ui.LibraryScreen
import hu.bbara.purefin.core.data.navigation.Route
import hu.bbara.purefin.login.ui.LoginScreen
import hu.bbara.purefin.feature.shared.navigation.Route
import hu.bbara.purefin.ui.screen.library.LibraryScreen
import hu.bbara.purefin.ui.screen.login.LoginScreen
import hu.bbara.purefin.ui.screen.AppScreen
import hu.bbara.purefin.ui.screen.episode.EpisodeScreen
import hu.bbara.purefin.ui.screen.movie.MovieScreen
import hu.bbara.purefin.ui.screen.series.SeriesScreen
fun EntryProviderScope<Route>.appRouteEntryBuilder() {
entry<Route.Home> {

View File

@@ -12,7 +12,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import dagger.hilt.android.AndroidEntryPoint
import hu.bbara.purefin.core.player.viewmodel.PlayerViewModel
import hu.bbara.purefin.player.ui.PlayerScreen
import hu.bbara.purefin.ui.screen.player.PlayerScreen
import hu.bbara.purefin.ui.theme.AppTheme
@AndroidEntryPoint

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui
package hu.bbara.purefin.ui.common
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
@@ -27,7 +27,6 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.common.ui.components.PurefinSearchBar
import hu.bbara.purefin.feature.shared.search.SearchViewModel
@Composable
@@ -56,24 +55,6 @@ fun DefaultTopBar(
.fillMaxWidth(),
contentAlignment = Alignment.CenterEnd
) {
PurefinSearchBar(
onQueryChange = {
searchViewModel.search(it)
},
onSearch = {
searchViewModel.search(it)
},
onExpandedChange = { expanded ->
isSearchExpanded = expanded
if (expanded) {
isProfileMenuExpanded = false
}
},
searchResults = searchResult.value,
modifier = Modifier
.fillMaxWidth()
.padding(end = if (isSearchExpanded) 0.dp else 72.dp),
)
if (!isSearchExpanded) {
Box {
IconButton(

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.shared
package hu.bbara.purefin.ui.common.badge
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.CircleShape

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui.components
package hu.bbara.purefin.ui.common.badge
import androidx.compose.foundation.background
import androidx.compose.foundation.border

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui.components
package hu.bbara.purefin.ui.common.badge
import androidx.compose.foundation.background
import androidx.compose.foundation.border

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui.components
package hu.bbara.purefin.ui.common.bar
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui.components
package hu.bbara.purefin.ui.common.button
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui.components
package hu.bbara.purefin.ui.common.button
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui.components
package hu.bbara.purefin.ui.common.button
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -77,7 +77,7 @@ fun MediaResumeButton(
}
@Composable
private fun ButtonContent(text: String, color: androidx.compose.ui.graphics.Color) {
private fun ButtonContent(text: String, color: Color) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui.components
package hu.bbara.purefin.ui.common.button
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui
package hu.bbara.purefin.ui.common.button
import androidx.compose.foundation.layout.RowScope
import androidx.compose.material3.Button

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui
package hu.bbara.purefin.ui.common.card
import androidx.compose.foundation.background
import androidx.compose.foundation.border
@@ -23,12 +23,12 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil3.request.ImageRequest
import hu.bbara.purefin.common.ui.components.PurefinAsyncImage
import hu.bbara.purefin.common.ui.components.UnwatchedEpisodeIndicator
import hu.bbara.purefin.common.ui.components.WatchStateIndicator
import hu.bbara.purefin.feature.shared.home.PosterItem
import org.jellyfin.sdk.model.UUID
import org.jellyfin.sdk.model.api.BaseItemKind
import hu.bbara.purefin.ui.common.badge.UnwatchedEpisodeIndicator
import hu.bbara.purefin.ui.common.badge.WatchStateIndicator
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
import java.util.UUID
import hu.bbara.purefin.core.model.MediaKind
@Composable
fun PosterCard(
@@ -47,9 +47,9 @@ fun PosterCard(
fun openItem(posterItem: PosterItem) {
when (posterItem.type) {
BaseItemKind.MOVIE -> onMovieSelected(posterItem.id)
BaseItemKind.SERIES -> onSeriesSelected(posterItem.id)
BaseItemKind.EPISODE -> {
MediaKind.MOVIE -> onMovieSelected(posterItem.id)
MediaKind.SERIES -> onSeriesSelected(posterItem.id)
MediaKind.EPISODE -> {
val ep = posterItem.episode!!
onEpisodeSelected(ep.seriesId, ep.seasonId, ep.id)
}
@@ -78,7 +78,7 @@ fun PosterCard(
contentScale = ContentScale.Crop
)
when (item.type) {
BaseItemKind.MOVIE -> {
MediaKind.MOVIE -> {
val m = item.movie!!
WatchStateIndicator(
size = 28,
@@ -88,7 +88,7 @@ fun PosterCard(
started = (m.progress ?: 0.0) > 0
)
}
BaseItemKind.EPISODE -> {
MediaKind.EPISODE -> {
val ep = item.episode!!
WatchStateIndicator(
size = 28,
@@ -98,7 +98,7 @@ fun PosterCard(
started = (ep.progress ?: 0.0) > 0
)
}
BaseItemKind.SERIES -> UnwatchedEpisodeIndicator(
MediaKind.SERIES -> UnwatchedEpisodeIndicator(
size = 28,
modifier = Modifier.align(Alignment.TopEnd)
.padding(8.dp),

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.shared
package hu.bbara.purefin.ui.common.header
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui.components
package hu.bbara.purefin.ui.common.image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui.components
package hu.bbara.purefin.ui.common.image
import android.graphics.BitmapFactory
import androidx.compose.foundation.Image

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui
package hu.bbara.purefin.ui.common.media
import androidx.compose.foundation.background
import androidx.compose.foundation.border
@@ -33,8 +33,8 @@ 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.common.ui.components.PurefinAsyncImage
import hu.bbara.purefin.core.model.CastMember
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
@Composable
fun MediaMetaChip(

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui.components
package hu.bbara.purefin.ui.common.media
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
@@ -11,6 +11,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.dp
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
@Composable
fun MediaHero(

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui.components
package hu.bbara.purefin.ui.common.media
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui
package hu.bbara.purefin.ui.common.media
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui
package hu.bbara.purefin.ui.common.textfield
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui
package hu.bbara.purefin.ui.common.textfield
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.common.ui.components
package hu.bbara.purefin.ui.common.visual
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.EnterTransition

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home
package hu.bbara.purefin.ui.screen
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Collections

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home
package hu.bbara.purefin.ui.screen
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
@@ -10,8 +10,11 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.LifecycleResumeEffect
import hu.bbara.purefin.app.home.ui.HomeNavItem
import hu.bbara.purefin.feature.shared.home.AppViewModel
import hu.bbara.purefin.ui.screen.download.DownloadsScreen
import hu.bbara.purefin.ui.screen.home.HomeScreen
import hu.bbara.purefin.ui.screen.home.components.HomeNavItem
import hu.bbara.purefin.ui.screen.libraries.LibrariesScreen
@Composable
fun AppScreen(
@@ -52,7 +55,12 @@ fun AppScreen(
onMovieSelected = viewModel::onMovieSelected,
onSeriesSelected = viewModel::onSeriesSelected,
onEpisodeSelected = viewModel::onEpisodeSelected,
onLibrarySelected = { library -> viewModel.onLibrarySelected(library.id, library.name) },
onLibrarySelected = { library ->
viewModel.onLibrarySelected(
library.id,
library.name
)
},
onProfileClick = {},
onSettingsClick = {},
onLogoutClick = viewModel::logout,

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home
package hu.bbara.purefin.ui.screen.download
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
@@ -6,7 +6,8 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import hu.bbara.purefin.app.home.ui.downloads.DownloadsContent
import hu.bbara.purefin.ui.screen.download.components.DownloadsContent
import hu.bbara.purefin.ui.screen.AppBottomBar
@Composable
fun DownloadsScreen(

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.downloads
package hu.bbara.purefin.ui.screen.download.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -26,7 +26,7 @@ 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 hu.bbara.purefin.common.ui.components.PurefinAsyncImage
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
import hu.bbara.purefin.feature.shared.download.ActiveDownloadItem
@Composable

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.downloads
package hu.bbara.purefin.ui.screen.download.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
@@ -23,7 +23,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.common.ui.PosterCard
import hu.bbara.purefin.ui.common.card.PosterCard
import hu.bbara.purefin.feature.shared.download.DownloadsViewModel
@Composable

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.content.episode
package hu.bbara.purefin.ui.screen.episode
import android.Manifest
import android.os.Build
@@ -34,17 +34,20 @@ 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.common.ui.MediaMetaChip
import hu.bbara.purefin.common.ui.PurefinWaitingScreen
import hu.bbara.purefin.common.ui.components.MediaHero
import hu.bbara.purefin.ui.common.media.MediaMetaChip
import hu.bbara.purefin.ui.screen.waiting.PurefinWaitingScreen
import hu.bbara.purefin.ui.common.media.MediaHero
import hu.bbara.purefin.core.data.download.DownloadState
import hu.bbara.purefin.core.data.image.JellyfinImageHelper
import hu.bbara.purefin.core.data.navigation.EpisodeDto
import hu.bbara.purefin.core.data.navigation.LocalNavigationBackStack
import hu.bbara.purefin.core.data.navigation.Route
import hu.bbara.purefin.feature.shared.navigation.EpisodeDto
import hu.bbara.purefin.navigation.LocalNavigationBackStack
import hu.bbara.purefin.feature.shared.navigation.Route
import hu.bbara.purefin.core.model.CastMember
import hu.bbara.purefin.core.model.Episode
import hu.bbara.purefin.feature.shared.content.episode.EpisodeScreenViewModel
import hu.bbara.purefin.ui.screen.episode.components.EpisodeDetails
import hu.bbara.purefin.ui.screen.episode.components.EpisodeTopBar
import hu.bbara.purefin.ui.screen.episode.components.EpisodeTopBarShortcut
import hu.bbara.purefin.ui.theme.AppTheme
import org.jellyfin.sdk.model.api.ImageType
import java.util.UUID

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.content.episode
package hu.bbara.purefin.ui.screen.episode.components
import android.content.Intent
import androidx.compose.foundation.background
@@ -13,11 +13,8 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Add
import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.material.icons.outlined.Cast
import androidx.compose.material.icons.outlined.Close
@@ -37,12 +34,12 @@ 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.common.ui.MediaCastRow
import hu.bbara.purefin.common.ui.MediaSynopsis
import hu.bbara.purefin.common.ui.components.GhostIconButton
import hu.bbara.purefin.common.ui.components.MediaActionButton
import hu.bbara.purefin.common.ui.components.MediaPlaybackSettings
import hu.bbara.purefin.common.ui.components.MediaResumeButton
import hu.bbara.purefin.ui.common.media.MediaCastRow
import hu.bbara.purefin.ui.common.media.MediaSynopsis
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.core.data.download.DownloadState
import hu.bbara.purefin.core.model.Episode
import hu.bbara.purefin.player.PlayerActivity

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home
package hu.bbara.purefin.ui.screen.home
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
@@ -13,15 +13,16 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import hu.bbara.purefin.app.home.ui.HomeContent
import hu.bbara.purefin.app.home.ui.HomeTopBar
import hu.bbara.purefin.app.home.ui.search.HomeSearchOverlay
import hu.bbara.purefin.ui.screen.home.components.HomeContent
import hu.bbara.purefin.ui.screen.home.components.HomeTopBar
import hu.bbara.purefin.ui.screen.home.components.search.HomeSearchOverlay
import hu.bbara.purefin.feature.shared.home.ContinueWatchingItem
import hu.bbara.purefin.feature.shared.home.LibraryItem
import hu.bbara.purefin.feature.shared.home.NextUpItem
import hu.bbara.purefin.feature.shared.home.PosterItem
import hu.bbara.purefin.feature.shared.home.SuggestedItem
import org.jellyfin.sdk.model.UUID
import hu.bbara.purefin.ui.screen.AppBottomBar
import java.util.UUID
@OptIn(ExperimentalMaterial3Api::class)
@Composable

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui
package hu.bbara.purefin.ui.screen.home.components
import android.util.Log
import androidx.compose.foundation.background
@@ -22,18 +22,17 @@ import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import hu.bbara.purefin.app.home.ui.continuewatching.ContinueWatchingSection
import hu.bbara.purefin.app.home.ui.featured.SuggestionsSection
import hu.bbara.purefin.app.home.ui.library.LibraryPosterSection
import hu.bbara.purefin.app.home.ui.nextup.NextUpSection
import hu.bbara.purefin.app.home.ui.shared.HomeEmptyState
import hu.bbara.purefin.feature.shared.home.ContinueWatchingItem
import hu.bbara.purefin.feature.shared.home.LibraryItem
import hu.bbara.purefin.feature.shared.home.NextUpItem
import hu.bbara.purefin.feature.shared.home.PosterItem
import hu.bbara.purefin.feature.shared.home.SuggestedItem
import org.jellyfin.sdk.model.UUID
import org.jellyfin.sdk.model.api.BaseItemKind
import hu.bbara.purefin.ui.screen.home.components.continuewatching.ContinueWatchingSection
import hu.bbara.purefin.ui.screen.home.components.featured.SuggestionsSection
import hu.bbara.purefin.ui.screen.home.components.library.LibraryPosterSection
import hu.bbara.purefin.ui.screen.home.components.nextup.NextUpSection
import java.util.UUID
import hu.bbara.purefin.core.model.MediaKind
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -106,9 +105,9 @@ fun HomeContent(
items = suggestions,
onItemOpen = { item ->
when (item.type) {
BaseItemKind.MOVIE -> onMovieSelected(item.id)
BaseItemKind.SERIES -> onSeriesSelected(item.id)
BaseItemKind.EPISODE -> onEpisodeSelected(item.id, item.id, item.id)
MediaKind.MOVIE -> onMovieSelected(item.id)
MediaKind.SERIES -> onSeriesSelected(item.id)
MediaKind.EPISODE -> onEpisodeSelected(item.id, item.id, item.id)
else -> {
Log.e("HomeContent", "Unsupported item type: ${item.type}")
}

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.shared
package hu.bbara.purefin.ui.screen.home.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -21,6 +21,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import hu.bbara.purefin.ui.common.badge.ContentBadge
@Composable
fun HomeEmptyState(

View File

@@ -1,6 +1,6 @@
package hu.bbara.purefin.app.home.ui
package hu.bbara.purefin.ui.screen.home.components
import org.jellyfin.sdk.model.UUID
import java.util.UUID
data class HomeNavItem(
val id: UUID,

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui
package hu.bbara.purefin.ui.screen.home.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
@@ -31,7 +31,7 @@ import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import hu.bbara.purefin.common.ui.components.PurefinLogo
import hu.bbara.purefin.ui.common.image.PurefinLogo
@OptIn(ExperimentalMaterial3Api::class)
@Composable

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.continuewatching
package hu.bbara.purefin.ui.screen.home.components.continuewatching
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -23,12 +23,12 @@ 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 hu.bbara.purefin.common.ui.components.MediaProgressBar
import hu.bbara.purefin.common.ui.components.PurefinAsyncImage
import hu.bbara.purefin.ui.common.bar.MediaProgressBar
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
import hu.bbara.purefin.core.data.image.JellyfinImageHelper
import hu.bbara.purefin.feature.shared.home.ContinueWatchingItem
import org.jellyfin.sdk.model.UUID
import org.jellyfin.sdk.model.api.BaseItemKind
import java.util.UUID
import hu.bbara.purefin.core.model.MediaKind
import org.jellyfin.sdk.model.api.ImageType
@Composable
@@ -40,12 +40,12 @@ internal fun ContinueWatchingCard(
) {
val scheme = MaterialTheme.colorScheme
val supportingText = when (item.type) {
BaseItemKind.MOVIE -> listOf(
MediaKind.MOVIE -> listOf(
item.movie?.year,
item.movie?.runtime
).filterNotNull().filter { it.isNotBlank() }.joinToString("")
BaseItemKind.EPISODE -> listOf(
MediaKind.EPISODE -> listOf(
"Episode ${item.episode?.index}",
item.episode?.runtime
).filterNotNull().filter { it.isNotBlank() }.joinToString("")
@@ -53,11 +53,11 @@ internal fun ContinueWatchingCard(
else -> ""
}
val imageUrl = when (item.type) {
BaseItemKind.MOVIE -> JellyfinImageHelper.finishImageUrl(
MediaKind.MOVIE -> JellyfinImageHelper.finishImageUrl(
prefixImageUrl = item.movie?.imageUrlPrefix,
imageType = ImageType.PRIMARY
)
BaseItemKind.EPISODE -> JellyfinImageHelper.finishImageUrl(
MediaKind.EPISODE -> JellyfinImageHelper.finishImageUrl(
prefixImageUrl = item.episode?.imageUrlPrefix,
imageType = ImageType.PRIMARY
)
@@ -74,8 +74,8 @@ internal fun ContinueWatchingCard(
.fillMaxWidth()
.clickable {
when (item.type) {
BaseItemKind.MOVIE -> onMovieSelected(item.movie!!.id)
BaseItemKind.EPISODE -> {
MediaKind.MOVIE -> onMovieSelected(item.movie!!.id)
MediaKind.EPISODE -> {
val episode = item.episode!!
onEpisodeSelected(episode.seriesId, episode.seasonId, episode.id)
}

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.continuewatching
package hu.bbara.purefin.ui.screen.home.components.continuewatching
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -9,9 +9,9 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import hu.bbara.purefin.app.home.ui.shared.SectionHeader
import hu.bbara.purefin.ui.common.header.SectionHeader
import hu.bbara.purefin.feature.shared.home.ContinueWatchingItem
import org.jellyfin.sdk.model.UUID
import java.util.UUID
@Composable
fun ContinueWatchingSection(

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.featured
package hu.bbara.purefin.ui.screen.home.components.featured
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -24,8 +24,8 @@ 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 hu.bbara.purefin.common.ui.components.MediaProgressBar
import hu.bbara.purefin.common.ui.components.PurefinAsyncImage
import hu.bbara.purefin.ui.common.bar.MediaProgressBar
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
import hu.bbara.purefin.feature.shared.home.SuggestedItem
@Composable

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.featured
package hu.bbara.purefin.ui.screen.home.components.featured
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.animateDpAsState

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.library
package hu.bbara.purefin.ui.screen.home.components.library
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -23,12 +23,12 @@ 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 hu.bbara.purefin.common.ui.components.PurefinAsyncImage
import hu.bbara.purefin.common.ui.components.UnwatchedEpisodeIndicator
import hu.bbara.purefin.common.ui.components.WatchStateIndicator
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
import hu.bbara.purefin.ui.common.badge.UnwatchedEpisodeIndicator
import hu.bbara.purefin.ui.common.badge.WatchStateIndicator
import hu.bbara.purefin.feature.shared.home.PosterItem
import org.jellyfin.sdk.model.UUID
import org.jellyfin.sdk.model.api.BaseItemKind
import java.util.UUID
import hu.bbara.purefin.core.model.MediaKind
@Composable
internal fun HomeBrowseCard(
@@ -40,16 +40,16 @@ internal fun HomeBrowseCard(
) {
val scheme = MaterialTheme.colorScheme
val supportingText = when (item.type) {
BaseItemKind.MOVIE -> listOf(
MediaKind.MOVIE -> listOf(
item.movie?.year,
item.movie?.runtime
).filterNotNull().filter { it.isNotBlank() }.joinToString("")
BaseItemKind.SERIES -> item.series!!.let { series ->
MediaKind.SERIES -> item.series!!.let { series ->
if (series.seasonCount == 1) "1 season" else "${series.seasonCount} seasons"
}
BaseItemKind.EPISODE -> listOf(
MediaKind.EPISODE -> listOf(
"Episode ${item.episode?.index}",
item.episode?.runtime
).filterNotNull().filter { it.isNotBlank() }.joinToString("")
@@ -67,9 +67,9 @@ internal fun HomeBrowseCard(
.fillMaxWidth()
.clickable {
when (item.type) {
BaseItemKind.MOVIE -> onMovieSelected(item.id)
BaseItemKind.SERIES -> onSeriesSelected(item.id)
BaseItemKind.EPISODE -> {
MediaKind.MOVIE -> onMovieSelected(item.id)
MediaKind.SERIES -> onSeriesSelected(item.id)
MediaKind.EPISODE -> {
val episode = item.episode!!
onEpisodeSelected(episode.seriesId, episode.seasonId, episode.id)
}
@@ -92,7 +92,7 @@ internal fun HomeBrowseCard(
contentScale = ContentScale.Crop
)
when (item.type) {
BaseItemKind.MOVIE -> {
MediaKind.MOVIE -> {
val movie = item.movie!!
WatchStateIndicator(
size = 28,
@@ -104,7 +104,7 @@ internal fun HomeBrowseCard(
)
}
BaseItemKind.EPISODE -> {
MediaKind.EPISODE -> {
val episode = item.episode!!
WatchStateIndicator(
size = 28,
@@ -116,7 +116,7 @@ internal fun HomeBrowseCard(
)
}
BaseItemKind.SERIES -> {
MediaKind.SERIES -> {
UnwatchedEpisodeIndicator(
size = 28,
modifier = Modifier

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.library
package hu.bbara.purefin.ui.screen.home.components.library
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -9,10 +9,10 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import hu.bbara.purefin.app.home.ui.shared.SectionHeader
import hu.bbara.purefin.feature.shared.home.LibraryItem
import hu.bbara.purefin.feature.shared.home.PosterItem
import org.jellyfin.sdk.model.UUID
import hu.bbara.purefin.ui.common.header.SectionHeader
import java.util.UUID
@Composable
fun LibraryPosterSection(

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.nextup
package hu.bbara.purefin.ui.screen.home.components.nextup
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -22,10 +22,10 @@ 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 hu.bbara.purefin.common.ui.components.PurefinAsyncImage
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
import hu.bbara.purefin.core.data.image.JellyfinImageHelper
import hu.bbara.purefin.feature.shared.home.NextUpItem
import org.jellyfin.sdk.model.UUID
import java.util.UUID
import org.jellyfin.sdk.model.api.ImageType
@Composable

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.nextup
package hu.bbara.purefin.ui.screen.home.components.nextup
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -9,9 +9,9 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import hu.bbara.purefin.app.home.ui.shared.SectionHeader
import hu.bbara.purefin.ui.common.header.SectionHeader
import hu.bbara.purefin.feature.shared.home.NextUpItem
import org.jellyfin.sdk.model.UUID
import java.util.UUID
@Composable
fun NextUpSection(

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.search
package hu.bbara.purefin.ui.screen.home.components.search
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
@@ -36,8 +36,8 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.feature.shared.search.SearchViewModel
import org.jellyfin.sdk.model.UUID
import org.jellyfin.sdk.model.api.BaseItemKind
import java.util.UUID
import hu.bbara.purefin.core.model.MediaKind
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -142,8 +142,8 @@ fun HomeSearchOverlay(
item = item,
onClick = {
when (item.type) {
BaseItemKind.MOVIE -> onMovieSelected(item.id)
BaseItemKind.SERIES -> onSeriesSelected(item.id)
MediaKind.MOVIE -> onMovieSelected(item.id)
MediaKind.SERIES -> onSeriesSelected(item.id)
else -> Unit
}
}

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.search
package hu.bbara.purefin.ui.screen.home.components.search
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
@@ -17,9 +17,9 @@ 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 hu.bbara.purefin.common.ui.components.PurefinAsyncImage
import hu.bbara.purefin.core.model.SearchResult
import org.jellyfin.sdk.model.api.BaseItemKind
import hu.bbara.purefin.core.model.MediaKind
import hu.bbara.purefin.feature.shared.search.SearchResult
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
@Composable
internal fun HomeSearchResultCard(
@@ -59,8 +59,8 @@ internal fun HomeSearchResultCard(
)
Text(
text = when (item.type) {
BaseItemKind.MOVIE -> "Movie"
BaseItemKind.SERIES -> "Series"
MediaKind.MOVIE -> "Movie"
MediaKind.SERIES -> "Series"
else -> "Title"
},
style = MaterialTheme.typography.labelMedium,

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.search
package hu.bbara.purefin.ui.screen.home.components.search
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home
package hu.bbara.purefin.ui.screen.libraries
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
@@ -6,9 +6,10 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import hu.bbara.purefin.app.home.ui.DefaultTopBar
import hu.bbara.purefin.app.home.ui.HomeNavItem
import hu.bbara.purefin.app.home.ui.libraries.LibrariesContent
import hu.bbara.purefin.ui.common.DefaultTopBar
import hu.bbara.purefin.ui.screen.home.components.HomeNavItem
import hu.bbara.purefin.ui.screen.AppBottomBar
import hu.bbara.purefin.ui.screen.libraries.components.LibrariesContent
@Composable
fun LibrariesScreen(

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.libraries
package hu.bbara.purefin.ui.screen.libraries.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
@@ -9,7 +9,7 @@ import androidx.compose.foundation.lazy.grid.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import hu.bbara.purefin.app.home.ui.HomeNavItem
import hu.bbara.purefin.ui.screen.home.components.HomeNavItem
@Composable
fun LibrariesContent(

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.home.ui.libraries
package hu.bbara.purefin.ui.screen.libraries.components
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
@@ -11,8 +11,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import hu.bbara.purefin.app.home.ui.HomeNavItem
import hu.bbara.purefin.common.ui.components.PurefinAsyncImage
import hu.bbara.purefin.ui.screen.home.components.HomeNavItem
import hu.bbara.purefin.ui.common.image.PurefinAsyncImage
@Composable
fun LibraryListItem(

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.library.ui
package hu.bbara.purefin.ui.screen.library
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
@@ -21,9 +21,9 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.common.ui.PosterCard
import hu.bbara.purefin.common.ui.components.PurefinIconButton
import hu.bbara.purefin.core.data.navigation.LibraryDto
import hu.bbara.purefin.ui.common.card.PosterCard
import hu.bbara.purefin.ui.common.button.PurefinIconButton
import hu.bbara.purefin.feature.shared.navigation.LibraryDto
import hu.bbara.purefin.feature.shared.home.PosterItem
import hu.bbara.purefin.feature.shared.library.LibraryViewModel

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.login.ui
package hu.bbara.purefin.ui.screen.login
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
@@ -37,10 +37,10 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.common.ui.PurefinComplexTextField
import hu.bbara.purefin.common.ui.PurefinPasswordField
import hu.bbara.purefin.common.ui.PurefinTextButton
import hu.bbara.purefin.common.ui.PurefinWaitingScreen
import hu.bbara.purefin.ui.common.textfield.PurefinComplexTextField
import hu.bbara.purefin.ui.common.textfield.PurefinPasswordField
import hu.bbara.purefin.ui.common.button.PurefinTextButton
import hu.bbara.purefin.ui.screen.waiting.PurefinWaitingScreen
import hu.bbara.purefin.feature.shared.login.LoginViewModel
import kotlinx.coroutines.launch

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.content.movie
package hu.bbara.purefin.ui.screen.movie
import android.Manifest
import android.os.Build
@@ -32,15 +32,17 @@ 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.common.ui.MediaMetaChip
import hu.bbara.purefin.common.ui.PurefinWaitingScreen
import hu.bbara.purefin.common.ui.components.MediaHero
import hu.bbara.purefin.ui.common.media.MediaMetaChip
import hu.bbara.purefin.ui.screen.waiting.PurefinWaitingScreen
import hu.bbara.purefin.ui.common.media.MediaHero
import hu.bbara.purefin.core.data.download.DownloadState
import hu.bbara.purefin.core.data.image.JellyfinImageHelper
import hu.bbara.purefin.core.data.navigation.MovieDto
import hu.bbara.purefin.feature.shared.navigation.MovieDto
import hu.bbara.purefin.core.model.CastMember
import hu.bbara.purefin.core.model.Movie
import hu.bbara.purefin.feature.shared.content.movie.MovieScreenViewModel
import hu.bbara.purefin.ui.screen.movie.components.MovieDetails
import hu.bbara.purefin.ui.screen.movie.components.MovieTopBar
import hu.bbara.purefin.ui.theme.AppTheme
import org.jellyfin.sdk.model.api.ImageType
import java.util.UUID

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.app.content.movie
package hu.bbara.purefin.ui.screen.movie.components
import android.content.Intent
import androidx.compose.foundation.layout.Arrangement
@@ -29,12 +29,12 @@ 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.common.ui.MediaCastRow
import hu.bbara.purefin.common.ui.MediaSynopsis
import hu.bbara.purefin.common.ui.components.GhostIconButton
import hu.bbara.purefin.common.ui.components.MediaActionButton
import hu.bbara.purefin.common.ui.components.MediaPlaybackSettings
import hu.bbara.purefin.common.ui.components.MediaResumeButton
import hu.bbara.purefin.ui.common.media.MediaCastRow
import hu.bbara.purefin.ui.common.media.MediaSynopsis
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.core.data.download.DownloadState
import hu.bbara.purefin.core.model.Movie
import hu.bbara.purefin.player.PlayerActivity

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.player.ui
package hu.bbara.purefin.ui.screen.player
import android.app.Activity
import android.content.Context
@@ -37,16 +37,16 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.media3.common.util.UnstableApi
import androidx.media3.ui.AspectRatioFrameLayout
import androidx.media3.ui.PlayerView
import hu.bbara.purefin.common.ui.components.EmptyValueTimedVisibility
import hu.bbara.purefin.common.ui.components.ValueChangeTimedVisibility
import hu.bbara.purefin.core.player.viewmodel.PlayerViewModel
import hu.bbara.purefin.player.ui.components.PersistentOverlayContainer
import hu.bbara.purefin.player.ui.components.PlayerAdjustmentIndicator
import hu.bbara.purefin.player.ui.components.PlayerControlsOverlay
import hu.bbara.purefin.player.ui.components.PlayerGesturesLayer
import hu.bbara.purefin.player.ui.components.PlayerLoadingErrorEndCard
import hu.bbara.purefin.player.ui.components.PlayerQueuePanel
import hu.bbara.purefin.player.ui.components.rememberPersistentOverlayController
import hu.bbara.purefin.ui.common.visual.EmptyValueTimedVisibility
import hu.bbara.purefin.ui.common.visual.ValueChangeTimedVisibility
import hu.bbara.purefin.ui.screen.player.components.PersistentOverlayContainer
import hu.bbara.purefin.ui.screen.player.components.PlayerAdjustmentIndicator
import hu.bbara.purefin.ui.screen.player.components.PlayerControlsOverlay
import hu.bbara.purefin.ui.screen.player.components.PlayerGesturesLayer
import hu.bbara.purefin.ui.screen.player.components.PlayerLoadingErrorEndCard
import hu.bbara.purefin.ui.screen.player.components.PlayerQueuePanel
import hu.bbara.purefin.ui.screen.player.components.rememberPersistentOverlayController
import kotlin.math.abs
import kotlin.math.roundToInt
@@ -101,7 +101,7 @@ fun PlayerScreen(
onTap = { viewModel.toggleControlsVisibility() },
onDoubleTapRight = { viewModel.seekBy(30_000) },
onDoubleTapLeft = { viewModel.seekBy(-10_000) },
onDoubleTapCenter = {viewModel.togglePlayPause()},
onDoubleTapCenter = { viewModel.togglePlayPause() },
onVerticalDragLeft = { delta ->
val diff = (-delta / 800f)
brightness = (brightness + diff).coerceIn(0f, 1f)

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.player.ui.components
package hu.bbara.purefin.ui.screen.player.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn

View File

@@ -1,4 +1,4 @@
package hu.bbara.purefin.player.ui.components
package hu.bbara.purefin.ui.screen.player.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box

Some files were not shown because too many files have changed in this diff Show More