Continue refinement of RoomList (and remove avatar library)

This commit is contained in:
ganfra 2022-11-03 18:02:53 +01:00
parent 5984ffc960
commit f55bb16bfa
22 changed files with 305 additions and 322 deletions

View file

@ -1 +0,0 @@
/build

View file

@ -1,12 +0,0 @@
plugins {
id("io.element.android-compose")
}
android {
namespace = "io.element.android.x.libraries.avatar"
}
dependencies {
implementation(project(":libraries:matrix"))
implementation(libs.coil.compose)
}

View file

@ -1,21 +0,0 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

@ -1,24 +0,0 @@
package io.element.android.x.avatar
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("io.element.android.x.avatar.test", appContext.packageName)
}
}

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View file

@ -1,33 +0,0 @@
package io.element.android.x.avatar
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(avatarData: AvatarData) {
Image(
painter = rememberAsyncImagePainter(
model = avatarData.url,
onError = {
Log.e("TAG", "Error $it\n${it.result}", it.result.throwable)
}),
contentDescription = null,
modifier = Modifier
.size(avatarData.size)
.clip(CircleShape)
.border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
)
}

View file

@ -1,10 +0,0 @@
package io.element.android.x.avatar
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
data class AvatarData(
val url: String,
val size: Dp = 48.dp
)

View file

@ -1,41 +0,0 @@
package io.element.android.x.avatar
import coil.ImageLoader
import coil.fetch.FetchResult
import coil.fetch.Fetcher
import coil.request.Options
import io.element.android.x.matrix.MatrixClient
import org.matrix.rustcomponents.sdk.mediaSourceFromUrl
class AvatarFetcher(
private val matrixClient: MatrixClient,
private val avatarData: AvatarData,
private val options: Options,
private val imageLoader: ImageLoader
) :
Fetcher {
override suspend fun fetch(): FetchResult? {
val mediaSource = mediaSourceFromUrl(avatarData.url)
val mediaContent = matrixClient.loadMediaContentForSource(mediaSource)
return mediaContent.fold(
{ mediaContent ->
val byteArray = mediaContent.toUByteArray().toByteArray()
val fetcher = imageLoader.components.newFetcher(byteArray, options, imageLoader)
fetcher?.first?.fetch()
},
{null}
)
}
class Factory(private val matrixClient: MatrixClient) : Fetcher.Factory<AvatarData> {
override fun create(
data: AvatarData,
options: Options,
imageLoader: ImageLoader
): Fetcher? {
return AvatarFetcher(matrixClient, data, options, imageLoader)
}
}
}

View file

@ -1,17 +0,0 @@
package io.element.android.x.avatar
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View file

@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
@ -20,18 +21,17 @@ import io.element.android.x.designsystem.components.avatar.AvatarData
@Composable
fun Avatar(avatarData: AvatarData, modifier: Modifier = Modifier) {
val commonModifier = modifier
.size(avatarData.size.dp)
.clip(CircleShape)
if (avatarData.model == null) {
InitialsAvatar(
modifier = modifier
.size(avatarData.size.dp)
.clip(CircleShape),
modifier = commonModifier,
initials = avatarData.initials
)
} else {
ImageAvatar(
modifier = modifier
.size(avatarData.size.dp)
.clip(CircleShape),
modifier = commonModifier,
avatarData = avatarData
)
}
@ -50,8 +50,6 @@ private fun ImageAvatar(
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = modifier
.size(avatarData.size.dp)
.clip(CircleShape)
)
}
@ -65,15 +63,15 @@ private fun InitialsAvatar(
listOf(
AvatarGradientStart,
AvatarGradientEnd,
)
),
start = Offset(0.0f, 100f),
end = Offset(100f, 0f)
)
Box(
modifier
.background(brush = initialsGradient)
modifier.background(brush = initialsGradient)
) {
Text(
modifier = Modifier
.align(Alignment.Center),
modifier = Modifier.align(Alignment.Center),
text = initials,
fontSize = 24.sp,
color = Color.White,

View file

@ -6,7 +6,7 @@ import androidx.compose.runtime.Stable
data class AvatarData(
val initials: String = "",
val model: ByteArray? = null,
val size: Int = 0
val size: AvatarSize = AvatarSize.MEDIUM
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
@ -27,7 +27,7 @@ data class AvatarData(
override fun hashCode(): Int {
var result = initials.hashCode()
result = 31 * result + (model?.contentHashCode() ?: 0)
result = 31 * result + size
result = 31 * result + size.value
return result
}

View file

@ -0,0 +1,11 @@
package io.element.android.x.designsystem.components.avatar
import androidx.compose.ui.unit.dp
enum class AvatarSize(val value: Int) {
SMALL(32),
MEDIUM(40),
BIG(48);
val dp = value.dp
}