Skip to content

Commit 90d8aea

Browse files
authored
Merge pull request #75 from CodandoTV/feature/68-componente-pra-exibir-videos
[ISSUE-68] Componente pra exibir videos
2 parents 70b950b + 622dee4 commit 90d8aea

File tree

17 files changed

+279
-44
lines changed

17 files changed

+279
-44
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
}

core-shared-ui/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ dependencies {
99
implementation(libs.bundles.koin)
1010
implementation(libs.bundles.kotlin)
1111
implementation(libs.bundles.androidSupport)
12+
implementation(libs.android.youtube.player)
1213
testImplementation(libs.bundles.test)
1314
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package com.codandotv.streamplayerapp.core_shared_ui.widget
2+
3+
import androidx.compose.foundation.layout.Box
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.fillMaxSize
6+
import androidx.compose.foundation.layout.fillMaxWidth
7+
import androidx.compose.foundation.layout.height
8+
import androidx.compose.runtime.Composable
9+
import androidx.compose.runtime.DisposableEffect
10+
import androidx.compose.runtime.remember
11+
import androidx.compose.ui.Alignment
12+
import androidx.compose.ui.Modifier
13+
import androidx.compose.ui.platform.LocalContext
14+
import androidx.compose.ui.unit.dp
15+
import androidx.compose.ui.viewinterop.AndroidView
16+
import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews
17+
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants
18+
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer
19+
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerListener
20+
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
21+
22+
@Composable
23+
fun PlayerComponent(videoId: String, modifier: Modifier = Modifier) {
24+
25+
val context = LocalContext.current
26+
27+
val youtubePlayerView = remember {
28+
YouTubePlayerView(context).apply {
29+
enableAutomaticInitialization = false
30+
31+
addYouTubePlayerListener(object : YouTubePlayerListener {
32+
override fun onApiChange(youTubePlayer: YouTubePlayer) {}
33+
34+
override fun onCurrentSecond(youTubePlayer: YouTubePlayer, second: Float) {}
35+
36+
override fun onError(
37+
youTubePlayer: YouTubePlayer,
38+
error: PlayerConstants.PlayerError
39+
) {
40+
}
41+
42+
override fun onPlaybackQualityChange(
43+
youTubePlayer: YouTubePlayer,
44+
playbackQuality: PlayerConstants.PlaybackQuality
45+
) {
46+
}
47+
48+
override fun onPlaybackRateChange(
49+
youTubePlayer: YouTubePlayer,
50+
playbackRate: PlayerConstants.PlaybackRate
51+
) {
52+
}
53+
54+
override fun onReady(youTubePlayer: YouTubePlayer) {
55+
youTubePlayer.loadVideo(videoId, 0f)
56+
}
57+
58+
override fun onStateChange(
59+
youTubePlayer: YouTubePlayer,
60+
state: PlayerConstants.PlayerState
61+
) {
62+
}
63+
64+
override fun onVideoDuration(youTubePlayer: YouTubePlayer, duration: Float) {}
65+
66+
override fun onVideoId(youTubePlayer: YouTubePlayer, videoId: String) {}
67+
68+
override fun onVideoLoadedFraction(
69+
youTubePlayer: YouTubePlayer,
70+
loadedFraction: Float
71+
) {
72+
}
73+
})
74+
}
75+
}
76+
77+
78+
Column(
79+
modifier = modifier
80+
.fillMaxSize()
81+
) {
82+
Box {
83+
AndroidView(
84+
modifier = Modifier
85+
.fillMaxWidth()
86+
.height(200.dp)
87+
.align(Alignment.TopCenter),
88+
factory = {
89+
youtubePlayerView
90+
}
91+
)
92+
}
93+
}
94+
95+
DisposableEffect(
96+
key1 = Unit,
97+
effect = {
98+
onDispose { youtubePlayerView.release() }
99+
},
100+
)
101+
}
102+
103+
@Composable
104+
@ThemePreviews
105+
fun PlayerComponentPreview() {
106+
PlayerComponent(
107+
videoId = "BigBuckBunny.mp4",
108+
modifier = Modifier.fillMaxWidth()
109+
)
110+
}
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2-
android:width="24dp"
3-
android:height="24dp"
4-
android:viewportWidth="960"
5-
android:viewportHeight="960"
6-
android:tint="?attr/colorControlNormal">
2+
android:width="512dp"
3+
android:height="512dp"
4+
android:viewportWidth="512"
5+
android:viewportHeight="512">
76
<path
8-
android:fillColor="@android:color/black"
9-
android:pathData="M320,760L320,200L760,480L320,760Z"/>
7+
android:fillColor="#FF000000"
8+
android:pathData="M128,96v320l256,-160L128,96L128,96z"/>
109
</vector>

core-shared-ui/src/main/res/values/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,8 @@
2020
<string name="instagram_not_installed_message">Por favor, instale o aplicativo Instagram</string>
2121
<string name="sms_app_error_message">Erro ao abrir o app Mensagens</string>
2222
<!-- endregion Sharing Content -->
23+
24+
<!-- region Player -->
25+
<string name="player_preview">Preview</string>
26+
<!-- endregion Player -->
2327
</resources>

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+
videoId = it.key,
21+
movieId = this.id
22+
)
23+
}

0 commit comments

Comments
 (0)