diff --git a/newsfragment/3182.feature b/newsfragment/3182.feature
new file mode 100644
index 0000000000..83eee3c29c
--- /dev/null
+++ b/newsfragment/3182.feature
@@ -0,0 +1 @@
+Update Message Composer design
\ No newline at end of file
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt
index ea28a0901b..9ed4feebc4 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt
@@ -547,15 +547,15 @@ class RoomDetailFragment @Inject constructor(
.fromRootView(views.rootConstraintLayout)
.setKeyboardAnimationStyle(R.style.emoji_fade_animation_style)
.setOnEmojiPopupShownListener {
- views.composerLayout.views.composerEmojiButton.let {
- it.setImageResource(R.drawable.ic_keyboard)
- it.contentDescription = getString(R.string.a11y_close_emoji_picker)
+ views.composerLayout.views.composerEmojiButton.apply {
+ contentDescription = getString(R.string.a11y_close_emoji_picker)
+ setImageResource(R.drawable.ic_keyboard)
}
}
.setOnEmojiPopupDismissListener {
- views.composerLayout.views.composerEmojiButton.let {
- it.setImageResource(R.drawable.ic_insert_emoji)
- it.contentDescription = getString(R.string.a11y_open_emoji_picker)
+ views.composerLayout.views.composerEmojiButton.apply {
+ contentDescription = getString(R.string.a11y_open_emoji_picker)
+ setImageResource(R.drawable.ic_insert_emoji)
}
}
.build(views.composerLayout.views.composerEditText)
@@ -1188,6 +1188,10 @@ class RoomDetailFragment @Inject constructor(
override fun onRichContentSelected(contentUri: Uri): Boolean {
return sendUri(contentUri)
}
+
+ override fun onTextEmptyStateChanged(isEmpty: Boolean) {
+ // No op
+ }
}
}
@@ -1201,6 +1205,7 @@ class RoomDetailFragment @Inject constructor(
views.composerLayout.collapse(true)
lockSendButton = true
roomDetailViewModel.handle(RoomDetailAction.SendMessage(text, vectorPreferences.isMarkdownEnabled()))
+ emojiPopup.dismiss()
}
}
@@ -1250,7 +1255,7 @@ class RoomDetailFragment @Inject constructor(
if (state.tombstoneEvent == null) {
if (state.canSendMessage) {
views.composerLayout.visibility = View.VISIBLE
- views.composerLayout.setRoomEncrypted(summary.isEncrypted, summary.roomEncryptionTrustLevel)
+ views.composerLayout.setRoomEncrypted(summary.isEncrypted)
views.notificationAreaView.render(NotificationAreaView.State.Hidden)
} else {
views.composerLayout.visibility = View.GONE
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt
index 45c937ca5e..2a2ae56c4c 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt
@@ -37,9 +37,11 @@ class ComposerEditText @JvmOverloads constructor(context: Context, attrs: Attrib
interface Callback {
fun onRichContentSelected(contentUri: Uri): Boolean
+ fun onTextEmptyStateChanged(isEmpty: Boolean)
}
var callback: Callback? = null
+ private var isEmptyText = true
override fun onCreateInputConnection(editorInfo: EditorInfo): InputConnection? {
val ic = super.onCreateInputConnection(editorInfo) ?: return null
@@ -93,6 +95,11 @@ class ComposerEditText @JvmOverloads constructor(context: Context, attrs: Attrib
}
spanToRemove = null
}
+ // Report blank status of EditText to be able to arrange other elements of the composer
+ if (s.isEmpty() != isEmptyText) {
+ isEmptyText = !isEmptyText
+ callback?.onTextEmptyStateChanged(isEmptyText)
+ }
}
}
)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt
index 6c7721ca02..d5e24dbb6b 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt
@@ -24,6 +24,7 @@ import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.text.toSpannable
+import androidx.core.view.isVisible
import androidx.transition.ChangeBounds
import androidx.transition.Fade
import androidx.transition.Transition
@@ -32,8 +33,6 @@ import androidx.transition.TransitionSet
import im.vector.app.R
import im.vector.app.databinding.ComposerLayoutBinding
-import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel
-
/**
* Encapsulate the timeline composer UX.
*
@@ -70,6 +69,10 @@ class TextComposerView @JvmOverloads constructor(
override fun onRichContentSelected(contentUri: Uri): Boolean {
return callback?.onRichContentSelected(contentUri) ?: false
}
+
+ override fun onTextEmptyStateChanged(isEmpty: Boolean) {
+ views.sendButton.isVisible = currentConstraintSetId == R.layout.composer_layout_constraint_set_expanded || !isEmpty
+ }
}
views.composerRelatedMessageCloseButton.setOnClickListener {
collapse()
@@ -93,6 +96,7 @@ class TextComposerView @JvmOverloads constructor(
}
currentConstraintSetId = R.layout.composer_layout_constraint_set_compact
applyNewConstraintSet(animate, transitionComplete)
+ views.sendButton.isVisible = !views.composerEditText.text.isNullOrEmpty()
}
fun expand(animate: Boolean = true, transitionComplete: (() -> Unit)? = null) {
@@ -102,6 +106,7 @@ class TextComposerView @JvmOverloads constructor(
}
currentConstraintSetId = R.layout.composer_layout_constraint_set_expanded
applyNewConstraintSet(animate, transitionComplete)
+ views.sendButton.isVisible = true
}
private fun applyNewConstraintSet(animate: Boolean, transitionComplete: (() -> Unit)?) {
@@ -110,8 +115,6 @@ class TextComposerView @JvmOverloads constructor(
}
ConstraintSet().also {
it.clone(context, currentConstraintSetId)
- // in case shield is hidden, we will have glitch without this
- it.getConstraint(R.id.composerShieldImageView).propertySet.visibility = views.composerShieldImageView.visibility
it.applyTo(this)
}
}
@@ -139,13 +142,11 @@ class TextComposerView @JvmOverloads constructor(
TransitionManager.beginDelayedTransition((parent as? ViewGroup ?: this), transition)
}
- fun setRoomEncrypted(isEncrypted: Boolean, roomEncryptionTrustLevel: RoomEncryptionTrustLevel?) {
+ fun setRoomEncrypted(isEncrypted: Boolean) {
if (isEncrypted) {
views.composerEditText.setHint(R.string.room_message_placeholder)
- views.composerShieldImageView.render(roomEncryptionTrustLevel)
} else {
views.composerEditText.setHint(R.string.room_message_placeholder)
- views.composerShieldImageView.render(null)
}
}
}
diff --git a/vector/src/main/res/drawable/bg_composer_edit_text.xml b/vector/src/main/res/drawable/bg_composer_edit_text.xml
new file mode 100644
index 0000000000..8398fb3dc3
--- /dev/null
+++ b/vector/src/main/res/drawable/bg_composer_edit_text.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/drawable/ic_attachment.xml b/vector/src/main/res/drawable/ic_attachment.xml
index ea01e94372..8f2deff482 100644
--- a/vector/src/main/res/drawable/ic_attachment.xml
+++ b/vector/src/main/res/drawable/ic_attachment.xml
@@ -3,19 +3,19 @@
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
-
-
-
+
+
+
diff --git a/vector/src/main/res/drawable/ic_insert_emoji.xml b/vector/src/main/res/drawable/ic_insert_emoji.xml
index c35000342b..ed1a94c2ff 100644
--- a/vector/src/main/res/drawable/ic_insert_emoji.xml
+++ b/vector/src/main/res/drawable/ic_insert_emoji.xml
@@ -1,21 +1,15 @@
-
-
-
-
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+
+
+
diff --git a/vector/src/main/res/drawable/ic_keyboard.xml b/vector/src/main/res/drawable/ic_keyboard.xml
index 5e5d431abb..c83c8d9ea7 100644
--- a/vector/src/main/res/drawable/ic_keyboard.xml
+++ b/vector/src/main/res/drawable/ic_keyboard.xml
@@ -1,4 +1,9 @@
-
-
+
+
diff --git a/vector/src/main/res/layout/composer_layout.xml b/vector/src/main/res/layout/composer_layout.xml
index 25347d1bf9..3816c206b4 100644
--- a/vector/src/main/res/layout/composer_layout.xml
+++ b/vector/src/main/res/layout/composer_layout.xml
@@ -25,13 +25,6 @@
android:background="?vctr_list_separator"
tools:ignore="MissingConstraints" />
-
-
-
+ android:background="@drawable/bg_composer_edit_text" />
+ app:tint="?vctr_content_tertiary"
+ tools:ignore="MissingConstraints,MissingPrefix" />
-
-
-
-
+
+ app:layout_constraintTop_toTopOf="@id/attachmentButton"
+ app:layout_goneMarginEnd="8dp"
+ app:tint="?vctr_content_quaternary"
+ tools:ignore="MissingPrefix" />
+ tools:ignore="MissingPrefix"
+ tools:visibility="visible" />
\ No newline at end of file
diff --git a/vector/src/main/res/layout/composer_layout_constraint_set_expanded.xml b/vector/src/main/res/layout/composer_layout_constraint_set_expanded.xml
index ff2a67f4f8..4c5034ed96 100644
--- a/vector/src/main/res/layout/composer_layout_constraint_set_expanded.xml
+++ b/vector/src/main/res/layout/composer_layout_constraint_set_expanded.xml
@@ -26,15 +26,6 @@
app:layout_constraintStart_toStartOf="@+id/related_message_background"
app:layout_constraintTop_toTopOf="@id/related_message_background" />
-
-
-
+ app:layout_constraintTop_toBottomOf="@id/composer_preview_barrier"
+ app:layout_goneMarginEnd="12dp" />
+ app:layout_goneMarginBottom="52dp"
+ app:layout_goneMarginEnd="8dp"
+ app:tint="?vctr_content_quaternary"
+ tools:ignore="MissingPrefix" />
+ tools:ignore="MissingPrefix"
+ tools:visibility="visible" />
\ 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 1d6c272a11..ae7494894c 100644
--- a/vector/src/main/res/layout/fragment_room_detail.xml
+++ b/vector/src/main/res/layout/fragment_room_detail.xml
@@ -173,6 +173,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:colorBackground"
+ android:minHeight="56dp"
android:transitionName="composer"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/vector/src/main/res/values/styles_riot.xml b/vector/src/main/res/values/styles_riot.xml
index 5f285a13c7..56f7f95d87 100644
--- a/vector/src/main/res/values/styles_riot.xml
+++ b/vector/src/main/res/values/styles_riot.xml
@@ -225,7 +225,7 @@