diff --git a/Jetcaster/app/build.gradle.kts b/Jetcaster/app/build.gradle.kts index 311ea2a67e..eae707a950 100644 --- a/Jetcaster/app/build.gradle.kts +++ b/Jetcaster/app/build.gradle.kts @@ -85,6 +85,7 @@ android { } dependencies { + implementation(project(":core:model")) val composeBom = platform(libs.androidx.compose.bom) implementation(composeBom) androidTestImplementation(composeBom) diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/Home.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/Home.kt index d84ef9bf58..dee51f23da 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/Home.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/Home.kt @@ -108,13 +108,13 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.window.core.layout.WindowHeightSizeClass import coil.compose.AsyncImage import com.example.jetcaster.R -import com.example.jetcaster.core.data.model.CategoryInfo -import com.example.jetcaster.core.data.model.EpisodeInfo -import com.example.jetcaster.core.data.model.FilterableCategoriesModel -import com.example.jetcaster.core.data.model.LibraryInfo -import com.example.jetcaster.core.data.model.PlayerEpisode -import com.example.jetcaster.core.data.model.PodcastCategoryFilterResult -import com.example.jetcaster.core.data.model.PodcastInfo +import com.example.jetcaster.core.model.CategoryInfo +import com.example.jetcaster.core.model.EpisodeInfo +import com.example.jetcaster.core.model.FilterableCategoriesModel +import com.example.jetcaster.core.model.LibraryInfo +import com.example.jetcaster.core.model.PlayerEpisode +import com.example.jetcaster.core.model.PodcastCategoryFilterResult +import com.example.jetcaster.core.model.PodcastInfo import com.example.jetcaster.ui.home.discover.discoverItems import com.example.jetcaster.ui.home.library.libraryItems import com.example.jetcaster.ui.podcast.PodcastDetailsScreen diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt index bfeddd3e28..da80232a9b 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt @@ -19,18 +19,18 @@ package com.example.jetcaster.ui.home import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.example.jetcaster.core.data.database.model.EpisodeToPodcast +import com.example.jetcaster.core.data.database.model.asExternalModel import com.example.jetcaster.core.data.domain.FilterableCategoriesUseCase import com.example.jetcaster.core.data.domain.PodcastCategoryFilterUseCase -import com.example.jetcaster.core.data.model.CategoryInfo -import com.example.jetcaster.core.data.model.FilterableCategoriesModel -import com.example.jetcaster.core.data.model.LibraryInfo -import com.example.jetcaster.core.data.model.PlayerEpisode -import com.example.jetcaster.core.data.model.PodcastCategoryFilterResult -import com.example.jetcaster.core.data.model.PodcastInfo -import com.example.jetcaster.core.data.model.asExternalModel import com.example.jetcaster.core.data.repository.EpisodeStore import com.example.jetcaster.core.data.repository.PodcastStore import com.example.jetcaster.core.data.repository.PodcastsRepository +import com.example.jetcaster.core.model.CategoryInfo +import com.example.jetcaster.core.model.FilterableCategoriesModel +import com.example.jetcaster.core.model.LibraryInfo +import com.example.jetcaster.core.model.PlayerEpisode +import com.example.jetcaster.core.model.PodcastCategoryFilterResult +import com.example.jetcaster.core.model.PodcastInfo import com.example.jetcaster.core.player.EpisodePlayer import com.example.jetcaster.core.util.combine import dagger.hilt.android.lifecycle.HiltViewModel diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/PreviewData.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/PreviewData.kt index 5030d56866..f4ef9e6df5 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/PreviewData.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/PreviewData.kt @@ -16,10 +16,10 @@ package com.example.jetcaster.ui.home -import com.example.jetcaster.core.data.model.CategoryInfo -import com.example.jetcaster.core.data.model.EpisodeInfo -import com.example.jetcaster.core.data.model.PodcastCategoryEpisode -import com.example.jetcaster.core.data.model.PodcastInfo +import com.example.jetcaster.core.model.CategoryInfo +import com.example.jetcaster.core.model.EpisodeInfo +import com.example.jetcaster.core.model.PodcastCategoryEpisode +import com.example.jetcaster.core.model.PodcastInfo import java.time.OffsetDateTime import java.time.ZoneOffset diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/category/PodcastCategory.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/category/PodcastCategory.kt index 857a5572d1..29c6e15115 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/category/PodcastCategory.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/category/PodcastCategory.kt @@ -46,10 +46,10 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil.compose.AsyncImage import coil.request.ImageRequest -import com.example.jetcaster.core.data.model.EpisodeInfo -import com.example.jetcaster.core.data.model.PlayerEpisode -import com.example.jetcaster.core.data.model.PodcastCategoryFilterResult -import com.example.jetcaster.core.data.model.PodcastInfo +import com.example.jetcaster.core.model.EpisodeInfo +import com.example.jetcaster.core.model.PlayerEpisode +import com.example.jetcaster.core.model.PodcastCategoryFilterResult +import com.example.jetcaster.core.model.PodcastInfo import com.example.jetcaster.designsystem.theme.Keyline1 import com.example.jetcaster.ui.home.PreviewEpisodes import com.example.jetcaster.ui.home.PreviewPodcasts diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/discover/Discover.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/discover/Discover.kt index 835fb03441..f8b8884cf9 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/discover/Discover.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/discover/Discover.kt @@ -38,12 +38,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.example.jetcaster.R -import com.example.jetcaster.core.data.model.CategoryInfo -import com.example.jetcaster.core.data.model.EpisodeInfo -import com.example.jetcaster.core.data.model.FilterableCategoriesModel -import com.example.jetcaster.core.data.model.PlayerEpisode -import com.example.jetcaster.core.data.model.PodcastCategoryFilterResult -import com.example.jetcaster.core.data.model.PodcastInfo +import com.example.jetcaster.core.model.CategoryInfo +import com.example.jetcaster.core.model.EpisodeInfo +import com.example.jetcaster.core.model.FilterableCategoriesModel +import com.example.jetcaster.core.model.PlayerEpisode +import com.example.jetcaster.core.model.PodcastCategoryFilterResult +import com.example.jetcaster.core.model.PodcastInfo import com.example.jetcaster.designsystem.theme.Keyline1 import com.example.jetcaster.ui.home.category.podcastCategory import com.example.jetcaster.util.fullWidthItem @@ -183,7 +183,9 @@ private fun ChoiceChipContent( Icon( imageVector = Icons.Default.Check, contentDescription = stringResource(id = R.string.cd_selected_category), - modifier = Modifier.height(18.dp).padding(end = 8.dp) + modifier = Modifier + .height(18.dp) + .padding(end = 8.dp) ) } Text( diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/library/Library.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/library/Library.kt index d33934376b..f425042ae4 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/library/Library.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/library/Library.kt @@ -28,9 +28,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.example.jetcaster.R -import com.example.jetcaster.core.data.model.EpisodeInfo -import com.example.jetcaster.core.data.model.LibraryInfo -import com.example.jetcaster.core.data.model.PlayerEpisode +import com.example.jetcaster.core.model.EpisodeInfo +import com.example.jetcaster.core.model.LibraryInfo +import com.example.jetcaster.core.model.PlayerEpisode import com.example.jetcaster.designsystem.theme.Keyline1 import com.example.jetcaster.ui.shared.EpisodeListItem import com.example.jetcaster.util.fullWidthItem diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/player/PlayerScreen.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/player/PlayerScreen.kt index 93c7b8e0c7..67c74d98a7 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/player/PlayerScreen.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/player/PlayerScreen.kt @@ -67,6 +67,7 @@ import androidx.compose.runtime.DisposableEffect 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.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext @@ -87,8 +88,9 @@ import androidx.window.layout.FoldingFeature import coil.compose.AsyncImage import coil.request.ImageRequest import com.example.jetcaster.R -import com.example.jetcaster.core.data.model.PlayerEpisode +import com.example.jetcaster.core.model.PlayerEpisode import com.example.jetcaster.core.player.EpisodePlayerState +import com.example.jetcaster.designsystem.component.ImageBackgroundColorScrim import com.example.jetcaster.ui.theme.JetcasterTheme import com.example.jetcaster.util.isBookPosture import com.example.jetcaster.util.isSeparatingPosture @@ -150,7 +152,7 @@ private fun PlayerScreen( } Surface(modifier) { if (uiState.episodePlayerState.currentEpisode != null) { - PlayerContent( + PlayerContentWithBackground( uiState, windowSizeClass, displayFeatures, @@ -168,6 +170,52 @@ private fun PlayerScreen( } } +@Composable +private fun PlayerBackground( + episode: PlayerEpisode?, + modifier: Modifier, +) { + ImageBackgroundColorScrim( + url = episode?.podcastImageUrl, + color = Color.Black.copy(alpha = 0.68f), + modifier = modifier, + ) +} + +@Composable +fun PlayerContentWithBackground( + uiState: PlayerUiState, + windowSizeClass: WindowSizeClass, + displayFeatures: List, + onBackPress: () -> Unit, + onPlayPress: () -> Unit, + onPausePress: () -> Unit, + onAdvanceBy: (Duration) -> Unit, + onRewindBy: (Duration) -> Unit, + onNext: () -> Unit, + onPrevious: () -> Unit, + modifier: Modifier = Modifier +) { + Box(modifier = modifier, contentAlignment = Alignment.Center) { + PlayerBackground( + episode = uiState.episodePlayerState.currentEpisode, + modifier = Modifier.fillMaxSize() + ) + PlayerContent( + uiState, + windowSizeClass, + displayFeatures, + onBackPress, + onPlayPress, + onPausePress, + onAdvanceBy, + onRewindBy, + onNext, + onPrevious, + ) + } +} + @Composable fun PlayerContent( uiState: PlayerUiState, diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/player/PlayerViewModel.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/player/PlayerViewModel.kt index 7748a10c20..73804e2177 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/player/PlayerViewModel.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/player/PlayerViewModel.kt @@ -23,7 +23,7 @@ import androidx.compose.runtime.setValue import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.example.jetcaster.core.data.model.toPlayerEpisode +import com.example.jetcaster.core.data.database.model.toPlayerEpisode import com.example.jetcaster.core.data.repository.EpisodeStore import com.example.jetcaster.core.player.EpisodePlayer import com.example.jetcaster.core.player.EpisodePlayerState diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/podcast/PodcastDetailsScreen.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/podcast/PodcastDetailsScreen.kt index 0237a4eb1d..f8db646b71 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/podcast/PodcastDetailsScreen.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/podcast/PodcastDetailsScreen.kt @@ -65,9 +65,9 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import coil.compose.AsyncImage import coil.request.ImageRequest import com.example.jetcaster.R -import com.example.jetcaster.core.data.model.EpisodeInfo -import com.example.jetcaster.core.data.model.PlayerEpisode -import com.example.jetcaster.core.data.model.PodcastInfo +import com.example.jetcaster.core.model.EpisodeInfo +import com.example.jetcaster.core.model.PlayerEpisode +import com.example.jetcaster.core.model.PodcastInfo import com.example.jetcaster.designsystem.theme.Keyline1 import com.example.jetcaster.ui.home.PreviewEpisodes import com.example.jetcaster.ui.home.PreviewPodcasts diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/podcast/PodcastDetailsViewModel.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/podcast/PodcastDetailsViewModel.kt index 22c78fa9c9..858289bc0d 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/podcast/PodcastDetailsViewModel.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/podcast/PodcastDetailsViewModel.kt @@ -19,12 +19,12 @@ package com.example.jetcaster.ui.podcast import android.net.Uri import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.example.jetcaster.core.data.model.EpisodeInfo -import com.example.jetcaster.core.data.model.PlayerEpisode -import com.example.jetcaster.core.data.model.PodcastInfo -import com.example.jetcaster.core.data.model.asExternalModel +import com.example.jetcaster.core.data.database.model.asExternalModel import com.example.jetcaster.core.data.repository.EpisodeStore import com.example.jetcaster.core.data.repository.PodcastStore +import com.example.jetcaster.core.model.EpisodeInfo +import com.example.jetcaster.core.model.PlayerEpisode +import com.example.jetcaster.core.model.PodcastInfo import com.example.jetcaster.core.player.EpisodePlayer import dagger.assisted.Assisted import dagger.assisted.AssistedFactory diff --git a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/shared/EpisodeListItem.kt b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/shared/EpisodeListItem.kt index 693be0136a..bafb863074 100644 --- a/Jetcaster/app/src/main/java/com/example/jetcaster/ui/shared/EpisodeListItem.kt +++ b/Jetcaster/app/src/main/java/com/example/jetcaster/ui/shared/EpisodeListItem.kt @@ -55,9 +55,9 @@ import androidx.compose.ui.unit.dp import coil.compose.AsyncImage import coil.request.ImageRequest import com.example.jetcaster.R -import com.example.jetcaster.core.data.model.EpisodeInfo -import com.example.jetcaster.core.data.model.PlayerEpisode -import com.example.jetcaster.core.data.model.PodcastInfo +import com.example.jetcaster.core.model.EpisodeInfo +import com.example.jetcaster.core.model.PlayerEpisode +import com.example.jetcaster.core.model.PodcastInfo import com.example.jetcaster.ui.home.PreviewEpisodes import com.example.jetcaster.ui.home.PreviewPodcasts import com.example.jetcaster.ui.theme.JetcasterTheme diff --git a/Jetcaster/core/build.gradle.kts b/Jetcaster/core/build.gradle.kts index 2457fad326..402d1e1d41 100644 --- a/Jetcaster/core/build.gradle.kts +++ b/Jetcaster/core/build.gradle.kts @@ -38,6 +38,7 @@ dependencies { implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) implementation(libs.androidx.compose.runtime) + implementation(project(":core:model")) // Image loading implementation(libs.coil.kt.compose) diff --git a/Jetcaster/core/model/.gitignore b/Jetcaster/core/model/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/Jetcaster/core/model/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/Jetcaster/core/model/build.gradle.kts b/Jetcaster/core/model/build.gradle.kts new file mode 100644 index 0000000000..2e4dd2b851 --- /dev/null +++ b/Jetcaster/core/model/build.gradle.kts @@ -0,0 +1,35 @@ +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) +} + +android { + compileSdk = libs.versions.compileSdk.get().toInt() + namespace = "com.example.jetcaster.core.model" + + defaultConfig { + minSdk = libs.versions.minSdk.get().toInt() + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + isCoreLibraryDesugaringEnabled = true + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } +} + +dependencies { + coreLibraryDesugaring(libs.core.jdk.desugaring) +} diff --git a/Jetcaster/core/model/consumer-rules.pro b/Jetcaster/core/model/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Jetcaster/core/model/proguard-rules.pro b/Jetcaster/core/model/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/Jetcaster/core/model/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/Jetcaster/core/model/src/main/AndroidManifest.xml b/Jetcaster/core/model/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..8bdb7e14b3 --- /dev/null +++ b/Jetcaster/core/model/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/CategoryInfo.kt b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/CategoryInfo.kt similarity index 76% rename from Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/CategoryInfo.kt rename to Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/CategoryInfo.kt index 766ae3cc0f..9ebf1a9577 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/CategoryInfo.kt +++ b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/CategoryInfo.kt @@ -14,17 +14,9 @@ * limitations under the License. */ -package com.example.jetcaster.core.data.model - -import com.example.jetcaster.core.data.database.model.Category +package com.example.jetcaster.core.model data class CategoryInfo( val id: Long, val name: String ) - -fun Category.asExternalModel() = - CategoryInfo( - id = id, - name = name - ) diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/EpisodeInfo.kt b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/EpisodeInfo.kt similarity index 72% rename from Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/EpisodeInfo.kt rename to Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/EpisodeInfo.kt index 4f184f7a6c..88b2d1f158 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/EpisodeInfo.kt +++ b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/EpisodeInfo.kt @@ -14,9 +14,8 @@ * limitations under the License. */ -package com.example.jetcaster.core.data.model +package com.example.jetcaster.core.model -import com.example.jetcaster.core.data.database.model.Episode import java.time.Duration import java.time.OffsetDateTime @@ -32,14 +31,3 @@ data class EpisodeInfo( val published: OffsetDateTime = OffsetDateTime.MIN, val duration: Duration? = null, ) - -fun Episode.asExternalModel(): EpisodeInfo = - EpisodeInfo( - uri = uri, - title = title, - subTitle = subtitle ?: "", - summary = summary ?: "", - author = author ?: "", - published = published, - duration = duration, - ) diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/FilterableCategoriesModel.kt b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/FilterableCategoriesModel.kt similarity index 95% rename from Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/FilterableCategoriesModel.kt rename to Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/FilterableCategoriesModel.kt index ca02e7fb56..4cca646940 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/FilterableCategoriesModel.kt +++ b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/FilterableCategoriesModel.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.example.jetcaster.core.data.model +package com.example.jetcaster.core.model /** * Model holding a list of categories and a selected category in the collection diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/LibraryInfo.kt b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/LibraryInfo.kt similarity index 94% rename from Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/LibraryInfo.kt rename to Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/LibraryInfo.kt index 7a1a3df058..a502a0bb29 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/LibraryInfo.kt +++ b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/LibraryInfo.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.example.jetcaster.core.data.model +package com.example.jetcaster.core.model data class LibraryInfo( val podcast: PodcastInfo? = null, diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/PlayerEpisode.kt b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PlayerEpisode.kt similarity index 73% rename from Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/PlayerEpisode.kt rename to Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PlayerEpisode.kt index e7305e5b5e..7b4c7d4ad2 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/PlayerEpisode.kt +++ b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PlayerEpisode.kt @@ -14,9 +14,8 @@ * limitations under the License. */ -package com.example.jetcaster.core.data.model +package com.example.jetcaster.core.model -import com.example.jetcaster.core.data.database.model.EpisodeToPodcast import java.time.Duration import java.time.OffsetDateTime @@ -46,16 +45,3 @@ data class PlayerEpisode( uri = episodeInfo.uri ) } - -fun EpisodeToPodcast.toPlayerEpisode(): PlayerEpisode = - PlayerEpisode( - uri = episode.uri, - title = episode.title, - subTitle = episode.subtitle ?: "", - published = episode.published, - duration = episode.duration, - podcastName = podcast.title, - author = episode.author ?: podcast.author ?: "", - summary = episode.summary ?: "", - podcastImageUrl = podcast.imageUrl ?: "", - ) diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/PodcastCategoryFilterResult.kt b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastCategoryFilterResult.kt similarity index 75% rename from Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/PodcastCategoryFilterResult.kt rename to Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastCategoryFilterResult.kt index dbc39daddf..e1d27306ed 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/PodcastCategoryFilterResult.kt +++ b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastCategoryFilterResult.kt @@ -14,9 +14,7 @@ * limitations under the License. */ -package com.example.jetcaster.core.data.model - -import com.example.jetcaster.core.data.database.model.EpisodeToPodcast +package com.example.jetcaster.core.model /** * A model holding top podcasts and matching episodes when filtering based on a category. @@ -30,9 +28,3 @@ data class PodcastCategoryEpisode( val episode: EpisodeInfo, val podcast: PodcastInfo, ) - -fun EpisodeToPodcast.asPodcastCategoryEpisode(): PodcastCategoryEpisode = - PodcastCategoryEpisode( - episode = episode.asExternalModel(), - podcast = podcast.asExternalModel(), - ) diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/PodcastInfo.kt b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastInfo.kt similarity index 61% rename from Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/PodcastInfo.kt rename to Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastInfo.kt index 147a840944..5aced90656 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/PodcastInfo.kt +++ b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastInfo.kt @@ -14,10 +14,8 @@ * limitations under the License. */ -package com.example.jetcaster.core.data.model +package com.example.jetcaster.core.model -import com.example.jetcaster.core.data.database.model.Podcast -import com.example.jetcaster.core.data.database.model.PodcastWithExtraInfo import java.time.OffsetDateTime /** @@ -32,18 +30,3 @@ data class PodcastInfo( val isSubscribed: Boolean? = null, val lastEpisodeDate: OffsetDateTime? = null, ) - -fun Podcast.asExternalModel(): PodcastInfo = - PodcastInfo( - uri = this.uri, - title = this.title, - author = this.author ?: "", - imageUrl = this.imageUrl ?: "", - description = this.description ?: "", - ) - -fun PodcastWithExtraInfo.asExternalModel(): PodcastInfo = - this.podcast.asExternalModel().copy( - isSubscribed = isFollowed, - lastEpisodeDate = lastEpisodeDate, - ) diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/Category.kt b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/Category.kt index 4dff2871ef..4b90f4b1c8 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/Category.kt +++ b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/Category.kt @@ -21,6 +21,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.Index import androidx.room.PrimaryKey +import com.example.jetcaster.core.model.CategoryInfo @Entity( tableName = "categories", @@ -33,3 +34,9 @@ data class Category( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Long = 0, @ColumnInfo(name = "name") val name: String ) + +fun Category.asExternalModel() = + CategoryInfo( + id = id, + name = name + ) diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/Episode.kt b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/Episode.kt index 6a035d9646..cf9ae998e5 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/Episode.kt +++ b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/Episode.kt @@ -22,6 +22,7 @@ import androidx.room.Entity import androidx.room.ForeignKey import androidx.room.Index import androidx.room.PrimaryKey +import com.example.jetcaster.core.model.EpisodeInfo import java.time.Duration import java.time.OffsetDateTime @@ -52,3 +53,14 @@ data class Episode( @ColumnInfo(name = "published") val published: OffsetDateTime, @ColumnInfo(name = "duration") val duration: Duration? = null ) + +fun Episode.asExternalModel(): EpisodeInfo = + EpisodeInfo( + uri = uri, + title = title, + subTitle = subtitle ?: "", + summary = summary ?: "", + author = author ?: "", + published = published, + duration = duration, + ) diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/EpisodeToPodcast.kt b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/EpisodeToPodcast.kt index 7945f20316..4646849aca 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/EpisodeToPodcast.kt +++ b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/EpisodeToPodcast.kt @@ -19,6 +19,8 @@ package com.example.jetcaster.core.data.database.model import androidx.room.Embedded import androidx.room.Ignore import androidx.room.Relation +import com.example.jetcaster.core.model.PlayerEpisode +import com.example.jetcaster.core.model.PodcastCategoryEpisode import java.util.Objects class EpisodeToPodcast { @@ -46,3 +48,22 @@ class EpisodeToPodcast { override fun hashCode(): Int = Objects.hash(episode, _podcasts) } + +fun EpisodeToPodcast.toPlayerEpisode(): PlayerEpisode = + PlayerEpisode( + uri = episode.uri, + title = episode.title, + subTitle = episode.subtitle ?: "", + published = episode.published, + duration = episode.duration, + podcastName = podcast.title, + author = episode.author ?: podcast.author ?: "", + summary = episode.summary ?: "", + podcastImageUrl = podcast.imageUrl ?: "", + ) + +fun EpisodeToPodcast.asPodcastCategoryEpisode(): PodcastCategoryEpisode = + PodcastCategoryEpisode( + episode = episode.asExternalModel(), + podcast = podcast.asExternalModel(), + ) diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/Podcast.kt b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/Podcast.kt index 1d86f31f91..642759db3c 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/Podcast.kt +++ b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/Podcast.kt @@ -21,6 +21,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.Index import androidx.room.PrimaryKey +import com.example.jetcaster.core.model.PodcastInfo @Entity( tableName = "podcasts", @@ -37,3 +38,12 @@ data class Podcast( @ColumnInfo(name = "image_url") val imageUrl: String? = null, @ColumnInfo(name = "copyright") val copyright: String? = null ) + +fun Podcast.asExternalModel(): PodcastInfo = + PodcastInfo( + uri = this.uri, + title = this.title, + author = this.author ?: "", + imageUrl = this.imageUrl ?: "", + description = this.description ?: "", + ) diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/PodcastWithExtraInfo.kt b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/PodcastWithExtraInfo.kt index 8794a46e47..e76c4b22f2 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/PodcastWithExtraInfo.kt +++ b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/PodcastWithExtraInfo.kt @@ -18,6 +18,7 @@ package com.example.jetcaster.core.data.database.model import androidx.room.ColumnInfo import androidx.room.Embedded +import com.example.jetcaster.core.model.PodcastInfo import java.time.OffsetDateTime import java.util.Objects @@ -50,3 +51,9 @@ class PodcastWithExtraInfo { override fun hashCode(): Int = Objects.hash(podcast, lastEpisodeDate, isFollowed) } + +fun PodcastWithExtraInfo.asExternalModel(): PodcastInfo = + this.podcast.asExternalModel().copy( + isSubscribed = isFollowed, + lastEpisodeDate = lastEpisodeDate, + ) diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/domain/FilterableCategoriesUseCase.kt b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/domain/FilterableCategoriesUseCase.kt index c7255b9466..cd55b68a8a 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/domain/FilterableCategoriesUseCase.kt +++ b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/domain/FilterableCategoriesUseCase.kt @@ -16,10 +16,10 @@ package com.example.jetcaster.core.data.domain -import com.example.jetcaster.core.data.model.CategoryInfo -import com.example.jetcaster.core.data.model.FilterableCategoriesModel -import com.example.jetcaster.core.data.model.asExternalModel +import com.example.jetcaster.core.data.database.model.asExternalModel import com.example.jetcaster.core.data.repository.CategoryStore +import com.example.jetcaster.core.model.CategoryInfo +import com.example.jetcaster.core.model.FilterableCategoriesModel import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCase.kt b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCase.kt index 68aa0d22a6..71e3d160a3 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCase.kt +++ b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCase.kt @@ -17,11 +17,11 @@ package com.example.jetcaster.core.data.domain import com.example.jetcaster.core.data.database.model.Category -import com.example.jetcaster.core.data.model.CategoryInfo -import com.example.jetcaster.core.data.model.PodcastCategoryFilterResult -import com.example.jetcaster.core.data.model.asExternalModel -import com.example.jetcaster.core.data.model.asPodcastCategoryEpisode +import com.example.jetcaster.core.data.database.model.asExternalModel +import com.example.jetcaster.core.data.database.model.asPodcastCategoryEpisode import com.example.jetcaster.core.data.repository.CategoryStore +import com.example.jetcaster.core.model.CategoryInfo +import com.example.jetcaster.core.model.PodcastCategoryFilterResult import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/player/EpisodePlayer.kt b/Jetcaster/core/src/main/java/com/example/jetcaster/core/player/EpisodePlayer.kt index 648e10ec6b..173ac5eb73 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/player/EpisodePlayer.kt +++ b/Jetcaster/core/src/main/java/com/example/jetcaster/core/player/EpisodePlayer.kt @@ -16,7 +16,7 @@ package com.example.jetcaster.core.player -import com.example.jetcaster.core.data.model.PlayerEpisode +import com.example.jetcaster.core.model.PlayerEpisode import java.time.Duration import kotlinx.coroutines.flow.StateFlow diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/player/MockEpisodePlayer.kt b/Jetcaster/core/src/main/java/com/example/jetcaster/core/player/MockEpisodePlayer.kt index 72c857eec3..a33b308b14 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/player/MockEpisodePlayer.kt +++ b/Jetcaster/core/src/main/java/com/example/jetcaster/core/player/MockEpisodePlayer.kt @@ -16,7 +16,7 @@ package com.example.jetcaster.core.player -import com.example.jetcaster.core.data.model.PlayerEpisode +import com.example.jetcaster.core.model.PlayerEpisode import java.time.Duration import kotlin.reflect.KProperty import kotlinx.coroutines.CoroutineDispatcher diff --git a/Jetcaster/core/src/test/kotlin/com/example/jetcaster/core/data/domain/FilterableCategoriesUseCaseTest.kt b/Jetcaster/core/src/test/kotlin/com/example/jetcaster/core/data/domain/FilterableCategoriesUseCaseTest.kt index 13b5cb4533..3f76041790 100644 --- a/Jetcaster/core/src/test/kotlin/com/example/jetcaster/core/data/domain/FilterableCategoriesUseCaseTest.kt +++ b/Jetcaster/core/src/test/kotlin/com/example/jetcaster/core/data/domain/FilterableCategoriesUseCaseTest.kt @@ -17,8 +17,8 @@ package com.example.jetcaster.core.data.domain import com.example.jetcaster.core.data.database.model.Category -import com.example.jetcaster.core.data.model.asExternalModel import com.example.jetcaster.core.data.repository.TestCategoryStore +import com.example.jetcaster.model.asExternalModel import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals diff --git a/Jetcaster/core/src/test/kotlin/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCaseTest.kt b/Jetcaster/core/src/test/kotlin/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCaseTest.kt index bb20c1915b..c8065424b4 100644 --- a/Jetcaster/core/src/test/kotlin/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCaseTest.kt +++ b/Jetcaster/core/src/test/kotlin/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCaseTest.kt @@ -21,9 +21,9 @@ import com.example.jetcaster.core.data.database.model.Episode import com.example.jetcaster.core.data.database.model.EpisodeToPodcast import com.example.jetcaster.core.data.database.model.Podcast import com.example.jetcaster.core.data.database.model.PodcastWithExtraInfo -import com.example.jetcaster.core.data.model.asExternalModel -import com.example.jetcaster.core.data.model.asPodcastCategoryEpisode import com.example.jetcaster.core.data.repository.TestCategoryStore +import com.example.jetcaster.model.asExternalModel +import com.example.jetcaster.model.asPodcastCategoryEpisode import java.time.OffsetDateTime import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest diff --git a/Jetcaster/designsystem/build.gradle.kts b/Jetcaster/designsystem/build.gradle.kts index ce86e815dc..7fdf99b1fd 100644 --- a/Jetcaster/designsystem/build.gradle.kts +++ b/Jetcaster/designsystem/build.gradle.kts @@ -21,6 +21,16 @@ android { proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") } } + + buildFeatures { + compose = true + buildConfig = true + } + + composeOptions { + kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get() + } + compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 @@ -34,6 +44,7 @@ dependencies { implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.ui.graphics) implementation(libs.androidx.compose.ui.text) + implementation(libs.coil.kt.compose) implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) diff --git a/Jetcaster/designsystem/src/main/java/com/example/jetcaster/designsystem/component/ImageBackground.kt b/Jetcaster/designsystem/src/main/java/com/example/jetcaster/designsystem/component/ImageBackground.kt new file mode 100644 index 0000000000..83670bf6a5 --- /dev/null +++ b/Jetcaster/designsystem/src/main/java/com/example/jetcaster/designsystem/component/ImageBackground.kt @@ -0,0 +1,88 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.jetcaster.designsystem.component + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawWithCache +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.BlendMode +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.layout.ContentScale +import coil.compose.AsyncImage + +@Composable +fun ImageBackgroundColorScrim( + url: String?, + color: Color, + modifier: Modifier = Modifier, +) { + ImageBackground( + url = url, + modifier = modifier, + overlay = { + drawRect(color, blendMode = BlendMode.Multiply) + } + ) +} + +@Composable +fun ImageBackgroundRadialGradientScrim( + url: String?, + colors: List, + modifier: Modifier = Modifier, +) { + ImageBackground( + url = url, + modifier = modifier, + overlay = { + val brush = Brush.radialGradient( + colors = colors, + center = Offset(0f, size.height), + radius = size.width * 1.5f + ) + drawRect(brush, blendMode = BlendMode.Multiply) + } + ) +} + +/** + * Displays an image scaled 150% overlaid by [overlay] + */ +@Composable +fun ImageBackground( + url: String?, + overlay: DrawScope.() -> Unit, + modifier: Modifier = Modifier, +) { + AsyncImage( + model = url, + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = modifier + .fillMaxWidth() + .drawWithCache { + onDrawWithContent { + drawContent() + overlay() + } + } + ) +} diff --git a/Jetcaster/settings.gradle.kts b/Jetcaster/settings.gradle.kts index f25709ae64..a0016bc0dd 100644 --- a/Jetcaster/settings.gradle.kts +++ b/Jetcaster/settings.gradle.kts @@ -35,5 +35,5 @@ dependencyResolutionManagement { } } rootProject.name = "Jetcaster" -include(":app", ":core", ":designsystem", ":tv-app", ":wear") +include(":app", ":core", ":core:model", ":designsystem", ":tv-app", ":wear") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") diff --git a/Jetcaster/tv-app/build.gradle.kts b/Jetcaster/tv-app/build.gradle.kts index c94a090d89..8264edad44 100644 --- a/Jetcaster/tv-app/build.gradle.kts +++ b/Jetcaster/tv-app/build.gradle.kts @@ -76,7 +76,6 @@ dependencies { implementation(libs.androidx.tv.foundation) implementation(libs.androidx.tv.material) implementation(libs.androidx.lifecycle.runtime) - implementation(libs.androidx.lifecycle.runtime.compose) implementation(libs.androidx.activity.compose) implementation(libs.androidx.navigation.compose) implementation(libs.coil.kt.compose) @@ -84,8 +83,10 @@ dependencies { // Dependency injection implementation(libs.androidx.hilt.navigation.compose) implementation(libs.hilt.android) + implementation(project(":core:model")) ksp(libs.hilt.compiler) + implementation(project(":core")) implementation(project(":designsystem")) diff --git a/Jetcaster/tv-app/src/main/java/com/example/jetcaster/tv/ui/component/Background.kt b/Jetcaster/tv-app/src/main/java/com/example/jetcaster/tv/ui/component/Background.kt index 3f2264b332..752cbdf3f7 100644 --- a/Jetcaster/tv-app/src/main/java/com/example/jetcaster/tv/ui/component/Background.kt +++ b/Jetcaster/tv-app/src/main/java/com/example/jetcaster/tv/ui/component/Background.kt @@ -19,74 +19,35 @@ package com.example.jetcaster.tv.ui.component import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawWithCache -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.BlendMode -import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.drawscope.DrawScope -import androidx.compose.ui.layout.ContentScale -import coil.compose.AsyncImage import com.example.jetcaster.core.data.database.model.Podcast -import com.example.jetcaster.core.data.model.PlayerEpisode +import com.example.jetcaster.core.model.PlayerEpisode +import com.example.jetcaster.designsystem.component.ImageBackgroundRadialGradientScrim @Composable internal fun Background( podcast: Podcast, modifier: Modifier = Modifier, - overlay: DrawScope.() -> Unit = { - val brush = Brush.radialGradient( - listOf(Color.Black, Color.Transparent), - center = Offset(0f, size.height), - radius = size.width * 1.5f - ) - drawRect(brush, blendMode = BlendMode.Multiply) - } -) = Background(imageUrl = podcast.imageUrl, modifier, overlay) +) = Background(imageUrl = podcast.imageUrl, modifier) @Composable internal fun Background( episode: PlayerEpisode, modifier: Modifier = Modifier, - overlay: DrawScope.() -> Unit = { - val brush = Brush.radialGradient( - listOf(Color.Black, Color.Transparent), - center = Offset(0f, size.height), - radius = size.width * 1.5f - ) - drawRect(brush, blendMode = BlendMode.Multiply) - } -) = Background(imageUrl = episode.podcastImageUrl, modifier, overlay) +) = Background(imageUrl = episode.podcastImageUrl, modifier) @Composable internal fun Background( imageUrl: String?, modifier: Modifier = Modifier, - overlay: DrawScope.() -> Unit = { - val brush = Brush.radialGradient( - listOf(Color.Black, Color.Transparent), - center = Offset(0f, size.height), - radius = size.width * 1.5f - ) - drawRect(brush, blendMode = BlendMode.Multiply) - } ) { - AsyncImage( - model = imageUrl, - contentDescription = null, - contentScale = ContentScale.Crop, - modifier = modifier - .fillMaxWidth() - .drawWithCache { - onDrawWithContent { - drawContent() - overlay() - } - } + ImageBackgroundRadialGradientScrim( + url = imageUrl, + colors = listOf(Color.Black, Color.Transparent), + modifier = modifier, ) } @@ -94,19 +55,11 @@ internal fun Background( internal fun BackgroundContainer( playerEpisode: PlayerEpisode, modifier: Modifier = Modifier, - overlay: DrawScope.() -> Unit = { - val brush = Brush.radialGradient( - listOf(Color.Black, Color.Transparent), - center = Offset(0f, size.height), - radius = size.width * 1.5f - ) - drawRect(brush, blendMode = BlendMode.Multiply) - }, contentAlignment: Alignment = Alignment.Center, content: @Composable BoxScope.() -> Unit ) { Box(modifier = modifier, contentAlignment = contentAlignment) { - Background(episode = playerEpisode, overlay = overlay, modifier = Modifier.fillMaxSize()) + Background(episode = playerEpisode, modifier = Modifier.fillMaxSize()) content() } } diff --git a/Jetcaster/wear/build.gradle b/Jetcaster/wear/build.gradle index 72cf8f8436..8736969a88 100644 --- a/Jetcaster/wear/build.gradle +++ b/Jetcaster/wear/build.gradle @@ -75,6 +75,7 @@ android { dependencies { + implementation project(':core:model') def composeBom = platform(libs.androidx.compose.bom) // General compose dependencies diff --git a/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/home/HomeScreen.kt b/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/home/HomeScreen.kt index 8150fd77af..aabff8a686 100644 --- a/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/home/HomeScreen.kt +++ b/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/home/HomeScreen.kt @@ -32,7 +32,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.wear.compose.material.ChipDefaults import androidx.wear.compose.material.Text import com.example.jetcaster.R -import com.example.jetcaster.core.data.model.PodcastInfo +import com.example.jetcaster.core.model.PodcastInfo import com.google.android.horologist.composables.PlaceholderChip import com.google.android.horologist.compose.layout.ScalingLazyColumn import com.google.android.horologist.compose.layout.ScalingLazyColumnDefaults diff --git a/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt b/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt index 513a83b0fe..c3538e99f2 100644 --- a/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt +++ b/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt @@ -21,15 +21,15 @@ import androidx.lifecycle.viewModelScope import com.example.jetcaster.core.data.database.model.EpisodeToPodcast import com.example.jetcaster.core.data.database.model.Podcast import com.example.jetcaster.core.data.database.model.PodcastWithExtraInfo +import com.example.jetcaster.core.data.database.model.toPlayerEpisode import com.example.jetcaster.core.data.domain.FilterableCategoriesUseCase import com.example.jetcaster.core.data.domain.PodcastCategoryFilterUseCase -import com.example.jetcaster.core.data.model.CategoryInfo -import com.example.jetcaster.core.data.model.FilterableCategoriesModel -import com.example.jetcaster.core.data.model.PodcastCategoryFilterResult -import com.example.jetcaster.core.data.model.toPlayerEpisode import com.example.jetcaster.core.data.repository.EpisodeStore import com.example.jetcaster.core.data.repository.PodcastStore import com.example.jetcaster.core.data.repository.PodcastsRepository +import com.example.jetcaster.core.model.CategoryInfo +import com.example.jetcaster.core.model.FilterableCategoriesModel +import com.example.jetcaster.core.model.PodcastCategoryFilterResult import com.example.jetcaster.core.player.EpisodePlayer import com.example.jetcaster.core.util.combine import dagger.hilt.android.lifecycle.HiltViewModel diff --git a/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/LatestEpisodeViewModel.kt b/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/LatestEpisodeViewModel.kt index c270b83c40..366602bd64 100644 --- a/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/LatestEpisodeViewModel.kt +++ b/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/LatestEpisodeViewModel.kt @@ -20,7 +20,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.example.jetcaster.core.data.database.model.EpisodeToPodcast import com.example.jetcaster.core.data.domain.GetLatestFollowedEpisodesUseCase -import com.example.jetcaster.core.data.model.PlayerEpisode +import com.example.jetcaster.core.model.PlayerEpisode import com.example.jetcaster.core.player.EpisodePlayer import com.example.jetcaster.core.util.combine import dagger.hilt.android.lifecycle.HiltViewModel diff --git a/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/LatestEpisodesScreen.kt b/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/LatestEpisodesScreen.kt index 58e4042aa7..58f6f47fce 100644 --- a/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/LatestEpisodesScreen.kt +++ b/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/LatestEpisodesScreen.kt @@ -38,8 +38,8 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.wear.compose.material.ChipDefaults import com.example.jetcaster.R import com.example.jetcaster.core.data.database.model.EpisodeToPodcast -import com.example.jetcaster.core.data.model.PlayerEpisode -import com.example.jetcaster.core.data.model.toPlayerEpisode +import com.example.jetcaster.core.data.database.model.toPlayerEpisode +import com.example.jetcaster.core.model.PlayerEpisode import com.google.android.horologist.annotations.ExperimentalHorologistApi import com.google.android.horologist.compose.layout.ScreenScaffold import com.google.android.horologist.compose.layout.rememberColumnState diff --git a/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/PodcastsScreen.kt b/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/PodcastsScreen.kt index a78da459e7..328afba234 100644 --- a/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/PodcastsScreen.kt +++ b/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/PodcastsScreen.kt @@ -41,7 +41,7 @@ import androidx.wear.compose.material.Text import androidx.wear.compose.material.dialog.Alert import androidx.wear.compose.material.dialog.Dialog import com.example.jetcaster.R -import com.example.jetcaster.core.data.model.PodcastInfo +import com.example.jetcaster.core.model.PodcastInfo import com.google.android.horologist.annotations.ExperimentalHorologistApi import com.google.android.horologist.composables.PlaceholderChip import com.google.android.horologist.composables.Section diff --git a/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/PodcastsViewModel.kt b/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/PodcastsViewModel.kt index e7bb50fb85..5e18dc1ebd 100644 --- a/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/PodcastsViewModel.kt +++ b/Jetcaster/wear/src/main/java/com/example/jetcaster/ui/library/PodcastsViewModel.kt @@ -19,9 +19,9 @@ package com.example.jetcaster.ui.library import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.example.jetcaster.core.data.database.model.PodcastWithExtraInfo -import com.example.jetcaster.core.data.model.PodcastInfo -import com.example.jetcaster.core.data.model.asExternalModel +import com.example.jetcaster.core.data.database.model.asExternalModel import com.example.jetcaster.core.data.repository.PodcastStore +import com.example.jetcaster.core.model.PodcastInfo import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import kotlinx.coroutines.flow.SharingStarted