Skip to content

Commit

Permalink
Document attachment widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
wingio committed Dec 6, 2023
1 parent b83ca57 commit 9c51c2b
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ import androidx.compose.ui.unit.dp
import com.google.accompanist.pager.HorizontalPagerIndicator
import xyz.wingio.dimett.rest.dto.post.MediaAttachment

@OptIn(ExperimentalFoundationApi::class)
/**
* Just shows [SingleAttachment] if [attachments] only contains one item, otherwise uses a [HorizontalPager]
*/
@Composable
@OptIn(ExperimentalFoundationApi::class)
fun Attachments(
attachments: List<MediaAttachment>
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ import androidx.media3.exoplayer.source.ProgressiveMediaSource
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
import xyz.wingio.dimett.rest.dto.post.MediaAttachment

/**
* For audio attachments we just use the [MediaControls]
*/
// TODO: Make more distinct player for audio
@Composable
@OptIn(UnstableApi::class)
fun AudioAttachment(
attachment: MediaAttachment
) {
val context = LocalContext.current
val player = remember(context) {
val player = remember(context, attachment) {
val tSelector = DefaultTrackSelector(context)
ExoPlayer.Builder(context)
.setTrackSelector(tSelector)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
Expand All @@ -31,25 +32,38 @@ import kotlinx.coroutines.delay
import xyz.wingio.dimett.R
import kotlin.time.Duration.Companion.seconds

/**
* Displays controls such as a play/pause button and a seekbar
*
* @param player [ExoPlayer] instance getting controlled
*/
@Composable
fun MediaControls(
player: ExoPlayer
) {
// Whether or not the user is actively using the seekbar
var seeking by remember(player) {
mutableStateOf(false)
}

// Whether or not the video/audio is playing
var playing by remember(player) {
mutableStateOf(player.isPlaying)
}

// The length of the video/audio
var duration by remember(player) {
mutableStateOf(player.duration)
mutableLongStateOf(player.duration)
}

// Current position in the video/audio
var position by remember(player) {
mutableStateOf(player.currentPosition)
mutableLongStateOf(player.currentPosition)
}

DisposableEffect(player) {
val listener = object : Player.Listener {
// Updates all our state variables
override fun onIsPlayingChanged(isPlaying: Boolean) {
playing = isPlaying
duration = player.duration
Expand All @@ -58,10 +72,12 @@ fun MediaControls(
}
player.addListener(listener)

onDispose { player.removeListener(listener) }
onDispose { player.removeListener(listener) } // Remove the listener when the component leaves the scope
}

if (playing) {
LaunchedEffect(Unit) {
// We kinda have to do this bc ExoPlayer doesn't provide a listener for player position
while (!seeking) {
position = player.currentPosition
delay(1.seconds)
Expand All @@ -82,7 +98,7 @@ fun MediaControls(
player.pause()
else {
if (player.currentPosition >= player.duration)
player.seekTo(0)
player.seekTo(0) // Replay the media if its finished playing
player.play()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage

/**
* Adds an overlay on videos and gifs with the videos preview image, disappears after clicking
*
* @param previewUrl Url to the video/gifs preview image
* @param contentDescription Content description of the video/gif
* @param onPlay Called when the component is clicked
*/
@Composable
fun PlayButtonOverlay(
previewUrl: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ import androidx.media3.ui.PlayerView
import xyz.wingio.dimett.rest.dto.post.MediaAttachment
import xyz.wingio.dimett.ui.components.Text

/**
* Displays a silent looping video, as GIF is kind of a bad format
*/
@Composable
@OptIn(androidx.media3.common.util.UnstableApi::class)
fun SingleGifAttachment(
Expand All @@ -48,7 +51,7 @@ fun SingleGifAttachment(
mutableStateOf(false)
}

val player = remember(context) {
val player = remember(context, attachment) {
ExoPlayer.Builder(context).build().apply {
val dataSourceFactory = DefaultDataSource.Factory(context)
val source = ProgressiveMediaSource.Factory(dataSourceFactory)
Expand All @@ -66,7 +69,8 @@ fun SingleGifAttachment(
) {
val height = with(LocalDensity.current) {
((9f / 16f) * constraints.maxWidth).toDp()
}
} // Calculates the height so that the gif is always 16:9

Box(
modifier = Modifier
.shadow(3.dp, RoundedCornerShape(12.dp))
Expand All @@ -76,16 +80,17 @@ fun SingleGifAttachment(
) {
Box {
DisposableEffect(
AndroidView(factory = {
PlayerView(it).apply {
// As far as I know there isn't an existing compose wrapper for ExoPlayer
AndroidView(factory = { ctx ->
PlayerView(ctx).apply {
hideController()
useController = false
useController = false // Gifs don't need :)
this.player = player
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM

layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT
/* width = */ FrameLayout.LayoutParams.MATCH_PARENT,
/* height = */ FrameLayout.LayoutParams.WRAP_CONTENT
)
}
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package xyz.wingio.dimett.ui.widgets.attachments

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.fillMaxWidth
Expand All @@ -11,6 +12,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
Expand All @@ -23,6 +25,9 @@ import com.ondev.imageblurkt_lib.IBlurModel
import com.ondev.imageblurkt_lib.R
import xyz.wingio.dimett.rest.dto.post.MediaAttachment

/**
* Displays an image (with blurhash if supported)
*/
@OptIn(ExperimentalCoilApi::class)
@Composable
fun SingleImageAttachment(
Expand All @@ -33,11 +38,12 @@ fun SingleImageAttachment(
) {
val height = with(LocalDensity.current) {
((9f / 16f) * constraints.maxWidth).toDp()
}
} // Make sure the image is always 16:9

Box(
modifier = Modifier
.shadow(3.dp, RoundedCornerShape(12.dp))
.clip(RoundedCornerShape(12.dp))
.shadow(elevation = 3.dp, shape = RoundedCornerShape(12.dp), clip = true)
.background(Color.Black)
.fillMaxWidth()
.heightIn(max = height)
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,25 @@ import androidx.media3.ui.AspectRatioFrameLayout
import androidx.media3.ui.PlayerView
import xyz.wingio.dimett.rest.dto.post.MediaAttachment

/**
* Displays a basic video player
*/
@Composable
@OptIn(androidx.media3.common.util.UnstableApi::class)
fun VideoAttachment(attachment: MediaAttachment) {
val context = LocalContext.current

// Whether or not the MediaControls component is visible
var showControls by remember {
mutableStateOf(false)
}

// Whether or not the video is currently loading
var loading by remember {
mutableStateOf(false)
}

val player = remember(context) {
val player = remember(context, attachment) {
ExoPlayer.Builder(context).build().apply {
val dataSourceFactory = DefaultDataSource.Factory(context)
val source = ProgressiveMediaSource.Factory(dataSourceFactory)
Expand Down

0 comments on commit 9c51c2b

Please sign in to comment.