Browse Source

Merge pull request #3642 from element-hq/feature/fga/improve_avatar_rendering

Improve avatar rendering
pull/3662/head
ganfra 1 week ago committed by GitHub
parent
commit
7a85cdda9d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt
  2. 18
      libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatatarDataExt.kt
  3. 6
      libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/CoilMediaFetcher.kt
  4. 4
      libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderFactories.kt
  5. 3
      libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/MediaRequestDataFetcherFactory.kt
  6. 5
      libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotificationBitmapLoader.kt
  7. 9
      libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultRoomGroupMessageCreatorTest.kt

3
libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt

@ -7,7 +7,6 @@ @@ -7,7 +7,6 @@
package io.element.android.libraries.matrix.ui.media
import android.content.Context
import coil.ImageLoader
import coil.fetch.Fetcher
import coil.request.Options
@ -15,7 +14,6 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarData @@ -15,7 +14,6 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.matrix.api.MatrixClient
internal class AvatarDataFetcherFactory(
private val context: Context,
private val client: MatrixClient
) : Fetcher.Factory<AvatarData> {
override fun create(
@ -24,7 +22,6 @@ internal class AvatarDataFetcherFactory( @@ -24,7 +22,6 @@ internal class AvatarDataFetcherFactory(
imageLoader: ImageLoader
): Fetcher {
return CoilMediaFetcher(
scalingFunction = { context.resources.displayMetrics.density * it },
mediaLoader = client.mediaLoader,
mediaData = data.toMediaRequestData(),
options = options

18
libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatatarDataExt.kt

@ -9,11 +9,25 @@ package io.element.android.libraries.matrix.ui.media @@ -9,11 +9,25 @@ package io.element.android.libraries.matrix.ui.media
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.matrix.api.media.MediaSource
import kotlin.math.roundToLong
/**
* The size in pixel of the thumbnail to generate for the avatar.
* This is not the size of the avatar displayed in the UI but the size to get from the servers.
* Servers SHOULD produce thumbnails with the following dimensions and methods:
*
* 32x32, crop
* 96x96, crop
* 320x240, scale
* 640x480, scale
* 800x600, scale
*
* Let's always use the same size so coil caching works properly.
*/
const val AVATAR_THUMBNAIL_SIZE_IN_PIXEL = 240L
internal fun AvatarData.toMediaRequestData(): MediaRequestData {
return MediaRequestData(
source = url?.let { MediaSource(it) },
kind = MediaRequestData.Kind.Thumbnail(size.dp.value.roundToLong())
kind = MediaRequestData.Kind.Thumbnail(AVATAR_THUMBNAIL_SIZE_IN_PIXEL)
)
}

6
libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/CoilMediaFetcher.kt

@ -20,10 +20,8 @@ import okio.Buffer @@ -20,10 +20,8 @@ import okio.Buffer
import okio.Path.Companion.toOkioPath
import timber.log.Timber
import java.nio.ByteBuffer
import kotlin.math.roundToLong
internal class CoilMediaFetcher(
private val scalingFunction: (Float) -> Float,
private val mediaLoader: MatrixMediaLoader,
private val mediaData: MediaRequestData,
private val options: Options
@ -74,8 +72,8 @@ internal class CoilMediaFetcher( @@ -74,8 +72,8 @@ internal class CoilMediaFetcher(
private suspend fun fetchThumbnail(mediaSource: MediaSource, kind: MediaRequestData.Kind.Thumbnail, options: Options): FetchResult? {
return mediaLoader.loadMediaThumbnail(
source = mediaSource,
width = scalingFunction(kind.width.toFloat()).roundToLong(),
height = scalingFunction(kind.height.toFloat()).roundToLong(),
width = kind.width,
height = kind.height,
).map { byteArray ->
byteArray.asSourceResult(options)
}.onFailure {

4
libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/ImageLoaderFactories.kt

@ -43,8 +43,8 @@ class DefaultLoggedInImageLoaderFactory @Inject constructor( @@ -43,8 +43,8 @@ class DefaultLoggedInImageLoaderFactory @Inject constructor(
}
add(AvatarDataKeyer())
add(MediaRequestDataKeyer())
add(AvatarDataFetcherFactory(context, matrixClient))
add(MediaRequestDataFetcherFactory(context, matrixClient))
add(AvatarDataFetcherFactory(matrixClient))
add(MediaRequestDataFetcherFactory(matrixClient))
}
.build()
}

3
libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/MediaRequestDataFetcherFactory.kt

@ -7,14 +7,12 @@ @@ -7,14 +7,12 @@
package io.element.android.libraries.matrix.ui.media
import android.content.Context
import coil.ImageLoader
import coil.fetch.Fetcher
import coil.request.Options
import io.element.android.libraries.matrix.api.MatrixClient
internal class MediaRequestDataFetcherFactory(
private val context: Context,
private val client: MatrixClient
) : Fetcher.Factory<MediaRequestData> {
override fun create(
@ -23,7 +21,6 @@ internal class MediaRequestDataFetcherFactory( @@ -23,7 +21,6 @@ internal class MediaRequestDataFetcherFactory(
imageLoader: ImageLoader
): Fetcher {
return CoilMediaFetcher(
scalingFunction = { context.resources.displayMetrics.density * it },
mediaLoader = client.mediaLoader,
mediaData = data,
options = options

5
libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotificationBitmapLoader.kt

@ -19,6 +19,7 @@ import com.squareup.anvil.annotations.ContributesBinding @@ -19,6 +19,7 @@ import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.matrix.api.media.MediaSource
import io.element.android.libraries.matrix.ui.media.AVATAR_THUMBNAIL_SIZE_IN_PIXEL
import io.element.android.libraries.matrix.ui.media.MediaRequestData
import io.element.android.libraries.push.api.notifications.NotificationBitmapLoader
import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider
@ -45,7 +46,7 @@ class DefaultNotificationBitmapLoader @Inject constructor( @@ -45,7 +46,7 @@ class DefaultNotificationBitmapLoader @Inject constructor(
private suspend fun loadRoomBitmap(path: String, imageLoader: ImageLoader): Bitmap? {
return try {
val imageRequest = ImageRequest.Builder(context)
.data(MediaRequestData(MediaSource(path), MediaRequestData.Kind.Thumbnail(1024)))
.data(MediaRequestData(MediaSource(path), MediaRequestData.Kind.Thumbnail(AVATAR_THUMBNAIL_SIZE_IN_PIXEL)))
.transformations(CircleCropTransformation())
.build()
val result = imageLoader.execute(imageRequest)
@ -73,7 +74,7 @@ class DefaultNotificationBitmapLoader @Inject constructor( @@ -73,7 +74,7 @@ class DefaultNotificationBitmapLoader @Inject constructor(
private suspend fun loadUserIcon(path: String, imageLoader: ImageLoader): IconCompat? {
return try {
val imageRequest = ImageRequest.Builder(context)
.data(MediaRequestData(MediaSource(path), MediaRequestData.Kind.Thumbnail(1024)))
.data(MediaRequestData(MediaSource(path), MediaRequestData.Kind.Thumbnail(AVATAR_THUMBNAIL_SIZE_IN_PIXEL)))
.transformations(CircleCropTransformation())
.build()
val result = imageLoader.execute(imageRequest)

9
libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultRoomGroupMessageCreatorTest.kt

@ -15,6 +15,7 @@ import io.element.android.libraries.matrix.api.media.MediaSource @@ -15,6 +15,7 @@ import io.element.android.libraries.matrix.api.media.MediaSource
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_TIMESTAMP
import io.element.android.libraries.matrix.ui.components.aMatrixUser
import io.element.android.libraries.matrix.ui.media.AVATAR_THUMBNAIL_SIZE_IN_PIXEL
import io.element.android.libraries.matrix.ui.media.MediaRequestData
import io.element.android.libraries.push.impl.notifications.factories.createNotificationCreator
import io.element.android.libraries.push.impl.notifications.fixtures.aNotifiableMessageEvent
@ -84,7 +85,7 @@ class DefaultRoomGroupMessageCreatorTest { @@ -84,7 +85,7 @@ class DefaultRoomGroupMessageCreatorTest {
expectedCoilRequests = listOf(
MediaRequestData(
source = MediaSource(url = A_ROOM_AVATAR),
kind = MediaRequestData.Kind.Thumbnail(1024)
kind = MediaRequestData.Kind.Thumbnail(AVATAR_THUMBNAIL_SIZE_IN_PIXEL)
)
)
)
@ -98,15 +99,15 @@ class DefaultRoomGroupMessageCreatorTest { @@ -98,15 +99,15 @@ class DefaultRoomGroupMessageCreatorTest {
expectedCoilRequests = listOf(
MediaRequestData(
source = MediaSource(url = A_USER_AVATAR_1),
kind = MediaRequestData.Kind.Thumbnail(1024)
kind = MediaRequestData.Kind.Thumbnail(AVATAR_THUMBNAIL_SIZE_IN_PIXEL)
),
MediaRequestData(
source = MediaSource(url = A_USER_AVATAR_2),
kind = MediaRequestData.Kind.Thumbnail(1024)
kind = MediaRequestData.Kind.Thumbnail(AVATAR_THUMBNAIL_SIZE_IN_PIXEL)
),
MediaRequestData(
source = MediaSource(url = A_ROOM_AVATAR),
kind = MediaRequestData.Kind.Thumbnail(1024)
kind = MediaRequestData.Kind.Thumbnail(AVATAR_THUMBNAIL_SIZE_IN_PIXEL)
),
)
)

Loading…
Cancel
Save