Menu action for non room messages

This commit is contained in:
Valere 2019-06-07 10:45:24 +02:00
parent 7409003949
commit 5cf9deb329
6 changed files with 64 additions and 42 deletions

View File

@ -23,6 +23,7 @@ import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProviders
import butterknife.BindView
import butterknife.ButterKnife
@ -35,6 +36,7 @@ import im.vector.riotredesign.R
import im.vector.riotredesign.core.glide.GlideApp
import im.vector.riotredesign.features.home.AvatarRenderer
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
import kotlinx.android.synthetic.main.bottom_sheet_message_actions.*

/**
* Bottom sheet fragment that shows a message preview with list of contextual actions
@ -115,20 +117,27 @@ class MessageActionsBottomSheet : BaseMvRxBottomSheetDialog() {
}

override fun invalidate() = withState(viewModel) {
senderNameTextView.text = it.senderName
messageBodyTextView.text = it.messageBody
messageTimestampText.text = it.ts
if (it.showPreview) {
bottom_sheet_message_preview.isVisible = true
senderNameTextView.text = it.senderName
messageBodyTextView.text = it.messageBody
messageTimestampText.text = it.ts

GlideApp.with(this).clear(senderAvatarImageView)
if (it.senderAvatarPath != null) {
GlideApp.with(this)
.load(it.senderAvatarPath)
.circleCrop()
.placeholder(AvatarRenderer.getPlaceholderDrawable(requireContext(), it.userId, it.senderName))
.into(senderAvatarImageView)
GlideApp.with(this).clear(senderAvatarImageView)
if (it.senderAvatarPath != null) {
GlideApp.with(this)
.load(it.senderAvatarPath)
.circleCrop()
.placeholder(AvatarRenderer.getPlaceholderDrawable(requireContext(), it.userId, it.senderName))
.into(senderAvatarImageView)
} else {
senderAvatarImageView.setImageDrawable(AvatarRenderer.getPlaceholderDrawable(requireContext(), it.userId, it.senderName))
}
} else {
senderAvatarImageView.setImageDrawable(AvatarRenderer.getPlaceholderDrawable(requireContext(), it.userId, it.senderName))
bottom_sheet_message_preview.isVisible = false
}
quickReactBottomDivider.isVisible = it.canReact
bottom_sheet_quick_reaction_container.isVisible = it.canReact
return@withState
}


View File

@ -19,6 +19,7 @@ import com.airbnb.mvrx.MvRxState
import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.message.MessageContent
import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
@ -34,10 +35,12 @@ import java.util.*


data class MessageActionState(
val userId: String,
val senderName: String,
val messageBody: CharSequence,
val ts: String?,
val userId: String = "",
val senderName: String = "",
val messageBody: CharSequence? = null,
val ts: String? = null,
val showPreview: Boolean = false,
val canReact: Boolean = false,
val senderAvatarPath: String? = null)
: MvRxState

@ -59,21 +62,21 @@ class MessageActionsViewModel(initialState: MessageActionState) : VectorViewMode
val messageContent: MessageContent? = event.annotations?.editSummary?.aggregatedContent?.toModel()
?: event.root.content.toModel()
val originTs = event.root.originServerTs
var body: CharSequence = messageContent?.body ?: ""
var body: CharSequence? = messageContent?.body
if (messageContent is MessageTextContent && messageContent.format == MessageType.FORMAT_MATRIX_HTML) {
val parser = Parser.builder().build()
val document = parser.parse(messageContent.formattedBody ?: messageContent.body)
// val renderer = HtmlRenderer.builder().build()
body = Markwon.builder(viewModelContext.activity)
.usePlugin(HtmlPlugin.create()).build().render(document)
// body = renderer.render(document)
}
MessageActionState(
event.root.sender ?: "",
parcel.informationData.memberName.toString(),
body,
dateFormat.format(Date(originTs ?: 0)),
currentSession.contentUrlResolver().resolveFullSize(parcel.informationData.avatarUrl)
userId = event.root.sender ?: "",
senderName = parcel.informationData.memberName.toString(),
messageBody = body,
ts = dateFormat.format(Date(originTs ?: 0)),
showPreview = event.root.type == EventType.MESSAGE,
canReact = event.root.type == EventType.MESSAGE,
senderAvatarPath = currentSession.contentUrlResolver().resolveFullSize(parcel.informationData.avatarUrl)
)
} else {
//can this happen?

View File

@ -73,7 +73,9 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
}
//TODO is downloading attachement?

this.add(SimpleAction(ACTION_ADD_REACTION, R.string.message_add_reaction, R.drawable.ic_add_reaction, event.root.eventId))
if (canReact(event, messageContent)) {
this.add(SimpleAction(ACTION_ADD_REACTION, R.string.message_add_reaction, R.drawable.ic_add_reaction, event.root.eventId))
}
if (canCopy(type)) {
//TODO copy images? html? see ClipBoard
this.add(SimpleAction(ACTION_COPY, R.string.copy, R.drawable.ic_copy, messageContent!!.body))
@ -125,7 +127,7 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
}
this.add(SimpleAction(ACTION_COPY_PERMALINK, R.string.permalink, R.drawable.ic_permalink, parcel.eventId))

if (currentSession.sessionParams.credentials.userId != event.root.sender) {
if (currentSession.sessionParams.credentials.userId != event.root.sender && event.root.type == EventType.MESSAGE) {
//not sent by me
this.add(SimpleAction(ACTION_FLAG, R.string.report_content, R.drawable.ic_flag, parcel.eventId))
}
@ -149,6 +151,11 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
}
}

private fun canReact(event: TimelineEvent, messageContent: MessageContent?): Boolean {
//Only event of type Event.EVENT_TYPE_MESSAGE are supported for the moment
return event.root.type == EventType.MESSAGE
}

private fun canQuote(event: TimelineEvent, messageContent: MessageContent?): Boolean {
//Only event of type Event.EVENT_TYPE_MESSAGE are supported for the moment
if (event.root.type != EventType.MESSAGE) return false

View File

@ -32,15 +32,14 @@ enum class TriggleState {
}

data class QuickReactionState(
val agreeTrigleState: TriggleState,
val likeTriggleState: TriggleState,
val agreeTrigleState: TriggleState = TriggleState.NONE,
val likeTriggleState: TriggleState = TriggleState.NONE,
/** Pair of 'clickedOn' and current toggles state*/
val selectionResult: Pair<String, List<String>>? = null,
val eventId: String) : MvRxState
val eventId: String = "") : MvRxState

