From 2ba7ec48f690fdbee93424691af174e051d2815a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 4 Jun 2019 17:36:49 +0200 Subject: [PATCH 01/22] Code cleanup, remove duplicate code, and add some comments --- .../matrix/android/api/MatrixPatterns.kt | 53 +++++++++-------- .../session/room/model/message/MessageType.kt | 20 +++---- .../features/home/AvatarRenderer.kt | 29 ---------- .../riotredesign/features/home/UserColor.kt | 49 ++++++++++++++++ .../home/room/detail/RoomDetailFragment.kt | 4 +- .../action/BaseMvRxBottomSheetDialog.kt | 6 ++ .../action/MessageActionsBottomSheet.kt | 18 +++--- .../timeline/factory/MessageItemFactory.kt | 57 +++++++------------ .../timeline/factory/TimelineItemFactory.kt | 9 ++- .../room/detail/timeline/item/DefaultItem.kt | 2 +- .../room/detail/timeline/item/NoticeItem.kt | 2 +- 11 files changed, 131 insertions(+), 118 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotredesign/features/home/UserColor.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/MatrixPatterns.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/MatrixPatterns.kt index 9557434c48..19dc37e615 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/MatrixPatterns.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/MatrixPatterns.kt @@ -16,7 +16,6 @@ package im.vector.matrix.android.api -import java.util.* import java.util.regex.Pattern /** @@ -25,53 +24,53 @@ import java.util.regex.Pattern object MatrixPatterns { // 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. // 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" - val PATTERN_CONTAIN_MATRIX_USER_IDENTIFIER = Pattern.compile(MATRIX_USER_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE) + private const val MATRIX_USER_IDENTIFIER_REGEX = "@[A-Z0-9\\x21-\\x39\\x3B-\\x7F]+$DOMAIN_REGEX" + 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. - private 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 const val MATRIX_ROOM_IDENTIFIER_REGEX = "![A-Z0-9]+$DOMAIN_REGEX" + 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. - private 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 const val MATRIX_ROOM_ALIAS_REGEX = "#[A-Z0-9._%#@=+-]+$DOMAIN_REGEX" + private val PATTERN_CONTAIN_MATRIX_ALIAS = Pattern.compile(MATRIX_ROOM_ALIAS_REGEX, Pattern.CASE_INSENSITIVE) // regex pattern to find message ids in a string. - private 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 const val MATRIX_EVENT_IDENTIFIER_REGEX = "\\$[A-Z0-9]+$DOMAIN_REGEX" + 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. - private 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 const val MATRIX_EVENT_IDENTIFIER_V3_REGEX = "\\$[A-Z0-9/+]+" + 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. - private 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 const val MATRIX_GROUP_IDENTIFIER_REGEX = "\\+[A-Z0-9=_\\-./]+$DOMAIN_REGEX" + private val PATTERN_CONTAIN_MATRIX_GROUP_IDENTIFIER = Pattern.compile(MATRIX_GROUP_IDENTIFIER_REGEX, Pattern.CASE_INSENSITIVE) // regex pattern to find permalink with message id. // Android does not support in URL so extract it. - private val PERMALINK_BASE_REGEX = "https://matrix\\.to/#/" - private val APP_BASE_REGEX = "https://[A-Z0-9.-]+\\.[A-Z]{2,}/[A-Z]{3,}/#/room/" - val SEP_REGEX = "/" + private const val PERMALINK_BASE_REGEX = "https://matrix\\.to/#/" + private const val APP_BASE_REGEX = "https://[A-Z0-9.-]+\\.[A-Z]{2,}/[A-Z]{3,}/#/room/" + const val SEP_REGEX = "/" - private 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 const val LINK_TO_ROOM_ID_REGEXP = PERMALINK_BASE_REGEX + MATRIX_ROOM_IDENTIFIER_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX + 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 - val PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ALIAS = Pattern.compile(LINK_TO_ROOM_ALIAS_REGEXP, Pattern.CASE_INSENSITIVE) + private const val LINK_TO_ROOM_ALIAS_REGEXP = PERMALINK_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX + 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 - val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ID = Pattern.compile(LINK_TO_APP_ROOM_ID_REGEXP, Pattern.CASE_INSENSITIVE) + private const val LINK_TO_APP_ROOM_ID_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_IDENTIFIER_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX + 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 - val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ALIAS = Pattern.compile(LINK_TO_APP_ROOM_ALIAS_REGEXP, Pattern.CASE_INSENSITIVE) + private const val LINK_TO_APP_ROOM_ALIAS_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX + 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. - val MATRIX_PATTERNS = Arrays.asList( + val MATRIX_PATTERNS = listOf( PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ID, PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ALIAS, PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ID, @@ -133,4 +132,4 @@ object MatrixPatterns { fun isGroupId(str: String?): Boolean { return str != null && PATTERN_CONTAIN_MATRIX_GROUP_IDENTIFIER.matcher(str).matches() } -}// Cannot be instantiated +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageType.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageType.kt index 0b239f6c78..7db3301898 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageType.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/message/MessageType.kt @@ -18,16 +18,16 @@ package im.vector.matrix.android.api.session.room.model.message object MessageType { - val MSGTYPE_TEXT = "m.text" - val MSGTYPE_EMOTE = "m.emote" - val MSGTYPE_NOTICE = "m.notice" - val MSGTYPE_IMAGE = "m.image" - val MSGTYPE_AUDIO = "m.audio" - val MSGTYPE_VIDEO = "m.video" - val MSGTYPE_LOCATION = "m.location" - val MSGTYPE_FILE = "m.file" - val FORMAT_MATRIX_HTML = "org.matrix.custom.html" + const val MSGTYPE_TEXT = "m.text" + const val MSGTYPE_EMOTE = "m.emote" + const val MSGTYPE_NOTICE = "m.notice" + const val MSGTYPE_IMAGE = "m.image" + const val MSGTYPE_AUDIO = "m.audio" + const val MSGTYPE_VIDEO = "m.video" + const val MSGTYPE_LOCATION = "m.location" + const val MSGTYPE_FILE = "m.file" + const val FORMAT_MATRIX_HTML = "org.matrix.custom.html" // 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 - val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker" + const val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker" } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt b/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt index d86872a8b4..be16ac5ca4 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt @@ -118,33 +118,4 @@ object AvatarRenderer { .load(resolvedUrl) .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 - } - } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/UserColor.kt b/vector/src/main/java/im/vector/riotredesign/features/home/UserColor.kt new file mode 100644 index 0000000000..8e26bf30bb --- /dev/null +++ b/vector/src/main/java/im/vector/riotredesign/features/home/UserColor.kt @@ -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 + } +} \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt index 98d0325ad9..4653d75166 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt @@ -75,6 +75,7 @@ import im.vector.riotredesign.features.command.Command import im.vector.riotredesign.features.home.AvatarRenderer import im.vector.riotredesign.features.home.HomeModule 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.TextComposerView import im.vector.riotredesign.features.home.room.detail.composer.TextComposerViewModel @@ -223,8 +224,7 @@ class RoomDetailFragment : //switch to expanded bar composerLayout.composerRelatedMessageTitle.apply { 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? diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/BaseMvRxBottomSheetDialog.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/BaseMvRxBottomSheetDialog.kt index a37a5eaf82..c3a068be8d 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/BaseMvRxBottomSheetDialog.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/BaseMvRxBottomSheetDialog.kt @@ -16,6 +16,8 @@ package im.vector.riotredesign.features.home.room.detail.timeline.action import android.os.Bundle +import android.os.Parcelable +import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.MvRxView import com.airbnb.mvrx.MvRxViewModelStore import com.google.android.material.bottomsheet.BottomSheetDialogFragment @@ -51,6 +53,10 @@ abstract class BaseMvRxBottomSheetDialog : BottomSheetDialogFragment(), MvRxView // subscribe to a ViewModel. 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" \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt index 1d50d893f0..44a753afbf 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt @@ -144,15 +144,15 @@ class MessageActionsBottomSheet : BaseMvRxBottomSheetDialog() { companion object { fun newInstance(roomId: String, informationData: MessageInformationData): MessageActionsBottomSheet { - val args = Bundle() - val parcelableArgs = ParcelableArgs( - informationData.eventId, - roomId, - informationData - ) - args.putParcelable(MvRx.KEY_ARG, parcelableArgs) - return MessageActionsBottomSheet().apply { arguments = args } - + return MessageActionsBottomSheet().apply { + setArguments( + ParcelableArgs( + informationData.eventId, + roomId, + informationData + ) + ) + } } } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 4509b19e5a..25d1995d39 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -41,6 +41,7 @@ import im.vector.riotredesign.core.resources.ColorProvider import im.vector.riotredesign.core.resources.StringProvider import im.vector.riotredesign.core.utils.DebouncedClickListener 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.helper.TimelineDateFormatter 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 memberName = event.senderName ?: event.root.sender ?: "" 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 @@ -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? { return MessageFileItem_() .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? { return MessageFileItem_() .informationData(informationData) @@ -198,7 +201,8 @@ class MessageItemFactory(private val colorProvider: ColorProvider, return DefaultItem_().text(text) } - private fun buildImageMessageItem(messageContent: MessageImageContent, informationData: MessageInformationData, + private fun buildImageMessageItem(messageContent: MessageImageContent, + informationData: MessageInformationData, callback: TimelineEventController.Callback?): MessageImageVideoItem? { val (maxWidth, maxHeight) = timelineMediaSizeProvider.getMaxSize() @@ -233,14 +237,14 @@ class MessageItemFactory(private val colorProvider: ColorProvider, DebouncedClickListener(View.OnClickListener { view -> callback?.onEventCellClicked(informationData, messageContent, view) })) - .longClickListener { view -> return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view) ?: false } } - private fun buildVideoMessageItem(messageContent: MessageVideoContent, informationData: MessageInformationData, + private fun buildVideoMessageItem(messageContent: MessageVideoContent, + informationData: MessageInformationData, callback: TimelineEventController.Callback?): MessageImageVideoItem? { 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, hasBeenEdited: Boolean, editSummary: EditAggregatedSummary?, @@ -335,6 +340,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider, editSummary: EditAggregatedSummary?): SpannableStringBuilder { val spannable = SpannableStringBuilder() spannable.append(linkifiedBody) + // TODO i18n val editedSuffix = "(edited)" spannable.append(" ").append(editedSuffix) val color = colorProvider.getColorFromAttribute(R.attr.vctr_list_header_secondary_text_color) @@ -362,7 +368,8 @@ class MessageItemFactory(private val colorProvider: ColorProvider, return spannable } - private fun buildNoticeMessageItem(messageContent: MessageNoticeContent, informationData: MessageInformationData, + private fun buildNoticeMessageItem(messageContent: MessageNoticeContent, + informationData: MessageInformationData, callback: TimelineEventController.Callback?): MessageTextItem? { 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, editSummary: EditAggregatedSummary?, 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_() .informationData(informationData) .avatarClickListener( @@ -456,32 +465,4 @@ class MessageItemFactory(private val colorProvider: ColorProvider, VectorLinkify.addLinks(spannable, true) 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 - } - } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/TimelineItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/TimelineItemFactory.kt index db5e3e542c..022b7b0b10 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/TimelineItemFactory.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/TimelineItemFactory.kt @@ -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.VectorEpoxyModel import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController +import timber.log.Timber class TimelineItemFactory(private val messageItemFactory: MessageItemFactory, private val noticeItemFactory: NoticeItemFactory, @@ -32,8 +33,10 @@ class TimelineItemFactory(private val messageItemFactory: MessageItemFactory, val computedModel = try { when (event.root.type) { + // Message EventType.MESSAGE -> messageItemFactory.create(event, nextEvent, callback) + // State and call EventType.STATE_ROOM_NAME, EventType.STATE_ROOM_TOPIC, EventType.STATE_ROOM_MEMBER, @@ -42,12 +45,16 @@ class TimelineItemFactory(private val messageItemFactory: MessageItemFactory, EventType.CALL_HANGUP, EventType.CALL_ANSWER -> noticeItemFactory.create(event) + // Unhandled event types (yet) EventType.ENCRYPTED, EventType.ENCRYPTION, EventType.STATE_ROOM_THIRD_PARTY_INVITE, EventType.STICKER, EventType.STATE_ROOM_CREATE -> defaultItemFactory.create(event) - else -> null + else -> { + Timber.w("Ignored event (type: ${event.root.type}") + null + } } } catch (e: Exception) { defaultItemFactory.create(event, e) diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/DefaultItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/DefaultItem.kt index 3985e8c1d6..443290d343 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/DefaultItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/DefaultItem.kt @@ -40,6 +40,6 @@ abstract class DefaultItem : BaseEventItem() { } companion object { - private val STUB_ID = R.id.messageContentDefaultStub + private const val STUB_ID = R.id.messageContentDefaultStub } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt index dd06cb0cae..dcb0bdf4ad 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt @@ -57,6 +57,6 @@ abstract class NoticeItem : BaseEventItem() { } companion object { - private val STUB_ID = R.id.messageContentNoticeStub + private const val STUB_ID = R.id.messageContentNoticeStub } } \ No newline at end of file From e058fa90697ed4b991a7775a98b9095336f87829 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 4 Jun 2019 18:10:38 +0200 Subject: [PATCH 02/22] Add elevation on Toolbar --- vector/src/main/res/layout/fragment_home_detail.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/layout/fragment_home_detail.xml b/vector/src/main/res/layout/fragment_home_detail.xml index fd39b751f1..1c50543622 100644 --- a/vector/src/main/res/layout/fragment_home_detail.xml +++ b/vector/src/main/res/layout/fragment_home_detail.xml @@ -12,6 +12,7 @@ android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="#FFFFFF" + android:elevation="4dp" app:contentInsetStartWithNavigation="0dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" From 91114e2afebbc2db06ed1a8f63e9b253643c5670 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 5 Jun 2019 10:07:18 +0200 Subject: [PATCH 03/22] Quick and dirty implementation of password reveal on HomeScreen --- .../features/login/LoginActivity.kt | 25 ++++++++++++ vector/src/main/res/layout/activity_login.xml | 39 +++++++++++++------ 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/vector/src/main/java/im/vector/riotredesign/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/riotredesign/features/login/LoginActivity.kt index dc6f3aebb7..ffadac1186 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/login/LoginActivity.kt @@ -29,6 +29,7 @@ import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.sync.FilterService import im.vector.riotredesign.R +import im.vector.riotredesign.core.extensions.showPassword import im.vector.riotredesign.core.platform.VectorBaseActivity import im.vector.riotredesign.features.home.HomeActivity import io.reactivex.Observable @@ -44,14 +45,20 @@ class LoginActivity : VectorBaseActivity() { private val authenticator = Matrix.getInstance().authenticator() + private var passwordShown = false + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_login) setupAuthButton() + setupPasswordReveal() homeServerField.setText(DEFAULT_HOME_SERVER_URI) } private fun authenticate() { + passwordShown = false + renderPasswordField() + val login = loginField.text?.trim().toString() val password = passwordField.text?.trim().toString() buildHomeServerConnectionConfig().fold( @@ -105,6 +112,24 @@ class LoginActivity : VectorBaseActivity() { authenticateButton.setOnClickListener { authenticate() } } + private fun setupPasswordReveal() { + passwordShown = false + + passwordReveal.setOnClickListener { + passwordShown = !passwordShown + + renderPasswordField() + } + + renderPasswordField() + } + + private fun renderPasswordField() { + passwordField.showPassword(passwordShown) + + passwordReveal.setImageResource(if (passwordShown) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black) + } + private fun goToHome() { val intent = HomeActivity.newIntent(this) startActivity(intent) diff --git a/vector/src/main/res/layout/activity_login.xml b/vector/src/main/res/layout/activity_login.xml index 1b1da7276f..c86ee6dc36 100644 --- a/vector/src/main/res/layout/activity_login.xml +++ b/vector/src/main/res/layout/activity_login.xml @@ -42,21 +42,38 @@ android:maxLines="1" /> - - + android:orientation="horizontal"> - - + android:layout_marginTop="16dp" + android:layout_weight="1" + android:hint="@string/auth_password_placeholder"> + + + + + + + Date: Wed, 5 Jun 2019 14:31:11 +0200 Subject: [PATCH 04/22] Theme rework WIP --- .../features/home/AvatarRenderer.kt | 6 +- .../riotredesign/features/home/UserColor.kt | 18 ++-- .../main/res/layout/activity_bug_report.xml | 5 +- .../layout/activity_emoji_reaction_picker.xml | 3 +- .../layout/activity_image_media_viewer.xml | 5 +- vector/src/main/res/layout/activity_login.xml | 3 + .../res/layout/activity_vector_settings.xml | 4 +- .../layout/activity_video_media_viewer.xml | 6 +- .../res/layout/dialog_change_password.xml | 3 + .../main/res/layout/fragment_home_detail.xml | 8 +- .../main/res/layout/fragment_home_drawer.xml | 2 +- .../main/res/layout/fragment_public_rooms.xml | 9 +- .../main/res/layout/fragment_room_detail.xml | 11 +-- .../layout/fragment_room_directory_picker.xml | 1 + .../fragment_room_preview_no_preview.xml | 7 +- ...nt_settings_notifications_troubleshoot.xml | 4 +- .../src/main/res/layout/item_error_retry.xml | 1 - vector/src/main/res/layout/item_group.xml | 3 +- .../layout/item_notification_troubleshoot.xml | 2 +- .../item_timeline_event_text_message_stub.xml | 2 +- .../main/res/layout/vector_invite_view.xml | 2 +- .../src/main/res/layout/view_button_state.xml | 14 ++- .../src/main/res/values-v21/theme_light.xml | 7 +- .../src/main/res/values-v23/theme_light.xml | 15 +++ .../src/main/res/values-v27/theme_light.xml | 10 ++ vector/src/main/res/values/colors.xml | 4 +- vector/src/main/res/values/colors_riot.xml | 17 +--- vector/src/main/res/values/colors_riotx.xml | 99 +++++++++++++++++++ vector/src/main/res/values/styles_riot.xml | 43 ++++---- vector/src/main/res/values/styles_widget.xml | 12 --- vector/src/main/res/values/theme_common.xml | 11 +++ vector/src/main/res/values/theme_light.xml | 31 ++++-- vector/src/main/res/values/theme_status.xml | 2 - 33 files changed, 243 insertions(+), 127 deletions(-) create mode 100644 vector/src/main/res/values-v23/theme_light.xml create mode 100644 vector/src/main/res/values-v27/theme_light.xml create mode 100644 vector/src/main/res/values/colors_riotx.xml delete mode 100644 vector/src/main/res/values/styles_widget.xml create mode 100644 vector/src/main/res/values/theme_common.xml diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt b/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt index be16ac5ca4..7975206f50 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt @@ -45,9 +45,9 @@ object AvatarRenderer { private const val THUMBNAIL_SIZE = 250 private val AVATAR_COLOR_LIST = listOf( - R.color.avatar_color_1, - R.color.avatar_color_2, - R.color.avatar_color_3 + R.color.riotx_avatar_fill_1, + R.color.riotx_avatar_fill_2, + R.color.riotx_avatar_fill_3 ) @UiThread diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/UserColor.kt b/vector/src/main/java/im/vector/riotredesign/features/home/UserColor.kt index 8e26bf30bb..bd3f60f477 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/UserColor.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/UserColor.kt @@ -23,7 +23,7 @@ import im.vector.riotredesign.R @ColorRes fun getColorFromUserId(userId: String?): Int { if (userId.isNullOrBlank()) { - return R.color.username_1 + return R.color.riotx_username_1 } var hash = 0 @@ -37,13 +37,13 @@ fun getColorFromUserId(userId: String?): Int { } 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 + 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 } } \ No newline at end of file diff --git a/vector/src/main/res/layout/activity_bug_report.xml b/vector/src/main/res/layout/activity_bug_report.xml index 4d87ced748..b7727f0363 100644 --- a/vector/src/main/res/layout/activity_bug_report.xml +++ b/vector/src/main/res/layout/activity_bug_report.xml @@ -7,9 +7,9 @@ + android:layout_height="wrap_content" + android:elevation="4dp" /> + app:layout_scrollFlags="scroll|exitUntilCollapsed|snap|enterAlways" /> + android:elevation="4dp" /> + android:layout_height="wrap_content" + android:elevation="4dp" /> + android:elevation="4dp" /> @@ -50,6 +51,7 @@ @@ -64,6 +66,7 @@ diff --git a/vector/src/main/res/layout/fragment_home_detail.xml b/vector/src/main/res/layout/fragment_home_detail.xml index 1c50543622..3867680f50 100644 --- a/vector/src/main/res/layout/fragment_home_detail.xml +++ b/vector/src/main/res/layout/fragment_home_detail.xml @@ -8,16 +8,12 @@ + app:layout_constraintTop_toTopOf="parent"> diff --git a/vector/src/main/res/layout/fragment_home_drawer.xml b/vector/src/main/res/layout/fragment_home_drawer.xml index 8bbd52c2be..7e7caf9c80 100644 --- a/vector/src/main/res/layout/fragment_home_drawer.xml +++ b/vector/src/main/res/layout/fragment_home_drawer.xml @@ -11,7 +11,7 @@ android:id="@+id/homeDrawerHeader" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?attr/colorPrimary" + android:background="@color/dark_two" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> diff --git a/vector/src/main/res/layout/fragment_public_rooms.xml b/vector/src/main/res/layout/fragment_public_rooms.xml index 6db130e864..03e78260c9 100644 --- a/vector/src/main/res/layout/fragment_public_rooms.xml +++ b/vector/src/main/res/layout/fragment_public_rooms.xml @@ -17,18 +17,15 @@ + android:layout_height="wrap_content" + android:elevation="4dp"> + app:layout_scrollFlags="noScroll"> + app:layout_constraintTop_toTopOf="parent"> + tools:text="@sample/matrix.json/data/roomName" /> + tools:text="@sample/matrix.json/data/roomTopic" /> diff --git a/vector/src/main/res/layout/fragment_room_directory_picker.xml b/vector/src/main/res/layout/fragment_room_directory_picker.xml index ec6e9f33a8..eb7af92bcb 100644 --- a/vector/src/main/res/layout/fragment_room_directory_picker.xml +++ b/vector/src/main/res/layout/fragment_room_directory_picker.xml @@ -16,6 +16,7 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" + android:elevation="4dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/vector/src/main/res/layout/fragment_room_preview_no_preview.xml b/vector/src/main/res/layout/fragment_room_preview_no_preview.xml index e18416dcc7..f05a95874c 100644 --- a/vector/src/main/res/layout/fragment_room_preview_no_preview.xml +++ b/vector/src/main/res/layout/fragment_room_preview_no_preview.xml @@ -13,13 +13,10 @@ + android:elevation="4dp" + app:contentInsetStartWithNavigation="0dp"> - diff --git a/vector/src/main/res/layout/vector_invite_view.xml b/vector/src/main/res/layout/vector_invite_view.xml index c4660fccb5..0a6a8cf62b 100644 --- a/vector/src/main/res/layout/vector_invite_view.xml +++ b/vector/src/main/res/layout/vector_invite_view.xml @@ -74,12 +74,12 @@