From 45ea5c356e193a55969b50e1cde901298d16c43b Mon Sep 17 00:00:00 2001
From: Valere <valeref@matrix.org>
Date: Thu, 23 May 2019 16:44:51 +0200
Subject: [PATCH] WIP / edit message

---
 .../room/model/annotation/ReactionService.kt  |  10 +
 .../api/session/room/send/SendService.kt      |   1 +
 .../room/annotation/DefaultReactionService.kt |  20 ++
 .../session/room/send/DefaultSendService.kt   |  11 +
 .../room/send/LocalEchoEventFactory.kt        |  25 ++
 .../riotredesign/core/utils/AnimationUtils.kt |  39 +++
 .../riotredesign/features/DebugActivity.kt    |  12 +
 .../home/room/detail/RoomDetailActions.kt     |   7 +-
 .../home/room/detail/RoomDetailFragment.kt    |  96 +++++++-
 .../home/room/detail/RoomDetailViewModel.kt   | 231 +++++++++++++-----
 .../home/room/detail/RoomDetailViewState.kt   |  19 +-
 .../timeline/action/MessageMenuViewModel.kt   |  22 +-
 .../drawable-hdpi/ic_attach_file_white.png    | Bin 394 -> 0 bytes
 .../main/res/drawable-hdpi/ic_send_white.png  | Bin 335 -> 0 bytes
 .../drawable-mdpi/ic_attach_file_white.png    | Bin 285 -> 0 bytes
 .../main/res/drawable-mdpi/ic_send_white.png  | Bin 257 -> 0 bytes
 .../drawable-xhdpi/ic_attach_file_white.png   | Bin 507 -> 0 bytes
 .../main/res/drawable-xhdpi/ic_send_white.png | Bin 423 -> 0 bytes
 .../drawable-xxhdpi/ic_attach_file_white.png  | Bin 809 -> 0 bytes
 .../res/drawable-xxhdpi/ic_send_white.png     | Bin 550 -> 0 bytes
 .../drawable-xxxhdpi/ic_attach_file_white.png | Bin 1059 -> 0 bytes
 .../res/drawable-xxxhdpi/ic_send_white.png    | Bin 728 -> 0 bytes
 .../src/main/res/drawable/ic_add_reaction.xml |  54 ++++
 .../src/main/res/drawable/ic_attachment.xml   |  14 ++
 .../src/main/res/drawable/ic_close_round.xml  |  20 ++
 .../drawable/{ic_smile.xml => ic_delete.xml}  |  20 +-
 vector/src/main/res/drawable/ic_edit.xml      |   8 +-
 vector/src/main/res/drawable/ic_send.xml      |  14 ++
 .../main/res/layout/adapter_item_action.xml   |   8 +-
 ...constraint_set_composer_layout_compact.xml | 153 ++++++++++++
 ...onstraint_set_composer_layout_expanded.xml | 156 ++++++++++++
 .../main/res/layout/fragment_room_detail.xml  |  55 +----
 .../res/layout/include_composer_layout.xml    | 123 ++++++++++
 vector/src/main/res/values/attrs.xml          |   1 +
 vector/src/main/res/values/colors_riot.xml    |   1 +
 vector/src/main/res/values/theme_black.xml    |   1 +
 vector/src/main/res/values/theme_dark.xml     |   1 +
 vector/src/main/res/values/theme_light.xml    |   1 +
 vector/src/main/res/values/theme_status.xml   |   1 +
 39 files changed, 978 insertions(+), 146 deletions(-)
 create mode 100644 vector/src/main/java/im/vector/riotredesign/core/utils/AnimationUtils.kt
 create mode 100644 vector/src/main/java/im/vector/riotredesign/features/DebugActivity.kt
 delete mode 100644 vector/src/main/res/drawable-hdpi/ic_attach_file_white.png
 delete mode 100644 vector/src/main/res/drawable-hdpi/ic_send_white.png
 delete mode 100644 vector/src/main/res/drawable-mdpi/ic_attach_file_white.png
 delete mode 100644 vector/src/main/res/drawable-mdpi/ic_send_white.png
 delete mode 100644 vector/src/main/res/drawable-xhdpi/ic_attach_file_white.png
 delete mode 100644 vector/src/main/res/drawable-xhdpi/ic_send_white.png
 delete mode 100644 vector/src/main/res/drawable-xxhdpi/ic_attach_file_white.png
 delete mode 100644 vector/src/main/res/drawable-xxhdpi/ic_send_white.png
 delete mode 100644 vector/src/main/res/drawable-xxxhdpi/ic_attach_file_white.png
 delete mode 100644 vector/src/main/res/drawable-xxxhdpi/ic_send_white.png
 create mode 100644 vector/src/main/res/drawable/ic_add_reaction.xml
 create mode 100644 vector/src/main/res/drawable/ic_attachment.xml
 create mode 100644 vector/src/main/res/drawable/ic_close_round.xml
 rename vector/src/main/res/drawable/{ic_smile.xml => ic_delete.xml} (51%)
 create mode 100644 vector/src/main/res/drawable/ic_send.xml
 create mode 100644 vector/src/main/res/layout/constraint_set_composer_layout_compact.xml
 create mode 100644 vector/src/main/res/layout/constraint_set_composer_layout_expanded.xml
 create mode 100644 vector/src/main/res/layout/include_composer_layout.xml

diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/annotation/ReactionService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/annotation/ReactionService.kt
index ace61159..3f8fec00 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/annotation/ReactionService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/annotation/ReactionService.kt
@@ -17,6 +17,7 @@ package im.vector.matrix.android.api.session.room.model.annotation
 
 import im.vector.matrix.android.api.util.Cancelable
 
