@@ -18,9 +18,13 @@ package com.google.jetstream.presentation.screens.videoPlayer.components
1818
1919import androidx.compose.foundation.horizontalScroll
2020import androidx.compose.foundation.layout.Arrangement
21+ import androidx.compose.foundation.layout.Column
2122import androidx.compose.foundation.layout.Row
23+ import androidx.compose.foundation.layout.fillMaxWidth
2224import androidx.compose.foundation.layout.padding
25+ import androidx.compose.foundation.layout.size
2326import androidx.compose.foundation.rememberScrollState
27+ import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
2428import androidx.compose.runtime.Composable
2529import androidx.compose.runtime.LaunchedEffect
2630import androidx.compose.runtime.remember
@@ -36,11 +40,17 @@ import com.google.jetstream.presentation.screens.videoPlayer.components.button.C
3640import com.google.jetstream.presentation.screens.videoPlayer.components.button.ImmersiveModeButton
3741import com.google.jetstream.presentation.screens.videoPlayer.components.button.NextButton
3842import com.google.jetstream.presentation.screens.videoPlayer.components.button.PlayListButton
43+ import com.google.jetstream.presentation.screens.videoPlayer.components.button.PlayPauseButton
3944import com.google.jetstream.presentation.screens.videoPlayer.components.button.PreviousButton
4045import com.google.jetstream.presentation.screens.videoPlayer.components.button.RepeatButton
4146import com.google.jetstream.presentation.screens.videoPlayer.components.button.SettingsButton
4247import kotlin.time.Duration.Companion.milliseconds
4348
49+ private val DefaultActionSpacing = 12 .dp
50+ private val TabletopActionSpacing = 15 .dp
51+ private val TabletopButtonSize = 70 .dp
52+ private val BottomPadding = 16 .dp
53+
4454@Composable
4555fun VideoPlayerControls (
4656 movieDetails : MovieDetails ,
@@ -53,45 +63,111 @@ fun VideoPlayerControls(
5363 focusRequester.tryRequestFocus()
5464 }
5565
56- val scrollState = rememberScrollState()
66+ val isTabletop = currentWindowAdaptiveInfo().windowPosture.isTabletop
5767
5868 VideoPlayerMainFrame (
5969 mediaTitle = {
6070 VideoPlayerMediaTitle (
6171 title = movieDetails.name,
6272 secondaryText = movieDetails.releaseDate,
6373 tertiaryText = movieDetails.director,
64- type = VideoPlayerMediaTitleType .DEFAULT
74+ type = VideoPlayerMediaTitleType .DEFAULT ,
75+ modifier = Modifier .fillMaxWidth()
6576 )
6677 },
6778 mediaActions = {
68- Row (
69- modifier = Modifier
70- .padding(bottom = 16 .dp)
71- .horizontalScroll(scrollState),
72- verticalAlignment = Alignment .CenterVertically ,
73- horizontalArrangement = Arrangement .spacedBy(12 .dp),
74- ) {
75- PreviousButton (player = player)
76- NextButton (player = player)
77- RepeatButton (player = player)
78- PlayListButton ()
79- ClosedCaptionButton ()
80- SettingsButton ()
81- if (isImmersiveModeAvailable) {
82- ImmersiveModeButton ()
83- }
79+ if (isTabletop) {
80+ TabletopMediaActions (player, isImmersiveModeAvailable)
81+ } else {
82+ DefaultMediaActions (player, isImmersiveModeAvailable)
8483 }
8584 },
8685 seeker = {
8786 VideoPlayerSeeker (
8887 player = player,
8988 onSeek = { player.seekTo(player.duration.times(it).toLong()) },
9089 contentDuration = player.duration.milliseconds,
91- modifier = Modifier .focusRequester(focusRequester)
90+ modifier = Modifier .focusRequester(focusRequester),
91+ shouldShowPlayPauseButton = ! isTabletop
9292 )
9393 },
9494 more = null ,
9595 modifier = modifier
9696 )
9797}
98+
99+ @Composable
100+ private fun TabletopMediaActions (
101+ player : Player ,
102+ isImmersiveModeAvailable : Boolean ,
103+ ) {
104+ Column (
105+ modifier = Modifier .fillMaxWidth(),
106+ horizontalAlignment = Alignment .CenterHorizontally
107+ ) {
108+ Row (
109+ modifier = Modifier
110+ .padding(bottom = BottomPadding )
111+ .weight(1f ),
112+ horizontalArrangement = Arrangement .spacedBy(
113+ TabletopActionSpacing ,
114+ Alignment .CenterHorizontally
115+ ),
116+ verticalAlignment = Alignment .CenterVertically
117+ ) {
118+ PreviousButton (player = player, modifier = Modifier .size(TabletopButtonSize ))
119+ PlayPauseButton (player = player, modifier = Modifier .size(TabletopButtonSize ))
120+ NextButton (player = player, modifier = Modifier .size(TabletopButtonSize ))
121+ }
122+ PlayerActions (
123+ player = player,
124+ isImmersiveModeAvailable = isImmersiveModeAvailable,
125+ modifier = Modifier .weight(1f ),
126+ horizontalArrangement = Arrangement .spacedBy(
127+ TabletopActionSpacing ,
128+ Alignment .CenterHorizontally
129+ )
130+ )
131+ }
132+ }
133+
134+ @Composable
135+ private fun DefaultMediaActions (
136+ player : Player ,
137+ isImmersiveModeAvailable : Boolean ,
138+ ) {
139+ val scrollState = rememberScrollState()
140+ Row (
141+ modifier = Modifier
142+ .padding(bottom = BottomPadding )
143+ .horizontalScroll(scrollState),
144+ verticalAlignment = Alignment .CenterVertically ,
145+ horizontalArrangement = Arrangement .spacedBy(DefaultActionSpacing ),
146+ ) {
147+ PreviousButton (player = player)
148+ NextButton (player = player)
149+ PlayerActions (player, isImmersiveModeAvailable)
150+ }
151+ }
152+
153+ @Composable
154+ private fun PlayerActions (
155+ player : Player ,
156+ isImmersiveModeAvailable : Boolean ,
157+ modifier : Modifier = Modifier ,
158+ horizontalArrangement : Arrangement .Horizontal = Arrangement .spacedBy(DefaultActionSpacing )
159+ ) {
160+ Row (
161+ modifier = modifier,
162+ horizontalArrangement = horizontalArrangement,
163+ verticalAlignment = Alignment .CenterVertically
164+ ) {
165+ RepeatButton (player = player)
166+ PlayListButton ()
167+ ClosedCaptionButton ()
168+ SettingsButton ()
169+ if (isImmersiveModeAvailable) {
170+ ImmersiveModeButton ()
171+ }
172+ }
173+ }
0 commit comments