forked from GitHub-Mirror/riotX-android
Undo Reaction
This commit is contained in:
@ -28,7 +28,10 @@ sealed class RoomDetailActions {
|
||||
data class EventDisplayed(val event: TimelineEvent) : RoomDetailActions()
|
||||
data class LoadMore(val direction: Timeline.Direction) : RoomDetailActions()
|
||||
data class SendReaction(val reaction: String, val targetEventId: String) : RoomDetailActions()
|
||||
data class RedactAction(val targetEventId: String, val reason: String? = "") : RoomDetailActions()
|
||||
data class UndoReaction(val targetEventId: String, val key: String, val reason: String? = "") : RoomDetailActions()
|
||||
object AcceptInvite : RoomDetailActions()
|
||||
object RejectInvite : RoomDetailActions()
|
||||
|
||||
|
||||
}
|
@ -521,7 +521,8 @@ class RoomDetailFragment :
|
||||
//we should test the current real state of reaction on this event
|
||||
roomDetailViewModel.process(RoomDetailActions.SendReaction(reaction, informationData.eventId))
|
||||
} else {
|
||||
//TODO it's an undo :/
|
||||
//I need to redact a reaction
|
||||
roomDetailViewModel.process(RoomDetailActions.UndoReaction(informationData.eventId,reaction))
|
||||
}
|
||||
}
|
||||
|
||||
@ -546,7 +547,11 @@ class RoomDetailFragment :
|
||||
snack.view.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.notification_accent_color))
|
||||
snack.show()
|
||||
}
|
||||
MessageMenuViewModel.ACTION_SHARE -> {
|
||||
MessageMenuViewModel.ACTION_DELETE -> {
|
||||
val eventId = actionData.data?.toString() ?: return
|
||||
roomDetailViewModel.process(RoomDetailActions.RedactAction(eventId,context?.getString(R.string.event_redacted_by_user_reason)))
|
||||
}
|
||||
MessageMenuViewModel.ACTION_SHARE -> {
|
||||
//TODO current data communication is too limited
|
||||
//Need to now the media type
|
||||
actionData.data?.toString()?.let {
|
||||
|
@ -80,6 +80,7 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
|
||||
is RoomDetailActions.SendReaction -> handleSendReaction(action)
|
||||
is RoomDetailActions.AcceptInvite -> handleAcceptInvite()
|
||||
is RoomDetailActions.RejectInvite -> handleRejectInvite()
|
||||
is RoomDetailActions.RedactAction -> handleRedactEvent(action)
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,6 +191,16 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
|
||||
room.sendReaction(action.reaction, action.targetEventId)
|
||||
}
|
||||
|
||||
private fun handleRedactEvent(action: RoomDetailActions.RedactAction) {
|
||||
val event = room.getTimeLineEvent(action.targetEventId) ?: return
|
||||
room.redactEvent(event.root, action.reason)
|
||||
}
|
||||
|
||||
private fun handleUndoReact(action: RoomDetailActions.UndoReaction) {
|
||||
room.undoReaction(action.key, action.targetEventId, session.sessionParams.credentials.userId)
|
||||
}
|
||||
|
||||
|
||||
private fun handleSendMedia(action: RoomDetailActions.SendMedia) {
|
||||
val attachments = action.mediaFiles.map {
|
||||
ContentAttachmentData(
|
||||
|
@ -73,6 +73,10 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
|
||||
this.add(SimpleAction(ACTION_COPY, R.string.copy, R.drawable.ic_copy, messageContent.body))
|
||||
}
|
||||
|
||||
if(canRedact(event, currentSession.sessionParams.credentials.userId)) {
|
||||
this.add(SimpleAction(ACTION_DELETE, R.string.delete, R.drawable.ic_material_delete, event.root.eventId))
|
||||
}
|
||||
|
||||
if (canQuote(event, messageContent)) {
|
||||
//TODO quote icon
|
||||
this.add(SimpleAction(ACTION_QUOTE, R.string.quote, R.drawable.ic_quote, parcel.eventId))
|
||||
@ -148,6 +152,14 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
|
||||
}
|
||||
}
|
||||
|
||||
private fun canRedact(event: TimelineEvent, myUserId: String): Boolean {
|
||||
//Only event of type Event.EVENT_TYPE_MESSAGE are supported for the moment
|
||||
if (event.root.type != EventType.MESSAGE) return false
|
||||
//TODO if user is admin or moderator
|
||||
return event.root.sender == myUserId
|
||||
}
|
||||
|
||||
|
||||
private fun canCopy(type: String): Boolean {
|
||||
return when (type) {
|
||||
MessageType.MSGTYPE_TEXT,
|
||||
@ -162,6 +174,8 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private fun canShare(type: String): Boolean {
|
||||
return when (type) {
|
||||
MessageType.MSGTYPE_IMAGE,
|
||||
|
@ -66,7 +66,6 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
||||
|| nextEvent?.root?.type != EventType.MESSAGE
|
||||
|| isNextMessageReceivedMoreThanOneHourAgo
|
||||
|
||||
val messageContent: MessageContent = event.root.content.toModel() ?: return null
|
||||
val time = timelineDateFormatter.formatMessageHour(date)
|
||||
val avatarUrl = event.senderAvatar
|
||||
val memberName = event.senderName ?: event.root.sender ?: ""
|
||||
@ -84,8 +83,12 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
||||
orderedReactionList = event.annotations?.reactionsSummary?.map { Triple(it.key, it.count, it.addedByMe) }
|
||||
)
|
||||
|
||||
//Test for reactions UX
|
||||
//informationData.orderedReactionList = listOf( Triple("👍",1,false), Triple("👎",2,false))
|
||||
if (event.root.unsignedData?.redactedEvent != null) {
|
||||
//message is redacted
|
||||
return buildRedactedItem(informationData)
|
||||
}
|
||||
|
||||
val messageContent: MessageContent = event.root.content.toModel() ?: return null
|
||||
|
||||
// val all = event.root.toContent()
|
||||
// val ev = all.toModel<Event>()
|
||||
@ -347,6 +350,11 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildRedactedItem(informationData: MessageInformationData): RedactedMessageItem? {
|
||||
return RedactedMessageItem_()
|
||||
.informationData(informationData)
|
||||
}
|
||||
|
||||
private fun linkifyBody(body: CharSequence, callback: TimelineEventController.Callback?): CharSequence {
|
||||
val spannable = SpannableStringBuilder(body)
|
||||
MatrixLinkify.addLinks(spannable, object : MatrixPermalinkSpan.Callback {
|
||||
|
@ -55,11 +55,11 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
|
||||
|
||||
var reactionClickListener: ReactionButton.ReactedListener = object : ReactionButton.ReactedListener {
|
||||
override fun onReacted(reactionButton: ReactionButton) {
|
||||
reactionPillCallback?.onClickOnReactionPill(informationData, reactionButton.reactionString,true)
|
||||
reactionPillCallback?.onClickOnReactionPill(informationData, reactionButton.reactionString, true)
|
||||
}
|
||||
|
||||
override fun onUnReacted(reactionButton: ReactionButton) {
|
||||
reactionPillCallback?.onClickOnReactionPill(informationData, reactionButton.reactionString,false)
|
||||
reactionPillCallback?.onClickOnReactionPill(informationData, reactionButton.reactionString, false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,10 +123,6 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun unbind(holder: H) {
|
||||
super.unbind(holder)
|
||||
}
|
||||
|
||||
protected fun View.renderSendState() {
|
||||
isClickable = informationData.sendState.isSent()
|
||||
alpha = if (informationData.sendState.isSent()) 1f else 0.5f
|
||||
|
@ -0,0 +1,22 @@
|
||||
package im.vector.riotredesign.features.home.room.detail.timeline.item
|
||||
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.riotredesign.R
|
||||
|
||||
@EpoxyModelClass(layout = R.layout.item_timeline_event_base)
|
||||
abstract class RedactedMessageItem : AbsMessageItem<RedactedMessageItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
override lateinit var informationData: MessageInformationData
|
||||
|
||||
override fun getStubType(): Int = STUB_ID
|
||||
|
||||
class Holder : AbsMessageItem.Holder() {
|
||||
override fun getStubId(): Int = STUB_ID
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val STUB_ID = R.id.messageContentRedactedStub
|
||||
}
|
||||
}
|
5
vector/src/main/res/drawable/redacted_background.xml
Normal file
5
vector/src/main/res/drawable/redacted_background.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<corners android:radius="10dp" />
|
||||
<solid android:color="?vctr_list_divider_color" />
|
||||
</shape>
|
@ -81,6 +81,12 @@
|
||||
android:layout="@layout/item_timeline_event_file_stub"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/messageContentRedactedStub"
|
||||
style="@style/TimelineContentStubLayoutParams"
|
||||
android:layout_height="20dp"
|
||||
android:layout="@layout/item_timeline_event_redacted_stub"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
|
||||
<!-- TODO: For now we show 8 reactions maximum, this will need rework when needed-->
|
||||
|
@ -0,0 +1,5 @@
|
||||
<View xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="20dp"
|
||||
android:background="@drawable/redacted_background"
|
||||
/>
|
@ -13,4 +13,7 @@
|
||||
<string name="reactions_like">Like</string>
|
||||
<string name="message_add_reaction">Add Reaction</string>
|
||||
|
||||
<string name="event_redacted_by_user_reason">Event deleted by user</string>
|
||||
<string name="event_redacted_by_admin_reason">Event moderated by room admin</string>
|
||||
|
||||
</resources>
|
Reference in New Issue
Block a user