mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Merge pull request #774 from vector-im/feature/breadcrumbs_fixes
Fix various UI issues
This commit is contained in:
commit
f14f1db0e0
@ -8,10 +8,12 @@ Improvements 🙌:
|
||||
-
|
||||
|
||||
Other changes:
|
||||
-
|
||||
- Use same default room colors than Riot-Web
|
||||
|
||||
Bugfix 🐛:
|
||||
-
|
||||
- Scroll breadcrumbs to top when opened
|
||||
- Render default room name when it starts with an emoji (#477)
|
||||
- Do not display " (IRC)") in display names https://github.com/vector-im/riot-android/issues/444
|
||||
|
||||
Translations 🗣:
|
||||
-
|
||||
|
@ -10,7 +10,7 @@ buildscript {
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.1'
|
||||
classpath 'com.android.tools.build:gradle:3.5.3'
|
||||
classpath 'com.google.gms:google-services:4.3.2'
|
||||
classpath "com.airbnb.okreplay:gradle-plugin:1.5.0"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
@ -16,11 +16,12 @@
|
||||
|
||||
package im.vector.matrix.android.api.session.room.send
|
||||
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
|
||||
/**
|
||||
* Tag class for spans that should mention a user.
|
||||
* These Spans will be transformed into pills when detected in message to send
|
||||
*/
|
||||
interface UserMentionSpan {
|
||||
val displayName: String
|
||||
val userId: String
|
||||
val matrixItem: MatrixItem
|
||||
}
|
||||
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.api.util
|
||||
|
||||
import im.vector.matrix.android.BuildConfig
|
||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import java.util.*
|
||||
|
||||
sealed class MatrixItem(
|
||||
open val id: String,
|
||||
open val displayName: String?,
|
||||
open val avatarUrl: String?
|
||||
) {
|
||||
data class UserItem(override val id: String,
|
||||
override val displayName: String? = null,
|
||||
override val avatarUrl: String? = null)
|
||||
: MatrixItem(id, displayName?.removeSuffix(ircPattern), avatarUrl) {
|
||||
init {
|
||||
if (BuildConfig.DEBUG) checkId()
|
||||
}
|
||||
}
|
||||
|
||||
data class EventItem(override val id: String,
|
||||
override val displayName: String? = null,
|
||||
override val avatarUrl: String? = null)
|
||||
: MatrixItem(id, displayName, avatarUrl) {
|
||||
init {
|
||||
if (BuildConfig.DEBUG) checkId()
|
||||
}
|
||||
}
|
||||
|
||||
data class RoomItem(override val id: String,
|
||||
override val displayName: String? = null,
|
||||
override val avatarUrl: String? = null)
|
||||
: MatrixItem(id, displayName, avatarUrl) {
|
||||
init {
|
||||
if (BuildConfig.DEBUG) checkId()
|
||||
}
|
||||
}
|
||||
|
||||
data class RoomAliasItem(override val id: String,
|
||||
override val displayName: String? = null,
|
||||
override val avatarUrl: String? = null)
|
||||
: MatrixItem(id, displayName, avatarUrl) {
|
||||
init {
|
||||
if (BuildConfig.DEBUG) checkId()
|
||||
}
|
||||
}
|
||||
|
||||
data class GroupItem(override val id: String,
|
||||
override val displayName: String? = null,
|
||||
override val avatarUrl: String? = null)
|
||||
: MatrixItem(id, displayName, avatarUrl) {
|
||||
init {
|
||||
if (BuildConfig.DEBUG) checkId()
|
||||
}
|
||||
}
|
||||
|
||||
fun getBestName(): String {
|
||||
return displayName?.takeIf { it.isNotBlank() } ?: id
|
||||
}
|
||||
|
||||
protected fun checkId() {
|
||||
if (!id.startsWith(getIdPrefix())) {
|
||||
error("Wrong usage of MatrixItem: check the id $id should start with ${getIdPrefix()}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the prefix as defined in the matrix spec (and not extracted from the id)
|
||||
*/
|
||||
fun getIdPrefix() = when (this) {
|
||||
is UserItem -> '@'
|
||||
is EventItem -> '$'
|
||||
is RoomItem -> '!'
|
||||
is RoomAliasItem -> '#'
|
||||
is GroupItem -> '+'
|
||||
}
|
||||
|
||||
fun firstLetterOfDisplayName(): String {
|
||||
return getBestName()
|
||||
.let { dn ->
|
||||
var startIndex = 0
|
||||
val initial = dn[startIndex]
|
||||
|
||||
if (initial in listOf('@', '#', '+') && dn.length > 1) {
|
||||
startIndex++
|
||||
}
|
||||
|
||||
var length = 1
|
||||
var first = dn[startIndex]
|
||||
|
||||
// LEFT-TO-RIGHT MARK
|
||||
if (dn.length >= 2 && 0x200e == first.toInt()) {
|
||||
startIndex++
|
||||
first = dn[startIndex]
|
||||
}
|
||||
|
||||
// check if it’s the start of a surrogate pair
|
||||
if (first.toInt() in 0xD800..0xDBFF && dn.length > startIndex + 1) {
|
||||
val second = dn[startIndex + 1]
|
||||
if (second.toInt() in 0xDC00..0xDFFF) {
|
||||
length++
|
||||
}
|
||||
}
|
||||
|
||||
dn.substring(startIndex, startIndex + length)
|
||||
}
|
||||
.toUpperCase(Locale.ROOT)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ircPattern = " (IRC)"
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================================================================
|
||||
* Extensions to create MatrixItem
|
||||
* ========================================================================================== */
|
||||
|
||||
fun User.toMatrixItem() = MatrixItem.UserItem(userId, displayName, avatarUrl)
|
||||
fun GroupSummary.toMatrixItem() = MatrixItem.GroupItem(groupId, displayName, avatarUrl)
|
||||
fun RoomSummary.toMatrixItem() = MatrixItem.RoomItem(roomId, displayName, avatarUrl)
|
||||
fun PublicRoom.toMatrixItem() = MatrixItem.RoomItem(roomId, name, avatarUrl)
|
@ -65,7 +65,7 @@ internal class TextPillsUtils @Inject constructor(
|
||||
// append text before pill
|
||||
append(text, currIndex, start)
|
||||
// append the pill
|
||||
append(String.format(template, urlSpan.userId, urlSpan.displayName))
|
||||
append(String.format(template, urlSpan.matrixItem.id, urlSpan.matrixItem.displayName))
|
||||
currIndex = end
|
||||
}
|
||||
// append text after the last pill
|
||||
|
@ -16,9 +16,7 @@
|
||||
|
||||
package im.vector.matrix.android.internal.util
|
||||
|
||||
import im.vector.matrix.android.api.MatrixPatterns
|
||||
import timber.log.Timber
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* Convert a string to an UTF8 String
|
||||
@ -51,10 +49,3 @@ fun convertFromUTF8(s: String): String {
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
fun String?.firstLetterOfDisplayName(): String {
|
||||
if (this.isNullOrEmpty()) return ""
|
||||
val isUserId = MatrixPatterns.isUserId(this)
|
||||
val firstLetterIndex = if (isUserId) 1 else 0
|
||||
return this[firstLetterIndex].toString().toUpperCase(Locale.ROOT)
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
@ -37,11 +38,7 @@ abstract class BottomSheetMessagePreviewItem : VectorEpoxyModel<BottomSheetMessa
|
||||
@EpoxyAttribute
|
||||
lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute
|
||||
lateinit var avatarUrl: String
|
||||
@EpoxyAttribute
|
||||
lateinit var senderId: String
|
||||
@EpoxyAttribute
|
||||
var senderName: String? = null
|
||||
lateinit var matrixItem: MatrixItem
|
||||
@EpoxyAttribute
|
||||
lateinit var body: CharSequence
|
||||
@EpoxyAttribute
|
||||
@ -50,8 +47,8 @@ abstract class BottomSheetMessagePreviewItem : VectorEpoxyModel<BottomSheetMessa
|
||||
var movementMethod: MovementMethod? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
avatarRenderer.render(avatarUrl, senderId, senderName, holder.avatar)
|
||||
holder.sender.setTextOrHide(senderName)
|
||||
avatarRenderer.render(matrixItem, holder.avatar)
|
||||
holder.sender.setTextOrHide(matrixItem.displayName)
|
||||
holder.body.movementMethod = movementMethod
|
||||
holder.body.text = body
|
||||
body.findPillsAndProcess { it.bind(holder.body) }
|
||||
|
@ -21,6 +21,7 @@ import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
@ -36,16 +37,12 @@ abstract class BottomSheetRoomPreviewItem : VectorEpoxyModel<BottomSheetRoomPrev
|
||||
@EpoxyAttribute
|
||||
lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute
|
||||
lateinit var avatarUrl: String
|
||||
@EpoxyAttribute
|
||||
lateinit var roomId: String
|
||||
@EpoxyAttribute
|
||||
var roomName: String? = null
|
||||
lateinit var matrixItem: MatrixItem
|
||||
@EpoxyAttribute var settingsClickListener: View.OnClickListener? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
avatarRenderer.render(avatarUrl, roomId, roomName, holder.avatar)
|
||||
holder.roomName.setTextOrHide(roomName)
|
||||
avatarRenderer.render(matrixItem, holder.avatar)
|
||||
holder.roomName.setTextOrHide(matrixItem.displayName)
|
||||
holder.roomSettings.setOnClickListener(settingsClickListener)
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,8 @@ import android.widget.ProgressBar
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceViewHolder
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.vectorComponent
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
@ -59,9 +61,9 @@ open class UserAvatarPreference : Preference {
|
||||
val session = mSession ?: return
|
||||
val view = mAvatarView ?: return
|
||||
session.getUser(session.myUserId)?.let {
|
||||
avatarRenderer.render(it, view)
|
||||
avatarRenderer.render(it.toMatrixItem(), view)
|
||||
} ?: run {
|
||||
avatarRenderer.render(null, session.myUserId, null, view)
|
||||
avatarRenderer.render(MatrixItem.UserItem(session.myUserId), view)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ import im.vector.riotx.R
|
||||
import im.vector.riotx.core.glide.GlideApp
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import im.vector.riotx.features.home.room.detail.timeline.item.ReadReceiptData
|
||||
import im.vector.riotx.features.home.room.detail.timeline.item.toMatrixItem
|
||||
import kotlinx.android.synthetic.main.view_read_receipts.view.*
|
||||
|
||||
private const val MAX_RECEIPT_DISPLAYED = 5
|
||||
@ -59,7 +60,7 @@ class ReadReceiptsView @JvmOverloads constructor(
|
||||
receiptAvatars[index].visibility = View.INVISIBLE
|
||||
} else {
|
||||
receiptAvatars[index].visibility = View.VISIBLE
|
||||
avatarRenderer.render(receiptData.avatarUrl, receiptData.userId, receiptData.displayName, receiptAvatars[index])
|
||||
avatarRenderer.render(receiptData.toMatrixItem(), receiptAvatars[index])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,11 +18,12 @@ package im.vector.riotx.features.autocomplete.user
|
||||
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.features.autocomplete.AutocompleteClickListener
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import javax.inject.Inject
|
||||
|
||||
class AutocompleteUserController @Inject constructor(): TypedEpoxyController<List<User>>() {
|
||||
class AutocompleteUserController @Inject constructor() : TypedEpoxyController<List<User>>() {
|
||||
|
||||
var listener: AutocompleteClickListener<User>? = null
|
||||
|
||||
@ -35,9 +36,7 @@ class AutocompleteUserController @Inject constructor(): TypedEpoxyController<Lis
|
||||
data.forEach { user ->
|
||||
autocompleteUserItem {
|
||||
id(user.userId)
|
||||
userId(user.userId)
|
||||
name(user.displayName)
|
||||
avatarUrl(user.avatarUrl)
|
||||
matrixItem(user.toMatrixItem())
|
||||
avatarRenderer(avatarRenderer)
|
||||
clickListener { _ ->
|
||||
listener?.onItemClick(user)
|
||||
|
@ -21,6 +21,7 @@ import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
@ -30,15 +31,13 @@ import im.vector.riotx.features.home.AvatarRenderer
|
||||
abstract class AutocompleteUserItem : VectorEpoxyModel<AutocompleteUserItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute var name: String? = null
|
||||
@EpoxyAttribute var userId: String = ""
|
||||
@EpoxyAttribute var avatarUrl: String? = null
|
||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
||||
@EpoxyAttribute var clickListener: View.OnClickListener? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
holder.view.setOnClickListener(clickListener)
|
||||
holder.nameView.text = name
|
||||
avatarRenderer.render(avatarUrl, userId, name, holder.avatarImageView)
|
||||
holder.nameView.text = matrixItem.getBestName()
|
||||
avatarRenderer.render(matrixItem, holder.avatarImageView)
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
|
@ -22,6 +22,8 @@ import androidx.lifecycle.Observer
|
||||
import butterknife.BindView
|
||||
import butterknife.OnClick
|
||||
import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTransaction
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
@ -57,10 +59,10 @@ class SASVerificationIncomingFragment @Inject constructor(
|
||||
otherDeviceTextView.text = viewModel.otherDeviceId
|
||||
|
||||
viewModel.otherUser?.let {
|
||||
avatarRenderer.render(it, avatarImageView)
|
||||
avatarRenderer.render(it.toMatrixItem(), avatarImageView)
|
||||
} ?: run {
|
||||
// Fallback to what we know
|
||||
avatarRenderer.render(null, viewModel.otherUserId ?: "", viewModel.otherUserId, avatarImageView)
|
||||
avatarRenderer.render(MatrixItem.UserItem(viewModel.otherUserId ?: "", viewModel.otherUserId), avatarImageView)
|
||||
}
|
||||
|
||||
viewModel.transactionState.observe(viewLifecycleOwner, Observer {
|
||||
|
@ -27,10 +27,7 @@ import com.bumptech.glide.request.RequestOptions
|
||||
import com.bumptech.glide.request.target.DrawableImageViewTarget
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import im.vector.matrix.android.api.session.content.ContentUrlResolver
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.matrix.android.internal.util.firstLetterOfDisplayName
|
||||
import im.vector.riotx.R
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||
import im.vector.riotx.core.glide.GlideApp
|
||||
import im.vector.riotx.core.glide.GlideRequest
|
||||
@ -45,76 +42,42 @@ class AvatarRenderer @Inject constructor(private val activeSessionHolder: Active
|
||||
|
||||
companion object {
|
||||
private const val THUMBNAIL_SIZE = 250
|
||||
|
||||
private val AVATAR_COLOR_LIST = listOf(
|
||||
R.color.riotx_avatar_fill_1,
|
||||
R.color.riotx_avatar_fill_2,
|
||||
R.color.riotx_avatar_fill_3
|
||||
)
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun render(roomSummary: RoomSummary, imageView: ImageView) {
|
||||
render(roomSummary.avatarUrl, roomSummary.roomId, roomSummary.displayName, imageView)
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun render(user: User, imageView: ImageView) {
|
||||
render(imageView.context, GlideApp.with(imageView), user.avatarUrl, user.userId, user.displayName, DrawableImageViewTarget(imageView))
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun render(avatarUrl: String?, identifier: String, name: String?, imageView: ImageView) {
|
||||
render(imageView.context, GlideApp.with(imageView), avatarUrl, identifier, name, DrawableImageViewTarget(imageView))
|
||||
fun render(matrixItem: MatrixItem, imageView: ImageView) {
|
||||
render(imageView.context,
|
||||
GlideApp.with(imageView),
|
||||
matrixItem,
|
||||
DrawableImageViewTarget(imageView))
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun render(context: Context,
|
||||
glideRequest: GlideRequests,
|
||||
avatarUrl: String?,
|
||||
identifier: String,
|
||||
name: String?,
|
||||
matrixItem: MatrixItem,
|
||||
target: Target<Drawable>) {
|
||||
val displayName = if (name.isNullOrBlank()) {
|
||||
identifier
|
||||
} else {
|
||||
name
|
||||
}
|
||||
val placeholder = getPlaceholderDrawable(context, identifier, displayName)
|
||||
buildGlideRequest(glideRequest, avatarUrl)
|
||||
val placeholder = getPlaceholderDrawable(context, matrixItem)
|
||||
buildGlideRequest(glideRequest, matrixItem.avatarUrl)
|
||||
.placeholder(placeholder)
|
||||
.into(target)
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
fun getPlaceholderDrawable(context: Context, identifier: String, text: String): Drawable {
|
||||
val avatarColor = ContextCompat.getColor(context, getColorFromUserId(identifier))
|
||||
return if (text.isEmpty()) {
|
||||
TextDrawable.builder().buildRound("", avatarColor)
|
||||
} else {
|
||||
val firstLetter = text.firstLetterOfDisplayName()
|
||||
TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.bold()
|
||||
.endConfig()
|
||||
.buildRound(firstLetter, avatarColor)
|
||||
fun getPlaceholderDrawable(context: Context, matrixItem: MatrixItem): Drawable {
|
||||
val avatarColor = when (matrixItem) {
|
||||
is MatrixItem.UserItem -> ContextCompat.getColor(context, getColorFromUserId(matrixItem.id))
|
||||
else -> ContextCompat.getColor(context, getColorFromRoomId(matrixItem.id))
|
||||
}
|
||||
return TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.bold()
|
||||
.endConfig()
|
||||
.buildRound(matrixItem.firstLetterOfDisplayName(), avatarColor)
|
||||
}
|
||||
|
||||
// PRIVATE API *********************************************************************************
|
||||
|
||||
// private fun getAvatarColor(text: String? = null): Int {
|
||||
// var colorIndex: Long = 0
|
||||
// if (!text.isNullOrEmpty()) {
|
||||
// var sum: Long = 0
|
||||
// for (i in 0 until text.length) {
|
||||
// sum += text[i].toLong()
|
||||
// }
|
||||
// colorIndex = sum % AVATAR_COLOR_LIST.size
|
||||
// }
|
||||
// return AVATAR_COLOR_LIST[colorIndex.toInt()]
|
||||
// }
|
||||
|
||||
private fun buildGlideRequest(glideRequest: GlideRequests, avatarUrl: String?): GlideRequest<Drawable> {
|
||||
val resolvedUrl = activeSessionHolder.getActiveSession().contentUrlResolver()
|
||||
.resolveThumbnail(avatarUrl, THUMBNAIL_SIZE, THUMBNAIL_SIZE, ContentUrlResolver.ThumbnailMethod.SCALE)
|
||||
|
@ -27,6 +27,7 @@ import com.google.android.material.bottomnavigation.BottomNavigationItemView
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationMenuView
|
||||
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState
|
||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.commitTransactionNow
|
||||
import im.vector.riotx.core.platform.ToolbarConfigurable
|
||||
@ -74,12 +75,7 @@ class HomeDetailFragment @Inject constructor(
|
||||
|
||||
private fun onGroupChange(groupSummary: GroupSummary?) {
|
||||
groupSummary?.let {
|
||||
avatarRenderer.render(
|
||||
it.avatarUrl,
|
||||
it.groupId,
|
||||
it.displayName,
|
||||
groupToolbarAvatarImageView
|
||||
)
|
||||
avatarRenderer.render(it.toMatrixItem(), groupToolbarAvatarImageView)
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,7 +151,7 @@ class HomeDetailFragment @Inject constructor(
|
||||
bottomNavigationView.selectedItemId = when (displayMode) {
|
||||
RoomListDisplayMode.PEOPLE -> R.id.bottom_action_people
|
||||
RoomListDisplayMode.ROOMS -> R.id.bottom_action_rooms
|
||||
else -> R.id.bottom_action_home
|
||||
else -> R.id.bottom_action_home
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ package im.vector.riotx.features.home
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.observeK
|
||||
import im.vector.riotx.core.extensions.replaceChildFragment
|
||||
@ -42,7 +43,7 @@ class HomeDrawerFragment @Inject constructor(
|
||||
session.liveUser(session.myUserId).observeK(this) { optionalUser ->
|
||||
val user = optionalUser?.getOrNull()
|
||||
if (user != null) {
|
||||
avatarRenderer.render(user.avatarUrl, user.userId, user.displayName, homeDrawerHeaderAvatarView)
|
||||
avatarRenderer.render(user.toMatrixItem(), homeDrawerHeaderAvatarView)
|
||||
homeDrawerUsernameView.text = user.displayName
|
||||
homeDrawerUserIdView.text = user.userId
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.riotx.features.home
|
||||
|
||||
import androidx.annotation.ColorRes
|
||||
import im.vector.riotx.R
|
||||
|
||||
@ColorRes
|
||||
fun getColorFromRoomId(roomId: String?): Int {
|
||||
return when ((roomId?.toList()?.sumBy { it.toInt() } ?: 0) % 3) {
|
||||
1 -> R.color.riotx_avatar_fill_2
|
||||
2 -> R.color.riotx_avatar_fill_3
|
||||
else -> R.color.riotx_avatar_fill_1
|
||||
}
|
||||
}
|
@ -22,28 +22,18 @@ import kotlin.math.abs
|
||||
|
||||
@ColorRes
|
||||
fun getColorFromUserId(userId: String?): Int {
|
||||
if (userId.isNullOrBlank()) {
|
||||
return R.color.riotx_username_1
|
||||
}
|
||||
|
||||
var hash = 0
|
||||
var i = 0
|
||||
var chr: Char
|
||||
|
||||
while (i < userId.length) {
|
||||
chr = userId[i]
|
||||
hash = (hash shl 5) - hash + chr.toInt()
|
||||
i++
|
||||
}
|
||||
userId?.toList()?.map { chr -> hash = (hash shl 5) - hash + chr.toInt() }
|
||||
|
||||
return when (abs(hash) % 8 + 1) {
|
||||
1 -> R.color.riotx_username_1
|
||||
2 -> R.color.riotx_username_2
|
||||
3 -> R.color.riotx_username_3
|
||||
4 -> R.color.riotx_username_4
|
||||
5 -> R.color.riotx_username_5
|
||||
6 -> R.color.riotx_username_6
|
||||
7 -> R.color.riotx_username_7
|
||||
else -> R.color.riotx_username_8
|
||||
return when (abs(hash) % 8) {
|
||||
1 -> R.color.riotx_username_2
|
||||
2 -> R.color.riotx_username_3
|
||||
3 -> R.color.riotx_username_4
|
||||
4 -> R.color.riotx_username_5
|
||||
5 -> R.color.riotx_username_6
|
||||
6 -> R.color.riotx_username_7
|
||||
7 -> R.color.riotx_username_8
|
||||
else -> R.color.riotx_username_1
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import androidx.core.content.ContextCompat
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import com.amulyakhare.textdrawable.TextDrawable
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
@ -34,22 +35,20 @@ import im.vector.riotx.features.home.AvatarRenderer
|
||||
abstract class CreateDirectRoomUserItem : VectorEpoxyModel<CreateDirectRoomUserItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute var name: String? = null
|
||||
@EpoxyAttribute var userId: String = ""
|
||||
@EpoxyAttribute var avatarUrl: String? = null
|
||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
||||
@EpoxyAttribute var clickListener: View.OnClickListener? = null
|
||||
@EpoxyAttribute var selected: Boolean = false
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
holder.view.setOnClickListener(clickListener)
|
||||
// If name is empty, use userId as name and force it being centered
|
||||
if (name.isNullOrEmpty()) {
|
||||
if (matrixItem.displayName.isNullOrEmpty()) {
|
||||
holder.userIdView.visibility = View.GONE
|
||||
holder.nameView.text = userId
|
||||
holder.nameView.text = matrixItem.id
|
||||
} else {
|
||||
holder.userIdView.visibility = View.VISIBLE
|
||||
holder.nameView.text = name
|
||||
holder.userIdView.text = userId
|
||||
holder.nameView.text = matrixItem.displayName
|
||||
holder.userIdView.text = matrixItem.id
|
||||
}
|
||||
renderSelection(holder, selected)
|
||||
}
|
||||
@ -62,7 +61,7 @@ abstract class CreateDirectRoomUserItem : VectorEpoxyModel<CreateDirectRoomUserI
|
||||
holder.avatarImageView.setImageDrawable(backgroundDrawable)
|
||||
} else {
|
||||
holder.avatarCheckedImageView.visibility = View.GONE
|
||||
avatarRenderer.render(avatarUrl, userId, name, holder.avatarImageView)
|
||||
avatarRenderer.render(matrixItem, holder.avatarImageView)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ import com.squareup.inject.assisted.AssistedInject
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.matrix.android.internal.util.firstLetterOfDisplayName
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.matrix.rx.rx
|
||||
import im.vector.riotx.core.extensions.postLiveEvent
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
@ -142,7 +142,7 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
|
||||
session.rx()
|
||||
.searchUsersDirectory(search, 50, emptySet())
|
||||
.map { users ->
|
||||
users.sortedBy { it.displayName.firstLetterOfDisplayName() }
|
||||
users.sortedBy { it.toMatrixItem().firstLetterOfDisplayName() }
|
||||
}
|
||||
}
|
||||
stream.toAsync {
|
||||
|
@ -19,9 +19,13 @@
|
||||
package im.vector.riotx.features.home.createdirect
|
||||
|
||||
import com.airbnb.epoxy.EpoxyController
|
||||
import com.airbnb.mvrx.*
|
||||
import com.airbnb.mvrx.Fail
|
||||
import com.airbnb.mvrx.Loading
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.errorWithRetryItem
|
||||
import im.vector.riotx.core.epoxy.loadingItem
|
||||
@ -94,9 +98,7 @@ class DirectoryUsersController @Inject constructor(private val session: Session,
|
||||
createDirectRoomUserItem {
|
||||
id(user.userId)
|
||||
selected(isSelected)
|
||||
userId(user.userId)
|
||||
name(user.displayName)
|
||||
avatarUrl(user.avatarUrl)
|
||||
matrixItem(user.toMatrixItem())
|
||||
avatarRenderer(avatarRenderer)
|
||||
clickListener { _ ->
|
||||
callback?.onItemClick(user)
|
||||
|
@ -23,7 +23,7 @@ import com.airbnb.mvrx.Incomplete
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.matrix.android.internal.util.firstLetterOfDisplayName
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.EmptyItem_
|
||||
import im.vector.riotx.core.epoxy.loadingItem
|
||||
@ -68,9 +68,7 @@ class KnownUsersController @Inject constructor(private val session: Session,
|
||||
CreateDirectRoomUserItem_()
|
||||
.id(item.userId)
|
||||
.selected(isSelected)
|
||||
.userId(item.userId)
|
||||
.name(item.displayName)
|
||||
.avatarUrl(item.avatarUrl)
|
||||
.matrixItem(item.toMatrixItem())
|
||||
.avatarRenderer(avatarRenderer)
|
||||
.clickListener { _ ->
|
||||
callback?.onItemClick(item)
|
||||
@ -87,8 +85,8 @@ class KnownUsersController @Inject constructor(private val session: Session,
|
||||
var lastFirstLetter: String? = null
|
||||
for (model in models) {
|
||||
if (model is CreateDirectRoomUserItem) {
|
||||
if (model.userId == session.myUserId) continue
|
||||
val currentFirstLetter = model.name.firstLetterOfDisplayName()
|
||||
if (model.matrixItem.id == session.myUserId) continue
|
||||
val currentFirstLetter = model.matrixItem.firstLetterOfDisplayName()
|
||||
val showLetter = !isFiltering && currentFirstLetter.isNotEmpty() && lastFirstLetter != currentFirstLetter
|
||||
lastFirstLetter = currentFirstLetter
|
||||
|
||||
|
@ -36,7 +36,7 @@ import im.vector.riotx.core.utils.LiveEvent
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.functions.BiFunction
|
||||
|
||||
const val ALL_COMMUNITIES_GROUP_ID = "ALL_COMMUNITIES_GROUP_ID"
|
||||
const val ALL_COMMUNITIES_GROUP_ID = "+ALL_COMMUNITIES_GROUP_ID"
|
||||
|
||||
class GroupListViewModel @AssistedInject constructor(@Assisted initialState: GroupListViewState,
|
||||
private val selectedGroupStore: SelectedGroupDataSource,
|
||||
|
@ -18,6 +18,7 @@ package im.vector.riotx.features.home.group
|
||||
|
||||
import com.airbnb.epoxy.EpoxyController
|
||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -49,10 +50,8 @@ class GroupSummaryController @Inject constructor(private val avatarRenderer: Ava
|
||||
groupSummaryItem {
|
||||
avatarRenderer(avatarRenderer)
|
||||
id(groupSummary.groupId)
|
||||
groupId(groupSummary.groupId)
|
||||
groupName(groupSummary.displayName)
|
||||
matrixItem(groupSummary.toMatrixItem())
|
||||
selected(isSelected)
|
||||
avatarUrl(groupSummary.avatarUrl)
|
||||
listener { callback?.onGroupSelected(groupSummary) }
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
@ -30,18 +31,16 @@ import im.vector.riotx.features.home.AvatarRenderer
|
||||
abstract class GroupSummaryItem : VectorEpoxyModel<GroupSummaryItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute lateinit var groupName: CharSequence
|
||||
@EpoxyAttribute lateinit var groupId: String
|
||||
@EpoxyAttribute var avatarUrl: String? = null
|
||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
||||
@EpoxyAttribute var selected: Boolean = false
|
||||
@EpoxyAttribute var listener: (() -> Unit)? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.rootView.setOnClickListener { listener?.invoke() }
|
||||
holder.groupNameView.text = groupName
|
||||
holder.groupNameView.text = matrixItem.displayName
|
||||
holder.rootView.isChecked = selected
|
||||
avatarRenderer.render(avatarUrl, groupId, groupName.toString(), holder.avatarImageView)
|
||||
avatarRenderer.render(matrixItem, holder.avatarImageView)
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
|
@ -18,6 +18,7 @@ package im.vector.riotx.features.home.room.breadcrumbs
|
||||
|
||||
import android.view.View
|
||||
import com.airbnb.epoxy.EpoxyController
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.core.utils.DebouncedClickListener
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import javax.inject.Inject
|
||||
@ -52,9 +53,7 @@ class BreadcrumbsController @Inject constructor(
|
||||
breadcrumbsItem {
|
||||
id(it.roomId)
|
||||
avatarRenderer(avatarRenderer)
|
||||
roomId(it.roomId)
|
||||
roomName(it.displayName)
|
||||
avatarUrl(it.avatarUrl)
|
||||
matrixItem(it.toMatrixItem())
|
||||
unreadNotificationCount(it.notificationCount)
|
||||
showHighlighted(it.highlightCount > 0)
|
||||
hasUnreadMessage(it.hasUnreadMessages)
|
||||
|
@ -67,4 +67,8 @@ class BreadcrumbsFragment @Inject constructor(
|
||||
override fun onBreadcrumbClicked(roomId: String) {
|
||||
sharedActionViewModel.post(RoomDetailSharedAction.SwitchToRoom(roomId))
|
||||
}
|
||||
|
||||
fun scrollToTop() {
|
||||
breadcrumbsRecyclerView.scrollToPosition(0)
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import android.widget.ImageView
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
@ -32,9 +33,7 @@ import im.vector.riotx.features.home.room.list.UnreadCounterBadgeView
|
||||
abstract class BreadcrumbsItem : VectorEpoxyModel<BreadcrumbsItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute lateinit var roomId: String
|
||||
@EpoxyAttribute lateinit var roomName: CharSequence
|
||||
@EpoxyAttribute var avatarUrl: String? = null
|
||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
||||
@EpoxyAttribute var unreadNotificationCount: Int = 0
|
||||
@EpoxyAttribute var showHighlighted: Boolean = false
|
||||
@EpoxyAttribute var hasUnreadMessage: Boolean = false
|
||||
@ -45,7 +44,7 @@ abstract class BreadcrumbsItem : VectorEpoxyModel<BreadcrumbsItem.Holder>() {
|
||||
super.bind(holder)
|
||||
holder.rootView.setOnClickListener(itemClickListener)
|
||||
holder.unreadIndentIndicator.isVisible = hasUnreadMessage
|
||||
avatarRenderer.render(avatarUrl, roomId, roomName.toString(), holder.avatarImageView)
|
||||
avatarRenderer.render(matrixItem, holder.avatarImageView)
|
||||
holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted))
|
||||
holder.draftIndentIndicator.isVisible = hasDraft
|
||||
}
|
||||
|
@ -86,9 +86,19 @@ class RoomDetailActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
private val drawerListener = object : DrawerLayout.SimpleDrawerListener() {
|
||||
override fun onDrawerStateChanged(newState: Int) {
|
||||
hideKeyboard()
|
||||
|
||||
if (!drawerLayout.isDrawerOpen(GravityCompat.START) && newState == DrawerLayout.STATE_DRAGGING) {
|
||||
// User is starting to open the drawer, scroll the list to op
|
||||
scrollBreadcrumbsToTop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun scrollBreadcrumbsToTop() {
|
||||
supportFragmentManager.fragments.filterIsInstance<BreadcrumbsFragment>()
|
||||
.forEach { it.scrollToTop() }
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
|
||||
drawerLayout.closeDrawer(GravityCompat.START)
|
||||
|
@ -66,6 +66,8 @@ import im.vector.matrix.android.api.session.room.timeline.Timeline
|
||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||
import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.dialogs.withColoredButton
|
||||
import im.vector.riotx.core.epoxy.LayoutManagerStateRestorer
|
||||
@ -408,9 +410,7 @@ class RoomDetailFragment @Inject constructor(
|
||||
composerLayout.sendButton.setContentDescription(getString(descriptionRes))
|
||||
|
||||
avatarRenderer.render(
|
||||
event.senderAvatar,
|
||||
event.root.senderId ?: "",
|
||||
event.getDisambiguatedDisplayName(),
|
||||
MatrixItem.UserItem(event.root.senderId ?: "", event.getDisambiguatedDisplayName(), event.senderAvatar),
|
||||
composerLayout.composerRelatedMessageAvatar
|
||||
)
|
||||
composerLayout.expand {
|
||||
@ -599,20 +599,19 @@ class RoomDetailFragment @Inject constructor(
|
||||
}
|
||||
|
||||
// Replace the word by its completion
|
||||
val displayName = item.displayName ?: item.userId
|
||||
val matrixItem = item.toMatrixItem()
|
||||
val displayName = matrixItem.getBestName()
|
||||
|
||||
// with a trailing space
|
||||
editable.replace(startIndex, endIndex, "$displayName ")
|
||||
|
||||
// Add the span
|
||||
val user = session.getUser(item.userId)
|
||||
val span = PillImageSpan(
|
||||
glideRequests,
|
||||
avatarRenderer,
|
||||
requireContext(),
|
||||
item.userId,
|
||||
user?.displayName ?: item.userId,
|
||||
user?.avatarUrl)
|
||||
matrixItem
|
||||
)
|
||||
span.bind(composerLayout.composerEditText)
|
||||
|
||||
editable.setSpan(span, startIndex, startIndex + displayName.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
@ -684,7 +683,7 @@ class RoomDetailFragment @Inject constructor(
|
||||
inviteView.visibility = View.GONE
|
||||
val uid = session.myUserId
|
||||
val meMember = session.getRoom(state.roomId)?.getRoomMember(uid)
|
||||
avatarRenderer.render(meMember?.avatarUrl, uid, meMember?.displayName, composerLayout.composerAvatarImageView)
|
||||
avatarRenderer.render(MatrixItem.UserItem(uid, meMember?.displayName, meMember?.avatarUrl), composerLayout.composerAvatarImageView)
|
||||
} else if (summary?.membership == Membership.INVITE && inviter != null) {
|
||||
inviteView.visibility = View.VISIBLE
|
||||
inviteView.render(inviter, VectorInviteView.Mode.LARGE)
|
||||
@ -711,7 +710,7 @@ class RoomDetailFragment @Inject constructor(
|
||||
activity?.finish()
|
||||
} else {
|
||||
roomToolbarTitleView.text = it.displayName
|
||||
avatarRenderer.render(it, roomToolbarAvatarImageView)
|
||||
avatarRenderer.render(it.toMatrixItem(), roomToolbarAvatarImageView)
|
||||
roomToolbarSubtitleView.setTextOrHide(it.topic)
|
||||
}
|
||||
jumpToBottomView.count = it.notificationCount
|
||||
@ -1195,9 +1194,8 @@ class RoomDetailFragment @Inject constructor(
|
||||
glideRequests,
|
||||
avatarRenderer,
|
||||
requireContext(),
|
||||
userId,
|
||||
displayName,
|
||||
roomMember?.avatarUrl)
|
||||
MatrixItem.UserItem(userId, displayName, roomMember?.avatarUrl)
|
||||
)
|
||||
.also { it.bind(composerLayout.composerEditText) },
|
||||
0,
|
||||
displayName.length,
|
||||
|
@ -22,6 +22,7 @@ import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import com.airbnb.epoxy.EpoxyModelWithHolder
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
@ -29,15 +30,13 @@ import im.vector.riotx.features.home.AvatarRenderer
|
||||
@EpoxyModelClass(layout = R.layout.item_display_read_receipt)
|
||||
abstract class DisplayReadReceiptItem : EpoxyModelWithHolder<DisplayReadReceiptItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute var name: String? = null
|
||||
@EpoxyAttribute var userId: String = ""
|
||||
@EpoxyAttribute var avatarUrl: String? = null
|
||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
||||
@EpoxyAttribute var timestamp: CharSequence? = null
|
||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
avatarRenderer.render(avatarUrl, userId, name, holder.avatarView)
|
||||
holder.displayNameView.text = name ?: userId
|
||||
avatarRenderer.render(matrixItem, holder.avatarView)
|
||||
holder.displayNameView.text = matrixItem.getBestName()
|
||||
timestamp?.let {
|
||||
holder.timestampView.text = it
|
||||
holder.timestampView.isVisible = true
|
||||
|
@ -21,6 +21,7 @@ import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.riotx.core.date.VectorDateFormatter
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import im.vector.riotx.features.home.room.detail.timeline.item.ReadReceiptData
|
||||
import im.vector.riotx.features.home.room.detail.timeline.item.toMatrixItem
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
@ -36,9 +37,7 @@ class DisplayReadReceiptsController @Inject constructor(private val dateFormatte
|
||||
val timestamp = dateFormatter.formatRelativeDateTime(it.timestamp)
|
||||
DisplayReadReceiptItem_()
|
||||
.id(it.userId)
|
||||
.userId(it.userId)
|
||||
.avatarUrl(it.avatarUrl)
|
||||
.name(it.displayName)
|
||||
.matrixItem(it.toMatrixItem())
|
||||
.avatarRenderer(avatarRender)
|
||||
.timestamp(timestamp)
|
||||
.addIf(session.myUserId != it.userId, this)
|
||||
|
@ -44,9 +44,7 @@ class MessageActionsEpoxyController @Inject constructor(private val stringProvid
|
||||
bottomSheetMessagePreviewItem {
|
||||
id("preview")
|
||||
avatarRenderer(avatarRenderer)
|
||||
avatarUrl(state.informationData.avatarUrl ?: "")
|
||||
senderId(state.informationData.senderId)
|
||||
senderName(state.senderName())
|
||||
matrixItem(state.informationData.matrixItem)
|
||||
movementMethod(createLinkMovementMethod(listener))
|
||||
body(body.linkify(listener))
|
||||
time(state.time())
|
||||
|
@ -60,7 +60,7 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses
|
||||
val avatarUrl = event.senderAvatar
|
||||
val memberName = event.getDisambiguatedDisplayName()
|
||||
val formattedMemberName = span(memberName) {
|
||||
textColor = colorProvider.getColor(getColorFromUserId(event.root.senderId ?: ""))
|
||||
textColor = colorProvider.getColor(getColorFromUserId(event.root.senderId))
|
||||
}
|
||||
|
||||
return MessageInformationData(
|
||||
|
@ -77,12 +77,7 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
|
||||
holder.timeView.visibility = View.VISIBLE
|
||||
holder.timeView.text = attributes.informationData.time
|
||||
holder.memberNameView.text = attributes.informationData.memberName
|
||||
attributes.avatarRenderer.render(
|
||||
attributes.informationData.avatarUrl,
|
||||
attributes.informationData.senderId,
|
||||
attributes.informationData.memberName?.toString(),
|
||||
holder.avatarImageView
|
||||
)
|
||||
attributes.avatarRenderer.render(attributes.informationData.matrixItem, holder.avatarImageView)
|
||||
holder.avatarImageView.setOnLongClickListener(attributes.itemLongClickListener)
|
||||
holder.memberNameView.setOnLongClickListener(attributes.itemLongClickListener)
|
||||
} else {
|
||||
|
@ -24,6 +24,7 @@ import androidx.core.view.children
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
|
||||
@ -54,7 +55,7 @@ abstract class MergedHeaderItem : BaseEventItem<MergedHeaderItem.Holder>() {
|
||||
val data = distinctMergeData.getOrNull(index)
|
||||
if (data != null && view is ImageView) {
|
||||
view.visibility = View.VISIBLE
|
||||
attributes.avatarRenderer.render(data.avatarUrl, data.userId, data.memberName, view)
|
||||
attributes.avatarRenderer.render(data.toMatrixItem(), view)
|
||||
} else {
|
||||
view.visibility = View.GONE
|
||||
}
|
||||
@ -87,6 +88,8 @@ abstract class MergedHeaderItem : BaseEventItem<MergedHeaderItem.Holder>() {
|
||||
val avatarUrl: String?
|
||||
)
|
||||
|
||||
fun Data.toMatrixItem() = MatrixItem.UserItem(userId, memberName, avatarUrl)
|
||||
|
||||
data class Attributes(
|
||||
val isCollapsed: Boolean,
|
||||
val mergeData: List<Data>,
|
||||
|
@ -18,6 +18,7 @@ package im.vector.riotx.features.home.room.detail.timeline.item
|
||||
|
||||
import android.os.Parcelable
|
||||
import im.vector.matrix.android.api.session.room.send.SendState
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
@ -34,7 +35,11 @@ data class MessageInformationData(
|
||||
val hasBeenEdited: Boolean = false,
|
||||
val hasPendingEdits: Boolean = false,
|
||||
val readReceipts: List<ReadReceiptData> = emptyList()
|
||||
) : Parcelable
|
||||
) : Parcelable {
|
||||
|
||||
val matrixItem: MatrixItem
|
||||
get() = MatrixItem.UserItem(senderId, memberName?.toString(), avatarUrl)
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class ReactionInfoData(
|
||||
@ -51,3 +56,5 @@ data class ReadReceiptData(
|
||||
val displayName: String?,
|
||||
val timestamp: Long
|
||||
) : Parcelable
|
||||
|
||||
fun ReadReceiptData.toMatrixItem() = MatrixItem.UserItem(userId, displayName, avatarUrl)
|
||||
|
@ -39,13 +39,7 @@ abstract class NoticeItem : BaseEventItem<NoticeItem.Holder>() {
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.noticeTextView.text = attributes.noticeText
|
||||
attributes.avatarRenderer.render(
|
||||
attributes.informationData.avatarUrl,
|
||||
attributes.informationData.senderId,
|
||||
attributes.informationData.memberName?.toString()
|
||||
?: attributes.informationData.senderId,
|
||||
holder.avatarImageView
|
||||
)
|
||||
attributes.avatarRenderer.render(attributes.informationData.matrixItem, holder.avatarImageView)
|
||||
holder.view.setOnLongClickListener(attributes.itemLongClickListener)
|
||||
holder.readReceiptsView.render(attributes.informationData.readReceipts, attributes.avatarRenderer, _readReceiptsClickListener)
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import android.widget.TextView
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
@ -33,10 +34,8 @@ import im.vector.riotx.features.home.AvatarRenderer
|
||||
abstract class RoomInvitationItem : VectorEpoxyModel<RoomInvitationItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute lateinit var roomName: CharSequence
|
||||
@EpoxyAttribute lateinit var roomId: String
|
||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
||||
@EpoxyAttribute var secondLine: CharSequence? = null
|
||||
@EpoxyAttribute var avatarUrl: String? = null
|
||||
@EpoxyAttribute var listener: (() -> Unit)? = null
|
||||
@EpoxyAttribute var invitationAcceptInProgress: Boolean = false
|
||||
@EpoxyAttribute var invitationAcceptInError: Boolean = false
|
||||
@ -85,9 +84,9 @@ abstract class RoomInvitationItem : VectorEpoxyModel<RoomInvitationItem.Holder>(
|
||||
rejectListener?.invoke()
|
||||
}
|
||||
}
|
||||
holder.titleView.text = roomName
|
||||
holder.titleView.text = matrixItem.getBestName()
|
||||
holder.subtitleView.setTextOrHide(secondLine)
|
||||
avatarRenderer.render(avatarUrl, roomId, roomName.toString(), holder.avatarImageView)
|
||||
avatarRenderer.render(matrixItem, holder.avatarImageView)
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
|
@ -23,6 +23,7 @@ import android.widget.TextView
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
@ -32,11 +33,9 @@ import im.vector.riotx.features.home.AvatarRenderer
|
||||
abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute lateinit var roomName: CharSequence
|
||||
@EpoxyAttribute lateinit var roomId: String
|
||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
||||
@EpoxyAttribute lateinit var lastFormattedEvent: CharSequence
|
||||
@EpoxyAttribute lateinit var lastEventTime: CharSequence
|
||||
@EpoxyAttribute var avatarUrl: String? = null
|
||||
@EpoxyAttribute var unreadNotificationCount: Int = 0
|
||||
@EpoxyAttribute var hasUnreadMessage: Boolean = false
|
||||
@EpoxyAttribute var hasDraft: Boolean = false
|
||||
@ -48,13 +47,13 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
||||
super.bind(holder)
|
||||
holder.rootView.setOnClickListener(itemClickListener)
|
||||
holder.rootView.setOnLongClickListener(itemLongClickListener)
|
||||
holder.titleView.text = roomName
|
||||
holder.titleView.text = matrixItem.getBestName()
|
||||
holder.lastEventTimeView.text = lastEventTime
|
||||
holder.lastEventView.text = lastFormattedEvent
|
||||
holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted))
|
||||
holder.unreadIndentIndicator.isVisible = hasUnreadMessage
|
||||
holder.draftView.isVisible = hasDraft
|
||||
avatarRenderer.render(avatarUrl, roomId, roomName.toString(), holder.avatarImageView)
|
||||
avatarRenderer.render(matrixItem, holder.avatarImageView)
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
|
@ -21,6 +21,7 @@ import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.date.VectorDateFormatter
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
@ -69,7 +70,7 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte
|
||||
return RoomInvitationItem_()
|
||||
.id(roomSummary.roomId)
|
||||
.avatarRenderer(avatarRenderer)
|
||||
.roomId(roomSummary.roomId)
|
||||
.matrixItem(roomSummary.toMatrixItem())
|
||||
.secondLine(secondLine)
|
||||
.invitationAcceptInProgress(joiningRoomsIds.contains(roomSummary.roomId))
|
||||
.invitationAcceptInError(joiningErrorRoomsIds.contains(roomSummary.roomId))
|
||||
@ -77,8 +78,6 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte
|
||||
.invitationRejectInError(rejectingErrorRoomsIds.contains(roomSummary.roomId))
|
||||
.acceptListener { listener?.onAcceptRoomInvitation(roomSummary) }
|
||||
.rejectListener { listener?.onRejectRoomInvitation(roomSummary) }
|
||||
.roomName(roomSummary.displayName)
|
||||
.avatarUrl(roomSummary.avatarUrl)
|
||||
.listener { listener?.onRoomClicked(roomSummary) }
|
||||
}
|
||||
|
||||
@ -125,11 +124,9 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte
|
||||
return RoomSummaryItem_()
|
||||
.id(roomSummary.roomId)
|
||||
.avatarRenderer(avatarRenderer)
|
||||
.roomId(roomSummary.roomId)
|
||||
.matrixItem(roomSummary.toMatrixItem())
|
||||
.lastEventTime(latestEventTime)
|
||||
.lastFormattedEvent(latestFormattedEvent)
|
||||
.roomName(roomSummary.displayName)
|
||||
.avatarUrl(roomSummary.avatarUrl)
|
||||
.showHighlighted(showHighlighted)
|
||||
.unreadNotificationCount(unreadCount)
|
||||
.hasUnreadMessage(roomSummary.hasUnreadMessages)
|
||||
|
@ -18,6 +18,7 @@ package im.vector.riotx.features.home.room.list.actions
|
||||
import android.view.View
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetActionItem
|
||||
import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetRoomPreviewItem
|
||||
import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetSeparatorItem
|
||||
@ -39,9 +40,7 @@ class RoomListQuickActionsEpoxyController @Inject constructor(private val avatar
|
||||
bottomSheetRoomPreviewItem {
|
||||
id("preview")
|
||||
avatarRenderer(avatarRenderer)
|
||||
roomName(roomSummary.displayName)
|
||||
avatarUrl(roomSummary.avatarUrl)
|
||||
roomId(roomSummary.roomId)
|
||||
matrixItem(roomSummary.toMatrixItem())
|
||||
settingsClickListener(View.OnClickListener { listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.Settings(roomSummary.roomId)) })
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ import android.content.Context
|
||||
import android.text.style.URLSpan
|
||||
import im.vector.matrix.android.api.permalinks.PermalinkData
|
||||
import im.vector.matrix.android.api.permalinks.PermalinkParser
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||
import im.vector.riotx.core.glide.GlideRequests
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
@ -41,8 +42,8 @@ class MxLinkTagHandler(private val glideRequests: GlideRequests,
|
||||
when (permalinkData) {
|
||||
is PermalinkData.UserLink -> {
|
||||
val user = sessionHolder.getSafeActiveSession()?.getUser(permalinkData.userId)
|
||||
val span = PillImageSpan(glideRequests, avatarRenderer, context, permalinkData.userId, user?.displayName
|
||||
?: permalinkData.userId, user?.avatarUrl)
|
||||
val span = PillImageSpan(glideRequests, avatarRenderer, context, MatrixItem.UserItem(permalinkData.userId, user?.displayName
|
||||
?: permalinkData.userId, user?.avatarUrl))
|
||||
SpannableBuilder.setSpans(
|
||||
visitor.builder(),
|
||||
span,
|
||||
|
@ -29,6 +29,7 @@ import com.bumptech.glide.request.target.SimpleTarget
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import com.google.android.material.chip.ChipDrawable
|
||||
import im.vector.matrix.android.api.session.room.send.UserMentionSpan
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.glide.GlideRequests
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
@ -42,9 +43,8 @@ import java.lang.ref.WeakReference
|
||||
class PillImageSpan(private val glideRequests: GlideRequests,
|
||||
private val avatarRenderer: AvatarRenderer,
|
||||
private val context: Context,
|
||||
override val userId: String,
|
||||
override val displayName: String,
|
||||
private val avatarUrl: String?) : ReplacementSpan(), UserMentionSpan {
|
||||
override val matrixItem: MatrixItem
|
||||
) : ReplacementSpan(), UserMentionSpan {
|
||||
|
||||
private val pillDrawable = createChipDrawable()
|
||||
private val target = PillImageSpanTarget(this)
|
||||
@ -53,7 +53,7 @@ class PillImageSpan(private val glideRequests: GlideRequests,
|
||||
@UiThread
|
||||
fun bind(textView: TextView) {
|
||||
tv = WeakReference(textView)
|
||||
avatarRenderer.render(context, glideRequests, avatarUrl, userId, displayName, target)
|
||||
avatarRenderer.render(context, glideRequests, matrixItem, target)
|
||||
}
|
||||
|
||||
// ReplacementSpan *****************************************************************************
|
||||
@ -101,12 +101,12 @@ class PillImageSpan(private val glideRequests: GlideRequests,
|
||||
private fun createChipDrawable(): ChipDrawable {
|
||||
val textPadding = context.resources.getDimension(R.dimen.pill_text_padding)
|
||||
return ChipDrawable.createFromResource(context, R.xml.pill_view).apply {
|
||||
text = displayName
|
||||
text = matrixItem.getBestName()
|
||||
textEndPadding = textPadding
|
||||
textStartPadding = textPadding
|
||||
setChipMinHeightResource(R.dimen.pill_min_height)
|
||||
setChipIconSizeResource(R.dimen.pill_avatar_size)
|
||||
chipIcon = avatarRenderer.getPlaceholderDrawable(context, userId, displayName)
|
||||
chipIcon = avatarRenderer.getPlaceholderDrawable(context, matrixItem)
|
||||
setBounds(0, 0, intrinsicWidth, intrinsicHeight)
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.HasScreenInjector
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
@ -56,7 +57,7 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib
|
||||
fun render(sender: User, mode: Mode = Mode.LARGE) {
|
||||
if (mode == Mode.LARGE) {
|
||||
updateLayoutParams { height = LayoutParams.MATCH_CONSTRAINT }
|
||||
avatarRenderer.render(sender.avatarUrl, sender.userId, sender.displayName, inviteAvatarView)
|
||||
avatarRenderer.render(sender.toMatrixItem(), inviteAvatarView)
|
||||
inviteIdentifierView.text = sender.userId
|
||||
inviteNameView.text = sender.displayName
|
||||
inviteLabelView.text = context.getString(R.string.send_you_invite)
|
||||
|
@ -21,6 +21,7 @@ import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
@ -35,13 +36,7 @@ abstract class PublicRoomItem : VectorEpoxyModel<PublicRoomItem.Holder>() {
|
||||
lateinit var avatarRenderer: AvatarRenderer
|
||||
|
||||
@EpoxyAttribute
|
||||
var avatarUrl: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var roomId: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var roomName: String? = null
|
||||
lateinit var matrixItem: MatrixItem
|
||||
|
||||
@EpoxyAttribute
|
||||
var roomAlias: String? = null
|
||||
@ -64,8 +59,8 @@ abstract class PublicRoomItem : VectorEpoxyModel<PublicRoomItem.Holder>() {
|
||||
override fun bind(holder: Holder) {
|
||||
holder.rootView.setOnClickListener { globalListener?.invoke() }
|
||||
|
||||
avatarRenderer.render(avatarUrl, roomId!!, roomName, holder.avatarView)
|
||||
holder.nameView.text = roomName
|
||||
avatarRenderer.render(matrixItem, holder.avatarView)
|
||||
holder.nameView.text = matrixItem.displayName
|
||||
holder.aliasView.setTextOrHide(roomAlias)
|
||||
holder.topicView.setTextOrHide(roomTopic)
|
||||
// TODO Use formatter for big numbers?
|
||||
|
@ -22,6 +22,7 @@ import com.airbnb.mvrx.Fail
|
||||
import com.airbnb.mvrx.Incomplete
|
||||
import com.airbnb.mvrx.Success
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.errorWithRetryItem
|
||||
import im.vector.riotx.core.epoxy.loadingItem
|
||||
@ -83,9 +84,7 @@ class PublicRoomsController @Inject constructor(private val stringProvider: Stri
|
||||
publicRoomItem {
|
||||
avatarRenderer(avatarRenderer)
|
||||
id(publicRoom.roomId)
|
||||
roomId(publicRoom.roomId)
|
||||
avatarUrl(publicRoom.avatarUrl)
|
||||
roomName(publicRoom.name)
|
||||
matrixItem(publicRoom.toMatrixItem())
|
||||
roomAlias(publicRoom.canonicalAlias)
|
||||
roomTopic(publicRoom.topic)
|
||||
nbOfMembers(publicRoom.numJoinedMembers)
|
||||
|
@ -21,6 +21,7 @@ import android.content.Intent
|
||||
import android.os.Parcelable
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.addFragment
|
||||
import im.vector.riotx.core.platform.ToolbarConfigurable
|
||||
@ -34,7 +35,10 @@ data class RoomPreviewData(
|
||||
val topic: String?,
|
||||
val worldReadable: Boolean,
|
||||
val avatarUrl: String?
|
||||
) : Parcelable
|
||||
) : Parcelable {
|
||||
val matrixItem: MatrixItem
|
||||
get() = MatrixItem.RoomItem(roomId, roomName, avatarUrl)
|
||||
}
|
||||
|
||||
class RoomPreviewActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
|
||||
|
@ -49,11 +49,11 @@ class RoomPreviewNoPreviewFragment @Inject constructor(
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setupToolbar(roomPreviewNoPreviewToolbar)
|
||||
// Toolbar
|
||||
avatarRenderer.render(roomPreviewData.avatarUrl, roomPreviewData.roomId, roomPreviewData.roomName, roomPreviewNoPreviewToolbarAvatar)
|
||||
avatarRenderer.render(roomPreviewData.matrixItem, roomPreviewNoPreviewToolbarAvatar)
|
||||
roomPreviewNoPreviewToolbarTitle.text = roomPreviewData.roomName
|
||||
|
||||
// Screen
|
||||
avatarRenderer.render(roomPreviewData.avatarUrl, roomPreviewData.roomId, roomPreviewData.roomName, roomPreviewNoPreviewAvatar)
|
||||
avatarRenderer.render(roomPreviewData.matrixItem, roomPreviewNoPreviewAvatar)
|
||||
roomPreviewNoPreviewName.text = roomPreviewData.roomName
|
||||
roomPreviewNoPreviewTopic.setTextOrHide(roomPreviewData.topic)
|
||||
|
||||
|
@ -18,6 +18,7 @@ package im.vector.riotx.features.settings.ignored
|
||||
|
||||
import com.airbnb.epoxy.EpoxyController
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.noResultItem
|
||||
import im.vector.riotx.core.resources.StringProvider
|
||||
@ -44,19 +45,19 @@ class IgnoredUsersController @Inject constructor(private val stringProvider: Str
|
||||
buildIgnoredUserModels(nonNullViewState.ignoredUsers)
|
||||
}
|
||||
|
||||
private fun buildIgnoredUserModels(userIds: List<User>) {
|
||||
if (userIds.isEmpty()) {
|
||||
private fun buildIgnoredUserModels(users: List<User>) {
|
||||
if (users.isEmpty()) {
|
||||
noResultItem {
|
||||
id("empty")
|
||||
text(stringProvider.getString(R.string.no_ignored_users))
|
||||
}
|
||||
} else {
|
||||
userIds.forEach { userId ->
|
||||
users.forEach { user ->
|
||||
userItem {
|
||||
id(userId.userId)
|
||||
id(user.userId)
|
||||
avatarRenderer(avatarRenderer)
|
||||
user(userId)
|
||||
itemClickAction { callback?.onUserIdClicked(userId.userId) }
|
||||
matrixItem(user.toMatrixItem())
|
||||
itemClickAction { callback?.onUserIdClicked(user.userId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.matrix.android.api.session.user.model.User
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
@ -37,7 +37,7 @@ abstract class UserItem : VectorEpoxyModel<UserItem.Holder>() {
|
||||
lateinit var avatarRenderer: AvatarRenderer
|
||||
|
||||
@EpoxyAttribute
|
||||
lateinit var user: User
|
||||
lateinit var matrixItem: MatrixItem
|
||||
|
||||
@EpoxyAttribute
|
||||
var itemClickAction: (() -> Unit)? = null
|
||||
@ -45,9 +45,9 @@ abstract class UserItem : VectorEpoxyModel<UserItem.Holder>() {
|
||||
override fun bind(holder: Holder) {
|
||||
holder.root.setOnClickListener { itemClickAction?.invoke() }
|
||||
|
||||
avatarRenderer.render(user, holder.avatarImage)
|
||||
holder.userIdText.setTextOrHide(user.userId)
|
||||
holder.displayNameText.setTextOrHide(user.displayName)
|
||||
avatarRenderer.render(matrixItem, holder.avatarImage)
|
||||
holder.userIdText.setTextOrHide(matrixItem.id)
|
||||
holder.displayNameText.setTextOrHide(matrixItem.displayName)
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
|
@ -40,10 +40,10 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:minWidth="16dp"
|
||||
android:minHeight="16dp"
|
||||
android:minWidth="18dp"
|
||||
android:minHeight="18dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="10sp"
|
||||
android:textSize="11sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintCircle="@+id/breadcrumbsImageView"
|
||||
app:layout_constraintCircleAngle="45"
|
||||
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.riotx.features.home
|
||||
|
||||
import im.vector.riotx.R
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class UserColorTest {
|
||||
|
||||
@Test
|
||||
fun testNull() {
|
||||
assertEquals(R.color.riotx_username_1, getColorFromUserId(null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testEmpty() {
|
||||
assertEquals(R.color.riotx_username_1, getColorFromUserId(""))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testName() {
|
||||
assertEquals(R.color.riotx_username_1, getColorFromUserId("@ganfra:matrix.org"))
|
||||
assertEquals(R.color.riotx_username_4, getColorFromUserId("@benoit0816:matrix.org"))
|
||||
assertEquals(R.color.riotx_username_5, getColorFromUserId("@hubert:uhoreg.ca"))
|
||||
assertEquals(R.color.riotx_username_7, getColorFromUserId("@nadonomy:matrix.org"))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user