+//TODO rename in relationService?
 interface ReactionService {
 
 
@@ -49,4 +50,13 @@ interface ReactionService {
      */
     fun updateQuickReaction(reaction: String, oppositeReaction: String, targetEventId: String, myUserId: String)
 
+
+    /**
+     * Edit a text message body. Limited to "m.text" contentType
+     * @param targetEventId The event to edit
+     * @param newBodyText The edited body
+     * @param compatibilityBodyText The text that will appear on clients that don't support yet edition
+     */
+    fun editTextMessage(targetEventId: String, newBodyText: String, compatibilityBodyText: String = "* $newBodyText"): Cancelable
+
 }
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/send/SendService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/send/SendService.kt
index 6852931c..551ab545 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/send/SendService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/send/SendService.kt
@@ -34,6 +34,7 @@ interface SendService {
      * @return a [Cancelable]
      */
     fun sendTextMessage(text: String, msgType: String = MessageType.MSGTYPE_TEXT): Cancelable
+    fun sendFormattedTextMessage(text: String,formattedText: String): Cancelable
 
     /**
      * Method to send a media asynchronously.
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/annotation/DefaultReactionService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/annotation/DefaultReactionService.kt
index dbef5461..fdb75a8f 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/annotation/DefaultReactionService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/annotation/DefaultReactionService.kt
@@ -19,6 +19,7 @@ import androidx.work.*
 import im.vector.matrix.android.api.MatrixCallback
 import im.vector.matrix.android.api.session.events.model.Event
 import im.vector.matrix.android.api.session.room.model.annotation.ReactionService
+import im.vector.matrix.android.api.session.room.model.message.MessageType
 import im.vector.matrix.android.api.util.Cancelable
 import im.vector.matrix.android.internal.session.room.send.LocalEchoEventFactory
 import im.vector.matrix.android.internal.session.room.send.RedactEventWorker
@@ -150,4 +151,23 @@ internal class DefaultReactionService(private val roomId: String,
                 .setBackoffCriteria(BackoffPolicy.LINEAR, BACKOFF_DELAY, TimeUnit.MILLISECONDS)
                 .build()
     }
+
+    override fun editTextMessage(targetEventId: String, newBodyText: String, compatibilityBodyText: String): Cancelable {
+        val event = eventFactory.createReplaceTextEvent(roomId, targetEventId, newBodyText, MessageType.MSGTYPE_TEXT, compatibilityBodyText)
+        val sendContentWorkerParams = SendEventWorker.Params(roomId, event)
+        val sendWorkData = WorkerParamsFactory.toData(sendContentWorkerParams)
+
+        //TODO use relation API?
+        val workRequest = OneTimeWorkRequestBuilder<SendEventWorker>()
+                .setConstraints(WORK_CONSTRAINTS)
+                .setInputData(sendWorkData)
+                .setBackoffCriteria(BackoffPolicy.LINEAR, BACKOFF_DELAY, TimeUnit.MILLISECONDS)
+                .build()
+
+        WorkManager.getInstance()
+                .beginUniqueWork(buildWorkIdentifier(REACTION_WORK), ExistingWorkPolicy.APPEND, workRequest)
+                .enqueue()
+        return CancelableWork(workRequest.id)
+
+    }
 }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt
index 28ae63b8..1d6197a3 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt
@@ -60,6 +60,17 @@ internal class DefaultSendService(private val roomId: String,
         return CancelableWork(sendWork.id)
     }
 
+    override fun sendFormattedTextMessage(text: String, formattedText: String): Cancelable {
+        val event = eventFactory.createFormattedTextEvent(roomId, text, formattedText).also {
+            saveLocalEcho(it)
+        }
+        val sendWork = createSendEventWork(event)
+        WorkManager.getInstance()
+                .beginUniqueWork(buildWorkIdentifier(SEND_WORK), ExistingWorkPolicy.APPEND, sendWork)
+                .enqueue()
+        return CancelableWork(sendWork.id)
+    }
+
     override fun sendMedias(attachments: List<ContentAttachmentData>): Cancelable {
         val cancelableBag = CancelableBag()
         attachments.forEach {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt
index a2076d3b..e1cc9c74 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt
@@ -25,6 +25,7 @@ import im.vector.matrix.android.api.session.events.model.RelationType
 import im.vector.matrix.android.api.session.events.model.toContent
 import im.vector.matrix.android.api.session.room.model.annotation.ReactionContent
 import im.vector.matrix.android.api.session.room.model.annotation.ReactionInfo
+import im.vector.matrix.android.api.session.room.model.annotation.RelationDefaultContent
 import im.vector.matrix.android.api.session.room.model.message.*
 import im.vector.matrix.android.internal.session.content.ThumbnailExtractor
 
@@ -35,6 +36,30 @@ internal class LocalEchoEventFactory(private val credentials: Credentials) {
         return createEvent(roomId, content)
     }
 
+    fun createFormattedTextEvent(roomId: String, text: String, formattedText: String): Event {
+        val content = MessageTextContent(
+                type = MessageType.MSGTYPE_TEXT,
+                format = MessageType.FORMAT_MATRIX_HTML,
+                body = text,
+                formattedBody = formattedText
+        )
+        return createEvent(roomId, content)
+    }
+
+
+    fun createReplaceTextEvent(roomId: String, targetEventId: String, newBodyText: String, msgType: String, compatibilityText: String): Event {
+        val content = MessageTextContent(
+                type = msgType,
+                body = compatibilityText,
+                relatesTo = RelationDefaultContent(RelationType.REPLACE, targetEventId),
+                newContent = MessageTextContent(
+                        type = MessageType.MSGTYPE_TEXT,
+                        body = newBodyText
+                ).toContent()
+        )
+        return createEvent(roomId, content)
+    }
+
     fun createMediaEvent(roomId: String, attachment: ContentAttachmentData): Event {
         return when (attachment.type) {
             ContentAttachmentData.Type.IMAGE -> createImageEvent(roomId, attachment)
diff --git a/vector/src/main/java/im/vector/riotredesign/core/utils/AnimationUtils.kt b/vector/src/main/java/im/vector/riotredesign/core/utils/AnimationUtils.kt
new file mode 100644
index 00000000..a773991d
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotredesign/core/utils/AnimationUtils.kt
@@ -0,0 +1,39 @@
+package im.vector.riotredesign.core.utils
+
+import android.view.animation.OvershootInterpolator
+import androidx.annotation.LayoutRes
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.transition.ChangeBounds
+import androidx.transition.Transition
+import androidx.transition.TransitionManager
+
+
+inline fun ConstraintLayout.updateConstraintSet(@LayoutRes layoutId: Int, rootLayoutForAnimation: ConstraintLayout? = null, noinline onAnimationEnd: (() -> Unit)? = null) {
+    if (rootLayoutForAnimation != null) {
+        val transition = ChangeBounds()
+        transition.interpolator = OvershootInterpolator()
+        transition.addListener(object : Transition.TransitionListener {
+            override fun onTransitionResume(transition: Transition) {
+            }
+
+            override fun onTransitionPause(transition: Transition) {
+            }
+
+            override fun onTransitionCancel(transition: Transition) {
+            }
+
+            override fun onTransitionStart(transition: Transition) {
+            }
+
+            override fun onTransitionEnd(transition: Transition) {
+                onAnimationEnd?.invoke()
+            }
+        })
+        TransitionManager.beginDelayedTransition(rootLayoutForAnimation, transition)
+    }
+    ConstraintSet().also {
+        it.clone(this@updateConstraintSet.context, layoutId)
+        it.applyTo(this@updateConstraintSet)
+    }
+}
\ No newline at end of file
diff --git a/vector/src/main/java/im/vector/riotredesign/features/DebugActivity.kt b/vector/src/main/java/im/vector/riotredesign/features/DebugActivity.kt
new file mode 100644
index 00000000..00708d03
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotredesign/features/DebugActivity.kt
@@ -0,0 +1,12 @@
+package im.vector.riotredesign.features
+
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+
+class DebugActivity : AppCompatActivity() {
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_debug)
+    }
+}
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailActions.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailActions.kt
index 7d6ffc04..190c37de 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailActions.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailActions.kt
@@ -31,10 +31,13 @@ sealed class 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()
-    data class UpdateQuickReactAction(val targetEventId: String,val selectedReaction: String,val opposite: String) : RoomDetailActions()
-    data class ShowEditHistoryAction(val event: String,val editAggregatedSummary: EditAggregatedSummary) : RoomDetailActions()
+    data class UpdateQuickReactAction(val targetEventId: String, val selectedReaction: String, val opposite: String) : RoomDetailActions()
+    data class ShowEditHistoryAction(val event: String, val editAggregatedSummary: EditAggregatedSummary) : RoomDetailActions()
     object AcceptInvite : RoomDetailActions()
     object RejectInvite : RoomDetailActions()
 
+    data class EnterEditMode(val eventId: String) : RoomDetailActions()
+    data class EnterQuoteMode(val eventId: String) : RoomDetailActions()
+
 
 }
\ 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 0278607a..0ae0dda5 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
@@ -32,14 +32,17 @@ import android.view.HapticFeedbackConstants
 import android.view.LayoutInflater
 import android.view.View
 import android.view.inputmethod.InputMethodManager
+import android.widget.ImageButton
 import android.widget.TextView
 import android.widget.Toast
 import androidx.appcompat.app.AlertDialog
+import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.content.ContextCompat
 import androidx.lifecycle.Observer
 import androidx.lifecycle.ViewModelProviders
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
+import butterknife.BindView
 import com.airbnb.epoxy.EpoxyVisibilityTracker
 import com.airbnb.mvrx.MvRx
 import com.airbnb.mvrx.fragmentViewModel
@@ -53,6 +56,7 @@ import com.otaliastudios.autocomplete.Autocomplete
 import com.otaliastudios.autocomplete.AutocompleteCallback
 import com.otaliastudios.autocomplete.CharPolicy
 import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.events.model.toModel
 import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
 import im.vector.matrix.android.api.session.room.model.Membership
 import im.vector.matrix.android.api.session.room.model.message.*
@@ -92,6 +96,7 @@ import im.vector.riotredesign.features.media.VideoMediaViewerActivity
 import im.vector.riotredesign.features.reactions.EmojiReactionPickerActivity
 import kotlinx.android.parcel.Parcelize
 import kotlinx.android.synthetic.main.fragment_room_detail.*
+import kotlinx.android.synthetic.main.include_composer_layout.*
 import org.koin.android.ext.android.inject
 import org.koin.android.scope.ext.android.bindScope
 import org.koin.android.scope.ext.android.getOrCreateScope
@@ -165,6 +170,15 @@ class RoomDetailFragment :
 
     private lateinit var actionViewModel: ActionsHandler
 
+    @BindView(R.id.composer_related_message_sender)
+    lateinit var composerRelatedMessageTitle: TextView
+    @BindView(R.id.composer_related_message_preview)
+    lateinit var composerRelatedMessageContent: TextView
+    @BindView(R.id.composerLayout)
+    lateinit var composerLayout: ConstraintLayout
+    @BindView(R.id.rootConstraintLayout)
+    lateinit var rootConstraintLayout: ConstraintLayout
+
     override fun onActivityCreated(savedInstanceState: Bundle?) {
         super.onActivityCreated(savedInstanceState)
         actionViewModel = ViewModelProviders.of(requireActivity()).get(ActionsHandler::class.java)
@@ -187,6 +201,65 @@ class RoomDetailFragment :
         actionViewModel.actionCommandEvent.observe(this, Observer {
             handleActions(it)
         })
+
+        roomDetailViewModel.selectSubscribe(RoomDetailViewState::sendMode, RoomDetailViewState::selectedEvent, RoomDetailViewState::roomId) { mode, event, roomId ->
+            when (mode) {
+                SendMode.REGULAR -> {
+                    val uid = session.sessionParams.credentials.userId
+                    val meMember = session.getRoom(roomId)?.getRoomMember(uid)
+                    AvatarRenderer.render(meMember?.avatarUrl, uid, meMember?.displayName, composer_avatar_view)
+                    composerLayout.updateConstraintSet(R.layout.constraint_set_composer_layout_compact, rootConstraintLayout) {
+                        focusComposerAndShowKeyboard()
+                    }
+                }
+                SendMode.EDIT,
+                SendMode.QUOTE -> {
+                    if (event == null) {
+                        //we should ignore? can this happen?
+                        Timber.e("Enter edit mode with no event selected")
+                        return@selectSubscribe
+                    }
+                    //switch to expanded bar
+                    composerRelatedMessageTitle.text = event.senderName
+                    composerRelatedMessageTitle.setTextColor(
+                            ContextCompat.getColor(requireContext(), AvatarRenderer.getColorFromUserId(event.root.sender
+                                    ?: ""))
+                    )
+
+                    val messageContent: MessageContent? =
+                            event.annotations?.editSummary?.aggregatedContent?.toModel()
+                                    ?: event.root.content.toModel()
+                    val eventTextBody = messageContent?.body
+                    composerRelatedMessageContent.text = eventTextBody
+
+
+                    if (mode == SendMode.EDIT) {
+                        composerEditText.setText(eventTextBody)
+                        composer_related_message_action_image.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_edit))
+                    } else {
+                        composerEditText.setText("")
+                        composer_related_message_action_image.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_quote))
+                    }
+
+                    AvatarRenderer.render(event.senderAvatar, event.root.sender
+                            ?: "", event.senderName, composer_avatar_view)
+
+                    composerEditText.setSelection(composerEditText.text.length)
+                    composerLayout.updateConstraintSet(R.layout.constraint_set_composer_layout_expanded, rootConstraintLayout) {
+                        focusComposerAndShowKeyboard()
+                    }
+
+                    view?.findViewById<ImageButton>(R.id.composer_related_message_close)?.setOnClickListener {
+
+                        composerRelatedMessageTitle.text = ""
+                        composerRelatedMessageContent.text = ""
+                        composerEditText.setText("")
+                        roomDetailViewModel.resetSendMode()
+                    }
+
+                }
+            }
+        }
     }
 
     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@@ -398,6 +471,11 @@ class RoomDetailFragment :
         if (summary?.membership == Membership.JOIN) {
             timelineEventController.setTimeline(state.timeline)
             inviteView.visibility = View.GONE
+
+            val uid = session.sessionParams.credentials.userId
+            val meMember = session.getRoom(state.roomId)?.getRoomMember(uid)
+            AvatarRenderer.render(meMember?.avatarUrl, uid, meMember?.displayName, composer_avatar_view)
+
         } else if (summary?.membership == Membership.INVITE && inviter != null) {
             inviteView.visibility = View.VISIBLE
             inviteView.render(inviter, VectorInviteView.Mode.LARGE)
@@ -601,6 +679,14 @@ class RoomDetailFragment :
                         roomDetailViewModel.process(RoomDetailActions.UpdateQuickReactAction(eventId, clickedOn, opposite))
                     }
                 }
+                MessageMenuViewModel.ACTION_EDIT -> {
+                    val eventId = actionData.data.toString() ?: return@let
+                    roomDetailViewModel.process(RoomDetailActions.EnterEditMode(eventId))
+                }
+                MessageMenuViewModel.ACTION_QUOTE -> {
+                    val eventId = actionData.data.toString() ?: return@let
+                    roomDetailViewModel.process(RoomDetailActions.EnterQuoteMode(eventId))
+                }
                 else -> {
                     Toast.makeText(context, "Action ${actionData.actionId} not implemented", Toast.LENGTH_LONG).show()
                 }
@@ -648,12 +734,16 @@ class RoomDetailFragment :
 //                    v.vibrate(100)
 //                }
 //            }
-            composerEditText.requestFocus()
-            val imm = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
-            imm?.showSoftInput(composerEditText, InputMethodManager.SHOW_FORCED)
+            focusComposerAndShowKeyboard()
         }
     }
 
+    private fun focusComposerAndShowKeyboard() {
+        composerEditText.requestFocus()
+        val imm = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
+        imm?.showSoftInput(composerEditText, InputMethodManager.SHOW_IMPLICIT)
+    }
+
     fun showSnackWithMessage(message: String, duration: Int = Snackbar.LENGTH_SHORT) {
         val snack = Snackbar.make(view!!, message, Snackbar.LENGTH_SHORT)
         snack.view.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.notification_accent_color))
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailViewModel.kt
index 44c2aa8f..f5664efc 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailViewModel.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailViewModel.kt
@@ -16,6 +16,7 @@
 
 package im.vector.riotredesign.features.home.room.detail
 
+import android.text.TextUtils
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import com.airbnb.mvrx.MvRxViewModelFactory
@@ -25,8 +26,11 @@ import com.jakewharton.rxrelay2.BehaviorRelay
 import im.vector.matrix.android.api.MatrixCallback
 import im.vector.matrix.android.api.session.Session
 import im.vector.matrix.android.api.session.content.ContentAttachmentData
+import im.vector.matrix.android.api.session.events.model.toModel
 import im.vector.matrix.android.api.session.room.model.Membership
+import im.vector.matrix.android.api.session.room.model.message.MessageContent
 import im.vector.matrix.android.api.session.room.model.message.MessageType
+import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
 import im.vector.matrix.rx.rx
 import im.vector.riotredesign.R
 import im.vector.riotredesign.core.platform.VectorViewModel
@@ -36,11 +40,14 @@ import im.vector.riotredesign.features.command.ParsedCommand
 import im.vector.riotredesign.features.home.room.VisibleRoomStore
 import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDisplayableEvents
 import io.reactivex.rxkotlin.subscribeBy
+import org.commonmark.parser.Parser
+import org.commonmark.renderer.html.HtmlRenderer
 import org.koin.android.ext.android.get
 import java.text.SimpleDateFormat
 import java.util.*
 import java.util.concurrent.TimeUnit
 
+
 class RoomDetailViewModel(initialState: RoomDetailViewState,
                           private val session: Session,
                           private val visibleRoomHolder: VisibleRoomStore
@@ -87,9 +94,28 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
             is RoomDetailActions.UndoReaction -> handleUndoReact(action)
             is RoomDetailActions.UpdateQuickReactAction -> handleUpdateQuickReaction(action)
             is RoomDetailActions.ShowEditHistoryAction -> handleShowEditHistoryReaction(action)
+            is RoomDetailActions.EnterEditMode -> handleEditAction(action)
+            is RoomDetailActions.EnterQuoteMode -> handleQuoteAction(action)
         }
     }
 
+    fun enterEditMode(event: TimelineEvent) {
+        setState {
+            copy(
+                    sendMode = SendMode.EDIT,
+                    selectedEvent = event
+            )
+        }
+    }
+
+    fun resetSendMode() {
+        setState {
+            copy(
+                    sendMode = SendMode.REGULAR,
+                    selectedEvent = null
+            )
+        }
+    }
 
     private val _nonBlockingPopAlert = MutableLiveData<LiveEvent<Pair<Int, List<Any>>>>()
     val nonBlockingPopAlert: LiveData<LiveEvent<Pair<Int, List<Any>>>>
@@ -103,71 +129,135 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
     // PRIVATE METHODS *****************************************************************************
 
     private fun handleSendMessage(action: RoomDetailActions.SendMessage) {
-        // Handle slash command
-        val slashCommandResult = CommandParser.parseSplashCommand(action.text)
+        withState { state ->
+            when (state.sendMode) {
+                SendMode.REGULAR -> {
+                    val slashCommandResult = CommandParser.parseSplashCommand(action.text)
 
-        when (slashCommandResult) {
-            is ParsedCommand.ErrorNotACommand -> {
-                // Send the text message to the room
-                room.sendTextMessage(action.text)
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.MessageSent))
-            }
-            is ParsedCommand.ErrorSyntax -> {
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandError(slashCommandResult.command)))
-            }
-            is ParsedCommand.ErrorEmptySlashCommand -> {
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandUnknown("/")))
-            }
-            is ParsedCommand.ErrorUnknownSlashCommand -> {
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandUnknown(slashCommandResult.slashCommand)))
-            }
-            is ParsedCommand.Invite -> {
-                handleInviteSlashCommand(slashCommandResult)
-            }
-            is ParsedCommand.SetUserPowerLevel -> {
-                // TODO
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
-            }
-            is ParsedCommand.ClearScalarToken -> {
-                // TODO
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
-            }
-            is ParsedCommand.SetMarkdown -> {
-                // TODO
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
-            }
-            is ParsedCommand.UnbanUser -> {
-                // TODO
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
-            }
-            is ParsedCommand.BanUser -> {
-                // TODO
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
-            }
-            is ParsedCommand.KickUser -> {
-                // TODO
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
-            }
-            is ParsedCommand.JoinRoom -> {
-                // TODO
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
-            }
-            is ParsedCommand.PartRoom -> {
-                // TODO
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
-            }
-            is ParsedCommand.SendEmote -> {
-                room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE)
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandHandled))
-            }
-            is ParsedCommand.ChangeTopic -> {
-                handleChangeTopicSlashCommand(slashCommandResult)
-            }
-            is ParsedCommand.ChangeDisplayName -> {
-                // TODO
-                _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
+                    when (slashCommandResult) {
+                        is ParsedCommand.ErrorNotACommand -> {
+                            // Send the text message to the room
+                            room.sendTextMessage(action.text)
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.MessageSent))
+                        }
+                        is ParsedCommand.ErrorSyntax -> {
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandError(slashCommandResult.command)))
+                        }
+                        is ParsedCommand.ErrorEmptySlashCommand -> {
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandUnknown("/")))
+                        }
+                        is ParsedCommand.ErrorUnknownSlashCommand -> {
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandUnknown(slashCommandResult.slashCommand)))
+                        }
+                        is ParsedCommand.Invite -> {
+                            handleInviteSlashCommand(slashCommandResult)
+                        }
+                        is ParsedCommand.SetUserPowerLevel -> {
+                            // TODO
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
+                        }
+                        is ParsedCommand.ClearScalarToken -> {
+                            // TODO
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
+                        }
+                        is ParsedCommand.SetMarkdown -> {
+                            // TODO
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
+                        }
+                        is ParsedCommand.UnbanUser -> {
+                            // TODO
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
+                        }
+                        is ParsedCommand.BanUser -> {
+                            // TODO
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
+                        }
+                        is ParsedCommand.KickUser -> {
+                            // TODO
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
+                        }
+                        is ParsedCommand.JoinRoom -> {
+                            // TODO
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
+                        }
+                        is ParsedCommand.PartRoom -> {
+                            // TODO
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
+                        }
+                        is ParsedCommand.SendEmote -> {
+                            room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE)
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandHandled))
+                        }
+                        is ParsedCommand.ChangeTopic -> {
+                            handleChangeTopicSlashCommand(slashCommandResult)
+                        }
+                        is ParsedCommand.ChangeDisplayName -> {
+                            // TODO
+                            _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.SlashCommandNotImplemented))
+                        }
+                    }
+                }
+                SendMode.EDIT -> {
+                    room.editTextMessage(state?.selectedEvent?.root?.eventId ?: "", action.text)
+                    setState {
+                        copy(
+                                sendMode = SendMode.REGULAR,
+                                selectedEvent = null
+                        )
+                    }
+                    _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.MessageSent))
+                }
+                SendMode.QUOTE -> {
+                    withState { state ->
+                        val messageContent: MessageContent? =
+                                state.selectedEvent?.annotations?.editSummary?.aggregatedContent?.toModel()
+                                        ?: state.selectedEvent?.root?.content.toModel()
+                        val textMsg = messageContent?.body
+
+                        val finalText = legacyRiotQuoteText(textMsg, action.text)
+
+                        //TODO Refactor this, just temporary for quotes
+                        val parser = Parser.builder().build()
+                        val document = parser.parse(finalText)
+                        val renderer = HtmlRenderer.builder().build()
+                        val htmlText = renderer.render(document)
+                        if (TextUtils.equals(finalText, htmlText)) {
+                            room.sendTextMessage(finalText)
+                        } else {
+                            room.sendFormattedTextMessage(finalText, htmlText)
+                        }
+                        setState {
+                            copy(
+                                    sendMode = SendMode.REGULAR,
+                                    selectedEvent = null
+                            )
+                        }
+                        _sendMessageResultLiveData.postValue(LiveEvent(SendMessageResult.MessageSent))
+                    }
+
+                }
             }
         }
+        // Handle slash command
+
+    }
+
+    private fun legacyRiotQuoteText(quotedText: String?, myText: String): String {
+        val messageParagraphs = quotedText?.split("\n\n".toRegex())?.dropLastWhile { it.isEmpty() }?.toTypedArray()
+        var quotedTextMsg = StringBuilder()
+        if (messageParagraphs != null) {
+            for (i in messageParagraphs.indices) {
+                if (messageParagraphs[i].trim({ it <= ' ' }) != "") {
+                    quotedTextMsg.append("> ").append(messageParagraphs[i])
+                }
+
+                if (i + 1 != messageParagraphs.size) {
+                    quotedTextMsg.append("\n\n")
+                }
+            }
+        }
+        val finalText = "$quotedTextMsg\n\n$myText"
+        return finalText
     }
 
     private fun handleShowEditHistoryReaction(action: RoomDetailActions.ShowEditHistoryAction) {
@@ -271,6 +361,23 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
         room.join(object : MatrixCallback<Unit> {})
     }
 
+    private fun handleEditAction(action: RoomDetailActions.EnterEditMode) {
+        room.getTimeLineEvent(action.eventId)?.let {
+            enterEditMode(it)
+        }
+    }
+
+    private fun handleQuoteAction(action: RoomDetailActions.EnterQuoteMode) {
+        room.getTimeLineEvent(action.eventId)?.let {
+            setState {
+                copy(
+                        sendMode = SendMode.QUOTE,
+                        selectedEvent = it
+                )
+            }
+        }
+    }
+
 
     private fun observeEventDisplayedActions() {
         // We are buffering scroll events for one second
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailViewState.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailViewState.kt
index 43fbe9bd..00ce0b47 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailViewState.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailViewState.kt
@@ -22,15 +22,32 @@ import com.airbnb.mvrx.Uninitialized
 import im.vector.matrix.android.api.session.room.model.RoomSummary
 import im.vector.matrix.android.api.session.room.timeline.Timeline
 import im.vector.matrix.android.api.session.room.timeline.TimelineData
+import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
 import im.vector.matrix.android.api.session.user.model.User
 
+/**
+ * Describes the current send mode:
+ * REGULAR: sends the text as a regular message
+ * QUOTE: User is currently quoting a message
+ * EDIT: User is currently editing an existing message
+ *
+ * Depending on the state the bottom toolbar will change (icons/preview/actions...)
+ */
+enum class SendMode {
+    REGULAR,
+    QUOTE,
+    EDIT
+}
+
 data class RoomDetailViewState(
         val roomId: String,
         val eventId: String?,
         val timeline: Timeline? = null,
         val inviter: Async<User> = Uninitialized,
         val asyncRoomSummary: Async<RoomSummary> = Uninitialized,
-        val asyncTimelineData: Async<TimelineData> = Uninitialized
+        val asyncTimelineData: Async<TimelineData> = Uninitialized,
+        val sendMode: SendMode = SendMode.REGULAR,
+        val selectedEvent: TimelineEvent? = null
 ) : MvRxState {
 
     constructor(args: RoomDetailArgs) : this(roomId = args.roomId, eventId = args.eventId)
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageMenuViewModel.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageMenuViewModel.kt
index c39da484..4fee2f41 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageMenuViewModel.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageMenuViewModel.kt
@@ -59,7 +59,7 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
                         listOf(
                                 SimpleAction(ACTION_RESEND, R.string.resend, R.drawable.ic_corner_down_right, event.root.eventId),
                                 //TODO delete icon
-                                SimpleAction(ACTION_DELETE, R.string.delete, R.drawable.ic_material_delete, event.root.eventId)
+                                SimpleAction(ACTION_DELETE, R.string.delete, R.drawable.ic_delete, event.root.eventId)
                         )
                 )
             }
@@ -67,14 +67,18 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
 
             //TODO determine if can copy, forward, reply, quote, report?
             val actions = ArrayList<SimpleAction>().apply {
-                this.add(SimpleAction(ACTION_ADD_REACTION, R.string.message_add_reaction, R.drawable.ic_smile, event.root.eventId))
+                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))
                 }
 
