diff --git a/app/build.gradle b/app/build.gradle index e91f74d450..58cc5e064f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -60,6 +60,7 @@ dependencies { def epoxy_version = "3.0.0" def arrow_version = "0.8.2" + def coroutines_version = "1.0.1" def markwon_version = '3.0.0-SNAPSHOT' implementation project(":matrix-sdk-android") @@ -67,6 +68,8 @@ dependencies { implementation 'com.android.support:multidex:1.0.3' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" implementation 'androidx.appcompat:appcompat:1.1.0-alpha01' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' diff --git a/app/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt b/app/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt index c2e4e6a509..3227dc6502 100644 --- a/app/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt +++ b/app/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt @@ -22,8 +22,6 @@ import android.widget.ImageView import androidx.core.content.ContextCompat import com.amulyakhare.textdrawable.TextDrawable import com.bumptech.glide.request.RequestOptions -import com.bumptech.glide.request.target.SimpleTarget -import com.bumptech.glide.request.transition.Transition import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.MatrixPatterns import im.vector.matrix.android.api.session.room.model.RoomMember @@ -31,6 +29,8 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.riotredesign.R import im.vector.riotredesign.core.glide.GlideApp import im.vector.riotredesign.core.glide.GlideRequest +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch object AvatarRenderer { @@ -46,53 +46,47 @@ object AvatarRenderer { if (name.isNullOrEmpty()) { return } - buildGlideRequest(imageView.context, name, avatarUrl).into(imageView) + val placeholder = buildPlaceholderDrawable(imageView.context, name) + buildGlideRequest(imageView.context, avatarUrl) + .placeholder(placeholder) + .into(imageView) } - fun load(context: Context, avatarUrl: String?, name: String?, callback: Callback) { + fun load(context: Context, avatarUrl: String?, name: String?, size: Int, callback: Callback) { if (name.isNullOrEmpty()) { return } - buildGlideRequest(context, name, avatarUrl).into(CallbackTarget(callback)) + val request = buildGlideRequest(context, avatarUrl) + GlobalScope.launch { + val placeholder = buildPlaceholderDrawable(context, name) + callback.onDrawableUpdated(placeholder) + try { + val drawable = request.submit(size, size).get() + callback.onDrawableUpdated(drawable) + } catch (exception: Exception) { + callback.onDrawableUpdated(placeholder) + } + } } - private fun buildGlideRequest(context: Context, name: String, avatarUrl: String?): GlideRequest { + private fun buildGlideRequest(context: Context, avatarUrl: String?): GlideRequest { val resolvedUrl = Matrix.getInstance().currentSession.contentUrlResolver().resolveFullSize(avatarUrl) + return GlideApp + .with(context) + .load(resolvedUrl) + .apply(RequestOptions.circleCropTransform()) + } + + private fun buildPlaceholderDrawable(context: Context, name: String): Drawable { val avatarColor = ContextCompat.getColor(context, R.color.pale_teal) val isNameUserId = MatrixPatterns.isUserId(name) val firstLetterIndex = if (isNameUserId) 1 else 0 val firstLetter = name[firstLetterIndex].toString().toUpperCase() - val fallbackDrawable = TextDrawable.builder().buildRound(firstLetter, avatarColor) - return GlideApp - .with(context) - .load(resolvedUrl) - .placeholder(fallbackDrawable) - .apply(RequestOptions.circleCropTransform()) + return TextDrawable.builder().buildRound(firstLetter, avatarColor) } interface Callback { fun onDrawableUpdated(drawable: Drawable?) - fun onDestroy() } - private class CallbackTarget(private val callback: Callback) : SimpleTarget() { - - override fun onDestroy() { - callback.onDestroy() - } - - override fun onResourceReady(resource: Drawable, transition: Transition?) { - callback.onDrawableUpdated(resource) - } - - override fun onLoadStarted(placeholder: Drawable?) { - callback.onDrawableUpdated(placeholder) - } - - override fun onLoadFailed(errorDrawable: Drawable?) { - callback.onDrawableUpdated(errorDrawable) - } - } - - } \ No newline at end of file diff --git a/app/src/main/java/im/vector/riotredesign/features/html/PillDrawableFactory.kt b/app/src/main/java/im/vector/riotredesign/features/html/PillDrawableFactory.kt index 05885491f1..9b87c67135 100644 --- a/app/src/main/java/im/vector/riotredesign/features/html/PillDrawableFactory.kt +++ b/app/src/main/java/im/vector/riotredesign/features/html/PillDrawableFactory.kt @@ -27,15 +27,18 @@ import java.lang.ref.WeakReference object PillDrawableFactory { fun create(context: Context, userId: String, user: User?): Drawable { + val textPadding = context.resources.getDimension(R.dimen.pill_text_padding) + val chipDrawable = ChipDrawable.createFromResource(context, R.xml.pill_view).apply { setText(user?.displayName ?: userId) - textEndPadding = 8f - textStartPadding = 8f - setBounds(0, 0, intrinsicWidth, (intrinsicHeight / 1.5f).toInt()) + textEndPadding = textPadding + textStartPadding = textPadding + setChipMinHeightResource(R.dimen.pill_min_height) + setChipIconSizeResource(R.dimen.pill_avatar_size) + setBounds(0, 0, intrinsicWidth, intrinsicHeight) } val avatarRendererCallback = AvatarRendererChipCallback(chipDrawable) - // TODO: need to work on getting drawable async - //AvatarRenderer.load(context, user?.avatarUrl, user?.displayName, avatarRendererCallback) + AvatarRenderer.load(context, user?.avatarUrl, user?.displayName, 80, avatarRendererCallback) return chipDrawable } @@ -43,19 +46,14 @@ object PillDrawableFactory { private val weakChipDrawable = WeakReference(chipDrawable) - override fun onDestroy() { - weakChipDrawable.clear() - } - override fun onDrawableUpdated(drawable: Drawable?) { weakChipDrawable.get()?.apply { chipIcon = drawable - setBounds(0, 0, intrinsicWidth, (intrinsicHeight / 1.5f).toInt()) + setBounds(0, 0, intrinsicWidth, intrinsicHeight) } } } - } diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000000..3d9cae027d --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,7 @@ + + + + 16dp + 20dp + 4dp + \ No newline at end of file