Adds a border in the image dialog to avoid overriding controllers.

This commit is contained in:
Vitor Pamplona
2023-10-15 17:07:35 -04:00
parent 33f8b6d6d8
commit 4028018605
2 changed files with 67 additions and 8 deletions
@@ -46,8 +46,10 @@ import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.isFinite import androidx.compose.ui.unit.isFinite
import androidx.compose.ui.unit.isSpecified
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleEventObserver
@@ -149,6 +151,7 @@ fun VideoView(
title: String? = null, title: String? = null,
thumb: VideoThumb? = null, thumb: VideoThumb? = null,
roundedCorner: Boolean, roundedCorner: Boolean,
topPaddingForControllers: Dp = Dp.Unspecified,
waveform: ImmutableList<Int>? = null, waveform: ImmutableList<Int>? = null,
artworkUri: String? = null, artworkUri: String? = null,
authorName: String? = null, authorName: String? = null,
@@ -166,6 +169,7 @@ fun VideoView(
title = title, title = title,
thumb = thumb, thumb = thumb,
roundedCorner = roundedCorner, roundedCorner = roundedCorner,
topPaddingForControllers = topPaddingForControllers,
waveform = waveform, waveform = waveform,
artworkUri = artworkUri, artworkUri = artworkUri,
authorName = authorName, authorName = authorName,
@@ -185,6 +189,7 @@ fun VideoViewInner(
title: String? = null, title: String? = null,
thumb: VideoThumb? = null, thumb: VideoThumb? = null,
roundedCorner: Boolean, roundedCorner: Boolean,
topPaddingForControllers: Dp = Dp.Unspecified,
waveform: ImmutableList<Int>? = null, waveform: ImmutableList<Int>? = null,
artworkUri: String? = null, artworkUri: String? = null,
authorName: String? = null, authorName: String? = null,
@@ -246,6 +251,7 @@ fun VideoViewInner(
controller = controller, controller = controller,
thumbData = thumb, thumbData = thumb,
roundedCorner = roundedCorner, roundedCorner = roundedCorner,
topPaddingForControllers = topPaddingForControllers,
waveform = waveform, waveform = waveform,
keepPlaying = keepPlaying, keepPlaying = keepPlaying,
automaticallyStartPlayback = automaticallyStartPlayback, automaticallyStartPlayback = automaticallyStartPlayback,
@@ -514,6 +520,7 @@ private fun RenderVideoPlayer(
controller: MediaController, controller: MediaController,
thumbData: VideoThumb?, thumbData: VideoThumb?,
roundedCorner: Boolean, roundedCorner: Boolean,
topPaddingForControllers: Dp = Dp.Unspecified,
waveform: ImmutableList<Int>? = null, waveform: ImmutableList<Int>? = null,
keepPlaying: MutableState<Boolean>, keepPlaying: MutableState<Boolean>,
automaticallyStartPlayback: MutableState<Boolean>, automaticallyStartPlayback: MutableState<Boolean>,
@@ -587,7 +594,17 @@ private fun RenderVideoPlayer(
controller.volume < 0.001 controller.volume < 0.001
} }
MuteButton(controllerVisible, startingMuteState) { mute: Boolean -> MuteButton(
controllerVisible,
startingMuteState,
remember {
if (topPaddingForControllers.isSpecified) {
Modifier.padding(top = topPaddingForControllers)
} else {
Modifier
}
}
) { mute: Boolean ->
// makes the new setting the default for new creations. // makes the new setting the default for new creations.
DefaultMutedSetting.value = mute DefaultMutedSetting.value = mute
@@ -601,7 +618,17 @@ private fun RenderVideoPlayer(
controller.volume = if (mute) 0f else 1f controller.volume = if (mute) 0f else 1f
} }
KeepPlayingButton(keepPlaying, controllerVisible, remember { Modifier.align(Alignment.TopEnd) }) { newKeepPlaying: Boolean -> KeepPlayingButton(
keepPlaying,
controllerVisible,
remember {
if (topPaddingForControllers.isSpecified) {
Modifier.align(Alignment.TopEnd).padding(top = topPaddingForControllers)
} else {
Modifier.align(Alignment.TopEnd)
}
}
) { newKeepPlaying: Boolean ->
// If something else is playing and the user marks this video to keep playing, stops the other one. // If something else is playing and the user marks this video to keep playing, stops the other one.
if (newKeepPlaying) { if (newKeepPlaying) {
if (keepPlayingMutex != null && keepPlayingMutex != controller) { if (keepPlayingMutex != null && keepPlayingMutex != controller) {
@@ -775,6 +802,7 @@ fun LayoutCoordinates.getDistanceToVertCenterIfVisible(view: View): Float? {
private fun MuteButton( private fun MuteButton(
controllerVisible: MutableState<Boolean>, controllerVisible: MutableState<Boolean>,
startingMuteState: Boolean, startingMuteState: Boolean,
modifier: Modifier,
toggle: (Boolean) -> Unit toggle: (Boolean) -> Unit
) { ) {
val holdOn = remember { val holdOn = remember {
@@ -794,6 +822,7 @@ private fun MuteButton(
AnimatedVisibility( AnimatedVisibility(
visible = holdOn.value || controllerVisible.value, visible = holdOn.value || controllerVisible.value,
modifier = modifier,
enter = fadeIn(), enter = fadeIn(),
exit = fadeOut() exit = fadeOut()
) { ) {
@@ -64,8 +64,10 @@ import androidx.compose.ui.text.Placeholder
import androidx.compose.ui.text.PlaceholderVerticalAlign import androidx.compose.ui.text.PlaceholderVerticalAlign
import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.isFinite import androidx.compose.ui.unit.isFinite
import androidx.compose.ui.unit.isSpecified
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import androidx.compose.ui.window.DialogWindowProvider import androidx.compose.ui.window.DialogWindowProvider
@@ -92,6 +94,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
import com.vitorpamplona.amethyst.ui.theme.Size20dp import com.vitorpamplona.amethyst.ui.theme.Size20dp
import com.vitorpamplona.amethyst.ui.theme.Size24dp import com.vitorpamplona.amethyst.ui.theme.Size24dp
import com.vitorpamplona.amethyst.ui.theme.Size30dp import com.vitorpamplona.amethyst.ui.theme.Size30dp
import com.vitorpamplona.amethyst.ui.theme.Size55dp
import com.vitorpamplona.amethyst.ui.theme.Size5dp import com.vitorpamplona.amethyst.ui.theme.Size5dp
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
import com.vitorpamplona.amethyst.ui.theme.imageModifier import com.vitorpamplona.amethyst.ui.theme.imageModifier
@@ -234,7 +237,7 @@ fun ZoomableContentView(
} }
when (content) { when (content) {
is ZoomableUrlImage -> UrlImageView(content, mainImageModifier, accountViewModel) is ZoomableUrlImage -> UrlImageView(content, mainImageModifier, accountViewModel = accountViewModel)
is ZoomableUrlVideo -> VideoView( is ZoomableUrlVideo -> VideoView(
videoUri = content.url, videoUri = content.url,
title = content.description, title = content.description,
@@ -246,7 +249,7 @@ fun ZoomableContentView(
accountViewModel = accountViewModel accountViewModel = accountViewModel
) )
is ZoomableLocalImage -> LocalImageView(content, mainImageModifier, accountViewModel) is ZoomableLocalImage -> LocalImageView(content, mainImageModifier, accountViewModel = accountViewModel)
is ZoomableLocalVideo -> is ZoomableLocalVideo ->
content.localFile?.let { content.localFile?.let {
VideoView( VideoView(
@@ -271,6 +274,7 @@ fun ZoomableContentView(
private fun LocalImageView( private fun LocalImageView(
content: ZoomableLocalImage, content: ZoomableLocalImage,
mainImageModifier: Modifier, mainImageModifier: Modifier,
topPaddingForControllers: Dp = Dp.Unspecified,
accountViewModel: AccountViewModel?, accountViewModel: AccountViewModel?,
alwayShowImage: Boolean = false alwayShowImage: Boolean = false
) { ) {
@@ -304,7 +308,11 @@ private fun LocalImageView(
if (maxHeight.isFinite) ContentScale.Fit else ContentScale.FillWidth if (maxHeight.isFinite) ContentScale.Fit else ContentScale.FillWidth
} }
val verifierModifier = Modifier.align(Alignment.TopEnd) val verifierModifier = if (topPaddingForControllers.isSpecified) {
Modifier.padding(top = topPaddingForControllers).align(Alignment.TopEnd)
} else {
Modifier.align(Alignment.TopEnd)
}
val painterState = remember { val painterState = remember {
mutableStateOf<AsyncImagePainter.State?>(null) mutableStateOf<AsyncImagePainter.State?>(null)
@@ -340,6 +348,7 @@ private fun LocalImageView(
private fun UrlImageView( private fun UrlImageView(
content: ZoomableUrlImage, content: ZoomableUrlImage,
mainImageModifier: Modifier, mainImageModifier: Modifier,
topPaddingForControllers: Dp = Dp.Unspecified,
accountViewModel: AccountViewModel?, accountViewModel: AccountViewModel?,
alwayShowImage: Boolean = false alwayShowImage: Boolean = false
) { ) {
@@ -374,7 +383,11 @@ private fun UrlImageView(
if (maxHeight.isFinite) ContentScale.Fit else ContentScale.FillWidth if (maxHeight.isFinite) ContentScale.Fit else ContentScale.FillWidth
} }
val verifierModifier = Modifier.align(Alignment.TopEnd) val verifierModifier = if (topPaddingForControllers.isSpecified) {
Modifier.padding(top = topPaddingForControllers).align(Alignment.TopEnd)
} else {
Modifier.align(Alignment.TopEnd)
}
val painterState = remember { val painterState = remember {
mutableStateOf<AsyncImagePainter.State?>(null) mutableStateOf<AsyncImagePainter.State?>(null)
@@ -679,6 +692,7 @@ private fun DialogContent(
RenderImageOrVideo( RenderImageOrVideo(
content = allImages[index], content = allImages[index],
roundedCorner = false, roundedCorner = false,
topPaddingForControllers = Size55dp,
onControllerVisibilityChanged = { onControllerVisibilityChanged = {
controllerVisible.value = it controllerVisible.value = it
}, },
@@ -689,6 +703,7 @@ private fun DialogContent(
RenderImageOrVideo( RenderImageOrVideo(
content = imageUrl, content = imageUrl,
roundedCorner = false, roundedCorner = false,
topPaddingForControllers = Size55dp,
onControllerVisibilityChanged = { onControllerVisibilityChanged = {
controllerVisible.value = it controllerVisible.value = it
}, },
@@ -798,6 +813,7 @@ private fun ShareImageAction(
private fun RenderImageOrVideo( private fun RenderImageOrVideo(
content: ZoomableContent, content: ZoomableContent,
roundedCorner: Boolean, roundedCorner: Boolean,
topPaddingForControllers: Dp = Dp.Unspecified,
onControllerVisibilityChanged: ((Boolean) -> Unit)? = null, onControllerVisibilityChanged: ((Boolean) -> Unit)? = null,
accountViewModel: AccountViewModel accountViewModel: AccountViewModel
) { ) {
@@ -806,7 +822,13 @@ private fun RenderImageOrVideo(
.zoomable(rememberZoomState()) .zoomable(rememberZoomState())
if (content is ZoomableUrlImage) { if (content is ZoomableUrlImage) {
UrlImageView(content = content, mainImageModifier = mainModifier, accountViewModel, alwayShowImage = true) UrlImageView(
content = content,
mainImageModifier = mainModifier,
topPaddingForControllers = topPaddingForControllers,
accountViewModel,
alwayShowImage = true
)
} else if (content is ZoomableUrlVideo) { } else if (content is ZoomableUrlVideo) {
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxSize(1f)) { Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxSize(1f)) {
VideoView( VideoView(
@@ -815,13 +837,20 @@ private fun RenderImageOrVideo(
artworkUri = content.artworkUri, artworkUri = content.artworkUri,
authorName = content.authorName, authorName = content.authorName,
roundedCorner = roundedCorner, roundedCorner = roundedCorner,
topPaddingForControllers = topPaddingForControllers,
onControllerVisibilityChanged = onControllerVisibilityChanged, onControllerVisibilityChanged = onControllerVisibilityChanged,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
alwaysShowVideo = true alwaysShowVideo = true
) )
} }
} else if (content is ZoomableLocalImage) { } else if (content is ZoomableLocalImage) {
LocalImageView(content = content, mainImageModifier = mainModifier, accountViewModel, alwayShowImage = true) LocalImageView(
content = content,
mainImageModifier = mainModifier,
topPaddingForControllers = topPaddingForControllers,
accountViewModel,
alwayShowImage = true
)
} else if (content is ZoomableLocalVideo) { } else if (content is ZoomableLocalVideo) {
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxSize(1f)) { Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxSize(1f)) {
content.localFile?.let { content.localFile?.let {
@@ -831,6 +860,7 @@ private fun RenderImageOrVideo(
artworkUri = content.artworkUri, artworkUri = content.artworkUri,
authorName = content.authorName, authorName = content.authorName,
roundedCorner = roundedCorner, roundedCorner = roundedCorner,
topPaddingForControllers = topPaddingForControllers,
onControllerVisibilityChanged = onControllerVisibilityChanged, onControllerVisibilityChanged = onControllerVisibilityChanged,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
alwaysShowVideo = true alwaysShowVideo = true