Skip to content

Commit da0107f

Browse files
committed
[ISSUE-68] Adding new endpoint to fetch youtube video meta data
1 parent 9b49d79 commit da0107f

File tree

10 files changed

+101
-12
lines changed

10 files changed

+101
-12
lines changed

build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import java.net.URI
2+
13
@Suppress("DSL_SCOPE_VIOLATION")
24
plugins {
35
alias(libs.plugins.android.application) apply false
@@ -13,5 +15,8 @@ allprojects {
1315
repositories {
1416
google()
1517
mavenCentral()
18+
maven {
19+
url = URI.create("https://jitpack.io")
20+
}
1621
}
1722
}

feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/DetailStreamRepository.kt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,23 @@ package com.codandotv.streamplayerapp.feature_list_streams.detail.data
22

33
import com.codandotv.streamplayerapp.core_networking.handleError.toFlow
44
import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStream
5+
import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.VideoStream
56
import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.toDetailStream
7+
import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.toVideoStreams
68
import kotlinx.coroutines.flow.Flow
9+
import kotlinx.coroutines.flow.first
10+
import kotlinx.coroutines.flow.firstOrNull
711
import kotlinx.coroutines.flow.map
812

913
interface DetailStreamRepository {
10-
suspend fun getMovie() : Flow<DetailStream>
14+
suspend fun getMovie(): Flow<DetailStream>
15+
16+
suspend fun getVideoStreams(): Flow<List<VideoStream>>
1117
}
1218

1319
class DetailStreamRepositoryImpl(
1420
private val movieId: String,
15-
private val service : DetailStreamService
21+
private val service: DetailStreamService
1622
) : DetailStreamRepository {
1723

1824
override suspend fun getMovie(): Flow<DetailStream> =
@@ -21,4 +27,11 @@ class DetailStreamRepositoryImpl(
2127
.map {
2228
it.toDetailStream()
2329
}
30+
31+
override suspend fun getVideoStreams(): Flow<List<VideoStream>> =
32+
service.getVideoStreams(movieId)
33+
.toFlow()
34+
.map {
35+
it.toVideoStreams()
36+
}
2437
}

feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/DetailStreamService.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@ package com.codandotv.streamplayerapp.feature_list_streams.detail.data
22

33
import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
44
import com.codandotv.streamplayerapp.feature_list_streams.detail.data.model.DetailStreamResponse
5+
import com.codandotv.streamplayerapp.feature_list_streams.detail.data.model.VideoStreamsResponse
56
import retrofit2.http.GET
67
import retrofit2.http.Path
78

89
interface DetailStreamService {
910
@GET("movie/{movie_id}")
10-
suspend fun getMovie(@Path("movie_id") movieId: String) : NetworkResponse<DetailStreamResponse>
11+
suspend fun getMovie(@Path("movie_id") movieId: String): NetworkResponse<DetailStreamResponse>
12+
13+
@GET("movie/{movie_id}/videos")
14+
suspend fun getVideoStreams(@Path("movie_id") movieId: String): NetworkResponse<VideoStreamsResponse>
1115
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.codandotv.streamplayerapp.feature_list_streams.detail.data.model
2+
3+
data class VideoStreamResponse(
4+
val id: String,
5+
val name: String,
6+
val key: String,
7+
val site: String,
8+
val size: Int,
9+
val official: Boolean,
10+
val type: String,
11+
)
12+
13+
data class VideoStreamsResponse(
14+
val id: Long,
15+
val results: List<VideoStreamResponse>
16+
)

feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/di/DetailStreamModule.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import com.codandotv.streamplayerapp.feature_list_streams.detail.data.DetailStre
55
import com.codandotv.streamplayerapp.feature_list_streams.detail.data.DetailStreamService
66
import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStreamUseCase
77
import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStreamUseCaseImpl
8+
import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.VideoStreamsUseCase
9+
import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.VideoStreamsUseCaseImpl
810
import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens.DetailStreamViewModel
911
import org.koin.androidx.viewmodel.dsl.viewModel
1012
import org.koin.core.parameter.parametersOf
@@ -15,7 +17,10 @@ object DetailStreamModule {
1517
val module = module {
1618
viewModel { (id: String) ->
1719
DetailStreamViewModel(
18-
useCase = get {
20+
detailStreamUseCase = get {
21+
parametersOf(id)
22+
},
23+
videoStreamsUseCase = get {
1924
parametersOf(id)
2025
}
2126
)
@@ -27,6 +32,13 @@ object DetailStreamModule {
2732
}
2833
)
2934
}
35+
factory<VideoStreamsUseCase> { (id: String) ->
36+
VideoStreamsUseCaseImpl(
37+
detailStreamRepository = get {
38+
parametersOf(id)
39+
}
40+
)
41+
}
3042
factory<DetailStreamRepository> { (id: String) ->
3143
DetailStreamRepositoryImpl(
3244
service = get(),

feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/DetailStreamMapper.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.codandotv.streamplayerapp.feature_list_streams.detail.domain
22

33
import com.codandotv.streamplayerapp.core_networking.Url.IMAGE_URL_SIZE_500
44
import com.codandotv.streamplayerapp.feature_list_streams.detail.data.model.DetailStreamResponse
5+
import com.codandotv.streamplayerapp.feature_list_streams.detail.data.model.VideoStreamsResponse
56

67
fun DetailStreamResponse.toDetailStream(): DetailStream =
78
DetailStream(
@@ -11,4 +12,12 @@ fun DetailStreamResponse.toDetailStream(): DetailStream =
1112
tagline = this.tagline,
1213
url = "$IMAGE_URL_SIZE_500${this.backdrop_path}",
1314
releaseYear = this.release_date.substring(0, 4)
14-
)
15+
)
16+
17+
fun VideoStreamsResponse.toVideoStreams(): List<VideoStream> =
18+
results.map {
19+
VideoStream(
20+
youtubeUrl = "http://youtube.com/watch?v=".plus(it.key),
21+
movieId = this.id
22+
)
23+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.codandotv.streamplayerapp.feature_list_streams.detail.domain
2+
3+
data class VideoStream(
4+
val movieId: Long,
5+
val youtubeUrl: String,
6+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.codandotv.streamplayerapp.feature_list_streams.detail.domain
2+
3+
import com.codandotv.streamplayerapp.feature_list_streams.detail.data.DetailStreamRepository
4+
import kotlinx.coroutines.flow.Flow
5+
6+
interface VideoStreamsUseCase {
7+
suspend fun getVideoStreams(): Flow<List<VideoStream>>
8+
}
9+
10+
class VideoStreamsUseCaseImpl(
11+
private val detailStreamRepository: DetailStreamRepository
12+
) : VideoStreamsUseCase {
13+
override suspend fun getVideoStreams(): Flow<List<VideoStream>> {
14+
return detailStreamRepository.getVideoStreams()
15+
}
16+
}

feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/screens/DetailStreamViewModel.kt

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,24 @@ import androidx.lifecycle.ViewModel
66
import androidx.lifecycle.viewModelScope
77
import com.codandotv.streamplayerapp.core_networking.handleError.catchFailure
88
import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStreamUseCase
9+
import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.VideoStreamsUseCase
910
import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens.DetailStreamsUIState.*
1011
import kotlinx.coroutines.flow.MutableStateFlow
1112
import kotlinx.coroutines.flow.SharingStarted
1213
import kotlinx.coroutines.flow.StateFlow
1314
import kotlinx.coroutines.flow.onStart
1415
import kotlinx.coroutines.flow.stateIn
1516
import kotlinx.coroutines.flow.update
17+
import kotlinx.coroutines.flow.zip
1618
import kotlinx.coroutines.launch
1719

1820
class DetailStreamViewModel(
19-
private val useCase: DetailStreamUseCase,
21+
private val detailStreamUseCase: DetailStreamUseCase,
22+
private val videoStreamsUseCase: VideoStreamsUseCase,
2023
) : ViewModel(), DefaultLifecycleObserver {
2124

2225
private val _uiState = MutableStateFlow<DetailStreamsUIState>(LoadingStreamUIState)
23-
val uiState : StateFlow<DetailStreamsUIState> = _uiState.stateIn(
26+
val uiState: StateFlow<DetailStreamsUIState> = _uiState.stateIn(
2427
viewModelScope,
2528
SharingStarted.Eagerly,
2629
initialValue = _uiState.value
@@ -30,16 +33,20 @@ class DetailStreamViewModel(
3033
super.onCreate(owner)
3134

3235
viewModelScope.launch {
33-
useCase.getMovie()
36+
detailStreamUseCase.getMovie()
37+
.zip(videoStreamsUseCase.getVideoStreams()) { detailStream, videoUrl ->
38+
DetailStreamsLoadedUIState(
39+
detailStream = detailStream,
40+
videoUrl = videoUrl.firstOrNull()?.youtubeUrl
41+
)
42+
}
3443
.onStart { onLoading() }
3544
.catchFailure {
3645
println(">>>> ${it.errorMessage}")
3746
}
38-
.collect { detailStream ->
47+
.collect { result ->
3948
_uiState.update {
40-
DetailStreamsLoadedUIState(
41-
detailStream = detailStream
42-
)
49+
result
4350
}
4451
}
4552
}

feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/screens/DetailStreamsUIState.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailSt
55
sealed class DetailStreamsUIState {
66
data class DetailStreamsLoadedUIState(
77
val detailStream: DetailStream,
8+
val videoUrl: String?,
89
) : DetailStreamsUIState()
910

1011
object LoadingStreamUIState : DetailStreamsUIState()

0 commit comments

Comments
 (0)