+                if (canEdit(event, currentSession.sessionParams.credentials.userId)) {
+                    this.add(SimpleAction(ACTION_EDIT, R.string.edit, R.drawable.ic_edit, event.root.eventId))
+                }
+
                 if (canRedact(event, currentSession.sessionParams.credentials.userId)) {
-                    this.add(SimpleAction(ACTION_DELETE, R.string.delete, R.drawable.ic_material_delete, event.root.eventId))
+                    this.add(SimpleAction(ACTION_DELETE, R.string.delete, R.drawable.ic_delete, event.root.eventId))
                 }
 
                 if (canQuote(event, messageContent)) {
@@ -159,6 +163,17 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
             return event.root.sender == myUserId
         }
 
+        private fun canEdit(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
+            val messageContent = event.root.content.toModel<MessageContent>()
+            return event.root.sender == myUserId && (
+                    messageContent?.type == MessageType.MSGTYPE_TEXT
+                            || messageContent?.type == MessageType.MSGTYPE_EMOTE
+                    )
+        }
+
 
         private fun canCopy(type: String): Boolean {
             return when (type) {
@@ -187,6 +202,7 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel<Mes
 
         const val ACTION_ADD_REACTION = "add_reaction"
         const val ACTION_COPY = "copy"
+        const val ACTION_EDIT = "edit"
         const val ACTION_QUOTE = "quote"
         const val ACTION_REPLY = "reply"
         const val ACTION_SHARE = "share"
diff --git a/vector/src/main/res/drawable-hdpi/ic_attach_file_white.png b/vector/src/main/res/drawable-hdpi/ic_attach_file_white.png
deleted file mode 100644
index 06f642bea5a174105f33b363b67a2028994dd67b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 394
zcmV;50d@X~P)<h;3K|Lk000e1NJLTq001Na001Ni1^@s6;Q*MJ0003|Nkl<Zc-rll
zL23dq6oy@nVg)y?E0^LziqLwFGDorA!y>5IQ?#}RC|!%)lu~tD_qrI-aTEW6e;_S7
zn$cviB=CU~-+TGUL@+NUgh(mkfI1ie5BT5%G(b8=y<ey%6v3z1J-!%YM97h3#=r$R
zkOg;~3#A+rLUl<dzvcV9Bz12>Xu!qXh!~eKLlZ(C7t2M&Trg&7LMR-kiu?aUyB0n)
z&I(x}D`bVNkQK5*R_NS?7JR;x<_etik`Q{~b01t$=9P0#NeGp}e9L8V21-c?g;LLa
zMILvibj*Kj6`?f?tK3R6%<**yO<4R!A*aTiZyiEC7H=x#w3yS@Ayj4Y6{s8#f6Z4V
z_*qLk=8+5h?2!rtri|_A><<MEsds6o9>6URZ-!^4CGE_cYHKFWbvG^TRMhCi=@T8(
oehbc27mT<gK7UPZl{52~4Io?>E>CY>q5uE@07*qoM6N<$f}e__;Q#;t

diff --git a/vector/src/main/res/drawable-hdpi/ic_send_white.png b/vector/src/main/res/drawable-hdpi/ic_send_white.png
deleted file mode 100644
index f133cdbeb2757f5d4f51321c302c7fcd81be52fa..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 335
zcmV-V0kHmwP)<h;3K|Lk000e1NJLTq001Na001Ni1^@s6;Q*MJ0003NNkl<Zc-rll
zv2DUY6hMtcOTh|3VF5A%kzjyi1gK0)MhI=FU<Bw%0VBWw6fgpj(ngATE-VEUf$!h{
z=8$~SYg|41`ObHak|c>jA}WRMU8oC{kc85)g#pw;5z59ljG-BdP&R(yv#6YTg#Hfm
zoUTIVIi*5oIemrHb7~5y<g^g-%4sPi%6WdF4lQ_rAxvNiJNPLgr%T@|JU|<I@D4Lr
z!$B*j<{Bb>x+gicg`VIQ-e3wV*yj+6B|>Sk20TL_MlgpBd<l{*pmQym^e$aq>JNAf
zVcN%%X|KI7{+s0%pN@-Jiu}0d%3{6!aL!`2K@(@u-okok(b(jxX7M=&nPib16iu_-
h^-;R~`%wzHas(7`hA~Sk`s4rr002ovPDHLkV1mtQjA#G=

diff --git a/vector/src/main/res/drawable-mdpi/ic_attach_file_white.png b/vector/src/main/res/drawable-mdpi/ic_attach_file_white.png
deleted file mode 100644
index a819f4034d49512d474d5dd27781f40d6837bd0a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 285
zcmV+&0pk9NP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0002wNkl<Zc-rli
zJqp4=5JqziF@>5&yolhb5=1KtwTyP^0hF9Tv=VP27K)%~8d2A8;S&~#`Pr;p0*~y@
z4)caBb}S);^-t0yH9!DDa03faHzkn8FW><BU;vKboK}*Q5U_YziP@CQO$b7E{v98J
zs|kVp+=#f#Gou1^tqNjgg`f}=f^32(=y2WT-l$;BN3I7>U}-||0v^{6Sb;l>R~h%1
zrzO~fNkYyH>~sZVKFg&a=QgLDuPbmk6E+bNS$xX|DtTsdi(Se>Q_$wMd}7VKLtjz@
jBi{9ce?PACtO9M`=wB&0PW1Bf00000NkvXXu0mjfmu++^

diff --git a/vector/src/main/res/drawable-mdpi/ic_send_white.png b/vector/src/main/res/drawable-mdpi/ic_send_white.png
deleted file mode 100644
index 34e49af7ab119a8581624cba15d1874ddb3ee8d0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 257
zcmV+c0sj7pP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0002UNkl<Zc-rOF
zF%AJi6o>IG(5t990^tH2frgqR&{1*(Y8sBf1tc7SR!1$0@ii-(STgUK*D%SiQ2mo{
z?QG<ni!4PyHLyb$Ije#AoH0hxY9Ky0EK#=_NFH@Q-vM<#>3}$&cECGd@<$#Ov@pO7
z8ys=h=JS168I;gK4->4g$K_K#$v_!R^fAR62V7GI7O15qs-le{=GfvSNHjvh;vsjC
z4gEKLW(fVFy<`Y=RlLpc&1L76L33S;GDto+sto`0O*ZiWxujSd^@pKl00000NkvXX
Hu0mjfBSB_$

diff --git a/vector/src/main/res/drawable-xhdpi/ic_attach_file_white.png b/vector/src/main/res/drawable-xhdpi/ic_attach_file_white.png
deleted file mode 100644
index c572c35997127449a4b660c4c9f1cd5c70ff7a1e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 507
zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezr3(Fdp)BaSW-r^>)^Iufq-k$1ZmV
z=4-tQtP-@HdT;e3W|5DYQCpWcl?yt4(0hB(UEsfnyhCl%BKD2j7uh-L=GsW4Cw3hc
znv`qi>o%wH{iJi}>h^EAIc2WJzW3Jkk$nt*R&iuCSt;;;<;rT{n!}jpAYNBdqkPB2
zoFVn!Mf3jOOB8dsUzGn73UQk3CA~mfclklq1uG<1w?C1~I=%7$<ARlUf3El=J*oa2
z;{s=%sXU*|J^yjDGxSRsRT`vw{+qze(CgVJ*id-3WoD1D8v~02I{L?Zpdlt+<@)rK
zU+vNvs=}&xqnti(za^;|-4NUCe9tJIVd-Xp&&xgKw%=f=ndrHksqQ|b?SrcKk2h(u
zKiRpYZ@St6>6sN*7oD?OdD&O^L7z{|))m3ZrBRto7dme*i0P5aIwQPtGf)-Ni^)E5
zoq>-VdfqoayOd`*SAh8y>o(J4H*#&#<c|i1`R+^ST_m(|PEp14_FF<Fo3l1QbCkao
zw~ps+^R){zx_A5fMt|12=cpZNzUwpNF`q@b$#yUO_GTH&K0YiVY8&(Un(brHE&rbv
uTIW3M&ir!IQT+df(8q7gK5b+V|I4r>ZAo!J6cZ?V89ZJ6T-G@yGywo`ncEKl

diff --git a/vector/src/main/res/drawable-xhdpi/ic_send_white.png b/vector/src/main/res/drawable-xhdpi/ic_send_white.png
deleted file mode 100644
index e5f9ba41acdb7d7f9353981e1aa0bcff06353b14..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 423
zcmV;Y0a*TtP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0004QNkl<Zc-rlm
zu`<L^6hKp;SE1z-7)#G5&@3&VKxe7eC+yZ%!6#5N44*(tMUB~gjxjrv$;9j=x%a;J
z%zHDZNq3Ty<mD!F&Sf!^C4nT61pc4EE$qTftO7&#yI$c07Gf0`uTMCK^;iY+>prx+
z$_|d)<n@!+aR_<U6)5Jl7OQ~wyd(vRdCmJ0kXj~rX$qL+WhJ1Nm$g7XuYp8fz6A2?
z4tDD16@oycyvh#F!ZK{Z0rcPsp5V(cua?I5z!WUP2JAr>F5m&)eB>qlT-LgJFVHE=
z%W~f$arHimd07iA!6xj(DO|!MyjKu7gH_FhR$v<rp%2&aERfI<%t_qDP0wQ0o45_r
zRUe}oXVKNoB$gN1pHG??wi4~wwi4q^S}wB9T&+w(5NNdH^!Z6SkjTXPqh34{D*?4k
zv<F-2nP`m`JE4viCk=PaGm#jti%bxF{NM;;0$o+$CbUe_U&<tq1d>3wd;=dyV1##h
Rc_07)002ovPDHLkV1lk5y~_Xq

diff --git a/vector/src/main/res/drawable-xxhdpi/ic_attach_file_white.png b/vector/src/main/res/drawable-xxhdpi/ic_attach_file_white.png
deleted file mode 100644
index a5dc29f0d272d854bf2ad39ead95d01b1d791d47..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 809
zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2VEW+c;uunK>+PJo-lC2Y?X8RF
zHvMAOIw7+9wbJ5xC9N0B_$R*5TQplwh4YfqZY>Qa)jj9!Jhb}6*hJ&R1H;2qYBj=2
zij6#0Zr;oM{$9`fH|H#?)9%jwyZ1vupVjAcXNuF(%Tm8@VR5{`bjE>+<*9#w`bB>q
z!OusGjF0cP_Ri5=w1DrC-beio{?KP;7vn@6ZI8TP@GnB8@0Z>ReGj?x8qq7lhA-Y9
zkuW^6;=8@lDfy4S0qqYrL@88thAs4yE}Zj2?aFW0oR6LtWD_Ukcl3&tnhWN){@Pw6
zct!I~827XyC$rCqE8ge5wc~gtZuj>d+ow4KpT7K5$nc7o5G{S;vYO5v{~7_4^}JbY
zI<s$z%d_ZaH%oa<c)e*__DOcfDjt;+rV3A*6*!s}L^y5}%4M;f%;6}&LNuC^>}b07
z%mT&htZQS|YBbelrOHVZ*$U-7*KS#G{LmST1ye0m&TQ#i#9^g2CD=$#XnMu7D=kLt
z-AW#Jzy7jXp&uu-bP-2T4u9A^ojk6u6;9!|$`|ewO4;qKxlM4rPMTl1OP^!+T)p5X
zv8{aZoto?Uq`$`8P&vP1{~xP^*?yYK{)MjHn{|z~_KH=_`9N#M$5GYtoAfe*UVlhG
z-t=tCH?2tVlDG)>GOMiY?H8`?T*G}!yQJz!VDw_A=(~~PODfiv{_;QLcZI{cY3ljb
zGbWpPr#Ja=&wo?gEqhXIYI;=0<CHj-wU3WR_GkN^s&_tN>pkVOl1Jf%f=A`H2Ys|8
zpRBlX{f*(0j}9k%4=2QZh%DKgeQt~5{SDp!mMePr{!DLk)ZKU>RxJAGiVX_wAE!i2
z4tMP06`XYFhu59wr`x*!Sn17S@hZBu`&IR<^9!ac^KExazH#+TB(J05?@oWtqi1$S
zOxUdCv2mJ(>z>uYXL#m6pK|$Cw%EQS8T|3qp+B_tocjN6#i#S4|Ej-dec_Kk%<3rc
bWXgYOqoS1K?z8p+vjBsqtDnm{r-UW|NG4=C

diff --git a/vector/src/main/res/drawable-xxhdpi/ic_send_white.png b/vector/src/main/res/drawable-xxhdpi/ic_send_white.png
deleted file mode 100644
index 0ba718b6e25df33c10d4a2b91af75d08ccf25eff..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 550
zcmV+>0@?kEP)<h;3K|Lk000e1NJLTq002k;002k`1^@s6RqeA!0005)Nkl<Zc-rlo
zy)r{l6h>2^SE1z*7@_A8XwdQqbbcxxfm#$i0yQJUBhX4kjY*Dg#$+aQ-5}@Qea_zJ
ze0ye9>DKIZ|I={JHOO!%fr2QAf+&cBD2Re6=qGnz3rtW@IbHWX9dHC@D5zXee?Gtk
zSf-$IL4(uIB|l$5ZXmzIl=G`9sF>eUPJ(*QZ<5MSLQqoqNeW6LzYu~<=NDR#x%__n
zF~q3PFSa1{`DqeV%x{{4{?4xzJ3q~W2In4Z#>mf#plJD76BIl@tAc{%mx3VC{8AEB
z%&#deXcEkWHLwd#!8LdSpSk4cYjzCGf)%h0j=?2(0Iw<KCw27Kx_u+(7vt(w%l7>%
zKaF?Lp||e^91P3P+7mv>?RziF&!V6?unKm-3Ah4};H?Hh=U~x7Vhdm$?13|I1D*vF
z+Xqvc4$@LvFzP{i1B}Ny&4=8AN*PIAC~DY(TFz8eZZ$M+flo#vw;EPw<cx9=<egCt
z56miMl%k-1Moq^@uJReB^4do%BddafWn@iI@QkboiuU%@DgXSX6+0teLA?MOnf`#P
zmrF*m1*y*{mY|N6j6w@)Tg%8-P&b#1Bn2grk%XY6GOA0EijOKa3QGPzVZMTHbIB;i
odoc>4AVNVDL_ripK@?=1FD5h?{9Ic8+W-In07*qoM6N<$f?2ikg8%>k

diff --git a/vector/src/main/res/drawable-xxxhdpi/ic_attach_file_white.png b/vector/src/main/res/drawable-xxxhdpi/ic_attach_file_white.png
deleted file mode 100644
index 60147bc7a378eb0cb32cfe4cc9ae61b4bcd046de..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1059
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>V1DK4;uunK>+RgT-Xeh#?Yae~
zckT3?4kc+`+x7aj(g*ny9~P}S>$7sV6YF~JUB<r_9O_=waX?^6#%Yc&hmL;@3%XBq
zIBimTwXA1?QFiZ)dx!UVbHA%jOZ$FiPT{xm2aJ)=YxX>!X<2+ua>mL+ndNLZnCCJu
z3NR=vP&wTxmo%fot48(N%*=njf7j3MZ)I@KQF80BJYN0FGe$j1VL{C_LFXg#%l|A{
z*T?N*%km>x`Qs(S>1rJ&EEUPtACDT&w-b(5Jn;7n|Dw;`s!J3XnDENA&Aop_W1?b^
zi|*t{_wzm&<{b{SWzk7FvGnmKm(A@(*MySwQs=fev<CZTZu>m_h5q6*jOVn^_FWSA
zFkkTO&0Fz~JDFz{wJR!|=Q^vToxPwY(_)tDB!LO{<0j<oILme_-u+37)h-1Edyy$#
zi`ic9(7aN}%k*h>#?qi;39@sYWc?Ks_OFiATFP^6W87wg)m4n2ot|HjTC>=1g)%#1
zQPi5R4h$?H<WL|Roaf#a$`9s2#Hd9!><^bV$@-+yYGcXqLH-5%!yk8N*;KdMyjM6-
zzu<ez<9K0hZ<+mFGekc1I5zxu;LrY~!6|F=MCIq1`B!A_Gc*2U4qZR*=aZ0mR|2Lr
zG<;%uYowqc?67;)t5n%=trvg18Mm#@V$snJKID3in^Eucua@I~*gN{=j@PW$XWH_u
z%UGIeALqe!-vZkvm3Hj#-t)Zg)JL28o^)$Y`KP9wxwHBfGi1)%ao8!EYfIL$og0Ne
z1aN#?;mTO+H2dB0zyp?wH`cf^Ui!W4{E<M1-2!jQ)&B>!Z@9hK>}y)9+18_h4O~B_
z3w#jde*04NmXY`|PQk6-|9X?Z@$QOC3(n8w>)gh&CHvX?<4!rpIeo2fJ<>_w{ODBt
zGM{fD?`@f%%ns)dz2cs&uX}gB<?m$`g(4w$vnwvDE$zz^SWvO%Wy^C$&w#o13s;ug
zoUz-WyP$RX{9W3K-47Gp%b%SWkY454u;_Mbu&-}qf4GIU*9YF~Zx`p!O*}5o%Gh;T
zuFQOS#qLEHpU+wxZhTe8Pd)dDoG4@0YPs*<>jlay{x6&QUbxgp`2V%z*}akdsd3vx
z%crnt_*p(&?l{}f-M8V<g44Y>LuPF>e5TLF$o2K^ad*bDe-$@2&poQP;DB8m{|v9J
z*4^q}hHkMAjj=~^&+4txTe-G3I`Qq>BcTqBZ0}BNKEhm=ViEhrC*tqluK6h|+cm9q
oZIe6JHr#0RYhd7D5c|pAuy^9+A9F0;05d;>r>mdKI;Vst01_g}=l}o!

diff --git a/vector/src/main/res/drawable-xxxhdpi/ic_send_white.png b/vector/src/main/res/drawable-xxxhdpi/ic_send_white.png
deleted file mode 100644
index f02b6453d5c3a05f683d2c49aaa8495033a14b8a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 728
zcmV;}0w?{6P)<h;3K|Lk000e1NJLTq003YB003YJ1^@s6;+S_h0007?Nkl<Zc-rlq
zyHXTE7)A*|V<Rr1K7y7gu{;7KqGtLCnt@0Fj{q?&6h4B68hCpIO}zvfvw-clwY60X
zUYK=e_V54i(^V&%BAC;CcIlbwok%H7fF0Zf1RwwqfB--M0ssLB00bZaG86DxJP?<;
zVKxGeQh$6C8)A+dXCq)Ry5c}Aa06`w43GEZseJ+6bn*Bqo{=Xz0puwY0mI{+xKEz!
z1dykO1RSSkMo;8Ed9o8go-z_Zo<<OGlG-1GJl#fsjetMp=@J5L1PsO(u`Xs2U^_zR
zsmevCDWCCH+>4YaZvw*Q$*X|jJas(hsmet^laJvtPmu(;%u_@GuJROFfQvj;xhT@;
z<>_foc`8l7`8?f1K;d~p!0&mQK|n!yLV$6es$6tMTo+5?vDg+b#K)GOmKBkwx_@9&
zTorf3L$N6iQ~!;*??Lml*JPgBZd~Nm^G2-H&6DMK;3%u7R-SU+sPeXY26>u~BEa+N
zshp>%54&?&J)gzezw%V#%TN}p=jd;FDpkNWu_zviE%97@5I<TJuq$qsl%N}8Sv(Ot
z;-&axkf2pD9q~hW+_QMp58=CF%KO*Q9A<It%;fx!SkAM!v2QxoTM?dS@&9DTbSomt
zEFLv8^J&c6(NSmdSTe%{8RH#K1dL%*4FMTv1_8#IL4a{)5ODVCRWCEHUQLYha;{ls
zN)^!f8w?1jo|&xPfG$Nqwwb9b;FQcDz;$LK32>R2x&m@Is-WXJGhPLR$&5Dvz2j;^
zod@ATK<LcW70~vPW#P{R%27a3naM?f`;$$q1a!%a-=mAkjKSgE`((!E_<Ay9@B<DU
zL2UFBCS=Ay0LRc933x?jYy|)U5C8~303ZMXfB*yl0uTTQh`}%A!-1tO8hI)J0000<
KMNUMnLSTYl^*@yW

diff --git a/vector/src/main/res/drawable/ic_add_reaction.xml b/vector/src/main/res/drawable/ic_add_reaction.xml
new file mode 100644
index 00000000..ba33bc3f
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_add_reaction.xml
@@ -0,0 +1,54 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="22dp"
+    android:viewportWidth="24"
+    android:viewportHeight="22">
+  <path
+      android:pathData="m13.5909,20.8117c-0.8681,0.2472 -1.7837,0.3795 -2.7298,0.3795 -5.5574,0 -10.0625,-4.5627 -10.0625,-10.1912 0,-5.6284 4.5051,-10.1912 10.0625,-10.1912 5.4556,0 9.8971,4.3972 10.058,9.8831h-0.9588c-0.1605,-4.9498 -4.1729,-8.9125 -9.0992,-8.9125 -5.0281,0 -9.1042,4.1282 -9.1042,9.2206 0,5.0924 4.0761,9.2206 9.1042,9.2206 0.951,0 1.868,-0.1477 2.7298,-0.4217z"
+      android:strokeLineJoin="round"
+      android:strokeWidth="1.047619"
+      android:fillColor="#00000000"
+      android:fillType="evenOdd"
+      android:strokeColor="#9e9e9e"
+      android:strokeLineCap="round"/>
+  <path
+      android:pathData="m14.6944,16.8235h7.6667"
+      android:strokeLineJoin="round"
+      android:strokeWidth="2.095238"
+      android:fillColor="#00000000"
+      android:fillType="evenOdd"
+      android:strokeColor="#9e9e9e"
+      android:strokeLineCap="round"/>
+  <path
+      android:pathData="m18.5278,12.9412l-0,7.7647"
+      android:strokeLineJoin="round"
+      android:strokeWidth="2.095238"
+      android:fillColor="#00000000"
+      android:fillType="evenOdd"
+      android:strokeColor="#9e9e9e"
+      android:strokeLineCap="round"/>
+  <path
+      android:pathData="m7.0278,12.9412s1.4375,1.9412 3.8333,1.9412c2.3958,0 3.8333,-1.9412 3.8333,-1.9412"
+      android:strokeLineJoin="round"
+      android:strokeWidth="2.095238"
+      android:fillColor="#00000000"
+      android:fillType="evenOdd"
+      android:strokeColor="#9e9e9e"
+      android:strokeLineCap="round"/>
+  <path
+      android:pathData="m7.9861,8.0882h0.0096"
+      android:strokeLineJoin="round"
+      android:strokeWidth="2.095238"
+      android:fillColor="#00000000"
+      android:fillType="evenOdd"
+      android:strokeColor="#9e9e9e"
+      android:strokeLineCap="round"/>
+  <path
+      android:pathData="m13.7361,8.0882h0.0096"
+      android:strokeLineJoin="round"
+      android:strokeWidth="2.095238"
+      android:fillColor="#00000000"
+      android:fillType="evenOdd"
+      android:strokeColor="#9e9e9e"
+      android:strokeLineCap="round"/>
+</vector>
diff --git a/vector/src/main/res/drawable/ic_attachment.xml b/vector/src/main/res/drawable/ic_attachment.xml
new file mode 100644
index 00000000..e54b9302
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_attachment.xml
@@ -0,0 +1,14 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="21dp"
+    android:height="22dp"
+    android:viewportWidth="21"
+    android:viewportHeight="22">
+  <path
+      android:pathData="M19.468,10.571l-8.73,8.753a5.693,5.693 0,0 1,-8.066 0,5.728 5.728,0 0,1 0,-8.086l8.73,-8.752a3.795,3.795 0,0 1,5.378 0,3.818 3.818,0 0,1 0,5.39L8.04,16.63a1.898,1.898 0,0 1,-2.689 0,1.91 1.91,0 0,1 0,-2.696l8.065,-8.076"
+      android:strokeLineJoin="round"
+      android:strokeWidth="2"
+      android:fillColor="#00000000"
+      android:fillType="evenOdd"
+      android:strokeColor="#9E9E9E"
+      android:strokeLineCap="round"/>
+</vector>
diff --git a/vector/src/main/res/drawable/ic_close_round.xml b/vector/src/main/res/drawable/ic_close_round.xml
new file mode 100644
index 00000000..413a233b
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_close_round.xml
@@ -0,0 +1,20 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="22dp"
+    android:height="22dp"
+    android:viewportWidth="22"
+    android:viewportHeight="22">
+  <path
+      android:pathData="M11,11m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
+      android:strokeWidth="2"
+      android:fillColor="#00000000"
+      android:strokeColor="#979797"
+      android:fillType="evenOdd"/>
+  <path
+      android:pathData="M7.667,7.667L14.333,14.333M14.333,7.667L7.667,14.333"
+      android:strokeLineJoin="round"
+      android:strokeWidth="2"
+      android:fillColor="#00000000"
+      android:strokeColor="#9E9E9E"
+      android:fillType="evenOdd"
+      android:strokeLineCap="round"/>
+</vector>
diff --git a/vector/src/main/res/drawable/ic_smile.xml b/vector/src/main/res/drawable/ic_delete.xml
similarity index 51%
rename from vector/src/main/res/drawable/ic_smile.xml
rename to vector/src/main/res/drawable/ic_delete.xml
index e2f3402e..b740db3c 100644
--- a/vector/src/main/res/drawable/ic_smile.xml
+++ b/vector/src/main/res/drawable/ic_delete.xml
@@ -4,31 +4,19 @@
     android:viewportWidth="22"
     android:viewportHeight="22">
   <path
-      android:pathData="M11,11m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
+      android:pathData="M3.222,1L18.778,1A2.222,2.222 0,0 1,21 3.222L21,18.778A2.222,2.222 0,0 1,18.778 21L3.222,21A2.222,2.222 0,0 1,1 18.778L1,3.222A2.222,2.222 0,0 1,3.222 1z"
       android:strokeLineJoin="round"
       android:strokeWidth="2"
       android:fillColor="#00000000"
-      android:strokeColor="#9E9E9E"
       android:fillType="evenOdd"
+      android:strokeColor="#9E9E9E"
       android:strokeLineCap="round"/>
   <path
-      android:pathData="M7,13C7,13 8.5,15 11,15C13.5,15 15,13 15,13"
+      android:pathData="M7.667,7.667l6.666,6.666M14.333,7.667l-6.666,6.666"
       android:strokeLineJoin="round"
       android:strokeWidth="2"
       android:fillColor="#00000000"
+      android:fillType="evenOdd"
       android:strokeColor="#9E9E9E"
-      android:fillType="evenOdd"
       android:strokeLineCap="round"/>
-  <path
-      android:pathData="M7.5,7.5m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"
-      android:strokeWidth="1"
-      android:fillColor="#9E9E9E"
-      android:fillType="evenOdd"
-      android:strokeColor="#00000000"/>
-  <path
-      android:pathData="M14.5,7.5m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"
-      android:strokeWidth="1"
-      android:fillColor="#9E9E9E"
-      android:fillType="evenOdd"
-      android:strokeColor="#00000000"/>
 </vector>
diff --git a/vector/src/main/res/drawable/ic_edit.xml b/vector/src/main/res/drawable/ic_edit.xml
index ec5cf418..1ad914fc 100644
--- a/vector/src/main/res/drawable/ic_edit.xml
+++ b/vector/src/main/res/drawable/ic_edit.xml
@@ -4,19 +4,19 @@
     android:viewportWidth="21"
     android:viewportHeight="22">
   <path
-      android:pathData="M9.497,3.06H2.888C1.845,3.06 1,3.93 1,5v13.576c0,1.07 0.845,1.94 1.888,1.94h13.218c1.042,0 1.888,-0.87 1.888,-1.94v-6.788"
+      android:pathData="M9.4969,3.0606L2.8882,3.0606C1.8454,3.0606 1,3.9289 1,5L1,18.5758C1,19.6469 1.8454,20.5152 2.8882,20.5152L16.1056,20.5152C17.1484,20.5152 17.9938,19.6469 17.9938,18.5758L17.9938,11.7879"
       android:strokeLineJoin="round"
       android:strokeWidth="2"
       android:fillColor="#00000000"
-      android:fillType="evenOdd"
       android:strokeColor="#9E9E9E"
+      android:fillType="evenOdd"
       android:strokeLineCap="round"/>
   <path
-      android:pathData="M16.578,1.606a1.966,1.966 0,0 1,2.832 0,2.097 2.097,0 0,1 0,2.91l-8.969,9.211 -3.776,0.97 0.944,-3.879 8.969,-9.212z"
+      android:pathData="M16.5776,1.6061C17.3598,0.8027 18.6278,0.8027 19.4099,1.6061C20.1921,2.4094 20.1921,3.7118 19.4099,4.5152L10.441,13.7273L6.6646,14.697L7.6087,10.8182L16.5776,1.6061Z"
       android:strokeLineJoin="round"
       android:strokeWidth="2"
       android:fillColor="#00000000"
-      android:fillType="evenOdd"
       android:strokeColor="#9E9E9E"
+      android:fillType="evenOdd"
       android:strokeLineCap="round"/>
 </vector>
diff --git a/vector/src/main/res/drawable/ic_send.xml b/vector/src/main/res/drawable/ic_send.xml
new file mode 100644
index 00000000..d79ba7c1
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_send.xml
@@ -0,0 +1,14 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="22dp"
+    android:height="22dp"
+    android:viewportWidth="22"
+    android:viewportHeight="22">
+  <path
+      android:pathData="M20.142,11H4.586M20.142,11L1.05,20.192 4.586,11 1.05,1.808z"
+      android:strokeLineJoin="round"
+      android:strokeWidth="2"
+      android:fillColor="#00000000"
+      android:fillType="evenOdd"
+      android:strokeColor="#03B381"
+      android:strokeLineCap="round"/>
+</vector>
diff --git a/vector/src/main/res/layout/adapter_item_action.xml b/vector/src/main/res/layout/adapter_item_action.xml
index 5ee60d32..ce518071 100644
--- a/vector/src/main/res/layout/adapter_item_action.xml
+++ b/vector/src/main/res/layout/adapter_item_action.xml
@@ -3,7 +3,6 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    tools:layout_height="50dp"
     android:clickable="true"
     android:focusable="true"
     android:foreground="?attr/selectableItemBackground"
@@ -12,7 +11,8 @@
     android:paddingLeft="@dimen/layout_horizontal_margin"
     android:paddingTop="8dp"
     android:paddingRight="@dimen/layout_horizontal_margin"
-    android:paddingBottom="8dp">
+    android:paddingBottom="8dp"
+    tools:layout_height="50dp">
 
     <ImageView
         android:id="@+id/action_icon"
@@ -21,8 +21,8 @@
         android:layout_gravity="center_vertical"
         android:layout_marginEnd="16dp"
         android:layout_marginRight="16dp"
-        android:src="@drawable/ic_material_delete"
-        android:tint="?android:attr/textColorSecondary" />
+        tools:src="@drawable/ic_delete"
+        android:tint="?android:attr/textColorTertiary" />
 
     <TextView
         android:id="@+id/action_title"
diff --git a/vector/src/main/res/layout/constraint_set_composer_layout_compact.xml b/vector/src/main/res/layout/constraint_set_composer_layout_compact.xml
new file mode 100644
index 00000000..8e7c3d85
--- /dev/null
+++ b/vector/src/main/res/layout/constraint_set_composer_layout_compact.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/composerLayout"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    app:layout_constraintBottom_toBottomOf="parent"
+    app:layout_constraintEnd_toEndOf="parent"
+    app:layout_constraintStart_toStartOf="parent">
+
+    <View
+        android:id="@+id/related_message_backround"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="?vctr_bottom_nav_background_color"
+        app:layout_constraintBottom_toTopOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        tools:layout_height="40dp" />
+
+    <View
+        android:id="@+id/related_message_background_top_separator"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="?vctr_bottom_nav_background_border_color"
+        app:layout_constraintBottom_toTopOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+    <View
+        android:id="@+id/related_message_background_bottom_separator"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="?vctr_bottom_nav_background_border_color"
+        app:layout_constraintBottom_toTopOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+    <TextView
+        android:id="@+id/composer_related_message_sender"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:textStyle="bold"
+        android:visibility="invisible"
+        app:layout_constraintBottom_toTopOf="@id/composer_related_message_preview"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        tools:text="@tools:sample/first_names" />
+
+    <TextView
+        android:id="@+id/composer_related_message_preview"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:visibility="invisible"
+        app:layout_constraintBottom_toTopOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        tools:text="@tools:sample/lorem/random" />
+
+    <ImageView
+        android:id="@+id/composer_related_message_action_image"
+        android:layout_width="20dp"
+        android:layout_height="20dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="38dp"
+        android:alpha="0"
+        android:tint="?android:attr/textColorTertiary"
+        app:layout_constraintEnd_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="parent"
+        tools:ignore="MissingConstraints"
+        tools:src="@drawable/ic_edit" />
+
+
+    <ImageButton
+        android:id="@+id/composer_related_message_close"
+        android:layout_width="22dp"
+        android:layout_height="22dp"
+        android:background="?android:attr/selectableItemBackground"
+        android:src="@drawable/ic_close_round"
+        android:tint="@color/rosy_pink"
+        app:layout_constraintBottom_toTopOf="parent"
+        app:layout_constraintStart_toEndOf="parent" />
+
+    <ImageView
+        android:id="@+id/composer_avatar_view"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:layout_marginStart="8dp"
+        android:layout_marginLeft="8dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginEnd="8dp"
+        android:layout_marginRight="8dp"
+        android:layout_marginBottom="8dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/composerEditText"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="1"
+        tools:src="@tools:sample/avatars" />
+
+    <ImageButton
+        android:id="@+id/attachmentButton"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:background="?android:attr/selectableItemBackground"
+        android:src="@drawable/ic_attachment"
+        android:tint="?attr/colorAccent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/sendButton"
+        app:layout_constraintStart_toEndOf="@id/composerEditText" />
+
+    <androidx.constraintlayout.widget.Barrier
+        android:id="@+id/composer_preview_barrier"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:barrierDirection="bottom"
+        app:barrierMargin="8dp"
+        app:constraint_referenced_ids="composer_related_message_preview,composer_related_message_action_image"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+    <ImageButton
+        android:id="@+id/sendButton"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:background="?android:attr/selectableItemBackground"
+        android:src="@drawable/ic_send"
+        android:tint="?attr/colorAccent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/attachmentButton" />
+
+    <EditText
+        android:id="@+id/composerEditText"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:background="@android:color/transparent"
+        android:hint="@string/room_message_placeholder_not_encrypted"
+        android:maxHeight="200dp"
+        android:minHeight="48dp"
+        android:nextFocusLeft="@id/composerEditText"
+        android:nextFocusUp="@id/composerEditText"
+        android:padding="16dp"
+        android:textSize="14sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/attachmentButton"
+        app:layout_constraintStart_toEndOf="@+id/composer_avatar_view"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="@tools:sample/lorem/random" />
+    <!--tools:text="@tools:sample/lorem/random"-->
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/vector/src/main/res/layout/constraint_set_composer_layout_expanded.xml b/vector/src/main/res/layout/constraint_set_composer_layout_expanded.xml
new file mode 100644
index 00000000..9a354fc2
--- /dev/null
+++ b/vector/src/main/res/layout/constraint_set_composer_layout_expanded.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/composerLayout"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    app:layout_constraintBottom_toBottomOf="parent"
+    app:layout_constraintEnd_toEndOf="parent"
+    app:layout_constraintStart_toStartOf="parent">
+
+    <View
+        android:id="@+id/related_message_backround"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:background="?vctr_bottom_nav_background_color"
+        app:layout_constraintBottom_toBottomOf="@id/composer_preview_barrier"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <View
+        android:id="@+id/related_message_background_top_separator"
+        android:layout_width="0dp"
+        android:layout_height="1dp"
+        android:background="?vctr_bottom_nav_background_border_color"
+        app:layout_constraintTop_toTopOf="@id/related_message_backround"
+        app:layout_constraintEnd_toEndOf="@id/related_message_backround"
+        app:layout_constraintStart_toStartOf="@+id/related_message_backround" />
+
+    <View
+        android:id="@+id/related_message_background_bottom_separator"
+        android:layout_width="0dp"
+        android:layout_height="1dp"
+        android:background="?vctr_bottom_nav_background_border_color"
+        app:layout_constraintBottom_toBottomOf="@id/related_message_backround"
+        app:layout_constraintEnd_toEndOf="@id/related_message_backround"
+        app:layout_constraintStart_toStartOf="@+id/related_message_backround" />
+
+    <TextView
+        android:id="@+id/composer_related_message_sender"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_margin="8dp"
+        android:textStyle="bold"
+        app:layout_constraintEnd_toStartOf="@id/composer_related_message_close"
+        app:layout_constraintStart_toEndOf="@id/composer_avatar_view"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="@tools:sample/first_names" />
+
+    <TextView
+        android:id="@+id/composer_related_message_preview"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:ellipsize="end"
+        android:maxLines="2"
+        android:textColor="?vctr_message_text_color"
+        app:layout_constrainedHeight="true"
+        app:layout_constraintEnd_toEndOf="@id/composer_related_message_sender"
+        app:layout_constraintStart_toStartOf="@id/composer_related_message_sender"
+        app:layout_constraintTop_toBottomOf="@id/composer_related_message_sender"
+        tools:text="@tools:sample/lorem/random" />
+
+    <ImageView
+        android:id="@+id/composer_related_message_action_image"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_marginTop="6dp"
+        android:layout_marginBottom="38dp"
+        android:alpha="1"
+        android:tint="?android:attr/textColorTertiary"
+        android:visibility="visible"
+        app:layout_constraintEnd_toEndOf="@id/composer_avatar_view"
+        app:layout_constraintStart_toStartOf="@id/composer_avatar_view"
+        app:layout_constraintTop_toBottomOf="@id/composer_avatar_view"
+        tools:src="@drawable/ic_edit" />
+
+
+    <ImageButton
+        android:id="@+id/composer_related_message_close"
+        android:layout_width="22dp"
+        android:layout_height="22dp"
+        android:layout_marginEnd="8dp"
+        android:layout_marginRight="8dp"
+        android:background="?android:attr/selectableItemBackground"
+        android:src="@drawable/ic_close_round"
+        android:tint="@color/rosy_pink"
+        app:layout_constraintBottom_toBottomOf="@id/composer_related_message_preview"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="@id/composer_related_message_preview" />
+
+
+    <ImageView
+        android:id="@+id/composer_avatar_view"
+        android:layout_width="40dp"
+        android:layout_height="40dp"
+        android:layout_marginStart="8dp"
+        android:layout_marginLeft="8dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="8dp"
+        app:layout_constraintBottom_toTopOf="@id/composer_related_message_action_image"
+        app:layout_constraintEnd_toStartOf="@+id/composer_related_message_sender"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="@id/composer_related_message_sender"
+        tools:src="@tools:sample/avatars" />
+
+
+    <ImageButton
+        android:id="@+id/attachmentButton"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:background="?android:attr/selectableItemBackground"
+        android:src="@drawable/ic_attachment"
+        android:tint="?attr/colorAccent"
+        app:layout_constraintEnd_toStartOf="@+id/sendButton"
+        app:layout_constraintTop_toBottomOf="parent" />
+
+    <androidx.constraintlayout.widget.Barrier
+        android:id="@+id/composer_preview_barrier"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:barrierDirection="bottom"
+        app:barrierMargin="8dp"
+        app:constraint_referenced_ids="composer_related_message_preview,composer_related_message_action_image"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+    <ImageButton
+        android:id="@+id/sendButton"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:background="?android:attr/selectableItemBackground"
+        android:src="@drawable/ic_send"
+        android:tint="?attr/colorAccent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/composerEditText"
+        app:layout_constraintTop_toBottomOf="@id/composer_preview_barrier"
+        app:layout_constraintVertical_bias="1" />
+
+    <EditText
+        android:id="@+id/composerEditText"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:background="@android:color/transparent"
+        android:hint="@string/room_message_placeholder_not_encrypted"
+        android:minHeight="48dp"
+        android:nextFocusLeft="@id/composerEditText"
+        android:nextFocusUp="@id/composerEditText"
+        android:padding="16dp"
+        android:textSize="14sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/sendButton"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/composer_preview_barrier"
+        tools:text="@tools:sample/lorem" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/vector/src/main/res/layout/fragment_room_detail.xml b/vector/src/main/res/layout/fragment_room_detail.xml
index a5711bce..0f631722 100644
--- a/vector/src/main/res/layout/fragment_room_detail.xml
+++ b/vector/src/main/res/layout/fragment_room_detail.xml
@@ -2,6 +2,7 @@
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/rootConstraintLayout"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
@@ -89,66 +90,18 @@
         android:background="?vctr_list_divider_color"
         app:layout_constraintBottom_toTopOf="@+id/composerLayout" />
 
-    <RelativeLayout
-        android:id="@+id/composerLayout"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent">
-
-        <ImageButton
-            android:id="@+id/attachmentButton"
-            android:layout_width="48dp"
-            android:layout_height="48dp"
-            android:layout_centerVertical="true"
-            android:layout_toStartOf="@id/sendButton"
-            android:layout_toLeftOf="@id/sendButton"
-            android:background="?android:attr/selectableItemBackground"
-            android:src="@drawable/ic_attach_file_white"
-            android:tint="?attr/colorAccent" />
-
-        <ImageButton
-            android:id="@+id/sendButton"
-            android:layout_width="48dp"
-            android:layout_height="48dp"
-            android:layout_alignParentEnd="true"
-            android:layout_alignParentRight="true"
-            android:layout_centerVertical="true"
-            android:background="?android:attr/selectableItemBackground"
-            android:src="@drawable/ic_send_white"
-            android:tint="?attr/colorAccent" />
-
-        <EditText
-            android:id="@+id/composerEditText"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentStart="true"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true"
-            android:layout_toStartOf="@id/attachmentButton"
-            android:layout_toLeftOf="@id/attachmentButton"
-            android:background="@android:color/transparent"
-            android:gravity="center_vertical"
-            android:hint="@string/room_message_placeholder_not_encrypted"
-            android:minHeight="48dp"
-            android:nextFocusLeft="@id/composerEditText"
-            android:nextFocusUp="@id/composerEditText"
-            android:padding="16dp"
-            android:textSize="14sp" />
-
-    </RelativeLayout>
+    <include layout="@layout/include_composer_layout" />
 
     <im.vector.riotredesign.features.invite.VectorInviteView
         android:id="@+id/inviteView"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:visibility="gone"
-        tools:visibility="visible"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@+id/toolbar"
-        app:layout_constraintVertical_bias="1.0" />
+        app:layout_constraintVertical_bias="1.0"
+        tools:visibility="gone" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/vector/src/main/res/layout/include_composer_layout.xml b/vector/src/main/res/layout/include_composer_layout.xml
new file mode 100644
index 00000000..655691e9
--- /dev/null
+++ b/vector/src/main/res/layout/include_composer_layout.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/composerLayout"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    app:constraintSet="@layout/constraint_set_composer_layout_compact"
+    app:layout_constraintBottom_toBottomOf="parent"
+    app:layout_constraintEnd_toEndOf="parent"
+    app:layout_constraintStart_toStartOf="parent">
+
+    <!-- ========================
+        /!\ Constraints for this layout are defined in external layout files that are used as constraint set for animation.
+        /!\ These 3 files must be modified to stay coherent!
+    ======================== -->
+    <View
+        android:id="@+id/related_message_backround"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="?vctr_bottom_nav_background_color"
+        tools:ignore="MissingConstraints" />
+
+    <View
+        android:id="@+id/related_message_background_top_separator"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="?vctr_bottom_nav_background_border_color"
+        tools:ignore="MissingConstraints" />
+
+    <View
+        android:id="@+id/related_message_background_bottom_separator"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="?vctr_bottom_nav_background_border_color"
+        tools:ignore="MissingConstraints" />
+
+    <TextView
+        android:id="@+id/composer_related_message_sender"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:textStyle="bold"
+        tools:ignore="MissingConstraints"
+        tools:text="@tools:sample/first_names"
+        tools:visibility="gone" />
+
+    <TextView
+        android:id="@+id/composer_related_message_preview"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:ellipsize="end"
+        android:maxLines="3"
+        android:textColor="?vctr_message_text_color"
+        tools:ignore="MissingConstraints"
+        tools:text="@tools:sample/lorem"
+        tools:visibility="gone" />
+
+    <ImageView
+        android:id="@+id/composer_related_message_action_image"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:tint="?android:attr/textColorTertiary"
+        tools:ignore="MissingConstraints" />
+
+    <ImageButton
+        android:id="@+id/composer_related_message_close"
+        android:layout_width="22dp"
+        android:layout_height="22dp"
+        android:background="?android:attr/selectableItemBackground"
+        android:src="@drawable/ic_close_round"
+        android:tint="@color/rosy_pink"
+        tools:ignore="MissingConstraints" />
+
+
+    <ImageView
+        android:id="@+id/composer_avatar_view"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        tools:ignore="MissingConstraints"
+        tools:src="@tools:sample/avatars" />
+
+    <ImageButton
+        android:id="@+id/attachmentButton"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="?android:attr/selectableItemBackground"
+        android:src="@drawable/ic_attachment"
+        android:tint="?attr/colorAccent"
+        tools:ignore="MissingConstraints" />
+
+    <androidx.constraintlayout.widget.Barrier
+        android:id="@+id/composer_preview_barrier"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:barrierDirection="bottom"
+        app:barrierMargin="8dp"
+        app:constraint_referenced_ids="composer_related_message_preview,composer_related_message_action_image"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+    <ImageButton
+        android:id="@+id/sendButton"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="?android:attr/selectableItemBackground"
+        android:src="@drawable/ic_send"
+        android:tint="?attr/colorAccent"
+        tools:ignore="MissingConstraints" />
+
+    <EditText
+        android:id="@+id/composerEditText"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:background="@android:color/transparent"
+        android:hint="@string/room_message_placeholder_not_encrypted"
+        android:nextFocusLeft="@id/composerEditText"
+        android:nextFocusUp="@id/composerEditText"
+        android:padding="8dp"
+        android:textColor="?vctr_message_text_color"
+        android:textSize="14sp"
+        tools:ignore="MissingConstraints" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/vector/src/main/res/values/attrs.xml b/vector/src/main/res/values/attrs.xml
index 17cb3d75..04c959ee 100644
--- a/vector/src/main/res/values/attrs.xml
+++ b/vector/src/main/res/values/attrs.xml
@@ -4,6 +4,7 @@
     <declare-styleable name="VectorStyles">
 
         <attr name="vctr_bottom_nav_background_color" format="color" />
+        <attr name="vctr_bottom_nav_background_border_color" format="color" />
 
         <!-- waiting view background -->
         <attr name="vctr_waiting_background_color" format="color" />
diff --git a/vector/src/main/res/values/colors_riot.xml b/vector/src/main/res/values/colors_riot.xml
index f60d4991..395ebbce 100644
--- a/vector/src/main/res/values/colors_riot.xml
+++ b/vector/src/main/res/values/colors_riot.xml
@@ -19,6 +19,7 @@
     <color name="tab_rooms">@color/accent_color_light</color>
     <color name="tab_rooms_secondary">#5EA584</color>
     <color name="tab_groups">#a6d0e5</color>
+
     <color name="tab_groups_secondary">#81bddb</color>
 
     <!-- color of the direct chat avatar ring (it's 50% of color accent) -->
diff --git a/vector/src/main/res/values/theme_black.xml b/vector/src/main/res/values/theme_black.xml
index f816b9be..dabd32ae 100644
--- a/vector/src/main/res/values/theme_black.xml
+++ b/vector/src/main/res/values/theme_black.xml
@@ -27,6 +27,7 @@
         <!-- activities background -->
         <item name="android:windowBackground">@color/riot_primary_background_color_black</item>
         <item name="vctr_bottom_nav_background_color">@color/primary_color_black</item>
+        <item name="vctr_bottom_nav_background_border_color">#FFE9EDF1</item>
 
         <item name="vctr_direct_chat_circle">@drawable/direct_chat_circle_black</item>
     </style>
diff --git a/vector/src/main/res/values/theme_dark.xml b/vector/src/main/res/values/theme_dark.xml
index 5c1a506e..ba78e510 100644
--- a/vector/src/main/res/values/theme_dark.xml
+++ b/vector/src/main/res/values/theme_dark.xml
@@ -21,6 +21,7 @@
         <!-- default background color -->
         <item name="android:colorBackground">@color/riot_primary_background_color_dark</item>
         <item name="vctr_bottom_nav_background_color">@color/primary_color_dark</item>
+        <item name="vctr_bottom_nav_background_border_color">#FFE9EDF1</item>
 
         <!-- waiting view background -->
         <item name="vctr_waiting_background_color">#55555555</item>
diff --git a/vector/src/main/res/values/theme_light.xml b/vector/src/main/res/values/theme_light.xml
index 68076a4b..e0b58bf0 100644
--- a/vector/src/main/res/values/theme_light.xml
+++ b/vector/src/main/res/values/theme_light.xml
@@ -23,6 +23,7 @@
         <!-- default background color -->
         <item name="android:colorBackground">@color/riot_primary_background_color_light</item>
         <item name="vctr_bottom_nav_background_color">#FFF3F8FD</item>
+        <item name="vctr_bottom_nav_background_border_color">#FFE9EDF1</item>
 
         <!-- default button -->
         <item name="android:buttonStyle">@style/Widget.Vector.Button</item>
diff --git a/vector/src/main/res/values/theme_status.xml b/vector/src/main/res/values/theme_status.xml
index d2874e69..9a50b88d 100644
--- a/vector/src/main/res/values/theme_status.xml
+++ b/vector/src/main/res/values/theme_status.xml
@@ -23,6 +23,7 @@
         <item name="android:colorBackground">@color/riot_primary_background_color_status</item>
         <item name="vctr_bottom_nav_background_color">@color/riot_primary_background_color_status
         </item>
+        <item name="vctr_bottom_nav_background_border_color">#FFE9EDF1</item>
 
         <item name="buttonStyle">@style/Widget.Vector.Button</item>