Merge pull request #338 from vector-im/feature/green_encrypt

Text in green when encrypting
This commit is contained in:
Benoit Marty 2019-07-15 10:46:44 +02:00 committed by GitHub
commit b15dea6de3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 105 additions and 89 deletions

View File

@ -68,6 +68,7 @@ class EncryptedItemFactory @Inject constructor(private val messageInformationDat
return MessageTextItem_()
.message(spannableStr)
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)

View File

@ -117,6 +117,7 @@ class MessageItemFactory @Inject constructor(
callback: TimelineEventController.Callback?): MessageFileItem? {
return MessageFileItem_()
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)
@ -144,6 +145,7 @@ class MessageItemFactory @Inject constructor(
callback: TimelineEventController.Callback?): MessageFileItem? {
return MessageFileItem_()
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)
@ -195,6 +197,7 @@ class MessageItemFactory @Inject constructor(
)
return MessageImageVideoItem_()
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.imageContentRenderer(imageContentRenderer)
.contentUploadStateTrackerBinder(contentUploadStateTrackerBinder)
.playable(messageContent.info?.mimeType == "image/gif")
@ -246,6 +249,7 @@ class MessageItemFactory @Inject constructor(
.imageContentRenderer(imageContentRenderer)
.contentUploadStateTrackerBinder(contentUploadStateTrackerBinder)
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.playable(true)
.informationData(informationData)
.highlighted(highlight)
@ -288,6 +292,7 @@ class MessageItemFactory @Inject constructor(
}
.avatarRenderer(avatarRenderer)
.informationData(informationData)
.colorProvider(colorProvider)
.highlighted(highlight)
.avatarCallback(callback)
.urlClickCallback(callback)
@ -353,6 +358,7 @@ class MessageItemFactory @Inject constructor(
return MessageTextItem_()
.avatarRenderer(avatarRenderer)
.message(message)
.colorProvider(colorProvider)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)
@ -393,6 +399,7 @@ class MessageItemFactory @Inject constructor(
}
}
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)
@ -414,6 +421,7 @@ class MessageItemFactory @Inject constructor(
callback: TimelineEventController.Callback?): RedactedMessageItem? {
return RedactedMessageItem_()
.avatarRenderer(avatarRenderer)
.colorProvider(colorProvider)
.informationData(informationData)
.highlighted(highlight)
.avatarCallback(callback)

View File

@ -23,12 +23,16 @@ import android.widget.ProgressBar
import android.widget.TextView
import androidx.core.view.isVisible
import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
import im.vector.matrix.android.api.session.room.send.SendState
import im.vector.riotx.R
import im.vector.riotx.core.di.ActiveSessionHolder
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.features.media.ImageContentRenderer
import im.vector.riotx.features.ui.getMessageTextColor
import javax.inject.Inject

class ContentUploadStateTrackerBinder @Inject constructor(private val activeSessionHolder: ActiveSessionHolder) {
class ContentUploadStateTrackerBinder @Inject constructor(private val activeSessionHolder: ActiveSessionHolder,
private val colorProvider: ColorProvider) {

private val updateListeners = mutableMapOf<String, ContentUploadStateTracker.UpdateListener>()

@ -38,7 +42,7 @@ class ContentUploadStateTrackerBinder @Inject constructor(private val activeSess

activeSessionHolder.getActiveSession().also { session ->
val uploadStateTracker = session.contentUploadProgressTracker()
val updateListener = ContentMediaProgressUpdater(progressLayout, mediaData)
val updateListener = ContentMediaProgressUpdater(progressLayout, mediaData, colorProvider)
updateListeners[eventId] = updateListener
uploadStateTracker.track(eventId, updateListener)
}
@ -56,7 +60,8 @@ class ContentUploadStateTrackerBinder @Inject constructor(private val activeSess
}

private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup,
private val mediaData: ImageContentRenderer.Data) : ContentUploadStateTracker.UpdateListener {
private val mediaData: ImageContentRenderer.Data,
private val colorProvider: ColorProvider) : ContentUploadStateTracker.UpdateListener {

override fun onUpdate(state: ContentUploadStateTracker.State) {
when (state) {
@ -79,6 +84,7 @@ private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup,
progressBar?.isIndeterminate = true
progressBar?.progress = 0
progressTextView?.text = progressLayout.context.getString(R.string.send_file_step_idle)
progressTextView?.setTextColor(colorProvider.getMessageTextColor(SendState.UNSENT))
} else {
progressLayout.isVisible = false
}
@ -106,6 +112,7 @@ private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup,
val progressTextView = progressLayout.findViewById<TextView>(R.id.mediaProgressTextView)
progressBar?.isIndeterminate = true
progressTextView?.text = progressLayout.context.getString(resId)
progressTextView?.setTextColor(colorProvider.getMessageTextColor(SendState.ENCRYPTING))
}

private fun doHandleProgress(resId: Int, current: Long, total: Long) {
@ -119,6 +126,7 @@ private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup,
progressTextView?.text = progressLayout.context.getString(resId,
Formatter.formatShortFileSize(progressLayout.context, current),
Formatter.formatShortFileSize(progressLayout.context, total))
progressTextView?.setTextColor(colorProvider.getMessageTextColor(SendState.SENDING))
}

private fun handleFailure(state: ContentUploadStateTracker.State.Failure) {
@ -126,8 +134,8 @@ private class ContentMediaProgressUpdater(private val progressLayout: ViewGroup,
val progressBar = progressLayout.findViewById<ProgressBar>(R.id.mediaProgressBar)
val progressTextView = progressLayout.findViewById<TextView>(R.id.mediaProgressTextView)
progressBar?.isVisible = false
// TODO Red text
progressTextView?.text = state.throwable.localizedMessage
progressTextView?.setTextColor(colorProvider.getMessageTextColor(SendState.UNDELIVERED))
}

private fun handleSuccess(state: ContentUploadStateTracker.State.Success) {

View File

@ -23,24 +23,32 @@ import android.view.ViewGroup
import android.view.ViewStub
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.IdRes
import androidx.constraintlayout.helper.widget.Flow
import androidx.core.view.children
import androidx.core.view.isGone
import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyAttribute
import im.vector.riotx.R
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.core.utils.DebouncedClickListener
import im.vector.riotx.core.utils.DimensionUtils.dpToPx
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotx.features.reactions.widget.ReactionButton
import im.vector.riotx.features.ui.getMessageTextColor


abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {

abstract val informationData: MessageInformationData
@EpoxyAttribute
lateinit var informationData: MessageInformationData

abstract val avatarRenderer: AvatarRenderer
@EpoxyAttribute
lateinit var avatarRenderer: AvatarRenderer

@EpoxyAttribute
lateinit var colorProvider: ColorProvider

@EpoxyAttribute
var longClickListener: View.OnLongClickListener? = null
@ -153,13 +161,12 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
return true
}

protected fun View.renderSendState() {
isClickable = informationData.sendState.isSent()
alpha = if (informationData.sendState.isSent()) 1f else 0.5f
protected fun renderSendState(root: View, textView: TextView?) {
root.isClickable = informationData.sendState.isSent()
textView?.setTextColor(colorProvider.getMessageTextColor(informationData.sendState))
}

abstract class Holder : BaseHolder() {

abstract class Holder(@IdRes stubId: Int) : BaseHolder(stubId) {
val avatarImageView by bind<ImageView>(R.id.messageAvatarImageView)
val memberNameView by bind<TextView>(R.id.messageMemberNameView)
val timeView by bind<TextView>(R.id.messageTimeView)

View File

@ -26,6 +26,9 @@ import im.vector.riotx.core.epoxy.VectorEpoxyModel
import im.vector.riotx.core.platform.CheckableView
import im.vector.riotx.core.utils.DimensionUtils.dpToPx

/**
* Children must override getViewType()
*/
abstract class BaseEventItem<H : BaseEventItem.BaseHolder> : VectorEpoxyModel<H>() {

var avatarStyle: AvatarStyle = AvatarStyle.SMALL
@ -43,31 +46,18 @@ abstract class BaseEventItem<H : BaseEventItem.BaseHolder> : VectorEpoxyModel<H>
holder.checkableBackground.isChecked = highlighted
}


override fun getViewType(): Int {
return getStubType()
}

abstract fun getStubType(): Int


abstract class BaseHolder : VectorEpoxyHolder() {

abstract class BaseHolder(@IdRes val stubId: Int) : VectorEpoxyHolder() {
val leftGuideline by bind<Guideline>(R.id.messageStartGuideline)
val checkableBackground by bind<CheckableView>(R.id.messageSelectedBackground)

@IdRes
abstract fun getStubId(): Int

override fun bindView(itemView: View) {
super.bindView(itemView)
inflateStub()
}

private fun inflateStub() {
view.findViewById<ViewStub>(getStubId()).inflate()
view.findViewById<ViewStub>(stubId).inflate()
}

}

companion object {

View File

@ -31,11 +31,9 @@ abstract class DefaultItem : BaseEventItem<DefaultItem.Holder>() {
holder.messageView.text = text
}

override fun getStubType(): Int = STUB_ID

class Holder : BaseHolder() {
override fun getStubId(): Int = STUB_ID
override fun getViewType() = STUB_ID

class Holder : BaseHolder(STUB_ID) {
val messageView by bind<TextView>(R.id.stateMessageView)
}


View File

@ -46,7 +46,7 @@ data class MergedHeaderItem(private val isCollapsed: Boolean,
return Holder()
}

override fun getStubType(): Int = STUB_ID
override fun getViewType() = STUB_ID

override fun bind(holder: Holder) {
super.bind(holder)
@ -84,8 +84,7 @@ data class MergedHeaderItem(private val isCollapsed: Boolean,
val avatarUrl: String?
)

class Holder : BaseHolder() {
override fun getStubId(): Int = STUB_ID
class Holder : BaseHolder(STUB_ID) {

val expandView by bind<TextView>(R.id.itemMergedExpandTextView)
val summaryView by bind<TextView>(R.id.itemMergedSummaryTextView)
@ -95,6 +94,6 @@ data class MergedHeaderItem(private val isCollapsed: Boolean,
}

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

View File

@ -25,7 +25,6 @@ import androidx.annotation.DrawableRes
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import im.vector.riotx.R
import im.vector.riotx.features.home.AvatarRenderer

@EpoxyModelClass(layout = R.layout.item_timeline_event_base)
abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
@ -36,34 +35,27 @@ abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
@DrawableRes
var iconRes: Int = 0
@EpoxyAttribute
override lateinit var informationData: MessageInformationData
@EpoxyAttribute
override lateinit var avatarRenderer: AvatarRenderer
@EpoxyAttribute
var clickListener: View.OnClickListener? = null

override fun bind(holder: Holder) {
super.bind(holder)
holder.fileLayout.renderSendState()
renderSendState(holder.fileLayout, holder.filenameView)
holder.filenameView.text = filename
holder.fileImageView.setImageResource(iconRes)
holder.filenameView.setOnClickListener(clickListener)
holder.filenameView.paintFlags = (holder.filenameView.paintFlags or Paint.UNDERLINE_TEXT_FLAG)
}

override fun getStubType(): Int = STUB_ID

class Holder : AbsMessageItem.Holder() {
override fun getStubId(): Int = STUB_ID
override fun getViewType() = STUB_ID

class Holder : AbsMessageItem.Holder(STUB_ID) {
val fileLayout by bind<ViewGroup>(R.id.messageFileLayout)
val fileImageView by bind<ImageView>(R.id.messageFileImageView)
val filenameView by bind<TextView>(R.id.messageFilenameView)

}

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

}

View File

@ -22,7 +22,6 @@ import android.widget.ImageView
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import im.vector.riotx.R
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
import im.vector.riotx.features.media.ImageContentRenderer

@ -32,10 +31,6 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
@EpoxyAttribute
lateinit var mediaData: ImageContentRenderer.Data
@EpoxyAttribute
override lateinit var informationData: MessageInformationData
@EpoxyAttribute
override lateinit var avatarRenderer: AvatarRenderer
@EpoxyAttribute
var playable: Boolean = false
@EpoxyAttribute
var clickListener: View.OnClickListener? = null
@ -52,7 +47,8 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
holder.imageView.setOnLongClickListener(longClickListener)
holder.mediaContentView.setOnClickListener(cellClickListener)
holder.mediaContentView.setOnLongClickListener(longClickListener)
holder.imageView.renderSendState()
// The sending state color will be apply to the progress text
renderSendState(holder.imageView, null)
holder.playContentView.visibility = if (playable) View.VISIBLE else View.GONE
}

@ -61,23 +57,17 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
super.unbind(holder)
}

override fun getStubType(): Int = STUB_ID

class Holder : AbsMessageItem.Holder() {

override fun getStubId(): Int = STUB_ID
override fun getViewType() = STUB_ID

class Holder : AbsMessageItem.Holder(STUB_ID) {
val progressLayout by bind<ViewGroup>(R.id.messageMediaUploadProgressLayout)
val imageView by bind<ImageView>(R.id.messageThumbnailView)
val playContentView by bind<ImageView>(R.id.messageMediaPlayView)

val mediaContentView by bind<ViewGroup>(R.id.messageContentMedia)

}


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

}

View File

@ -24,7 +24,6 @@ import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import im.vector.riotx.R
import im.vector.riotx.core.utils.containsOnlyEmojis
import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotx.features.html.PillImageSpan
import kotlinx.coroutines.Dispatchers
@ -39,10 +38,6 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
@EpoxyAttribute
var message: CharSequence? = null
@EpoxyAttribute
override lateinit var avatarRenderer: AvatarRenderer
@EpoxyAttribute
override lateinit var informationData: MessageInformationData
@EpoxyAttribute
var urlClickCallback: TimelineEventController.UrlClickCallback? = null

private val mvmtMethod = BetterLinkMovementMethod.newInstance().also {
@ -73,7 +68,7 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
null)

holder.messageView.setTextFuture(textFuture)
holder.messageView.renderSendState()
renderSendState(holder.messageView, holder.messageView)
holder.messageView.setOnClickListener(cellClickListener)
holder.messageView.setOnLongClickListener(longClickListener)
findPillsAndProcess { it.bind(holder.messageView) }
@ -90,12 +85,13 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
}
}

override fun getStubType(): Int = R.id.messageContentTextStub
override fun getViewType() = STUB_ID

class Holder : AbsMessageItem.Holder() {
class Holder : AbsMessageItem.Holder(STUB_ID) {
val messageView by bind<AppCompatTextView>(R.id.messageTextView)
override fun getStubId(): Int = R.id.messageContentTextStub

}

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

View File

@ -57,10 +57,9 @@ abstract class NoticeItem : BaseEventItem<NoticeItem.Holder>() {
holder.view.setOnLongClickListener(longClickListener)
}

override fun getStubType(): Int = STUB_ID
override fun getViewType() = STUB_ID

class Holder : BaseHolder() {
override fun getStubId(): Int = STUB_ID
class Holder : BaseHolder(STUB_ID) {
val avatarImageView by bind<ImageView>(R.id.itemNoticeAvatarView)
val noticeTextView by bind<TextView>(R.id.itemNoticeTextView)
}

View File

@ -16,28 +16,19 @@

package im.vector.riotx.features.home.room.detail.timeline.item

import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import im.vector.riotx.R
import im.vector.riotx.features.home.AvatarRenderer

@EpoxyModelClass(layout = R.layout.item_timeline_event_base)
abstract class RedactedMessageItem : AbsMessageItem<RedactedMessageItem.Holder>() {

@EpoxyAttribute
override lateinit var informationData: MessageInformationData
@EpoxyAttribute
override lateinit var avatarRenderer: AvatarRenderer

override fun getStubType(): Int = STUB_ID
override fun getViewType() = STUB_ID

override fun shouldShowReactionAtBottom() = false

class Holder : AbsMessageItem.Holder() {
override fun getStubId(): Int = STUB_ID
}
class Holder : AbsMessageItem.Holder(STUB_ID)

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

View File

@ -0,0 +1,37 @@
/*
* 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.ui

import androidx.annotation.ColorInt
import im.vector.matrix.android.api.session.room.send.SendState
import im.vector.riotx.R
import im.vector.riotx.core.resources.ColorProvider

@ColorInt
fun ColorProvider.getMessageTextColor(sendState: SendState): Int {
return when (sendState) {
// SendStates, in the classical order they will occur
SendState.UNKNOWN,
SendState.UNSENT -> getColorFromAttribute(R.attr.vctr_sending_message_text_color)
SendState.ENCRYPTING -> getColorFromAttribute(R.attr.vctr_encrypting_message_text_color)
SendState.SENDING -> getColorFromAttribute(R.attr.vctr_sending_message_text_color)
SendState.SENT,
SendState.SYNCED -> getColorFromAttribute(R.attr.vctr_message_text_color)
SendState.UNDELIVERED,
SendState.FAILED_UNKNOWN_DEVICES -> getColorFromAttribute(R.attr.vctr_unsent_message_text_color)
}
}

View File

@ -93,7 +93,7 @@
<item name="vctr_message_text_color">@android:color/white</item>
<item name="vctr_notice_text_color">@color/riot_primary_text_color_dark</item>
<item name="vctr_encrypting_message_text_color">@color/accent_color_dark</item>
<item name="vctr_sending_message_text_color">?android:textColorSecondary</item>
<item name="vctr_sending_message_text_color">@color/riotx_text_secondary_dark</item>
<item name="vctr_highlighted_message_text_color">@color/vector_fuchsia_color</item>
<item name="vctr_highlighted_searched_message_text_color">@color/primary_color_light</item>
<item name="vctr_search_mode_room_name_text_color">#CCC3C3C3</item>

View File

@ -93,7 +93,7 @@
<item name="vctr_message_text_color">@color/riot_primary_text_color_light</item>
<item name="vctr_notice_text_color">#FF61708b</item>
<item name="vctr_encrypting_message_text_color">@color/accent_color_light</item>
<item name="vctr_sending_message_text_color">?android:textColorSecondary</item>
<item name="vctr_sending_message_text_color">@color/riotx_text_secondary_light</item>
<item name="vctr_highlighted_message_text_color">@color/vector_fuchsia_color</item>
<item name="vctr_highlighted_searched_message_text_color">@color/primary_color_light</item>
<item name="vctr_search_mode_room_name_text_color">#333C3C3C</item>