From 2f659f613dd030d69c87f41a857a84973c777ab8 Mon Sep 17 00:00:00 2001
From: SpiritCroc <dev@spiritcroc.de>
Date: Tue, 12 May 2020 15:49:43 +0200
Subject: [PATCH] Initial message bubbles

Drawables taken from AOSP Messaging
---
 .../riotx/core/ui/views/WrapWidthTextView.kt  |  37 +++++++++++++++
 .../timeline/factory/MessageItemFactory.kt    |   2 +
 .../detail/timeline/item/MessageTextItem.kt   |  43 ++++++++++++++++++
 .../VectorSettingsPreferencesFragment.kt      |   6 +++
 .../riotx/features/themes/BubbleThemeUtils.kt |  27 +++++++++++
 .../drawable-hdpi/msg_bubble_incoming.9.png   | Bin 0 -> 469 bytes
 .../msg_bubble_incoming.9.png                 | Bin 0 -> 472 bytes
 .../msg_bubble_incoming.9.png                 | Bin 0 -> 344 bytes
 .../msg_bubble_incoming.9.png                 | Bin 0 -> 598 bytes
 .../msg_bubble_incoming.9.png                 | Bin 0 -> 1593 bytes
 .../msg_bubble_incoming.9.png                 | Bin 0 -> 1751 bytes
 .../drawable-mdpi/msg_bubble_incoming.9.png   | Bin 0 -> 339 bytes
 .../drawable-xhdpi/msg_bubble_incoming.9.png  | Bin 0 -> 597 bytes
 .../drawable-xxhdpi/msg_bubble_incoming.9.png | Bin 0 -> 1582 bytes
 .../msg_bubble_incoming.9.png                 | Bin 0 -> 1731 bytes
 .../res/layout/item_timeline_event_base.xml   |   1 +
 .../item_timeline_event_text_message_stub.xml |   4 +-
 vector/src/main/res/values-de/strings_sc.xml  |   5 ++
 vector/src/main/res/values/arrays_sc.xml      |  15 ++++++
 vector/src/main/res/values/attrs_sc.xml       |  11 +++++
 vector/src/main/res/values/strings_sc.xml     |   5 ++
 vector/src/main/res/values/theme_dark.xml     |   3 ++
 vector/src/main/res/values/theme_light.xml    |   3 ++
 vector/src/main/res/values/theme_sc.xml       |   3 ++
 .../res/xml/vector_settings_preferences.xml   |   9 ++++
 25 files changed, 172 insertions(+), 2 deletions(-)
 create mode 100644 vector/src/main/java/im/vector/riotx/core/ui/views/WrapWidthTextView.kt
 create mode 100644 vector/src/main/java/im/vector/riotx/features/themes/BubbleThemeUtils.kt
 create mode 100644 vector/src/main/res/drawable-hdpi/msg_bubble_incoming.9.png
 create mode 100644 vector/src/main/res/drawable-ldrtl-hdpi/msg_bubble_incoming.9.png
 create mode 100644 vector/src/main/res/drawable-ldrtl-mdpi/msg_bubble_incoming.9.png
 create mode 100644 vector/src/main/res/drawable-ldrtl-xhdpi/msg_bubble_incoming.9.png
 create mode 100644 vector/src/main/res/drawable-ldrtl-xxhdpi/msg_bubble_incoming.9.png
 create mode 100644 vector/src/main/res/drawable-ldrtl-xxxhdpi/msg_bubble_incoming.9.png
 create mode 100644 vector/src/main/res/drawable-mdpi/msg_bubble_incoming.9.png
 create mode 100644 vector/src/main/res/drawable-xhdpi/msg_bubble_incoming.9.png
 create mode 100644 vector/src/main/res/drawable-xxhdpi/msg_bubble_incoming.9.png
 create mode 100644 vector/src/main/res/drawable-xxxhdpi/msg_bubble_incoming.9.png
 create mode 100644 vector/src/main/res/values/arrays_sc.xml
 create mode 100644 vector/src/main/res/values/attrs_sc.xml

diff --git a/vector/src/main/java/im/vector/riotx/core/ui/views/WrapWidthTextView.kt b/vector/src/main/java/im/vector/riotx/core/ui/views/WrapWidthTextView.kt
new file mode 100644
index 0000000000..aaf1ee3030
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/core/ui/views/WrapWidthTextView.kt
@@ -0,0 +1,37 @@
+/*
+ * https://stackoverflow.com/questions/7439748/why-is-wrap-content-in-multiple-line-textview-filling-parent
+ */
+
+package im.vector.riotx.core.ui.views;
+
+import android.content.Context
+import android.text.Layout
+import android.util.AttributeSet
+import androidx.appcompat.widget.AppCompatTextView
+import kotlin.math.ceil
+
+class WrapWidthTextView @JvmOverloads constructor(
+        context: Context,
+        attrs: AttributeSet? = null,
+        defStyleAttr: Int = 0
+) : AppCompatTextView(context, attrs, defStyleAttr) {
+
+    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+        val layout = this.layout ?: return
+        val width = ceil(getMaxLineWidth(layout)).toInt() + compoundPaddingLeft + compoundPaddingRight
+        val height = measuredHeight
+        setMeasuredDimension(width, height)
+    }
+
+    private fun getMaxLineWidth(layout: Layout): Float {
+        var maxWidth = 0.0f
+        val lines = layout.lineCount
+        for (i in 0 until lines) {
+            if (layout.getLineWidth(i) > maxWidth) {
+                maxWidth = layout.getLineWidth(i)
+            }
+        }
+        return maxWidth
+    }
+}
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt
index ffb71a38c5..96cfcaf7cd 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt
@@ -397,6 +397,8 @@ class MessageItemFactory @Inject constructor(
                 .leftGuideline(avatarSizeProvider.leftGuideline)
                 .attributes(attributes)
                 .highlighted(highlight)
+                .outgoingMessage(informationData.sentByMe)
+                .incomingMessage(!informationData.sentByMe)
                 .movementMethod(createLinkMovementMethod(callback))
     }
 
diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageTextItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageTextItem.kt
index fabdf22d14..e544576cfb 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageTextItem.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageTextItem.kt
@@ -16,14 +16,24 @@
 
 package im.vector.riotx.features.home.room.detail.timeline.item
 
+import android.content.res.ColorStateList
 import android.text.method.MovementMethod
+import android.view.Gravity
+import android.widget.FrameLayout
 import androidx.appcompat.widget.AppCompatTextView
+import androidx.core.content.ContextCompat
 import androidx.core.text.PrecomputedTextCompat
 import androidx.core.widget.TextViewCompat
 import com.airbnb.epoxy.EpoxyAttribute
 import com.airbnb.epoxy.EpoxyModelClass
 import im.vector.riotx.R
 import im.vector.riotx.features.home.room.detail.timeline.tools.findPillsAndProcess
+import im.vector.riotx.features.themes.BubbleThemeUtils
+import im.vector.riotx.features.themes.BubbleThemeUtils.BUBBLE_STYLE_BOTH
+import im.vector.riotx.features.themes.BubbleThemeUtils.BUBBLE_STYLE_NONE
+import im.vector.riotx.features.themes.BubbleThemeUtils.BUBBLE_STYLE_START
+import im.vector.riotx.features.themes.ThemeUtils
+import kotlin.math.round
 
 @EpoxyModelClass(layout = R.layout.item_timeline_event_base)
 abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
@@ -36,6 +46,10 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
     var useBigFont: Boolean = false
     @EpoxyAttribute
     var movementMethod: MovementMethod? = null
+    @EpoxyAttribute
+    var incomingMessage: Boolean = false
+    @EpoxyAttribute
+    var outgoingMessage: Boolean = false
 
     override fun bind(holder: Holder) {
         super.bind(holder)
@@ -56,6 +70,35 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
                 TextViewCompat.getTextMetricsParams(holder.messageView),
                 null)
         holder.messageView.setTextFuture(textFuture)
+
+        var bubbleStyle = if (incomingMessage || outgoingMessage) BubbleThemeUtils.getBubbleStyle(holder.messageView.context) else BUBBLE_STYLE_NONE
+        when (bubbleStyle) {
+            BUBBLE_STYLE_NONE -> {
+                holder.messageView.background = null
+                holder.messageView.setPadding(0, 0, 0, 0)
+            }
+            BUBBLE_STYLE_START, BUBBLE_STYLE_BOTH -> {
+                holder.messageView.setBackgroundResource(R.drawable.msg_bubble_incoming)
+                var tintColor = ColorStateList(
+                        arrayOf(intArrayOf(0)),
+                        intArrayOf(ThemeUtils.getColor(holder.messageView.context,
+                                if (outgoingMessage) R.attr.sc_message_bg_outgoing else R.attr.sc_message_bg_incoming)
+                        )
+                )
+                holder.messageView.backgroundTintList = tintColor
+                val density = holder.messageView.resources.displayMetrics.density
+                holder.messageView.setPaddingRelative(
+                        round(20*density).toInt(),
+                        round(8*density).toInt(),
+                        round(8*density).toInt(),
+                        round(8*density).toInt()
+                )
+            }
+        }
+        if (holder.messageView.layoutParams is FrameLayout.LayoutParams) {
+            (holder.messageView.layoutParams as FrameLayout.LayoutParams).gravity =
+                    if (outgoingMessage && bubbleStyle == BUBBLE_STYLE_BOTH) Gravity.END else Gravity.START
+        }
     }
 
     override fun getViewType() = STUB_ID
diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt
index 9c240ad093..26f114cd44 100644
--- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt
@@ -28,6 +28,7 @@ import im.vector.riotx.R
 import im.vector.riotx.core.preference.VectorListPreference
 import im.vector.riotx.core.preference.VectorPreference
 import im.vector.riotx.features.configuration.VectorConfiguration
+import im.vector.riotx.features.themes.BubbleThemeUtils
 import im.vector.riotx.features.themes.ThemeUtils
 import javax.inject.Inject
 
@@ -66,6 +67,11 @@ class VectorSettingsPreferencesFragment @Inject constructor(
                 false
             }
         }
