Initial message bubbles

Drawables taken from AOSP Messaging
This commit is contained in:
SpiritCroc 2020-05-12 15:49:43 +02:00
parent ce48360022
commit 2f659f613d
25 changed files with 172 additions and 2 deletions

View File

@ -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
}
}

View File

@ -397,6 +397,8 @@ class MessageItemFactory @Inject constructor(
.leftGuideline(avatarSizeProvider.leftGuideline)
.attributes(attributes)
.highlighted(highlight)
.outgoingMessage(informationData.sentByMe)
.incomingMessage(!informationData.sentByMe)
.movementMethod(createLinkMovementMethod(callback))
}

View File

@ -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

View File

@ -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 {

View File

@ -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 = ""
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -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" />

View File

@ -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"

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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" />

View File

@ -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" />

View File

@ -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" />

View File

@ -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"