/**
* Quick reaction view model
* TODO: configure initial state from event
*/
class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel<QuickReactionState>(initialState) {

@ -88,15 +87,15 @@ class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel
private fun getReactions(state: QuickReactionState, newState1: TriggleState?, newState2: TriggleState?): List<String> {
return ArrayList<String>(4).apply {
when (newState2 ?: state.likeTriggleState) {
TriggleState.FIRST -> add(likePositive)
TriggleState.FIRST -> add(likePositive)
TriggleState.SECOND -> add(likeNegative)
else -> {
else -> {
}
}
when (newState1 ?: state.agreeTrigleState) {
TriggleState.FIRST -> add(agreePositive)
TriggleState.FIRST -> add(agreePositive)
TriggleState.SECOND -> add(agreeNegative)
else -> {
else -> {
}
}
}
@ -114,9 +113,9 @@ class QuickReactionViewModel(initialState: QuickReactionState) : VectorViewModel
return when (reaction) {
agreePositive -> agreeNegative
agreeNegative -> agreePositive
likePositive -> likeNegative
likeNegative -> likePositive
else -> null
likePositive -> likeNegative
likeNegative -> likePositive
else -> null
}
}


View File

@ -37,7 +37,6 @@ abstract class NoticeItem : BaseEventItem<NoticeItem.Holder>() {
@EpoxyAttribute
var baseCallback: TimelineEventController.BaseCallback? = null


private var longClickListener = View.OnLongClickListener {
baseCallback?.onEventLongClicked(informationData, null, it)
baseCallback != null

View File

@ -86,7 +86,8 @@
tools:text="Friday 8pm" />
</androidx.constraintlayout.widget.ConstraintLayout>

<LinearLayout
<View
android:id="@+id/quickReactTopDivider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/vctr_list_divider_color" />
@ -94,18 +95,22 @@
<FrameLayout
android:id="@+id/bottom_sheet_quick_reaction_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
tools:background="@android:color/holo_green_light"
tools:layout_height="180dp" />

<LinearLayout
<View
android:id="@+id/quickReactBottomDivider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/vctr_list_divider_color" />


<FrameLayout
android:id="@+id/bottom_sheet_menu_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
tools:background="@android:color/holo_blue_dark"
tools:layout_height="250dp" />

</LinearLayout>
</androidx.core.widget.NestedScrollView>