+        findPreference<VectorListPreference>(BubbleThemeUtils.BUBBLE_STYLE_KEY)!!
+                .onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, _ ->
+            BubbleThemeUtils.invalidateBubbleStyle()
+            true
+        }
 
         // Url preview
         findPreference<SwitchPreference>(VectorPreferences.SETTINGS_SHOW_URL_PREVIEW_KEY)!!.let {
diff --git a/vector/src/main/java/im/vector/riotx/features/themes/BubbleThemeUtils.kt b/vector/src/main/java/im/vector/riotx/features/themes/BubbleThemeUtils.kt
new file mode 100644
index 0000000000..bf765d0f94
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotx/features/themes/BubbleThemeUtils.kt
@@ -0,0 +1,27 @@
+package im.vector.riotx.features.themes
+
+import android.content.Context
+import androidx.preference.PreferenceManager
+
+/**
+ * Util class for managing themes.
+ */
+object BubbleThemeUtils {
+    const val BUBBLE_STYLE_KEY = "BUBBLE_STYLE_KEY"
+
+    const val BUBBLE_STYLE_NONE = "none"
+    const val BUBBLE_STYLE_START = "start"
+    const val BUBBLE_STYLE_BOTH = "both"
+    private var mBubbleStyle: String = ""
+
+    fun getBubbleStyle(context: Context): String {
+        if (mBubbleStyle == "") {
+            mBubbleStyle = PreferenceManager.getDefaultSharedPreferences(context).getString(BUBBLE_STYLE_KEY, BUBBLE_STYLE_START)!!
+        }
+        return mBubbleStyle
+    }
+
+    fun invalidateBubbleStyle() {
+        mBubbleStyle = ""
+    }
+}
diff --git a/vector/src/main/res/drawable-hdpi/msg_bubble_incoming.9.png b/vector/src/main/res/drawable-hdpi/msg_bubble_incoming.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..7fed0a806a03c789de0b41f502d7ec7db52ca7c3
GIT binary patch
literal 469
zcmV;`0V@89P)<h;3K|Lk000e1NJLTq000~S000{Z1^@s6ZwT)!00004b3#c}2nYxW
zd<bNS00009a7bBm000Y#000Y#0XNCZtpET4cS%G+R7i=v*1t;vVHgMS?+NKChngoG
z-r?flfrB{aQi|Xpx-|wZErDx`LqUH@TTqirfnY%t(kw)hqJv;ilZ3R`x1l2t&93fz
zA9%Kh_w)XEUfvgQKWOE`@Bjdl$x{M!DZj)(;Ekqv!CY>aolanOO1++sns(<RI-8o-
znn&w(m8#lZ8JbQX&u@OUnq)Bex)M;=yNge}T;8JB`|dg@Nz<R(tXSM3@ZmPPtb4)D
z%|o#u38qpf!axAvaOh(!b}bA905%%yRMkgeAONsdOE46A5e5PP^Z9+T;Apf)!?+R#
z0sx!MFr(22VIW|gXE^*U3<LmHDjSsLi7*fVSSoE(lBU8y0AQhT@E_2TN}td6%L0HN
zM@zKKzZ81_NRBu~8QZG!`zHV-=PQgv?rqh@<F|nIYjYHd#F?!+RXulX0Ra1bnYw<n
zv|%)@#dbUJ`)GF2!9Zpvb40^<`o5crGNx%>GMn9-`y#p=OE35*^du8)idcY&00000
LNkvXXu0mjfnCZqY

literal 0
HcmV?d00001

diff --git a/vector/src/main/res/drawable-ldrtl-hdpi/msg_bubble_incoming.9.png b/vector/src/main/res/drawable-ldrtl-hdpi/msg_bubble_incoming.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e7ccc0cc8127bbede5224fea2b375f9b9376fc2
GIT binary patch
literal 472
zcmV;}0Vn>6P)<h;3K|Lk000e1NJLTq000~S000{Z1^@s6ZwT)!00004b3#c}2nYxW
zd<bNS00009a7bBm000Y#000Y#0XNCZtpET4dPzh<R7i=v*1t;vVHgMS=Y%|!L(Nw>
zyu-!80|#-;#T3CobZZP+S_0P=hl2i+wxA}L0>OePqFIO}MF+v4CJAw|Z-aK>kIU=s
zy&ibBhxhZoJkJXck#S&_T*IZG-fH=f&F(?dF5&Zid}|;AmyE~HXbzL*2X2QirYzs1
z(-D8bWb(u@jIlOqH8$TYMQJ;N`Tg&xRN~9iAqW%hnA<%@skFUvavXTwCkln#)sz!p
zCUa!)D;xk5iBkXu9&a!bxk0}#8fkn%#-35HZ~lUD1OtILRI9Ny7)LOdJ1~K90#)@I
zgTcoCfZ^~H8jYYy%qAENzMAYC2higgp<LejBW4j4gb9kp9SfL6FrPoPi0PntOccj9
zFd`zj*4HfG&`!9BNFc9wWU5+{hBiH6`od`R&Qy6Q^k@^DZEcKQn5vG&&h3IkM1*E@
z{nn-^x9D~~TtFh4u8QgOJ~ZtLk~Gx+oT|Pcl{!YR#}6~Q196zj#rOgdW)p3Bra&nG
O0000<MNUMnLSTXbuE+ZT

literal 0
HcmV?d00001

diff --git a/vector/src/main/res/drawable-ldrtl-mdpi/msg_bubble_incoming.9.png b/vector/src/main/res/drawable-ldrtl-mdpi/msg_bubble_incoming.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..5ca9b14d6416441a6ebd6ca93a9d94ae3af8a639
GIT binary patch
literal 344
zcmeAS@N?(olHy`uVBq!ia0vp^!ayv<!3HFE@;uE1QY^(zo*^7SP{WbZ0pxQQctjR6
zFmQK*Fr)d&(`$i(zdT(WLo9liUb5|Caui^FkiNR-2fMNGTMLO9UhGv|f<E5`*e1WT
zG>MH6JIGwYpl)hnWcZ2Y-x4i5=A((%!<OG_^4s;I-#wi1yX)cDRY42~EXpL>n5UhV
zjx*`<6ZoSR*p#5dCiG(V=19APMLYM3inQ53*&n~LsiywaPn-YKHy&Jdm38q6Q$9Zy
z&C-<Zx6ODiGi96Ym&<8mIGx6yvvrYrw%UO$@9Y~{BKF!<GA=#RbyT!^Z~ym=PKn3;
z+?O}x-FO_*XY9wx$ROIl<F$0|#<!KxjMD-c7_Q6S-8#i;;l&9myPtI@w{N{QVd|+_
m2Ri3%Uvh1J(utJYb~elbM&V^YkGp_^hQZU-&t;ucLK6T84un(y

literal 0
HcmV?d00001

diff --git a/vector/src/main/res/drawable-ldrtl-xhdpi/msg_bubble_incoming.9.png b/vector/src/main/res/drawable-ldrtl-xhdpi/msg_bubble_incoming.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..52cb936a8ee6b84c2cec7c9dd9fc9c5a90d7749d
GIT binary patch
literal 598
zcmV-c0;&CpP)<h;3K|Lk000e1NJLTq001Na001Kh1^@s6`~|2W00004b3#c}2nYxW
zd<bNS00009a7bBm000Y#000Y#0XNCZtpET4_(?=TR9J=0*gZ?bKo|$`J4-4lsmYLt
z*n(8Chz-?2P!!G5O`Kf(2BL#Fy9l~CI9nX73icC-h!wI33PmWmiQr<PQV~&9s0x3F
zYHe+6O?tWZfrAWrlHa|B=R(Qffud_#<6b7wQYJ_w0x*mOR5gn)(N}|`&F{Z1g_x#{
zK;Qsg?}Otn|J^*EXG~2QKbXr)6}rC89YP2o2yZw$8!jE4aCilh^w<zkB(hkxkPr->
zHv}^`w^4CrLlmF6WBU5`094+&+%bOt4bthhs(YU+M$=MAr8=rpc!Q$Rp{gUp6(q}d
zSXh|+1H&0)81pqSoIozuJ4Q#>kWRNY2PhQU{Re~-sK5UN(P(FLfOLHafCWpQQdWL2
z30Zz1Jw2P0+AN`%j*O-yadFXZvnvivSu8ea6T=v!D7RQziqwH&3>qJwtrNotBnWSq
zm{>+8BQys{*S8oz7=d)%L_BVHM^yw-l7G1MaJzFPmlG+aw$iJC?0*<31!D{$q{2b5
z(b1G3N<{J1a;79bvF8w)A0b7_T2A$P?^$aI`JOUO+q2wbMTt8H>g_!us(SkGERW}f
zgu};9fC>TAl+o37So4hE-Mx=w(n=Lr2WonH3<CqJ@cFJFNlyiY%k=@D?+U@-HfCl<
koHW!b>54ymT>hYa0?`Sti=p%Jp8x;=07*qoM6N<$g5MJP2><{9

literal 0
HcmV?d00001

diff --git a/vector/src/main/res/drawable-ldrtl-xxhdpi/msg_bubble_incoming.9.png b/vector/src/main/res/drawable-ldrtl-xxhdpi/msg_bubble_incoming.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..5d8fc747ee34eee35d224b929b3ca4acbc356d1b
GIT binary patch
literal 1593
zcmaJ>eNfY87%$*BipaeAu@juc=p1ae`Dj|2NJmSX0=gnpHkdduB!Py~rb~itInN0q
z0^$Uj+ytEyL_XYfle<l;sB<SbPsYxj`iFPmsoN>%2Rc9ICi_Sc-2ULqUGl!q`~H5<
z_mi5;jMQn7F_8*|Vp@8d#V)T}`PD>(%iqM4Mwh(Ik;q(W1z#w6DS=g(7`}i7(p^*$
zYiB9O|KV9SNudbix$Imi*Y*xU^DZ?N#Hf8PkIYsml9GKMigvORP{0;(ZUZ=S>?8<q
zi~-Ei+F+Z<%sRNVGJ#!DmXS@DIcb~$livoCe1xpP#Yz<5bCtM7!e;=-^b+zucnpES
z7({X!z-Lb7+A;w%FR*}CtyR%5iU5hY8qs1nf-DA57|}oo457FRK?p37Ky<+P1IpF}
zrjW2(tmC$1$pAVe$wNSp*Xvb#HELccf)E_XAsB^FR3#%+qTel1K9yTsFrmT1inPFa
zB#w6jL5)-aUn&_u+0$nsxI8x7bH#3PJW+DWARpy{5H$?BT*0`;(4u5#|8rwfw3zMp
zu#lY<`BH(F>ruF1f-L9m#fE}F*&AZHz{y3SN-R8G>SEney2Sv>H)@7s2rW!wFbo%{
zD4NAoSb>IB>Gh~yg`t>M2h)j#41!MRnT$^+;v{Odnyfm^iXfy0w^&g<rq>`QtI2|r
zDHGguw<u9=nw_xC$+pM2_zSs&SzsxN7qWT2WTFc)9lXSg4&DQp%|N`3qB(a^P6*cM
zS;!Vv;MTH?Rp4E~Sds~D5(j7vj^HrHs&slSs>1XPt<tk7qJmi(*I+2Eqc8>>=QEQe
z&ngFxX>luwo6W)CQ(#<U!V^t8(t?o|k^~{yAt=}-|LdBGBe@lW+vhVN3(u#Bb<3k8
z$TMQpp^QQix+dLX%JyBp-Td{kl&qP3y^%b;w0_qoY4)#7j<k}9SGL4V;SRNbXS}?z
zsjBJEu-4AKU5_iP;QoXt<&@Y~dn8)X8qu}4I%BY;dR_A&@1Eax-8?;KNI052)O*En
z<Fjo$W8&`JY1vsHE!rv=Vfvysa!y^xUn2b#%e$eFo8a7xuJ7l@Jq2biZCfSv-h2AM
z<1IQ6etGb<4VNyVII#J8OzoNIN6AdjU}M<fm2vYMmG6axz&CH5s}DPzyBcVy?%vb3
zd-r_7m^6F#ey6i^@i$AO<LBjfe-u($Ix8)N1oK8x`|NSu!prBI+&i+%!|TtLhO}=#
zaDH@im2^WeOzRN$wYMz3@SCtoytXyQQCyrwZ~u7in=!W0_`!XjhnC-7Qvc}HUuW9m
zRX^K8YjYz1IG&$+bxTz3GB1jM(bJq7-fjyhjX(DHPc8GBLbXKT?9_`V!)8U@{l^|?
zNI5!49tj8$>mN5pwC4vJO!r%{9g(pQjc+N7U9Quoa*C9h*Y?FKFFbh?Fb-Q4?>4yG
zm9}k*O!o(Be8Wu<7l+n|ZK~*~xs$MQZ`}^JGPADtbYI`6mDbksOi}FF9%#!P{-rv4
z=!j-@z?rgh>+r&s{5kZ7gAF$Ss5z^mU=it`O*r%N-UnwK7)|KtStzaScwqng@vV_7
zGYBU?QvT5JL)`RDLo13;RP8s{Jj|-AD{0G$(kI=%bjNpfZF5ggMz+24TnqE<l@wj9
zvFm=^yw|_XYdAJA@Y7%?bZDEV@65&})VdQ39Gt(iyYcwYjJrg+L{z%|T8VP#K!0LL
axMF|qvY6fdl^+Cu=ILaH<zUL1ihltr!%RW|

literal 0
HcmV?d00001

diff --git a/vector/src/main/res/drawable-ldrtl-xxxhdpi/msg_bubble_incoming.9.png b/vector/src/main/res/drawable-ldrtl-xxxhdpi/msg_bubble_incoming.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..8378db57676ce11bf5d734d7ab2a518679528898
GIT binary patch
literal 1751
zcmaJ?c~BEq7>{TbqLHz~p|sj<AfqxS+1;GG5@=3{7{nNbDq1$1g`_0em@E+JU|T4n
zj52uDi$So6Ra*v>N*O8Gv4SW%C~7N*h>B=Mv5F#6Z8r$Ee>m>UzW2Vjzu$L%vm0Y$
zB3aBJCWFCXX`@tndXJ=EmG@+NZ3~%KMQ^hxbv(6<Orp{;C&7@LNFxDgZCEm)CoogS
z+GZk*!I(%|4DnRFZZV3JHXi1|@Z2^B&1NvdBHRuPPa!D4NF-bAGWNiU1~y<Z$=Gos
z9jJ3C39}_C(@8ALj4|MuDL7(cM}z}mZj@GFBPa}T+pKmM>Xxxb^`i9IbIoT1qYx@Z
z#(wQoye<|{l1>5;@kCr4gdsqJ@F0;8fuIEd3_=1v1oB~o3qhz*f<j_o>|xW^oTemH
zuhNX!q9qyIOi>P$&reTJ=cNmHq%)ZhAqc_;VLl9VX$04mVW%)R*X{})*PtR?xYOdG
zETkRqXvB<UDkWpnp1uyj=FsWhD7L%C5=Ezs@5UT_hzIg*HcwomXcwg?{&VB4XqO?w
zLGbm2i%fOmbUl)S$H{c=-fhSOq`g6xI4yKhFsq8hQ*DHu(yC-^`U}rwF`*(57lI&Y
z<YG7><O+=ff-9B6Qmzmdio_r;Nisq3xSqH16_8w_K{Rq$BoRQ6TBs08K`AXG3aK1Y
zh{18L*6yM(J5G$-w$Qf6xX3%XsM1Mb6zMdOq;<RtV$CE)y3C{lP%43WIt;hiJ@R}{
zjb4YWBAk{q!lZGMHefW#sO2pV5SS6drMQVpF9cU;f+SoiA%VC;LXc#FB_do5(!syx
zo8FQ<jRa8(MTka?D3x^Z0tJW&<cLHrR;z?+m0Hc_(+=@HUGl%K8NZ@i(Q|w=1GMmF
ziU>PBI!<~<y6czpG8kU3v?{s5-QHi+km4uzYfAoZb3jkfm%ytDD?jzl&(>8gt)4OM
z`!cP???<lnN}2z%@}t#{7KyH|Eb|s``Gd2;xHXzxG;_oKp`KM;va9F%uRrXp%UJlR
zSNikr+L6wdFUUI&7W?hJ$$9Z)YemowOVbc+9Ig!z`pELWWf%oX=nus;H=p(obazK`
z@A_QkFcuBI-yS$Hp)a7i+?#oCHU(mZQ*!&8s^NKM#NF6E>N!P`%wG#xvWw^T2e#;P
z6W1y5jB?J)JK*J|lkWs}TunH!H?7zA8j%v}D-CPr&)?a#T>N>`5HoG-78eUGG5=PV
z`|z6POrZbQ!zXjFrhp6cIf*Mu&$X`D^3#>I?<F3e*>c#H`|@uzNV;pax#-~b2NgL_
z4<}^SPW>e`e(qI9A0%8=Zak{>pTb=4Rkv|}1OHmf)LGL{!#k}B$HmfpCC6Gdhwk}R
zo*!-uPQqK)D{|U$D;}SLSVh(au8Elg=m=2Snb*EtJd^ohK3=?{%j|vq@cASCU1v)s
z-8|b|zp3hD@hG-<b<LrP1%|!K4&S&x8Npq^K;`D)`1Ht2H(Cex-A>(RxnYX_$B=J~
zi>Yd{&5ivg<H)5B-_ld1S>00`VZ6j=I>EfK+iTWD?%J3hLw*3MzF&5~5#F(%HT{5o
zjqgbGbMJ#xC}&W5&=9K5sc{CKi^`@=C6^QgwlxRG6_@GJ#$&Kmx}#jL$X=Ea$_bGU
zE?(2&PGBEz{HyZCvjFA?w_`tw@JSnPJ!!cibOcF5dkXv7(>e#zCs_B-cy_Czh8-88
zJECrS$$K&Fz);l1x?8XMIGc)05qU9pv&8lb2`|4Yknh!(`)6H5BC{@N8QbO{hJsI`
z%dfkNC-sI5s#g|0@!xZ}wqc?Eq-nvi9OY2kCHu(p?o^h*KWBGO+UZl;&jzc)f$dM%
z<+XE8&AOexi}!nqwqDirtTE(q;$R_rc2ziQw&<Fxw8Lr+ERnQMz4a&~D6pcl{!+xM
g@Ysd*JG;H6G0aUDp{g5`yF9-dtvW_kp-9aB7wY1x+yDRo

literal 0
HcmV?d00001

diff --git a/vector/src/main/res/drawable-mdpi/msg_bubble_incoming.9.png b/vector/src/main/res/drawable-mdpi/msg_bubble_incoming.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..4e7e464037695828ede0683d70ea9ff43acda8e2
GIT binary patch
literal 339
zcmeAS@N?(olHy`uVBq!ia0vp^!ayv<!3HFE@;uE1QY^(zo*^7SP{WbZ0pxQQctjR6
zFmQK*Fr)d&(`$i(Up-wMLo9mNUfG+)<S26V<Nn2)9*Mt+veXmXX4G2AC7APBKy%yK
z;v;4PP6_e{*e_hWq~*KH#!=|DN<~nMz!|TYcFTg<(SM#5bus>b@%|9QiCfi;=VY$r
z?bq_n-xBA(-#^E!G_v|NV_pB&pAXLpd0n>FUlUfXKW)R^Ygb>dtvQe^yGW<|>RUUu
zgA69KV^7RDuOQKI?D6Xai3YXFK38A43-CCci)B5`U?QV;IPr63{Ml#4K%vVkgBNeK
zZk;M7>iV;O2BX%}^WKxTFa8~t%^u>D$&p}k$}lbd#_^AbBhUFixwCZA6VDCd%RetV
im{9nEwQ|{oui}mx;bn4-e`A0Fz~JfX=d#Wzp$P!O{EM3a

literal 0
HcmV?d00001

diff --git a/vector/src/main/res/drawable-xhdpi/msg_bubble_incoming.9.png b/vector/src/main/res/drawable-xhdpi/msg_bubble_incoming.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..0661fdba789fa348568b01299482fa29fff2e17d
GIT binary patch
literal 597
zcmV-b0;>IqP)<h;3K|Lk000e1NJLTq001Na001Kh1^@s6`~|2W00004b3#c}2nYxW
zd<bNS00009a7bBm000Y#000Y#0XNCZtpET4_en%SR9J=0*s)9FP#g#F@3WNBl9~*O
zh%HDJi)g4f2#SYh=_XDt{SU+&<YpJ)ZgFt7IH-4E|AIrr3S9(+a!_!S!Yx;*cpRmr
zdQgS$Em|tJYHX6eAN(N0`;kxHFE8Xh0q=q>*P_#)J^)}e`ilTvPBc^3uW4CXX0x&O
z^ra<>p-|le)YA-yD~!bsnaioqQRn9~^!pp0qX5!0w|IG}KSw2#pL+sQlqwU6FYVj6
zy1LyHR6PE(J%|(>A3yLM6b#lotvs+)>Sr|i+iO%u5CE`H7^GnoJO;gjN~fo#0s#Qm
z))uL%f208c04?j2T%b}Zz`40i`h0g%fSRz$$?tN3(&-^iOq@ys0sxYrX?}AH)MpnY
zgaAfIcc7{j+fU<W@Zw^ChLP`i%buY2_C81j0syYBC#h*y(trSf^Ybfmfy!k+7Zx_U
z{o`~D)P$Mlu3Vr@W`L%d>joqqR2}z8wo#-&An*^3M!;^Zz{9@G$q+&iLcDwG9S3zA
zQi2?Nf105vHQP18;4J{*&J2aae{I)j+BM)-%QP)xYrLY=U>FDPff9)mghDrO9<S?X
z7#llw#qt=;=Z82l^5eyip`uhdJbcvl^urZYDmBY^e4mj>kv`vj3#7(Kq{ykMuUuaK
j*jnTK3VXr#mizt(eh06M7!YU`00000NkvXXu0mjfUCISm

literal 0
HcmV?d00001

diff --git a/vector/src/main/res/drawable-xxhdpi/msg_bubble_incoming.9.png b/vector/src/main/res/drawable-xxhdpi/msg_bubble_incoming.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab693b3e7c19e68ba8af37fbf5d9ead9aaa7fb32
GIT binary patch
literal 1582
zcmbVMX;2eq7>-CKWuV3jtq3klYXfz&M-sxW#0p8!h`|sMX-BJ@-7m00vTL%MNVOg{
zrCO`CW9<(QZaGR(It6CxAReuqs(@B1iqKkH9Y^gbGvYa7H%M%MIR5C)?0(<-eed(U
z_inak&W;S994?c|BF%G*HfhyLuUbAz`s&(dIi=-w(UdDL;2olub^}=|%i95DcG7vk
z255Hmil0G>Og7TPW#@{ymU$GzJ5_W*N9A)05?UrpdB-QvOaTxfJILc)dieICHW=bq
zJ-kS3!7PFS<a2Y1++aabW;Rn)z>qBb&P*u9M@a-uAkvV}S?KamK0Q3dOG*2{F$zON
zDq?{ie&$rJ#R?gCH-NM%Ey7>~4(Ui0uGNq@J{=-3T#e!wN{|SSQyLwGCqcsxELn52
z4$5XsAGRe)dN^Mc1qwyIUa!ilR`KpU6emd%#R!xj5J>~^tagdC4{>?ogA7LCVceV`
za=Z%)Fw%B@rKpD`PoIV06fBnK#4gWpqNJ3eK3YI=6^1&Ufw+dWJ)#Z#>&6SUJ=v=T
zfZBkEU+HF~dN|^PU@3PmHxy8myrJg1IjJagp^;}+I)O_x8}+bsqhdLh(qfDT!!SES
zGeCoA>}r4{ClkqthR|q}Fh=KKaU#g`B7C}zG-<S{Y7=QN;J8VhhLP%2QkR-!GHOgl
zlPQQbyF4Q8VnEO~C)pmx5--J41~;HZ-kr_!g~2Yc=JO)&$>#;gV1Sesn&DglIU!J^
zXCWJbn_C6gbT{vWhLTKiFK~dwbbufLjj%~LD+QmdLr6l6AwZLy%-BhWU}**(#<Tx7
zd8p(R8t9b&bWZR{YRAC#`5Z{X^GO0OX?)z$ocIRmG?^?U%WO=|_VwKAY0C(qCxr=1
z{n1;;!qsnl5mBg^JT`jc4{%s&PXVV?+%K&vs~TLdT%KR2FN;&1PKbClG^X4ZPHcoX
z*OYy-Z_U)i>pv~Y@!lUS{m3i$mOkli{qXlgA569X`FQ>460?5qtqbb0=I)}A#qIYR
z5>DzLteK7BjiGf^={l-z;l$98S2F1yWJ<@8qZ^h+=crmXTv{79rM|I$RCCMYCi-Hb
zd{4)WKbEPwn+7LjR9(3&q=bjv{JTA5{i@H8^!8Q?%AV%tQ3J>0cjPKw)6P6xzdb~l
zHN81*d|gGw-6tpCdatYdeB+~Ccjx{%GPbi;d9a(ir=MPOJL=6F{nsjDch1Rr8bAJ6
z)WmVWlqq)2>o`?ho;7uQb!A%Xkv)otYn5sJQwG+h#noHomt(%2r`%L~Loq*#mv3pQ
z(M9+V*4DoJ(ApHHnH2l}SK$Lu17&9#vXz_mmK-{I6Up$~V+Qt1q?xntT&<9x-_&n4
z7u&}SoG;Dq+P<w}uD@tQLXN2w)U?!8&xj(*6gi0xORKKh5_e9>>J0TCY-$<<{bf!Z
zf6U?7Z!xTGJg_`+OS--fQ;z_7O$Lj6#O}U9_QZwLR!8hp<qqqni!C~B-y~{Zd5U%P
zrMG|WDRSKLO}KaNKy_Z{nf^zQR$Z7Fd-nUt`0j*-F;^<e6DRk5SGnz&t*d{<<C0Uw
z*E9Cn8$bP8{_$d!yuE$V{;p}bfA1b&W8$sq1(^q?ZH`_%ZQP0FyE{6L&+l9k8QF6A
t{_S%oqk5fZAB-OJ+h=VLTRTG{WV$V1cKR#s9uEA$&8AFaL)x;9{{W`XQDOi9

literal 0
HcmV?d00001

diff --git a/vector/src/main/res/drawable-xxxhdpi/msg_bubble_incoming.9.png b/vector/src/main/res/drawable-xxxhdpi/msg_bubble_incoming.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..34130fc6d1b4a4216b93899e60a6c3c177d1f06c
GIT binary patch
literal 1731
zcmbVNYfuwc6pm=+QGARt3?fXI$RKKx-OU5Ck%)xwh!8{)ly=mz*(@Z5WW#2GfEHS8
zQQ8V3s8vxw>I1a40%J?D0-_Ye+9*W~l}bm@;P5Pt4rpmN2(~{Qe{^Sd&pr2k-#O==
z$8277RM-M1cP9peu|O6sjiF^2{Yo9?)87tn-wU)@Muo&t3L=3@M@gI!q$X52Ak(3V
zcnprJGg8{{00v{OQLBuj;^dJcjL>mV8-`=j8E7_x5fErHpjZ-40V+IEs~0mz>KmAV
zRxM_35y&CAAsE+a!!t=-kr}1LGLtYw%?w-z1eip$0Ub`EfJv9EH;PPR=CoZAy|!(G
zOkf&9C5f3YgNl<!1HlA|0|JhKjX_)(@JBeXfRDg13*bU94}>9*i?Cr>#P=7$e!$Gb
zq`i^q1W}AMbjBC0iJ2OTGKfGhJw2V1&f^edA_yZ00zzDn%VpCDwlPCbp(eK8xMJ3V
z6gOg|)<9_qJz%qls)$rd%%mfIc?F$8E`McMZ=6XKoifmb8bFu>fjXV-UejnJ6@&j9
z#%s|=WrhI<V{jvpN@8?95?0KT>D;~9kqt;kBicx6>7t;?QUXiW;d)9Y6*K7*j#{f0
z2_TFQL6C}#VmP18SMhMRP{<Xs`CPuh55oKt)G&9}&g=LRDUZtyMMAg&e?AO{@Fjd9
zBt$}k5Q#7dmiR%lT$$cTp?VCT^{u6S&v2!0<cfkx9Hj_SNf61iT@bAyD8i^A3_x%&
z;44Qlt=^`uveoG2m8CeTO~cipB%uSQlPuD{CIFPr<6$aX#l~PBm(54GC|l?+RI!DS
zA77w?ARdbGm@|C!|4kl92L;+X<v*P>yG6I7ZTV^rXyw%;;d**}NP14P&gfAF!|tI>
z8l*IJ50;2EE<tX&i9XCPnRPzWt1)w3RVbR>?Pk6b)nUoYdzzEFq@xsfx}b#iI<)wd
z<!ZdNpWI!wfAOx<SMoM^+%GuRxnl5q(U0{#6BFA_cOzPd`i>v%Ieg6GSs7v~Y&-S5
zqK#XsIIL?QWI0fhXJAA8xa&RpElp<*c#c2x8V&#Zw-hVY=%I0WcX$eQyYxl);xWfa
zORHB)W2ic3PloPhL<qUZ(VQP`KDXE7gkzS}*ZSFB4>bSU{lc~h=N5&1Rhd^s!pOlr
zYZe%G5Q^>6HPzi6vZE#(9rrQ0ZW==7aU3I%h8ypE6XtC#`P#!NwP9t`?(n{n?g9_=
zYNY$7@<$rW+0L3?M>i+S!t;YCSC3uBp`}4Xx2pP<kL1*uhr)XlKQDdOs4UwZyOH#@
zZ^F!KWMbQ}z`)`oRg0c$ca6udt?jOutSwFNwX=R(GI%bhJ^oO?I??f7JTjp@oE81+
zUnM8ZC$9w?;HReoz-Hz$dr>o4&6|Jx`Ca=e$-@5c2fXtqeZpd+Z{~)FF3Bd74tR>5
znde<jKrCbWs<1nwu`z*G_tJee#`WIK=i~>AJU^)0+$f`^`ybip#an*;87Wy+VVzs2
zei)cLR9*67o!Pm)t)NIDzFp2atDpspxFnv++*(}p^yBS$M|LBR_1DKG^7^F;G3R=@
z5bk_X<*{LiR@%#1ofiB318@HnR!(`Uibs>F{6%XHHj{A++w+w9PkR4;@m@;C{npQK
zXVvz{25uhx{dDtVd1t@2ppVtH>G+ecc0_(Rp5@Y36TRzZx?x`Jhm{Dmc0?6|vyc3F
zsS+tpDP+}|-9`@??2;$%{9>`|vftW5t$sKX_fg`Fh1RC7wHFul)H@$@a-C!)G^N$e
zf4?kbPFiMhbxrA~>vmS4t^?L$Q`*j{?1-za>vQK+zE!b&iM8-iM=#`NG3r8Bc6arz
lG6AgN;eD4_u~}0N5W{&}<?Vv82aj#P6<J7>^t>cK=N~z~tTq4u

literal 0
HcmV?d00001

diff --git a/vector/src/main/res/layout/item_timeline_event_base.xml b/vector/src/main/res/layout/item_timeline_event_base.xml
index 3ae80424cc..05d0dd797e 100644
--- a/vector/src/main/res/layout/item_timeline_event_base.xml
+++ b/vector/src/main/res/layout/item_timeline_event_base.xml
@@ -92,6 +92,7 @@
             android:id="@+id/messageContentTextStub"
             style="@style/TimelineContentStubBaseParams"
             android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
             android:inflatedId="@id/messageTextView"
             android:layout="@layout/item_timeline_event_text_message_stub"
             tools:visibility="visible" />
diff --git a/vector/src/main/res/layout/item_timeline_event_text_message_stub.xml b/vector/src/main/res/layout/item_timeline_event_text_message_stub.xml
index 59396db0e5..6b8f08833c 100644
--- a/vector/src/main/res/layout/item_timeline_event_text_message_stub.xml
+++ b/vector/src/main/res/layout/item_timeline_event_text_message_stub.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+<im.vector.riotx.core.ui.views.WrapWidthTextView xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/messageTextView"
-    android:layout_width="match_parent"
+    android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:textColor="?riotx_text_primary"
     android:textSize="14sp"
diff --git a/vector/src/main/res/values-de/strings_sc.xml b/vector/src/main/res/values-de/strings_sc.xml
index 38f792c3ae..70bf5c0a56 100644
--- a/vector/src/main/res/values-de/strings_sc.xml
+++ b/vector/src/main/res/values-de/strings_sc.xml
@@ -3,4 +3,9 @@
 
     <string name="redacted_stub_text">(Gelöschte Nachricht)</string>
 
+    <string name="bubble_style">Nachrichtblasen</string>
+    <string name="bubble_style_none">Keine</string>
+    <string name="bubble_style_start">Selbe Seite</string>
+    <string name="bubble_style_both">Beide Seiten</string>
+
 </resources>
diff --git a/vector/src/main/res/values/arrays_sc.xml b/vector/src/main/res/values/arrays_sc.xml
new file mode 100644
index 0000000000..2c5305c28e
--- /dev/null
+++ b/vector/src/main/res/values/arrays_sc.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string-array name="bubble_style_entries" translatable="false">
+        <item>@string/bubble_style_none</item>
+        <item>@string/bubble_style_start</item>
+        <item>@string/bubble_style_both</item>
+    </string-array>
+    <string-array name="bubble_style_values" translatable="false">
+        <item>none</item>
+        <item>start</item>
+        <item>both</item>
+    </string-array>
+
+</resources>
diff --git a/vector/src/main/res/values/attrs_sc.xml b/vector/src/main/res/values/attrs_sc.xml
new file mode 100644
index 0000000000..cafd386c83
--- /dev/null
+++ b/vector/src/main/res/values/attrs_sc.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <declare-styleable name="VectorStylesSC">
+
+        <attr name="sc_message_bg_incoming" format="color" />
+        <attr name="sc_message_bg_outgoing" format="color" />
+
+    </declare-styleable>
+
+</resources>
diff --git a/vector/src/main/res/values/strings_sc.xml b/vector/src/main/res/values/strings_sc.xml
index a24b245bc8..abc94df2b8 100644
--- a/vector/src/main/res/values/strings_sc.xml
+++ b/vector/src/main/res/values/strings_sc.xml
@@ -3,4 +3,9 @@
 
     <string name="redacted_stub_text">(Deleted message)</string>
 
+    <string name="bubble_style">Message bubbles</string>
+    <string name="bubble_style_none">None</string>
+    <string name="bubble_style_start">Same side</string>
+    <string name="bubble_style_both">Both sides</string>
+
 </resources>
diff --git a/vector/src/main/res/values/theme_dark.xml b/vector/src/main/res/values/theme_dark.xml
index a2be367e55..384d693562 100644
--- a/vector/src/main/res/values/theme_dark.xml
+++ b/vector/src/main/res/values/theme_dark.xml
@@ -216,6 +216,9 @@
         <item name="snackbarButtonStyle">@style/VectorSnackBarButton</item>
         <!-- Style to use for message text within a SnackBar in this theme. -->
         <item name="snackbarTextViewStyle">@style/VectorSnackBarText</item>
+
+        <item name="sc_message_bg_incoming">#FF465561</item>
+        <item name="sc_message_bg_outgoing">#FF1A2027</item>
     </style>
 
     <style name="AppTheme.Dark" parent="AppTheme.Base.Dark" />
diff --git a/vector/src/main/res/values/theme_light.xml b/vector/src/main/res/values/theme_light.xml
index 9709172f9d..9df4bed758 100644
--- a/vector/src/main/res/values/theme_light.xml
+++ b/vector/src/main/res/values/theme_light.xml
@@ -216,6 +216,9 @@
         <item name="snackbarButtonStyle">@style/VectorSnackBarButton</item>
         <!-- Style to use for message text within a SnackBar in this theme. -->
         <item name="snackbarTextViewStyle">@style/VectorSnackBarText</item>
+
+        <item name="sc_message_bg_incoming">#FF999999</item>
+        <item name="sc_message_bg_outgoing">#FFC7C7C7</item>
     </style>
 
     <style name="AppTheme.Light" parent="AppTheme.Base.Light" />
diff --git a/vector/src/main/res/values/theme_sc.xml b/vector/src/main/res/values/theme_sc.xml
index dfd89a0b29..45ba957e2f 100644
--- a/vector/src/main/res/values/theme_sc.xml
+++ b/vector/src/main/res/values/theme_sc.xml
@@ -203,6 +203,9 @@
         <item name="snackbarButtonStyle">@style/VectorSnackBarButton</item>
         <!-- Style to use for message text within a SnackBar in this theme. -->
         <item name="snackbarTextViewStyle">@style/VectorSnackBarText</item>
+
+        <item name="sc_message_bg_incoming">@color/background_floating_sc</item>
+        <item name="sc_message_bg_outgoing">@color/accent_sc_alpha25</item>
     </style>
 
     <style name="AppTheme.SC" parent="AppTheme.Base.SC" />
diff --git a/vector/src/main/res/xml/vector_settings_preferences.xml b/vector/src/main/res/xml/vector_settings_preferences.xml
index 47a344d452..765f015186 100644
--- a/vector/src/main/res/xml/vector_settings_preferences.xml
+++ b/vector/src/main/res/xml/vector_settings_preferences.xml
@@ -21,6 +21,15 @@
             android:title="@string/settings_theme"
             app:iconSpaceReserved="false" />
 
+        <im.vector.riotx.core.preference.VectorListPreference
+            android:defaultValue="start"
+            android:entries="@array/bubble_style_entries"
+            android:entryValues="@array/bubble_style_values"
+            android:key="BUBBLE_STYLE_KEY"
+            android:summary="%s"
+            android:title="@string/bubble_style"
+            app:iconSpaceReserved="false" />
+
         <im.vector.riotx.core.preference.VectorPreference
             android:dialogTitle="@string/font_size"
             android:key="SETTINGS_INTERFACE_TEXT_SIZE_KEY"