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"