Clean a bit avatar management
This commit is contained in:
parent
18c6472f32
commit
6d9907563e
|
@ -1,13 +0,0 @@
|
||||||
package im.vector.riotredesign.core.extensions
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.support.v4.content.ContextCompat
|
|
||||||
import com.amulyakhare.textdrawable.TextDrawable
|
|
||||||
import im.vector.riotredesign.R
|
|
||||||
|
|
||||||
|
|
||||||
fun Context.avatarDrawable(name: String): Drawable {
|
|
||||||
val avatarColor = ContextCompat.getColor(this, R.color.pale_teal)
|
|
||||||
return TextDrawable.builder().buildRound(name.firstCharAsString().toUpperCase(), avatarColor)
|
|
||||||
}
|
|
|
@ -2,7 +2,5 @@ package im.vector.riotredesign.core.utils
|
||||||
|
|
||||||
object Constants {
|
object Constants {
|
||||||
|
|
||||||
const val MEDIA_URL = "https://matrix.org/_matrix/media/v1/download/"
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package im.vector.riotredesign.features.home
|
||||||
|
|
||||||
|
import android.support.v4.content.ContextCompat
|
||||||
|
import android.widget.ImageView
|
||||||
|
import com.amulyakhare.textdrawable.TextDrawable
|
||||||
|
import com.bumptech.glide.request.RequestOptions
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.extensions.firstCharAsString
|
||||||
|
import im.vector.riotredesign.core.glide.GlideApp
|
||||||
|
|
||||||
|
private const val MEDIA_URL = "https://matrix.org/_matrix/media/v1/download/"
|
||||||
|
private const val MXC_PREFIX = "mxc://"
|
||||||
|
|
||||||
|
object AvatarRenderer {
|
||||||
|
|
||||||
|
fun render(roomMember: RoomMember, imageView: ImageView) {
|
||||||
|
render(roomMember.avatarUrl, roomMember.displayName, imageView)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun render(roomSummary: RoomSummary, imageView: ImageView) {
|
||||||
|
render(roomSummary.avatarUrl, roomSummary.displayName, imageView)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun render(avatarUrl: String?, name: String?, imageView: ImageView) {
|
||||||
|
if (name.isNullOrEmpty()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val resolvedUrl = avatarUrl?.replace(MXC_PREFIX, MEDIA_URL)
|
||||||
|
val avatarColor = ContextCompat.getColor(imageView.context, R.color.pale_teal)
|
||||||
|
val fallbackDrawable = TextDrawable.builder().buildRound(name.firstCharAsString().toUpperCase(), avatarColor)
|
||||||
|
|
||||||
|
GlideApp
|
||||||
|
.with(imageView)
|
||||||
|
.load(resolvedUrl)
|
||||||
|
.placeholder(fallbackDrawable)
|
||||||
|
.apply(RequestOptions.circleCropTransform())
|
||||||
|
.into(imageView)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -7,18 +7,15 @@ import android.support.v7.widget.LinearLayoutManager
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import com.bumptech.glide.request.RequestOptions
|
|
||||||
import im.vector.matrix.android.api.Matrix
|
import im.vector.matrix.android.api.Matrix
|
||||||
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
||||||
import im.vector.matrix.android.api.session.room.Room
|
import im.vector.matrix.android.api.session.room.Room
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.extensions.avatarDrawable
|
|
||||||
import im.vector.riotredesign.core.glide.GlideApp
|
|
||||||
import im.vector.riotredesign.core.platform.RiotFragment
|
import im.vector.riotredesign.core.platform.RiotFragment
|
||||||
import im.vector.riotredesign.core.platform.ToolbarConfigurable
|
import im.vector.riotredesign.core.platform.ToolbarConfigurable
|
||||||
import im.vector.riotredesign.core.utils.Constants
|
|
||||||
import im.vector.riotredesign.core.utils.FragmentArgumentDelegate
|
import im.vector.riotredesign.core.utils.FragmentArgumentDelegate
|
||||||
|
import im.vector.riotredesign.features.home.AvatarRenderer
|
||||||
import kotlinx.android.synthetic.main.fragment_room_detail.*
|
import kotlinx.android.synthetic.main.fragment_room_detail.*
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
|
@ -70,13 +67,7 @@ class RoomDetailFragment : RiotFragment() {
|
||||||
private fun renderRoomSummary(roomSummary: RoomSummary?) {
|
private fun renderRoomSummary(roomSummary: RoomSummary?) {
|
||||||
roomSummary?.let {
|
roomSummary?.let {
|
||||||
toolbarTitleView.text = it.displayName
|
toolbarTitleView.text = it.displayName
|
||||||
val avatarUrl = it.avatarUrl.replace("mxc://", Constants.MEDIA_URL)
|
AvatarRenderer.render(it, toolbarAvatarImageView)
|
||||||
GlideApp
|
|
||||||
.with(this)
|
|
||||||
.load(avatarUrl)
|
|
||||||
.placeholder(riotActivity.avatarDrawable(it.displayName))
|
|
||||||
.apply(RequestOptions.circleCropTransform())
|
|
||||||
.into(toolbarAvatarImageView)
|
|
||||||
if (it.topic.isNotEmpty()) {
|
if (it.topic.isNotEmpty()) {
|
||||||
toolbarSubtitleView.visibility = View.VISIBLE
|
toolbarSubtitleView.visibility = View.VISIBLE
|
||||||
toolbarSubtitleView.text = it.topic
|
toolbarSubtitleView.text = it.topic
|
||||||
|
|
|
@ -8,9 +8,7 @@ import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
import im.vector.matrix.android.api.session.events.model.roomMember
|
import im.vector.matrix.android.api.session.events.model.roomMember
|
||||||
import im.vector.matrix.android.api.session.room.model.MessageContent
|
import im.vector.matrix.android.api.session.room.model.MessageContent
|
||||||
import im.vector.riotredesign.core.extensions.avatarDrawable
|
|
||||||
import im.vector.riotredesign.core.extensions.localDateTime
|
import im.vector.riotredesign.core.extensions.localDateTime
|
||||||
import im.vector.riotredesign.core.utils.Constants
|
|
||||||
import im.vector.riotredesign.features.home.LoadingItemModel_
|
import im.vector.riotredesign.features.home.LoadingItemModel_
|
||||||
import org.threeten.bp.format.DateTimeFormatter
|
import org.threeten.bp.format.DateTimeFormatter
|
||||||
import org.threeten.bp.format.FormatStyle
|
import org.threeten.bp.format.FormatStyle
|
||||||
|
@ -72,16 +70,11 @@ class TimelineEventController(private val context: Context) : EpoxyController(
|
||||||
}
|
}
|
||||||
val showInformation = messagesDisplayedWithInformation.contains(event.root.eventId)
|
val showInformation = messagesDisplayedWithInformation.contains(event.root.eventId)
|
||||||
|
|
||||||
|
|
||||||
val avatarUrl = roomMember.avatarUrl?.replace("mxc://", Constants.MEDIA_URL) ?: ""
|
|
||||||
|
|
||||||
TimelineMessageItem(
|
TimelineMessageItem(
|
||||||
message = messageContent.body,
|
message = messageContent.body,
|
||||||
avatarUrl = avatarUrl,
|
avatarUrl = roomMember.avatarUrl,
|
||||||
showInformation = showInformation,
|
showInformation = showInformation,
|
||||||
time = date.toLocalTime().format(DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)),
|
time = date.toLocalTime().format(DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)),
|
||||||
fallbackAvatarDrawable = context.avatarDrawable(roomMember.displayName
|
|
||||||
?: ""),
|
|
||||||
memberName = roomMember.displayName
|
memberName = roomMember.displayName
|
||||||
)
|
)
|
||||||
.onBind { timeline?.loadAround(index) }
|
.onBind { timeline?.loadAround(index) }
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
package im.vector.riotredesign.features.home.room.detail
|
package im.vector.riotredesign.features.home.room.detail
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.bumptech.glide.request.RequestOptions
|
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.epoxy.KotlinModel
|
import im.vector.riotredesign.core.epoxy.KotlinModel
|
||||||
import im.vector.riotredesign.core.glide.GlideApp
|
import im.vector.riotredesign.features.home.AvatarRenderer
|
||||||
|
|
||||||
data class TimelineMessageItem(
|
data class TimelineMessageItem(
|
||||||
val message: CharSequence? = null,
|
val message: CharSequence? = null,
|
||||||
val time: CharSequence? = null,
|
val time: CharSequence? = null,
|
||||||
val avatarUrl: String,
|
val avatarUrl: String?,
|
||||||
val fallbackAvatarDrawable: Drawable? = null,
|
|
||||||
val memberName: CharSequence? = null,
|
val memberName: CharSequence? = null,
|
||||||
val showInformation: Boolean = true
|
val showInformation: Boolean = true
|
||||||
) : KotlinModel(R.layout.item_event_message) {
|
) : KotlinModel(R.layout.item_event_message) {
|
||||||
|
@ -29,16 +26,9 @@ data class TimelineMessageItem(
|
||||||
avatarImageView.visibility = View.VISIBLE
|
avatarImageView.visibility = View.VISIBLE
|
||||||
memberNameView.visibility = View.VISIBLE
|
memberNameView.visibility = View.VISIBLE
|
||||||
timeView.visibility = View.VISIBLE
|
timeView.visibility = View.VISIBLE
|
||||||
|
|
||||||
GlideApp
|
|
||||||
.with(avatarImageView)
|
|
||||||
.load(avatarUrl)
|
|
||||||
.placeholder(fallbackAvatarDrawable)
|
|
||||||
.apply(RequestOptions.circleCropTransform())
|
|
||||||
.into(avatarImageView)
|
|
||||||
|
|
||||||
timeView.text = time
|
timeView.text = time
|
||||||
memberNameView.text = memberName
|
memberNameView.text = memberName
|
||||||
|
AvatarRenderer.render(avatarUrl, memberName?.toString(), avatarImageView)
|
||||||
} else {
|
} else {
|
||||||
avatarImageView.visibility = View.GONE
|
avatarImageView.visibility = View.GONE
|
||||||
memberNameView.visibility = View.GONE
|
memberNameView.visibility = View.GONE
|
||||||
|
|
|
@ -36,7 +36,7 @@ class RoomListFragment : RiotFragment(), RoomSummaryController.Callback {
|
||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
roomController = RoomSummaryController(riotActivity, this)
|
roomController = RoomSummaryController(this)
|
||||||
stateView.contentView = epoxyRecyclerView
|
stateView.contentView = epoxyRecyclerView
|
||||||
epoxyRecyclerView.setController(roomController)
|
epoxyRecyclerView.setController(roomController)
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
package im.vector.riotredesign.features.home.room.list
|
package im.vector.riotredesign.features.home.room.list
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import com.airbnb.epoxy.Typed2EpoxyController
|
import com.airbnb.epoxy.Typed2EpoxyController
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.riotredesign.core.extensions.avatarDrawable
|
|
||||||
import im.vector.riotredesign.core.utils.Constants
|
|
||||||
|
|
||||||
class RoomSummaryController(private val context: Context,
|
class RoomSummaryController(private val callback: Callback? = null
|
||||||
private val callback: Callback? = null
|
|
||||||
) : Typed2EpoxyController<List<RoomSummary>, RoomSummary>() {
|
) : Typed2EpoxyController<List<RoomSummary>, RoomSummary>() {
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,12 +50,9 @@ class RoomSummaryController(private val context: Context,
|
||||||
private fun buildRoomModels(summaries: List<RoomSummary>, selected: RoomSummary?) {
|
private fun buildRoomModels(summaries: List<RoomSummary>, selected: RoomSummary?) {
|
||||||
|
|
||||||
summaries.forEach {
|
summaries.forEach {
|
||||||
val avatarUrl = it.avatarUrl.replace("mxc://", Constants.MEDIA_URL)
|
|
||||||
|
|
||||||
RoomSummaryItem(
|
RoomSummaryItem(
|
||||||
title = it.displayName,
|
roomName = it.displayName,
|
||||||
avatarUrl = avatarUrl,
|
avatarUrl = it.avatarUrl,
|
||||||
fallbackAvatarDrawable = context.avatarDrawable(it.displayName),
|
|
||||||
isSelected = it.roomId == selected?.roomId,
|
isSelected = it.roomId == selected?.roomId,
|
||||||
listener = { callback?.onRoomSelected(it) }
|
listener = { callback?.onRoomSelected(it) }
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
package im.vector.riotredesign.features.home.room.list
|
package im.vector.riotredesign.features.home.room.list
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.bumptech.glide.request.RequestOptions
|
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.epoxy.KotlinModel
|
import im.vector.riotredesign.core.epoxy.KotlinModel
|
||||||
import im.vector.riotredesign.core.glide.GlideApp
|
|
||||||
import im.vector.riotredesign.core.platform.CheckableFrameLayout
|
import im.vector.riotredesign.core.platform.CheckableFrameLayout
|
||||||
|
import im.vector.riotredesign.features.home.AvatarRenderer
|
||||||
|
|
||||||
|
|
||||||
data class RoomSummaryItem(
|
data class RoomSummaryItem(
|
||||||
val title: CharSequence,
|
val roomName: CharSequence,
|
||||||
val avatarUrl: String,
|
val avatarUrl: String?,
|
||||||
val fallbackAvatarDrawable: Drawable,
|
|
||||||
val isSelected: Boolean,
|
val isSelected: Boolean,
|
||||||
val listener: (() -> Unit)? = null
|
val listener: (() -> Unit)? = null
|
||||||
) : KotlinModel(R.layout.item_room) {
|
) : KotlinModel(R.layout.item_room) {
|
||||||
|
@ -25,12 +22,7 @@ data class RoomSummaryItem(
|
||||||
override fun bind() {
|
override fun bind() {
|
||||||
rootView.isChecked = isSelected
|
rootView.isChecked = isSelected
|
||||||
rootView.setOnClickListener { listener?.invoke() }
|
rootView.setOnClickListener { listener?.invoke() }
|
||||||
titleView.text = title
|
titleView.text = roomName
|
||||||
GlideApp
|
AvatarRenderer.render(avatarUrl, roomName.toString(), avatarImageView)
|
||||||
.with(avatarImageView)
|
|
||||||
.load(avatarUrl)
|
|
||||||
.placeholder(fallbackAvatarDrawable)
|
|
||||||
.apply(RequestOptions.circleCropTransform())
|
|
||||||
.into(avatarImageView)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue