Skip to content
This repository has been archived by the owner on Sep 23, 2024. It is now read-only.

Commit

Permalink
Video updates (#572)
Browse files Browse the repository at this point in the history
- Removing exoplayer from feeds and new post screen. It's kinda buggy
and can cause performance issues.
- Adding play button to videos in feeds
- Setting up custom exceptions for network call exceptions

---------

Co-authored-by: John Oberhauser <j.git-global@obez.io>
  • Loading branch information
JohnOberhauser and John Oberhauser authored May 30, 2024
1 parent 4e18b23 commit 4dd8cfe
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 55 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package social.firefly.common

sealed class LoadState {
object LOADING : social.firefly.common.LoadState()
data object LOADING : LoadState()

object LOADED : social.firefly.common.LoadState()
data object LOADED : LoadState()

object ERROR : social.firefly.common.LoadState()
data object ERROR : LoadState()
}
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ object FfIcons {
@Composable
fun play() = painterResource(id = R.drawable.play)

@Composable
fun playCircle() = painterResource(id = R.drawable.play_circle)

@Composable
fun plus() = painterResource(id = R.drawable.plus)

Expand Down Expand Up @@ -221,9 +224,6 @@ object FfIcons {
@Composable
fun caret() = rememberVectorPainter(image = Icons.Rounded.KeyboardArrowUp)

@Composable
fun bookmarkBorder() = rememberVectorPainter(image = Icons.Rounded.BookmarkBorder)

@Composable
fun public() = rememberVectorPainter(image = Icons.Rounded.Public)

Expand All @@ -245,24 +245,12 @@ object FfIcons {
@Composable
fun volumeUp() = rememberVectorPainter(image = Icons.Rounded.VolumeUp)

@Composable
fun send() = rememberVectorPainter(image = Icons.Rounded.Send)

@Composable
fun addPhotoAlternate() = rememberVectorPainter(image = Icons.Rounded.AddPhotoAlternate)

@Composable
fun poll() = rememberVectorPainter(image = Icons.Rounded.Poll)

@Composable
fun delete() = rememberVectorPainter(image = Icons.Rounded.Delete)

@Composable
fun deleteOutline() = rememberVectorPainter(image = Icons.Rounded.DeleteOutline)

@Composable
fun addCircleOutline() = rememberVectorPainter(image = Icons.Rounded.AddCircleOutline)

// This isn't part of the design system
object Sizes {
val small = 16.dp // Used for smaller icons
Expand Down
9 changes: 9 additions & 0 deletions core/designsystem/src/main/res/drawable/play_circle.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="256"
android:viewportHeight="256">
<path
android:pathData="M128,24A104,104 0,1 0,232 128,104.11 104.11,0 0,0 128,24ZM128,216a88,88 0,1 1,88 -88A88.1,88.1 0,0 1,128 216ZM176.24,121.22 L112.24,81.22A8,8 0,0 0,100 88v80a8,8 0,0 0,12.24 6.78l64,-40a8,8 0,0 0,0 -13.56ZM116,153.57L116,102.43L156.91,128Z"
android:fillColor="#000000"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package social.firefly.core.model.exceptions

class HttpException(
val code: Int,
val errorMessage: String,
override val cause: Throwable,
) : IllegalStateException()
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ package social.firefly.core.network.mastodon

import io.ktor.client.HttpClient
import io.ktor.client.HttpClientConfig
import io.ktor.client.call.body
import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.engine.HttpClientEngineConfig
import io.ktor.client.engine.HttpClientEngineFactory
import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.engine.okhttp.OkHttpConfig
import io.ktor.client.plugins.ClientRequestException
import io.ktor.client.plugins.HttpResponseValidator
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.json.Json
import okhttp3.logging.HttpLoggingInterceptor
import org.koin.core.qualifier.named
import org.koin.dsl.module
import social.firefly.core.model.exceptions.HttpException
import social.firefly.core.network.mastodon.interceptors.AuthCredentialInterceptor
import social.firefly.core.network.mastodon.ktor.AccountApiImpl
import social.firefly.core.network.mastodon.ktor.AppApiImpl
Expand All @@ -33,6 +37,7 @@ import social.firefly.core.network.mastodon.ktor.StatusApiImpl
import social.firefly.core.network.mastodon.ktor.TagsApiImpl
import social.firefly.core.network.mastodon.ktor.TimelineApiImpl
import social.firefly.core.network.mastodon.ktor.TrendsApiImpl
import social.firefly.core.network.mastodon.model.responseBody.NetworkError
import java.util.concurrent.TimeUnit

val mastodonNetworkModule =
Expand All @@ -51,6 +56,19 @@ val mastodonNetworkModule =
})
}
expectSuccess = true
HttpResponseValidator {
handleResponseExceptionWithRequest { cause, _ ->
if (cause !is ClientRequestException) return@handleResponseExceptionWithRequest

val errorMessage: NetworkError = cause.response.body()

throw HttpException(
code = cause.response.status.value,
errorMessage = errorMessage.error,
cause = cause,
)
}
}
}
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
package social.firefly.core.network.mastodon.model.responseBody

/**
* Represents an API error.
*/
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class NetworkError(
/**
* The error message.
*/
@SerialName("error")
val error: String,
/**
* A longer description of the error.
*/
val errorDescription: String? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ fun AttachmentMedia(
val context = LocalContext.current

when (fileType) {
FileType.VIDEO -> {
VideoPlayer(uri = uri, loadState = loadState)
}

FileType.VIDEO -> Image(imageUri = uri)
FileType.IMAGE -> Image(imageUri = uri)
FileType.UNKNOWN -> {}
}
Expand Down Expand Up @@ -98,8 +95,7 @@ fun AttachmentMedia(
@Composable
private fun Image(imageUri: Uri) {
AsyncImage(
modifier =
Modifier
modifier = Modifier
.fillMaxWidth(),
model = imageUri,
contentDescription = "",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
package social.firefly.core.ui.common.media

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.style.LineHeightStyle
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import coil.compose.AsyncImage
import social.firefly.core.designsystem.icon.FfIcons
import social.firefly.core.designsystem.theme.FfRadius
import social.firefly.core.designsystem.theme.FfTheme
import social.firefly.core.model.Attachment
import social.firefly.core.ui.common.utils.media
import kotlin.math.roundToInt
Expand Down Expand Up @@ -96,13 +105,23 @@ private fun SingleAttachment(
val aspectRatio by remember {
mutableFloatStateOf(attachment.meta?.calculateAspectRatio() ?: 1f)
}
attachment.url?.toUri()?.let {
VideoPlayer(
Box {
Attachment(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(aspectRatio),
uri = it,
onVideoClicked = { onAttachmentClicked(attachment) },
attachment = attachment,
onAttachmentClicked = onAttachmentClicked,
)

Icon(
modifier = Modifier
.align(Alignment.Center)
.size(100.dp)
.clip(CircleShape)
.background(FfTheme.colors.playerControlsBackground),
painter = FfIcons.playCircle(),
contentDescription = null
)
}
}
Expand All @@ -111,13 +130,23 @@ private fun SingleAttachment(
val aspectRatio by remember {
mutableFloatStateOf(attachment.meta?.calculateAspectRatio() ?: 1f)
}
attachment.url?.toUri()?.let {
VideoPlayer(
Box {
Attachment(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(aspectRatio),
uri = it,
onVideoClicked = { onAttachmentClicked(attachment) },
attachment = attachment,
onAttachmentClicked = onAttachmentClicked,
)

Icon(
modifier = Modifier
.align(Alignment.Center)
.size(100.dp)
.clip(CircleShape)
.background(FfTheme.colors.playerControlsBackground),
painter = FfIcons.playCircle(),
contentDescription = null
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import android.net.Uri
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
Expand Down Expand Up @@ -41,6 +40,7 @@ fun VideoPlayer(
uri: Uri,
modifier: Modifier = Modifier,
loadState: LoadState = LoadState.LOADED,
showMuteButton: Boolean = true,
onVideoClicked: (() -> Unit)? = null,
) {
Box(
Expand Down Expand Up @@ -96,7 +96,7 @@ fun VideoPlayer(
}

// Mute button
if (loadState == LoadState.LOADED) {
if (loadState == LoadState.LOADED && showMuteButton) {
MuteButton(exoPlayer = exoPlayer)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.MutableSharedFlow
import social.firefly.common.annotations.PreferUseCase
import social.firefly.common.utils.StringFactory
import social.firefly.core.model.ImageState
import social.firefly.core.model.MediaUpdate
import social.firefly.core.model.StatusVisibility
import social.firefly.core.model.request.MediaAttributes
import social.firefly.core.model.exceptions.HttpException
import social.firefly.core.model.request.PollCreate
import social.firefly.core.model.request.StatusCreate
import social.firefly.core.navigation.usecases.ShowSnackbar
Expand Down Expand Up @@ -81,6 +79,12 @@ class PostStatus internal constructor(
saveStatusToDatabase(status)
getThread.pushNewStatus(status.statusId)
timelineRepository.insertStatusIntoTimelines(status)
} catch (e: HttpException) {
showSnackbar(
text = StringFactory.literal(e.errorMessage),
isError = true,
)
throw PostStatusFailedException(e)
} catch (e: Exception) {
showSnackbar(
text = StringFactory.resource(R.string.error_sending_post_toast),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ import org.koin.core.parameter.parametersOf
import social.firefly.core.designsystem.icon.FfIcons
import social.firefly.core.designsystem.theme.FfTheme
import social.firefly.core.model.Attachment
import social.firefly.core.navigation.NavigationDestination
import social.firefly.core.navigation.navigationModule
import social.firefly.core.ui.common.FfSurface
import social.firefly.core.ui.common.appbar.FfCloseableTopAppBar
Expand Down

0 comments on commit 4dd8cfe

Please sign in to comment.