WIP: use placeholders when avatar is not available

Problem:
i want to load avatars and if no avatar is received, i want to show the placeholder.
However with coil it's not possible to make the placeholders rounded. See https://github.com/coil-kt/coil/issues/37

I could just set the old rounded drawables that we have, but then theming wouldn't work!

So i ask myself what the best solution could be:

- Somehow check beforehand if an avatar is set at all? and then choose between loading the avatar or loading the the static drawables in their own loading request.

- Somehow check if the avatar response is empty. And if yes, make another request to load the static drawables.

- Use jetpack compose instead of coil to clip the image? See https://stackoverflow.com/questions/66014834/how-to-draw-a-circular-image-in-android-jetpack-compose

- create new svg's? Somehow it should be possible to invert a circle and just overlay it over an image..?

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2023-04-19 16:59:11 +02:00
parent c3b468118a
commit ad15bca8ec
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
2 changed files with 28 additions and 11 deletions

View File

@ -179,8 +179,7 @@ class ConversationItem(
} }
ConversationType.ROOM_GROUP_CALL -> ConversationType.ROOM_GROUP_CALL ->
// holder.binding.dialogAvatar.loadDefaultGroupCallAvatar(viewThemeUtils) holder.binding.dialogAvatar.loadConversationAvatar(user, model)
holder.binding.dialogAvatar.loadConversationAvatar(user, model.token!!)
ConversationType.FORMER_ONE_TO_ONE -> ConversationType.FORMER_ONE_TO_ONE ->
holder.binding.dialogAvatar.loadDefaultGroupCallAvatar(viewThemeUtils) holder.binding.dialogAvatar.loadDefaultGroupCallAvatar(viewThemeUtils)

View File

@ -41,6 +41,7 @@ import coil.transform.RoundedCornersTransformation
import com.amulyakhare.textdrawable.TextDrawable import com.amulyakhare.textdrawable.TextDrawable
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
@ -49,16 +50,30 @@ private const val TAG = "ImageViewExtensions"
fun ImageView.loadConversationAvatar( fun ImageView.loadConversationAvatar(
user: User, user: User,
roomToken: String conversation: Conversation
): io.reactivex.disposables ): io.reactivex.disposables
.Disposable { .Disposable {
val imageRequestUri = ApiUtils.getUrlForConversationAvatar( val imageRequestUri = ApiUtils.getUrlForConversationAvatar(
1, 1,
user.baseUrl, user.baseUrl,
roomToken conversation.token
) )
return loadAvatarInternal(user, imageRequestUri, false) // TODO: improve this! using the "old" drawables for now. because the themed drawables are not rounded by
// themselves and coil is
// not able to make placeholders rounded!! https://github.com/coil-kt/coil/issues/37
val placeholder =
when (conversation.type) {
Conversation.ConversationType.ROOM_GROUP_CALL ->
ContextCompat.getDrawable(context, R.drawable.ic_circular_group)
Conversation.ConversationType.ROOM_PUBLIC_CALL ->
ContextCompat.getDrawable(context, R.drawable.ic_circular_link)
else -> ContextCompat.getDrawable(context, R.drawable.account_circle_96dp)
}
return loadAvatarInternal(user, imageRequestUri, false, placeholder)
} }
fun ImageView.loadAvatar( fun ImageView.loadAvatar(
@ -73,7 +88,7 @@ fun ImageView.loadAvatar(
requestBigSize requestBigSize
) )
return loadAvatarInternal(user, imageRequestUri, false) return loadAvatarInternal(user, imageRequestUri, false, null)
} }
fun ImageView.replaceAvatar( fun ImageView.replaceAvatar(
@ -88,14 +103,15 @@ fun ImageView.replaceAvatar(
requestBigSize requestBigSize
) )
return loadAvatarInternal(user, imageRequestUri, true) return loadAvatarInternal(user, imageRequestUri, true, null)
} }
@OptIn(ExperimentalCoilApi::class) @OptIn(ExperimentalCoilApi::class)
private fun ImageView.loadAvatarInternal( private fun ImageView.loadAvatarInternal(
user: User?, user: User?,
url: String, url: String,
replace: Boolean replace: Boolean,
placeholder: Drawable?
): io.reactivex.disposables ): io.reactivex.disposables
.Disposable { .Disposable {
if (replace && this.result is SuccessResult) { if (replace && this.result is SuccessResult) {
@ -118,7 +134,9 @@ private fun ImageView.loadAvatarInternal(
) )
} }
transformations(CircleCropTransformation()) transformations(CircleCropTransformation())
placeholder(R.drawable.account_circle_96dp) placeholder(placeholder ?: ContextCompat.getDrawable(context, R.drawable.account_circle_96dp))
error(placeholder ?: ContextCompat.getDrawable(context, R.drawable.account_circle_96dp))
fallback(placeholder ?: ContextCompat.getDrawable(context, R.drawable.account_circle_96dp))
listener(onError = { _, result -> listener(onError = { _, result ->
Log.w(TAG, "Can't load avatar with URL: $url", result.throwable) Log.w(TAG, "Can't load avatar with URL: $url", result.throwable)
}) })
@ -128,7 +146,7 @@ private fun ImageView.loadAvatarInternal(
@Deprecated("Use function loadAvatar", level = DeprecationLevel.WARNING) @Deprecated("Use function loadAvatar", level = DeprecationLevel.WARNING)
fun ImageView.loadAvatarWithUrl(user: User? = null, url: String): io.reactivex.disposables.Disposable { fun ImageView.loadAvatarWithUrl(user: User? = null, url: String): io.reactivex.disposables.Disposable {
return loadAvatarInternal(user, url, false) return loadAvatarInternal(user, url, false, null)
} }
fun ImageView.loadThumbnail(url: String, user: User): io.reactivex.disposables.Disposable { fun ImageView.loadThumbnail(url: String, user: User): io.reactivex.disposables.Disposable {
@ -188,7 +206,7 @@ fun ImageView.loadImage(url: String, user: User, placeholder: Drawable? = null):
fun ImageView.loadAvatarOrImagePreview(url: String, user: User, placeholder: Drawable? = null): io.reactivex fun ImageView.loadAvatarOrImagePreview(url: String, user: User, placeholder: Drawable? = null): io.reactivex
.disposables.Disposable { .disposables.Disposable {
return if (url.contains("/avatar/")) { return if (url.contains("/avatar/")) {
loadAvatarInternal(user, url, false) loadAvatarInternal(user, url, false, null)
} else { } else {
loadImage(url, user, placeholder) loadImage(url, user, placeholder)
} }