Code cleanup, remove duplicate code, and add some comments

This commit is contained in:
Benoit Marty 2019-06-04 17:36:49 +02:00
parent ab6220a4cb
commit 2ba7ec48f6
11 changed files with 131 additions and 118 deletions

View File

@ -16,7 +16,6 @@


package im.vector.matrix.android.api package im.vector.matrix.android.api


import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern


/** /**
@ -25,53 +24,53 @@ import java.util.regex.Pattern
object MatrixPatterns { object MatrixPatterns {


// Note: TLD is not mandatory (localhost, IP address...) // Note: TLD is not mandatory (localhost, IP address...)
private val DOMAIN_REGEX = ":[A-Z0-9.-]+(:[0-9]{2,5})?" private const val DOMAIN_REGEX = ":[A-Z0-9.-]+(:[0-9]{2,5})?"


// regex pattern to find matrix user ids in a string. // regex pattern to find matrix user ids in a string.
// See https://matrix.org/speculator/spec/HEAD/appendices.html#historical-user-ids // See https://matrix.org/speculator/spec/HEAD/appendices.html#historical-user-ids
private val MATRIX_USER_IDENTIFIER_REGEX = "@[A-Z0-9\\x21-\\x39\\x3B-\\x7F]+$DOMAIN_REGEX" private const val MATRIX_USER_IDENTIFIER_REGEX = "@[A-Z0-9\\x21-\\x39\\x3B-\\x7F]+$DOMAIN_REGEX"
val PATTERN_CONTAIN_MATRIX_USER_IDENTIFIER = Pattern.compile(MATRIX_USER_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE) private val PATTERN_CONTAIN_MATRIX_USER_IDENTIFIER = Pattern.compile(MATRIX_USER_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE)


// regex pattern to find room ids in a string. // regex pattern to find room ids in a string.
private val MATRIX_ROOM_IDENTIFIER_REGEX = "![A-Z0-9]+$DOMAIN_REGEX" private const val MATRIX_ROOM_IDENTIFIER_REGEX = "![A-Z0-9]+$DOMAIN_REGEX"
val PATTERN_CONTAIN_MATRIX_ROOM_IDENTIFIER = Pattern.compile(MATRIX_ROOM_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE) private val PATTERN_CONTAIN_MATRIX_ROOM_IDENTIFIER = Pattern.compile(MATRIX_ROOM_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE)


// regex pattern to find room aliases in a string. // regex pattern to find room aliases in a string.
private val MATRIX_ROOM_ALIAS_REGEX = "#[A-Z0-9._%#@=+-]+$DOMAIN_REGEX" private const val MATRIX_ROOM_ALIAS_REGEX = "#[A-Z0-9._%#@=+-]+$DOMAIN_REGEX"
val PATTERN_CONTAIN_MATRIX_ALIAS = Pattern.compile(MATRIX_ROOM_ALIAS_REGEX, Pattern.CASE_INSENSITIVE) private val PATTERN_CONTAIN_MATRIX_ALIAS = Pattern.compile(MATRIX_ROOM_ALIAS_REGEX, Pattern.CASE_INSENSITIVE)


// regex pattern to find message ids in a string. // regex pattern to find message ids in a string.
private val MATRIX_EVENT_IDENTIFIER_REGEX = "\\$[A-Z0-9]+$DOMAIN_REGEX" private const val MATRIX_EVENT_IDENTIFIER_REGEX = "\\$[A-Z0-9]+$DOMAIN_REGEX"
val PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER = Pattern.compile(MATRIX_EVENT_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE) private val PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER = Pattern.compile(MATRIX_EVENT_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE)


// regex pattern to find message ids in a string. // regex pattern to find message ids in a string.
private val MATRIX_EVENT_IDENTIFIER_V3_REGEX = "\\$[A-Z0-9/+]+" private const val MATRIX_EVENT_IDENTIFIER_V3_REGEX = "\\$[A-Z0-9/+]+"
val PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER_V3 = Pattern.compile(MATRIX_EVENT_IDENTIFIER_V3_REGEX, Pattern.CASE_INSENSITIVE) private val PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER_V3 = Pattern.compile(MATRIX_EVENT_IDENTIFIER_V3_REGEX, Pattern.CASE_INSENSITIVE)


// regex pattern to find group ids in a string. // regex pattern to find group ids in a string.
private val MATRIX_GROUP_IDENTIFIER_REGEX = "\\+[A-Z0-9=_\\-./]+$DOMAIN_REGEX" private const val MATRIX_GROUP_IDENTIFIER_REGEX = "\\+[A-Z0-9=_\\-./]+$DOMAIN_REGEX"
val PATTERN_CONTAIN_MATRIX_GROUP_IDENTIFIER = Pattern.compile(MATRIX_GROUP_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE) private val PATTERN_CONTAIN_MATRIX_GROUP_IDENTIFIER = Pattern.compile(MATRIX_GROUP_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE)


// regex pattern to find permalink with message id. // regex pattern to find permalink with message id.
// Android does not support in URL so extract it. // Android does not support in URL so extract it.
private val PERMALINK_BASE_REGEX = "https://matrix\\.to/#/" private const val PERMALINK_BASE_REGEX = "https://matrix\\.to/#/"
private val APP_BASE_REGEX = "https://[A-Z0-9.-]+\\.[A-Z]{2,}/[A-Z]{3,}/#/room/" private const val APP_BASE_REGEX = "https://[A-Z0-9.-]+\\.[A-Z]{2,}/[A-Z]{3,}/#/room/"
val SEP_REGEX = "/" const val SEP_REGEX = "/"


private val LINK_TO_ROOM_ID_REGEXP = PERMALINK_BASE_REGEX + MATRIX_ROOM_IDENTIFIER_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX private const val LINK_TO_ROOM_ID_REGEXP = PERMALINK_BASE_REGEX + MATRIX_ROOM_IDENTIFIER_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
val PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ID = Pattern.compile(LINK_TO_ROOM_ID_REGEXP, Pattern.CASE_INSENSITIVE) private val PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ID = Pattern.compile(LINK_TO_ROOM_ID_REGEXP, Pattern.CASE_INSENSITIVE)


private val LINK_TO_ROOM_ALIAS_REGEXP = PERMALINK_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX private const val LINK_TO_ROOM_ALIAS_REGEXP = PERMALINK_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
val PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ALIAS = Pattern.compile(LINK_TO_ROOM_ALIAS_REGEXP, Pattern.CASE_INSENSITIVE) private val PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ALIAS = Pattern.compile(LINK_TO_ROOM_ALIAS_REGEXP, Pattern.CASE_INSENSITIVE)


private val LINK_TO_APP_ROOM_ID_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_IDENTIFIER_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX private const val LINK_TO_APP_ROOM_ID_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_IDENTIFIER_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ID = Pattern.compile(LINK_TO_APP_ROOM_ID_REGEXP, Pattern.CASE_INSENSITIVE) private val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ID = Pattern.compile(LINK_TO_APP_ROOM_ID_REGEXP, Pattern.CASE_INSENSITIVE)


private val LINK_TO_APP_ROOM_ALIAS_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX private const val LINK_TO_APP_ROOM_ALIAS_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ALIAS = Pattern.compile(LINK_TO_APP_ROOM_ALIAS_REGEXP, Pattern.CASE_INSENSITIVE) private val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ALIAS = Pattern.compile(LINK_TO_APP_ROOM_ALIAS_REGEXP, Pattern.CASE_INSENSITIVE)


// list of patterns to find some matrix item. // list of patterns to find some matrix item.
val MATRIX_PATTERNS = Arrays.asList( val MATRIX_PATTERNS = listOf(
PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ID, PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ID,
PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ALIAS, PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ALIAS,
PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ID, PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ID,
@ -133,4 +132,4 @@ object MatrixPatterns {
fun isGroupId(str: String?): Boolean { fun isGroupId(str: String?): Boolean {
return str != null && PATTERN_CONTAIN_MATRIX_GROUP_IDENTIFIER.matcher(str).matches() return str != null && PATTERN_CONTAIN_MATRIX_GROUP_IDENTIFIER.matcher(str).matches()
} }
}// Cannot be instantiated }

View File

@ -18,16 +18,16 @@ package im.vector.matrix.android.api.session.room.model.message


object MessageType { object MessageType {


val MSGTYPE_TEXT = "m.text" const val MSGTYPE_TEXT = "m.text"
val MSGTYPE_EMOTE = "m.emote" const val MSGTYPE_EMOTE = "m.emote"
val MSGTYPE_NOTICE = "m.notice" const val MSGTYPE_NOTICE = "m.notice"
val MSGTYPE_IMAGE = "m.image" const val MSGTYPE_IMAGE = "m.image"
val MSGTYPE_AUDIO = "m.audio" const val MSGTYPE_AUDIO = "m.audio"
val MSGTYPE_VIDEO = "m.video" const val MSGTYPE_VIDEO = "m.video"
val MSGTYPE_LOCATION = "m.location" const val MSGTYPE_LOCATION = "m.location"
val MSGTYPE_FILE = "m.file" const val MSGTYPE_FILE = "m.file"
val FORMAT_MATRIX_HTML = "org.matrix.custom.html" const val FORMAT_MATRIX_HTML = "org.matrix.custom.html"
// Add, in local, a fake message type in order to StickerMessage can inherit Message class // Add, in local, a fake message type in order to StickerMessage can inherit Message class
// Because sticker isn't a message type but a event type without msgtype field // Because sticker isn't a message type but a event type without msgtype field
val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker" const val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker"
} }

View File

@ -118,33 +118,4 @@ object AvatarRenderer {
.load(resolvedUrl) .load(resolvedUrl)
.apply(RequestOptions.circleCropTransform()) .apply(RequestOptions.circleCropTransform())
} }


//Based on riot-web implementation
@ColorRes
fun getColorFromUserId(sender: String): Int {
var hash = 0
var i = 0
var chr: Char
if (sender.isEmpty()) {
return R.color.username_1
}
while (i < sender.length) {
chr = sender[i]
hash = (hash shl 5) - hash + chr.toInt()
hash = hash or 0
i++
}
val cI = Math.abs(hash) % 8 + 1
return when (cI) {
1 -> R.color.username_1
2 -> R.color.username_2
3 -> R.color.username_3
4 -> R.color.username_4
5 -> R.color.username_5
6 -> R.color.username_6
7 -> R.color.username_7
else -> R.color.username_8
}
}
} }

View File

@ -0,0 +1,49 @@
/*
* 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.riotredesign.features.home

import androidx.annotation.ColorRes
import im.vector.riotredesign.R


@ColorRes
fun getColorFromUserId(userId: String?): Int {
if (userId.isNullOrBlank()) {
return R.color.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++
}

return when (Math.abs(hash) % 8 + 1) {
1 -> R.color.username_1
2 -> R.color.username_2
3 -> R.color.username_3
4 -> R.color.username_4
5 -> R.color.username_5
6 -> R.color.username_6
7 -> R.color.username_7
else -> R.color.username_8
}
}

View File

@ -75,6 +75,7 @@ import im.vector.riotredesign.features.command.Command
import im.vector.riotredesign.features.home.AvatarRenderer import im.vector.riotredesign.features.home.AvatarRenderer
import im.vector.riotredesign.features.home.HomeModule import im.vector.riotredesign.features.home.HomeModule
import im.vector.riotredesign.features.home.HomePermalinkHandler import im.vector.riotredesign.features.home.HomePermalinkHandler
import im.vector.riotredesign.features.home.getColorFromUserId
import im.vector.riotredesign.features.home.room.detail.composer.TextComposerActions import im.vector.riotredesign.features.home.room.detail.composer.TextComposerActions
import im.vector.riotredesign.features.home.room.detail.composer.TextComposerView import im.vector.riotredesign.features.home.room.detail.composer.TextComposerView
import im.vector.riotredesign.features.home.room.detail.composer.TextComposerViewModel import im.vector.riotredesign.features.home.room.detail.composer.TextComposerViewModel
@ -223,8 +224,7 @@ class RoomDetailFragment :
//switch to expanded bar //switch to expanded bar
composerLayout.composerRelatedMessageTitle.apply { composerLayout.composerRelatedMessageTitle.apply {
text = event.senderName text = event.senderName
setTextColor(ContextCompat.getColor(requireContext(), AvatarRenderer.getColorFromUserId(event.root.sender setTextColor(ContextCompat.getColor(requireContext(), getColorFromUserId(event.root.sender)))
?: "")))
} }


//TODO this is used at several places, find way to refactor? //TODO this is used at several places, find way to refactor?

View File

@ -16,6 +16,8 @@
package im.vector.riotredesign.features.home.room.detail.timeline.action package im.vector.riotredesign.features.home.room.detail.timeline.action


import android.os.Bundle import android.os.Bundle
import android.os.Parcelable
import com.airbnb.mvrx.MvRx
import com.airbnb.mvrx.MvRxView import com.airbnb.mvrx.MvRxView
import com.airbnb.mvrx.MvRxViewModelStore import com.airbnb.mvrx.MvRxViewModelStore
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
@ -51,6 +53,10 @@ abstract class BaseMvRxBottomSheetDialog : BottomSheetDialogFragment(), MvRxView
// subscribe to a ViewModel. // subscribe to a ViewModel.
postInvalidate() postInvalidate()
} }

protected fun setArguments(args: Parcelable? = null) {
arguments = args?.let { Bundle().apply { putParcelable(MvRx.KEY_ARG, it) } }
}
} }


private const val PERSISTED_VIEW_ID_KEY = "mvrx:bottomsheet_persisted_view_id" private const val PERSISTED_VIEW_ID_KEY = "mvrx:bottomsheet_persisted_view_id"

View File

@ -144,15 +144,15 @@ class MessageActionsBottomSheet : BaseMvRxBottomSheetDialog() {


companion object { companion object {
fun newInstance(roomId: String, informationData: MessageInformationData): MessageActionsBottomSheet { fun newInstance(roomId: String, informationData: MessageInformationData): MessageActionsBottomSheet {
val args = Bundle() return MessageActionsBottomSheet().apply {
val parcelableArgs = ParcelableArgs( setArguments(
informationData.eventId, ParcelableArgs(
roomId, informationData.eventId,
informationData roomId,
) informationData
args.putParcelable(MvRx.KEY_ARG, parcelableArgs) )
return MessageActionsBottomSheet().apply { arguments = args } )

}
} }
} }
} }

View File

@ -41,6 +41,7 @@ import im.vector.riotredesign.core.resources.ColorProvider
import im.vector.riotredesign.core.resources.StringProvider import im.vector.riotredesign.core.resources.StringProvider
import im.vector.riotredesign.core.utils.DebouncedClickListener import im.vector.riotredesign.core.utils.DebouncedClickListener
import im.vector.riotredesign.features.home.AvatarRenderer import im.vector.riotredesign.features.home.AvatarRenderer
import im.vector.riotredesign.features.home.getColorFromUserId
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
@ -79,7 +80,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
val avatarUrl = event.senderAvatar val avatarUrl = event.senderAvatar
val memberName = event.senderName ?: event.root.sender ?: "" val memberName = event.senderName ?: event.root.sender ?: ""
val formattedMemberName = span(memberName) { val formattedMemberName = span(memberName) {
textColor = colorProvider.getColor(AvatarRenderer.getColorFromUserId(event.root.sender textColor = colorProvider.getColor(getColorFromUserId(event.root.sender
?: "")) ?: ""))
} }
val hasBeenEdited = event.annotations?.editSummary != null val hasBeenEdited = event.annotations?.editSummary != null
@ -135,7 +136,8 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
} }
} }


private fun buildAudioMessageItem(messageContent: MessageAudioContent, informationData: MessageInformationData, private fun buildAudioMessageItem(messageContent: MessageAudioContent,
informationData: MessageInformationData,
callback: TimelineEventController.Callback?): MessageFileItem? { callback: TimelineEventController.Callback?): MessageFileItem? {
return MessageFileItem_() return MessageFileItem_()
.informationData(informationData) .informationData(informationData)
@ -164,7 +166,8 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
} }
} }


private fun buildFileMessageItem(messageContent: MessageFileContent, informationData: MessageInformationData, private fun buildFileMessageItem(messageContent: MessageFileContent,
informationData: MessageInformationData,
callback: TimelineEventController.Callback?): MessageFileItem? { callback: TimelineEventController.Callback?): MessageFileItem? {
return MessageFileItem_() return MessageFileItem_()
.informationData(informationData) .informationData(informationData)
@ -198,7 +201,8 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
return DefaultItem_().text(text) return DefaultItem_().text(text)
} }


private fun buildImageMessageItem(messageContent: MessageImageContent, informationData: MessageInformationData, private fun buildImageMessageItem(messageContent: MessageImageContent,
informationData: MessageInformationData,
callback: TimelineEventController.Callback?): MessageImageVideoItem? { callback: TimelineEventController.Callback?): MessageImageVideoItem? {


val (maxWidth, maxHeight) = timelineMediaSizeProvider.getMaxSize() val (maxWidth, maxHeight) = timelineMediaSizeProvider.getMaxSize()
@ -233,14 +237,14 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
DebouncedClickListener(View.OnClickListener { view -> DebouncedClickListener(View.OnClickListener { view ->
callback?.onEventCellClicked(informationData, messageContent, view) callback?.onEventCellClicked(informationData, messageContent, view)
})) }))

.longClickListener { view -> .longClickListener { view ->
return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view) return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
?: false ?: false
} }
} }


private fun buildVideoMessageItem(messageContent: MessageVideoContent, informationData: MessageInformationData, private fun buildVideoMessageItem(messageContent: MessageVideoContent,
informationData: MessageInformationData,
callback: TimelineEventController.Callback?): MessageImageVideoItem? { callback: TimelineEventController.Callback?): MessageImageVideoItem? {


val (maxWidth, maxHeight) = timelineMediaSizeProvider.getMaxSize() val (maxWidth, maxHeight) = timelineMediaSizeProvider.getMaxSize()
@ -283,7 +287,8 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
} }
} }


private fun buildTextMessageItem(sendState: SendState, messageContent: MessageTextContent, private fun buildTextMessageItem(sendState: SendState,
messageContent: MessageTextContent,
informationData: MessageInformationData, informationData: MessageInformationData,
hasBeenEdited: Boolean, hasBeenEdited: Boolean,
editSummary: EditAggregatedSummary?, editSummary: EditAggregatedSummary?,
@ -335,6 +340,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
editSummary: EditAggregatedSummary?): SpannableStringBuilder { editSummary: EditAggregatedSummary?): SpannableStringBuilder {
val spannable = SpannableStringBuilder() val spannable = SpannableStringBuilder()
spannable.append(linkifiedBody) spannable.append(linkifiedBody)
// TODO i18n
val editedSuffix = "(edited)" val editedSuffix = "(edited)"
spannable.append(" ").append(editedSuffix) spannable.append(" ").append(editedSuffix)
val color = colorProvider.getColorFromAttribute(R.attr.vctr_list_header_secondary_text_color) val color = colorProvider.getColorFromAttribute(R.attr.vctr_list_header_secondary_text_color)
@ -362,7 +368,8 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
return spannable return spannable
} }


private fun buildNoticeMessageItem(messageContent: MessageNoticeContent, informationData: MessageInformationData, private fun buildNoticeMessageItem(messageContent: MessageNoticeContent,
informationData: MessageInformationData,
callback: TimelineEventController.Callback?): MessageTextItem? { callback: TimelineEventController.Callback?): MessageTextItem? {


val message = messageContent.body.let { val message = messageContent.body.let {
@ -395,7 +402,8 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
} }
} }


private fun buildEmoteMessageItem(messageContent: MessageEmoteContent, informationData: MessageInformationData, private fun buildEmoteMessageItem(messageContent: MessageEmoteContent,
informationData: MessageInformationData,
hasBeenEdited: Boolean, hasBeenEdited: Boolean,
editSummary: EditAggregatedSummary?, editSummary: EditAggregatedSummary?,
callback: TimelineEventController.Callback?): MessageTextItem? { callback: TimelineEventController.Callback?): MessageTextItem? {
@ -433,7 +441,8 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
} }
} }


private fun buildRedactedItem(informationData: MessageInformationData, callback: TimelineEventController.Callback?): RedactedMessageItem? { private fun buildRedactedItem(informationData: MessageInformationData,
callback: TimelineEventController.Callback?): RedactedMessageItem? {
return RedactedMessageItem_() return RedactedMessageItem_()
.informationData(informationData) .informationData(informationData)
.avatarClickListener( .avatarClickListener(
@ -456,32 +465,4 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
VectorLinkify.addLinks(spannable, true) VectorLinkify.addLinks(spannable, true)
return spannable return spannable
} }

//Based on riot-web implementation
@ColorRes
private fun getColorFor(sender: String): Int {
var hash = 0
var i = 0
var chr: Char
if (sender.isEmpty()) {
return R.color.username_1
}
while (i < sender.length) {
chr = sender[i]
hash = (hash shl 5) - hash + chr.toInt()
hash = hash or 0
i++
}
val cI = Math.abs(hash) % 8 + 1
return when (cI) {
1 -> R.color.username_1
2 -> R.color.username_2
3 -> R.color.username_3
4 -> R.color.username_4
5 -> R.color.username_5
6 -> R.color.username_6
7 -> R.color.username_7
else -> R.color.username_8
}
}
} }

View File

@ -21,6 +21,7 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.riotredesign.core.epoxy.EmptyItem_ import im.vector.riotredesign.core.epoxy.EmptyItem_
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
import timber.log.Timber


class TimelineItemFactory(private val messageItemFactory: MessageItemFactory, class TimelineItemFactory(private val messageItemFactory: MessageItemFactory,
private val noticeItemFactory: NoticeItemFactory, private val noticeItemFactory: NoticeItemFactory,
@ -32,8 +33,10 @@ class TimelineItemFactory(private val messageItemFactory: MessageItemFactory,


val computedModel = try { val computedModel = try {
when (event.root.type) { when (event.root.type) {
// Message
EventType.MESSAGE -> messageItemFactory.create(event, nextEvent, callback) EventType.MESSAGE -> messageItemFactory.create(event, nextEvent, callback)


// State and call
EventType.STATE_ROOM_NAME, EventType.STATE_ROOM_NAME,
EventType.STATE_ROOM_TOPIC, EventType.STATE_ROOM_TOPIC,
EventType.STATE_ROOM_MEMBER, EventType.STATE_ROOM_MEMBER,
@ -42,12 +45,16 @@ class TimelineItemFactory(private val messageItemFactory: MessageItemFactory,
EventType.CALL_HANGUP, EventType.CALL_HANGUP,
EventType.CALL_ANSWER -> noticeItemFactory.create(event) EventType.CALL_ANSWER -> noticeItemFactory.create(event)


// Unhandled event types (yet)
EventType.ENCRYPTED, EventType.ENCRYPTED,
EventType.ENCRYPTION, EventType.ENCRYPTION,
EventType.STATE_ROOM_THIRD_PARTY_INVITE, EventType.STATE_ROOM_THIRD_PARTY_INVITE,
EventType.STICKER, EventType.STICKER,
EventType.STATE_ROOM_CREATE -> defaultItemFactory.create(event) EventType.STATE_ROOM_CREATE -> defaultItemFactory.create(event)
else -> null else -> {
Timber.w("Ignored event (type: ${event.root.type}")
null
}
} }
} catch (e: Exception) { } catch (e: Exception) {
defaultItemFactory.create(event, e) defaultItemFactory.create(event, e)

View File

@ -40,6 +40,6 @@ abstract class DefaultItem : BaseEventItem<DefaultItem.Holder>() {
} }


companion object { companion object {
private val STUB_ID = R.id.messageContentDefaultStub private const val STUB_ID = R.id.messageContentDefaultStub
} }
} }

View File

@ -57,6 +57,6 @@ abstract class NoticeItem : BaseEventItem<NoticeItem.Holder>() {
} }


companion object { companion object {
private val STUB_ID = R.id.messageContentNoticeStub private const val STUB_ID = R.id.messageContentNoticeStub
} }
} }