diff --git a/androidenhancedvideoplayer/src/androidTest/java/com/profusion/androidenhancedvideoplayer/test/utils/DefaultPlayerControls.kt b/androidenhancedvideoplayer/src/androidTest/java/com/profusion/androidenhancedvideoplayer/test/utils/DefaultPlayerControls.kt index ec4630ad..0214efed 100644 --- a/androidenhancedvideoplayer/src/androidTest/java/com/profusion/androidenhancedvideoplayer/test/utils/DefaultPlayerControls.kt +++ b/androidenhancedvideoplayer/src/androidTest/java/com/profusion/androidenhancedvideoplayer/test/utils/DefaultPlayerControls.kt @@ -1,7 +1,6 @@ import androidx.compose.runtime.Composable import com.profusion.androidenhancedvideoplayer.components.playerOverlay.ControlsCustomization import com.profusion.androidenhancedvideoplayer.components.playerOverlay.PlayerControls -import com.profusion.androidenhancedvideoplayer.components.playerOverlay.SettingsControlsCustomization @Composable fun DefaultPlayerControls( @@ -10,19 +9,15 @@ fun DefaultPlayerControls( isPlaying: Boolean = false, isFullScreen: Boolean = false, hasEnded: Boolean = false, - speed: Float = 1f, - isLoopEnabled: Boolean = false, videoTimer: Long = 0, totalDuration: Long = 0, onPreviousClick: () -> Unit = {}, onPauseToggle: () -> Unit = {}, onNextClick: () -> Unit = {}, onFullScreenToggle: () -> Unit = {}, - onSpeedSelected: (Float) -> Unit = {}, - onIsLoopEnabledSelected: (Boolean) -> Unit = {}, + onSettingsToggle: () -> Unit = {}, onSeekBarValueChange: (Long) -> Unit = {}, - customization: ControlsCustomization = ControlsCustomization(), - settingsControlsCustomization: SettingsControlsCustomization = SettingsControlsCustomization() + customization: ControlsCustomization = ControlsCustomization() ) { PlayerControls( title = title, @@ -30,18 +25,14 @@ fun DefaultPlayerControls( isPlaying = isPlaying, isFullScreen = isFullScreen, hasEnded = hasEnded, - speed = speed, - isLoopEnabled = isLoopEnabled, currentTime = videoTimer, totalDuration = totalDuration, onPreviousClick = onPreviousClick, onPauseToggle = onPauseToggle, onNextClick = onNextClick, onFullScreenToggle = onFullScreenToggle, - onSpeedSelected = onSpeedSelected, - onIsLoopEnabledSelected = onIsLoopEnabledSelected, + onSettingsToggle = onSettingsToggle, onSeekBarValueChange = onSeekBarValueChange, - customization = customization, - settingsControlsCustomization = settingsControlsCustomization + customization = customization ) } diff --git a/androidenhancedvideoplayer/src/main/java/com/profusion/androidenhancedvideoplayer/components/EnhancedVideoPlayer.kt b/androidenhancedvideoplayer/src/main/java/com/profusion/androidenhancedvideoplayer/components/EnhancedVideoPlayer.kt index e3ac1edf..6b15ea8b 100644 --- a/androidenhancedvideoplayer/src/main/java/com/profusion/androidenhancedvideoplayer/components/EnhancedVideoPlayer.kt +++ b/androidenhancedvideoplayer/src/main/java/com/profusion/androidenhancedvideoplayer/components/EnhancedVideoPlayer.kt @@ -6,7 +6,9 @@ import androidx.compose.animation.core.* import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.material.* +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.* @@ -25,6 +27,7 @@ import androidx.media3.ui.PlayerView import com.profusion.androidenhancedvideoplayer.components.playerOverlay.ControlsCustomization import com.profusion.androidenhancedvideoplayer.components.playerOverlay.PlayerControls import com.profusion.androidenhancedvideoplayer.components.playerOverlay.SeekHandler +import com.profusion.androidenhancedvideoplayer.components.playerOverlay.Settings import com.profusion.androidenhancedvideoplayer.components.playerOverlay.SettingsControlsCustomization import com.profusion.androidenhancedvideoplayer.utils.TimeoutEffect import com.profusion.androidenhancedvideoplayer.utils.fillMaxSizeOnLandscape @@ -38,6 +41,7 @@ private const val CURRENT_TIME_TICK_IN_MS = 50L private const val PLAYER_CONTROLS_VISIBILITY_DURATION_IN_MS = 3000L // 3 seconds private const val DEFAULT_SEEK_TIME_MS = 10 * 1000L // 10 seconds +@OptIn(ExperimentalMaterial3Api::class) @androidx.annotation.OptIn(UnstableApi::class) @Composable fun EnhancedVideoPlayer( @@ -79,6 +83,7 @@ fun EnhancedVideoPlayer( mutableStateOf(exoPlayer.currentMediaItem?.mediaMetadata?.title?.toString()) } val isFullScreen = orientation == Configuration.ORIENTATION_LANDSCAPE + var isSettingsOpen by rememberSaveable { mutableStateOf(false) } if (enableImmersiveMode) { val shouldShowSystemUi = !isFullScreen @@ -161,46 +166,49 @@ fun EnhancedVideoPlayer( setControlsVisibility = ::setControlsVisibility, transformSeekIncrementRatio = transformSeekIncrementRatio ) + PlayerControls( + title = title, + isVisible = isControlsVisible, + isPlaying = isPlaying, + isFullScreen = isFullScreen, + hasEnded = hasEnded, + totalDuration = totalDuration, + currentTime = { currentTime }, + onPreviousClick = exoPlayer::seekToPrevious, + onNextClick = exoPlayer::seekToNext, + onPauseToggle = when { + hasEnded -> exoPlayer::seekToDefaultPosition + isPlaying -> exoPlayer::pause + else -> exoPlayer::play + }, + onFullScreenToggle = { + when (isFullScreen) { + true -> context.setPortrait() + false -> context.setLandscape() + } + }, + onSettingsToggle = { isSettingsOpen = !isSettingsOpen }, + onSeekBarValueChange = exoPlayer::seekTo, + customization = controlsCustomization + ) } - PlayerControls( - title = title, - isVisible = isControlsVisible, - isPlaying = isPlaying, - isFullScreen = isFullScreen, - hasEnded = hasEnded, - speed = speed, - isLoopEnabled = loop, - totalDuration = totalDuration, - currentTime = { currentTime }, - onPreviousClick = exoPlayer::seekToPrevious, - onNextClick = exoPlayer::seekToNext, - onPauseToggle = when { - hasEnded -> exoPlayer::seekToDefaultPosition - isPlaying -> exoPlayer::pause - else -> exoPlayer::play - }, - onFullScreenToggle = { - when (isFullScreen) { - true -> context.setPortrait() - false -> context.setLandscape() - } - }, - onSpeedSelected = exoPlayer::setPlaybackSpeed, - onIsLoopEnabledSelected = { value -> - exoPlayer.repeatMode = if (value) { - ExoPlayer.REPEAT_MODE_ALL - } else { - ExoPlayer.REPEAT_MODE_OFF - } - }, - onSeekBarValueChange = exoPlayer::seekTo, - customization = controlsCustomization, - settingsControlsCustomization = settingsControlsCustomization, - modifier = Modifier - .matchParentSize() - .testTag("PlayerControlsParent") - ) + if (isSettingsOpen) { + Settings( + onDismissRequest = { isSettingsOpen = false }, + speed = speed, + isLoopEnabled = loop, + onSpeedSelected = exoPlayer::setPlaybackSpeed, + onIsLoopEnabledSelected = { value -> + exoPlayer.repeatMode = if (value) { + ExoPlayer.REPEAT_MODE_ALL + } else { + ExoPlayer.REPEAT_MODE_OFF + } + }, + customization = settingsControlsCustomization + ) + } } } } diff --git a/androidenhancedvideoplayer/src/main/java/com/profusion/androidenhancedvideoplayer/components/playerOverlay/BottomControls.kt b/androidenhancedvideoplayer/src/main/java/com/profusion/androidenhancedvideoplayer/components/playerOverlay/BottomControls.kt index bffd5374..1f451b2b 100644 --- a/androidenhancedvideoplayer/src/main/java/com/profusion/androidenhancedvideoplayer/components/playerOverlay/BottomControls.kt +++ b/androidenhancedvideoplayer/src/main/java/com/profusion/androidenhancedvideoplayer/components/playerOverlay/BottomControls.kt @@ -8,14 +8,11 @@ import androidx.compose.foundation.layout.absolutePadding import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -24,20 +21,15 @@ import androidx.compose.ui.platform.testTag import com.profusion.androidenhancedvideoplayer.styling.Dimensions import com.profusion.androidenhancedvideoplayer.utils.formatElapsedTime -@OptIn(ExperimentalMaterial3Api::class) @Composable fun BottomControls( isFullScreen: Boolean, - speed: Float, - isLoopEnabled: Boolean, currentTime: () -> Long, totalDuration: Long, - onSpeedSelected: (Float) -> Unit, - onIsLoopEnabledSelected: (Boolean) -> Unit, + onSettingsToggle: () -> Unit, onFullScreenToggle: () -> Unit, onSeekBarValueChange: (Long) -> Unit, customization: ControlsCustomization, - settingsControlsCustomization: SettingsControlsCustomization, modifier: Modifier = Modifier ) { Column( @@ -54,8 +46,6 @@ fun BottomControls( Row( verticalAlignment = Alignment.CenterVertically ) { - var isSettingsOpen by rememberSaveable { mutableStateOf(false) } - Text( text = formatElapsedTime(currentTime(), totalDuration), style = MaterialTheme.typography.titleMedium.copy( @@ -65,7 +55,7 @@ fun BottomControls( ) Spacer(modifier = Modifier.weight(1f)) IconButton( - onClick = { isSettingsOpen = !isSettingsOpen }, + onClick = onSettingsToggle, modifier = Modifier.testTag("SettingsButton") ) { customization.settingsIconContent() @@ -79,17 +69,6 @@ fun BottomControls( false -> customization.fullScreenIconContent() } } - - if (isSettingsOpen) { - Settings( - onDismissRequest = { isSettingsOpen = false }, - speed = speed, - isLoopEnabled = isLoopEnabled, - onSpeedSelected = onSpeedSelected, - onIsLoopEnabledSelected = onIsLoopEnabledSelected, - customization = settingsControlsCustomization - ) - } } } } diff --git a/androidenhancedvideoplayer/src/main/java/com/profusion/androidenhancedvideoplayer/components/playerOverlay/PlayerControls.kt b/androidenhancedvideoplayer/src/main/java/com/profusion/androidenhancedvideoplayer/components/playerOverlay/PlayerControls.kt index a942cb1a..b11141df 100644 --- a/androidenhancedvideoplayer/src/main/java/com/profusion/androidenhancedvideoplayer/components/playerOverlay/PlayerControls.kt +++ b/androidenhancedvideoplayer/src/main/java/com/profusion/androidenhancedvideoplayer/components/playerOverlay/PlayerControls.kt @@ -28,19 +28,15 @@ fun PlayerControls( isPlaying: Boolean, isFullScreen: Boolean, hasEnded: Boolean, - speed: Float, - isLoopEnabled: Boolean, currentTime: () -> Long, totalDuration: Long, onPreviousClick: () -> Unit, onPauseToggle: () -> Unit, onNextClick: () -> Unit, onFullScreenToggle: () -> Unit, - onSpeedSelected: (Float) -> Unit, - onIsLoopEnabledSelected: (Boolean) -> Unit, + onSettingsToggle: () -> Unit, onSeekBarValueChange: (Long) -> Unit, - customization: ControlsCustomization, - settingsControlsCustomization: SettingsControlsCustomization + customization: ControlsCustomization ) { PlayerControlsScaffold( modifier = modifier.testTag("PlayerControlsParent"), @@ -53,16 +49,12 @@ fun PlayerControls( bottomContent = { BottomControls( isFullScreen = isFullScreen, - speed = speed, - isLoopEnabled = isLoopEnabled, currentTime = currentTime, totalDuration = totalDuration, onFullScreenToggle = onFullScreenToggle, - onSpeedSelected = onSpeedSelected, - onIsLoopEnabledSelected = onIsLoopEnabledSelected, + onSettingsToggle = onSettingsToggle, onSeekBarValueChange = onSeekBarValueChange, - customization = customization, - settingsControlsCustomization = settingsControlsCustomization + customization = customization ) } ) { @@ -87,18 +79,14 @@ private fun PreviewPlayerControls() { isPlaying = true, hasEnded = false, isFullScreen = false, - speed = 1f, - isLoopEnabled = false, currentTime = { 0L }, totalDuration = 0L, onPreviousClick = {}, onPauseToggle = {}, onNextClick = {}, onFullScreenToggle = {}, - onSpeedSelected = {}, - onIsLoopEnabledSelected = {}, + onSettingsToggle = {}, onSeekBarValueChange = {}, - customization = ControlsCustomization(), - settingsControlsCustomization = SettingsControlsCustomization() + customization = ControlsCustomization() ) }