-
Notifications
You must be signed in to change notification settings - Fork 2
Added VideoClipEntity and TvShowEntity #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,33 @@ data class ContinueWatchingEntity( | |
val lastEngagementTimeMillis: Long, | ||
val continueWatchingType: ContinueWatchingType, | ||
val profileId: String, | ||
) | ||
) { | ||
val releaseYear: Int | ||
get() = when (entity) { | ||
is MovieEntity -> entity.releaseYear | ||
is TvEpisodeEntity -> entity.releaseYear | ||
is VideoClipEntity -> entity.releaseYear | ||
else -> throw IllegalStateException("Unsupported video type for Continue Watching: $entity") | ||
} | ||
val duration: Duration | ||
get() = when (entity) { | ||
is MovieEntity -> entity.duration | ||
is TvEpisodeEntity -> entity.duration | ||
is VideoClipEntity -> entity.duration | ||
else -> throw IllegalStateException("Unsupported video type for Continue Watching: $entity") | ||
} | ||
|
||
val genre: String | ||
get() = when (entity) { | ||
is MovieEntity -> entity.genre | ||
is TvEpisodeEntity -> entity.genre | ||
is VideoClipEntity -> entity.genre | ||
else -> throw IllegalStateException("Unsupported video type for Continue Watching: $entity") | ||
Comment on lines
+18
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's change the The benefit is that when we add a new entity type in future, we will be warned by compiler that we need to update this place. If we use the generic |
||
} | ||
|
||
val progressPercent: Float | ||
get() = playbackPosition.inWholeMilliseconds.toFloat() / duration.inWholeMilliseconds | ||
} | ||
|
||
fun ContinueWatchingEntity.toDbContinueWatchingEntity(): DbContinueWatchingEntity { | ||
return DbContinueWatchingEntity( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
package com.google.android.googlevideodiscovery.common.models | ||
|
||
enum class EntityType { | ||
MOVIE, | ||
TV_EPISODE, | ||
Movie, | ||
TvEpisode, | ||
TvShow, | ||
VideoClip | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,12 +6,7 @@ import kotlin.time.Duration.Companion.seconds | |
|
||
sealed interface VideoEntity { | ||
val id: String | ||
val duration: Duration | ||
val name: String | ||
val playbackUris: PlatformSpecificUris | ||
val images: List<Image> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: we can keep the |
||
val releaseYear: Int | ||
val genre: String | ||
val type: EntityType | ||
|
||
fun toContinueWatchingEntity( | ||
|
@@ -33,16 +28,14 @@ sealed interface VideoEntity { | |
data class MovieEntity( | ||
override val id: String, | ||
override val name: String, | ||
override val duration: Duration, | ||
override val playbackUris: PlatformSpecificUris, | ||
override val images: List<Image>, | ||
override val releaseYear: Int, | ||
override val genre: String, | ||
val images: List<Image>, | ||
val duration: Duration, | ||
val playbackUris: PlatformSpecificUris, | ||
val releaseYear: Int, | ||
val genre: String, | ||
var nextMovieEntity: MovieEntity?, | ||
) : VideoEntity { | ||
override val type = EntityType.MOVIE | ||
|
||
fun toPlaybackEntity() = toPlaybackEntity(playbackPosition = null) | ||
override val type = EntityType.Movie | ||
override fun toPlaybackEntity(playbackPosition: Duration?) = PlaybackEntity( | ||
entityId = id, | ||
title = name, | ||
|
@@ -56,24 +49,71 @@ data class MovieEntity( | |
data class TvEpisodeEntity( | ||
override val id: String, | ||
override val name: String, | ||
override val duration: Duration, | ||
override val playbackUris: PlatformSpecificUris, | ||
override val images: List<Image>, | ||
override val releaseYear: Int, | ||
override val genre: String, | ||
val images: List<Image>, | ||
val duration: Duration, | ||
val playbackUris: PlatformSpecificUris, | ||
val releaseYear: Int, | ||
val genre: String, | ||
val episodeNumber: Int, | ||
val seasonNumber: Int, | ||
val showTitle: String, | ||
var nextEpisode: TvEpisodeEntity?, | ||
) : VideoEntity { | ||
override val type = EntityType.TV_EPISODE | ||
override val type = EntityType.TvEpisode | ||
|
||
fun toPlaybackEntity() = toPlaybackEntity(playbackPosition = null) | ||
override fun toPlaybackEntity(playbackPosition: Duration?) = PlaybackEntity( | ||
entityId = id, | ||
title = name, | ||
duration = duration, | ||
releaseYear = releaseYear, | ||
genre = genre, | ||
playbackPosition = playbackPosition ?: 0.seconds | ||
) | ||
} | ||
|
||
data class VideoClipEntity( | ||
override val id: String, | ||
override val name: String, | ||
val images: List<Image>, | ||
val duration: Duration, | ||
val playbackUris: PlatformSpecificUris, | ||
val releaseYear: Int, | ||
val genre: String, | ||
val creatorImage: String, | ||
val creator: String, | ||
var nextVideoClipEntity: VideoClipEntity?, | ||
) : VideoEntity { | ||
override val type = EntityType.VideoClip | ||
|
||
override fun toPlaybackEntity(playbackPosition: Duration?) = PlaybackEntity( | ||
entityId = id, | ||
title = name, | ||
duration = duration, | ||
releaseYear = releaseYear, | ||
genre = genre, | ||
playbackPosition = playbackPosition ?: 0.seconds | ||
) | ||
} | ||
|
||
data class TvShowEntity( | ||
override val id: String, | ||
override val name: String, | ||
val images: List<Image>, | ||
val description: String, | ||
val platformSpecificUris: PlatformSpecificUris, | ||
val releaseYear: Int, | ||
val genre: String, | ||
val seasonCount: Integer, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's remove the season count for now. When we want to make use of seasons, we can create a new entity called data class TvShowEntity(
...
) {
val seasonCount = seasons.size()
} This way, we will avoid having fragmented state and it will help us prevent out-of-sync issues. |
||
val duration: Duration, | ||
var nextTvShowEntity: TvShowEntity?, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's remove this as a |
||
) : VideoEntity { | ||
override val type = EntityType.TvShow | ||
|
||
override fun toPlaybackEntity(playbackPosition: Duration?) = PlaybackEntity( | ||
entityId = id, | ||
title = name, | ||
duration = duration, | ||
releaseYear = releaseYear, | ||
genre = genre, | ||
playbackPosition = playbackPosition ?: 0.seconds | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ import com.google.android.googlevideodiscovery.common.models.ContinueWatchingEnt | |
import com.google.android.googlevideodiscovery.common.models.ContinueWatchingType | ||
import com.google.android.googlevideodiscovery.common.models.MovieEntity | ||
import com.google.android.googlevideodiscovery.common.models.TvEpisodeEntity | ||
import com.google.android.googlevideodiscovery.common.models.VideoClipEntity | ||
import com.google.android.googlevideodiscovery.common.room.repository.ContinueWatchingRepository | ||
import kotlinx.coroutines.flow.Flow | ||
import java.time.Instant | ||
|
@@ -61,7 +62,7 @@ class ContinueWatchingService @Inject constructor( | |
|
||
private fun isNearingEnd(continueWatchingEntity: ContinueWatchingEntity): Boolean { | ||
val playbackPosition = continueWatchingEntity.playbackPosition | ||
val duration = continueWatchingEntity.entity.duration | ||
val duration = continueWatchingEntity.duration | ||
return duration - playbackPosition < END_THRESHOLD | ||
} | ||
|
||
|
@@ -82,6 +83,11 @@ class ContinueWatchingService @Inject constructor( | |
playbackPosition = 0.seconds, | ||
lastEngagementTime = Instant.now() | ||
) | ||
|
||
is VideoClipEntity -> null | ||
|
||
else -> throw IllegalStateException("Unsupported video type for Continue Watching: $entity") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's change the |
||
|
||
} | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ import com.google.android.googlevideodiscovery.common.models.ContinueWatchingEnt | |
import com.google.android.googlevideodiscovery.common.models.MovieEntity | ||
import com.google.android.googlevideodiscovery.common.models.PlaybackEntity | ||
import com.google.android.googlevideodiscovery.common.models.TvEpisodeEntity | ||
import com.google.android.googlevideodiscovery.common.models.VideoClipEntity | ||
import com.google.android.googlevideodiscovery.common.ui.screens.EntityScreenDefaults | ||
import com.google.android.googlevideodiscovery.common.ui.screens.HomeScreenDefaults | ||
import com.google.android.googlevideodiscovery.common.ui.screens.ProfilesScreenDefaults | ||
|
@@ -100,29 +101,29 @@ class NavigationScreensImpl : NavigationScreens { | |
cardContent = { index -> | ||
val continueWatchingEntity = continueWatchingEntities[index] | ||
val entity = continueWatchingEntity.entity | ||
val progressPercent = | ||
continueWatchingEntity.playbackPosition.inWholeMilliseconds.toFloat() / entity.duration.inWholeMilliseconds | ||
val cardTitle = when (entity) { | ||
is MovieEntity -> entity.name | ||
is TvEpisodeEntity -> HomeScreenDefaults.buildEpisodeTitle( | ||
episodeName = entity.name, | ||
episodeNumber = entity.episodeNumber, | ||
) | ||
is VideoClipEntity -> entity.name | ||
else -> throw IllegalStateException("Unsupported video type for Continue Watching: $entity") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's change the |
||
} | ||
|
||
HomeScreenDefaults.ChannelCard( | ||
title = cardTitle, | ||
subtitle = HomeScreenDefaults.buildSubtitle( | ||
releaseYear = entity.releaseYear, | ||
duration = entity.duration, | ||
genre = entity.genre | ||
releaseYear = continueWatchingEntity.releaseYear, | ||
duration = continueWatchingEntity.duration, | ||
genre = continueWatchingEntity.genre | ||
), | ||
onClick = { onEntityClick(entity.id) }, | ||
onLongClick = { | ||
confirmRemoveContinueWatchingEntity = continueWatchingEntity | ||
} | ||
) { | ||
HomeScreenDefaults.ProgressBar(progressPercent = progressPercent) | ||
HomeScreenDefaults.ProgressBar(progressPercent = continueWatchingEntity.progressPercent) | ||
} | ||
} | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's change the
else
tois TvShowEntity
instead.