From 3dedfbe022683e72ad7d39676cb4326256fb37c7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 28 Oct 2022 16:21:10 +0200 Subject: [PATCH] Avatar working - WIP --- .../android/x/sdk/matrix/MatrixClient.kt | 4 +++ .../x/ui/screen/roomlist/MatrixUser.kt | 1 + .../x/ui/screen/roomlist/RoomListActivity.kt | 11 ++---- .../x/ui/screen/roomlist/RoomListViewModel.kt | 9 +++-- libraries/ui/theme/build.gradle | 2 ++ .../android/x/ui/theme/components/Avatar.kt | 36 +++++++++++++++++++ 6 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 libraries/ui/theme/src/main/java/io/element/android/x/ui/theme/components/Avatar.kt diff --git a/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/MatrixClient.kt b/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/MatrixClient.kt index d1528d363f..7cf37ebc5b 100644 --- a/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/MatrixClient.kt +++ b/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/MatrixClient.kt @@ -65,9 +65,13 @@ class MatrixClient internal constructor( sessionStore.reset() } + fun userId(): String = client.userId() fun username(): String = client.displayName() fun avatarUrl(): String = client.avatarUrl() + fun loadMedia(source: MediaSource) = client.getMediaContent(source) + fun loadMedia2(mxcUrl: String) = client.getMediaContent(mediaSourceFromUrl(mxcUrl)) + interface SlidingSyncListener { fun onSyncUpdate(summary: UpdateSummary, rooms: List) } diff --git a/libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/MatrixUser.kt b/libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/MatrixUser.kt index aef8b72151..f62d0733f5 100644 --- a/libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/MatrixUser.kt +++ b/libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/MatrixUser.kt @@ -3,4 +3,5 @@ package io.element.android.x.ui.screen.roomlist data class MatrixUser( val username: String? = null, val avatarUrl: String? = null, + val avatarData: List? = null, ) diff --git a/libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/RoomListActivity.kt b/libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/RoomListActivity.kt index ff7cce00e7..cfa77df37f 100644 --- a/libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/RoomListActivity.kt +++ b/libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/RoomListActivity.kt @@ -1,6 +1,7 @@ package io.element.android.x.ui.screen.roomlist import android.os.Bundle +import android.util.Log import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.setContent @@ -23,6 +24,7 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.compose.collectAsState import com.airbnb.mvrx.compose.mavericksViewModel import io.element.android.x.ui.theme.ElementXTheme +import io.element.android.x.ui.theme.components.Avatar import org.matrix.rustcomponents.sdk.Room class RoomListActivity : ComponentActivity() { @@ -107,14 +109,7 @@ class RoomListActivity : ComponentActivity() { Row( modifier = Modifier.fillMaxWidth() ) { - Image( - painter = rememberAsyncImagePainter(matrixUser.avatarUrl), - contentDescription = null, - modifier = Modifier - .size(48.dp) - .clip(CircleShape) - .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape) - ) + Avatar(data = matrixUser.avatarData) Spacer(modifier = Modifier.width(8.dp)) Text("${matrixUser.username}") } diff --git a/libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/RoomListViewModel.kt b/libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/RoomListViewModel.kt index 4f473103dc..95cd777e75 100644 --- a/libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/RoomListViewModel.kt +++ b/libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/RoomListViewModel.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.launch import org.matrix.rustcomponents.sdk.Room import org.matrix.rustcomponents.sdk.StoppableSpawn import org.matrix.rustcomponents.sdk.UpdateSummary +import org.matrix.rustcomponents.sdk.mediaSourceFromUrl class RoomListViewModel(initialState: RoomListViewState) : MavericksViewModel(initialState), MatrixClient.SlidingSyncListener { @@ -29,11 +30,15 @@ class RoomListViewModel(initialState: RoomListViewState) : private fun handleInit() { viewModelScope.launch { val client = getClient() + val url = client.avatarUrl() + val mediaSource = mediaSourceFromUrl(url) + mediaSource.url() setState { copy( user = MatrixUser( - tryOrNull { client.username() } ?: "Room list", - tryOrNull { client.avatarUrl() } ?: "https://previews.123rf.com/images/lkeskinen/lkeskinen1802/lkeskinen180208322/95731150-exemple-de-tampon-%C3%A9tiquette-typographique-timbre-ou-ic%C3%B4ne.jpg", + username = tryOrNull { client.username() } ?: "Room list", + avatarUrl = mediaSource.url(), + avatarData = client.loadMedia2(url) ) ) } diff --git a/libraries/ui/theme/build.gradle b/libraries/ui/theme/build.gradle index fcc9ed818b..796034f2cf 100644 --- a/libraries/ui/theme/build.gradle +++ b/libraries/ui/theme/build.gradle @@ -47,4 +47,6 @@ dependencies { debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version" implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1" + + implementation 'io.coil-kt:coil-compose:2.2.1' } \ No newline at end of file diff --git a/libraries/ui/theme/src/main/java/io/element/android/x/ui/theme/components/Avatar.kt b/libraries/ui/theme/src/main/java/io/element/android/x/ui/theme/components/Avatar.kt new file mode 100644 index 0000000000..ab5f815bd2 --- /dev/null +++ b/libraries/ui/theme/src/main/java/io/element/android/x/ui/theme/components/Avatar.kt @@ -0,0 +1,36 @@ +package io.element.android.x.ui.theme.components + +import android.util.Log +import androidx.compose.foundation.Image +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import coil.compose.rememberAsyncImagePainter + +/** + * TODO fallback Avatar + */ +@Composable +fun Avatar( + data: List?, + size: Int = 48, +) { + Image( + painter = rememberAsyncImagePainter( + model = data?.toUByteArray()?.toByteArray(), + onError = { + Log.e("TAG", "Error $it\n${it.result}", it.result.throwable) + }), + contentDescription = null, + modifier = Modifier + .size(size.dp) + .clip(CircleShape) + .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape) + ) +} +