Fix mentions font weight and horizontal padding (#2025)
* Fix mentions font weight and horizontal padding --------- Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
parent
6e69952b6b
commit
e31b85f6c5
6 changed files with 85 additions and 8 deletions
1
changelog.d/1449.bugfix
Normal file
1
changelog.d/1449.bugfix
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Adjust mention pills font weight and horizontal padding
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.designsystem.text
|
||||||
|
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.State
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.platform.LocalFontFamilyResolver
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
|
import androidx.compose.ui.text.font.FontStyle
|
||||||
|
import androidx.compose.ui.text.font.FontSynthesis
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TextStyle.rememberTypeface(): State<Typeface> {
|
||||||
|
val resolver: FontFamily.Resolver = LocalFontFamilyResolver.current
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return remember(resolver, this) {
|
||||||
|
resolver.resolve(
|
||||||
|
fontFamily = fontFamily,
|
||||||
|
fontWeight = fontWeight ?: FontWeight.Normal,
|
||||||
|
fontStyle = fontStyle ?: FontStyle.Normal,
|
||||||
|
fontSynthesis = fontSynthesis ?: FontSynthesis.All,
|
||||||
|
)
|
||||||
|
} as State<Typeface>
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,7 @@ package io.element.android.libraries.textcomposer.mentions
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.graphics.RectF
|
import android.graphics.RectF
|
||||||
|
import android.graphics.Typeface
|
||||||
import android.text.style.ReplacementSpan
|
import android.text.style.ReplacementSpan
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
@ -26,6 +27,9 @@ class MentionSpan(
|
||||||
val type: Type,
|
val type: Type,
|
||||||
val backgroundColor: Int,
|
val backgroundColor: Int,
|
||||||
val textColor: Int,
|
val textColor: Int,
|
||||||
|
val startPadding: Int,
|
||||||
|
val endPadding: Int,
|
||||||
|
val typeface: Typeface = Typeface.DEFAULT,
|
||||||
) : ReplacementSpan() {
|
) : ReplacementSpan() {
|
||||||
|
|
||||||
override fun getSize(paint: Paint, text: CharSequence?, start: Int, end: Int, fm: Paint.FontMetricsInt?): Int {
|
override fun getSize(paint: Paint, text: CharSequence?, start: Int, end: Int, fm: Paint.FontMetricsInt?): Int {
|
||||||
|
|
@ -34,7 +38,8 @@ class MentionSpan(
|
||||||
if (mentionText != text.toString()) {
|
if (mentionText != text.toString()) {
|
||||||
actualEnd = end + 1
|
actualEnd = end + 1
|
||||||
}
|
}
|
||||||
return paint.measureText(mentionText, start, actualEnd).roundToInt() + 40
|
paint.typeface = typeface
|
||||||
|
return paint.measureText(mentionText, start, actualEnd).roundToInt() + startPadding + endPadding
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun draw(canvas: Canvas, text: CharSequence?, start: Int, end: Int, x: Float, top: Int, y: Int, bottom: Int, paint: Paint) {
|
override fun draw(canvas: Canvas, text: CharSequence?, start: Int, end: Int, x: Float, top: Int, y: Int, bottom: Int, paint: Paint) {
|
||||||
|
|
@ -46,11 +51,12 @@ class MentionSpan(
|
||||||
val textWidth = paint.measureText(mentionText, start, actualEnd)
|
val textWidth = paint.measureText(mentionText, start, actualEnd)
|
||||||
// Extra vertical space to add below the baseline (y). This helps us center the span vertically
|
// Extra vertical space to add below the baseline (y). This helps us center the span vertically
|
||||||
val extraVerticalSpace = y + paint.ascent() + paint.descent() - top
|
val extraVerticalSpace = y + paint.ascent() + paint.descent() - top
|
||||||
val rect = RectF(x, top.toFloat(), x + textWidth + 40, y.toFloat() + extraVerticalSpace)
|
val rect = RectF(x, top.toFloat(), x + textWidth + startPadding + endPadding, y.toFloat() + extraVerticalSpace)
|
||||||
paint.color = backgroundColor
|
paint.color = backgroundColor
|
||||||
canvas.drawRoundRect(rect, rect.height() / 2, rect.height() / 2, paint)
|
canvas.drawRoundRect(rect, rect.height() / 2, rect.height() / 2, paint)
|
||||||
paint.color = textColor
|
paint.color = textColor
|
||||||
canvas.drawText(mentionText, start, actualEnd, x + 20, y.toFloat(), paint)
|
paint.typeface = typeface
|
||||||
|
canvas.drawText(mentionText, start, actualEnd, x + startPadding, y.toFloat(), paint)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getActualText(text: CharSequence?, start: Int): String {
|
private fun getActualText(text: CharSequence?, start: Int): String {
|
||||||
|
|
|
||||||
|
|
@ -17,16 +17,24 @@
|
||||||
package io.element.android.libraries.textcomposer.mentions
|
package io.element.android.libraries.textcomposer.mentions
|
||||||
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
|
import android.graphics.Typeface
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.graphics.toArgb
|
import androidx.compose.ui.graphics.toArgb
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
import androidx.core.text.buildSpannedString
|
import androidx.core.text.buildSpannedString
|
||||||
|
import io.element.android.compound.theme.ElementTheme
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
|
import io.element.android.libraries.designsystem.text.rememberTypeface
|
||||||
import io.element.android.libraries.designsystem.theme.currentUserMentionPillBackground
|
import io.element.android.libraries.designsystem.theme.currentUserMentionPillBackground
|
||||||
import io.element.android.libraries.designsystem.theme.currentUserMentionPillText
|
import io.element.android.libraries.designsystem.theme.currentUserMentionPillText
|
||||||
import io.element.android.libraries.designsystem.theme.mentionPillBackground
|
import io.element.android.libraries.designsystem.theme.mentionPillBackground
|
||||||
|
|
@ -34,7 +42,6 @@ import io.element.android.libraries.designsystem.theme.mentionPillText
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
||||||
import io.element.android.compound.theme.ElementTheme
|
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
class MentionSpanProvider(
|
class MentionSpanProvider(
|
||||||
|
|
@ -44,6 +51,10 @@ class MentionSpanProvider(
|
||||||
private var otherTextColor: Int = 0,
|
private var otherTextColor: Int = 0,
|
||||||
private var otherBackgroundColor: Int = Color.WHITE,
|
private var otherBackgroundColor: Int = Color.WHITE,
|
||||||
) {
|
) {
|
||||||
|
private val paddingValues = PaddingValues(start = 4.dp, end = 6.dp)
|
||||||
|
|
||||||
|
private val paddingValuesPx = mutableStateOf(0 to 0)
|
||||||
|
private val typeface = mutableStateOf(Typeface.DEFAULT)
|
||||||
|
|
||||||
@Suppress("ComposableNaming")
|
@Suppress("ComposableNaming")
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -52,10 +63,18 @@ class MentionSpanProvider(
|
||||||
currentUserBackgroundColor = ElementTheme.colors.currentUserMentionPillBackground.toArgb()
|
currentUserBackgroundColor = ElementTheme.colors.currentUserMentionPillBackground.toArgb()
|
||||||
otherTextColor = ElementTheme.colors.mentionPillText.toArgb()
|
otherTextColor = ElementTheme.colors.mentionPillText.toArgb()
|
||||||
otherBackgroundColor = ElementTheme.colors.mentionPillBackground.toArgb()
|
otherBackgroundColor = ElementTheme.colors.mentionPillBackground.toArgb()
|
||||||
|
|
||||||
|
typeface.value = ElementTheme.typography.fontBodyLgMedium.rememberTypeface().value
|
||||||
|
with(LocalDensity.current) {
|
||||||
|
val leftPadding = paddingValues.calculateLeftPadding(LocalLayoutDirection.current).roundToPx()
|
||||||
|
val rightPadding = paddingValues.calculateRightPadding(LocalLayoutDirection.current).roundToPx()
|
||||||
|
paddingValuesPx.value = leftPadding to rightPadding
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMentionSpanFor(text: String, url: String): MentionSpan {
|
fun getMentionSpanFor(text: String, url: String): MentionSpan {
|
||||||
val permalinkData = PermalinkParser.parse(url)
|
val permalinkData = PermalinkParser.parse(url)
|
||||||
|
val (startPaddingPx, endPaddingPx) = paddingValuesPx.value
|
||||||
return when {
|
return when {
|
||||||
permalinkData is PermalinkData.UserLink -> {
|
permalinkData is PermalinkData.UserLink -> {
|
||||||
val isCurrentUser = permalinkData.userId == currentSessionId.value
|
val isCurrentUser = permalinkData.userId == currentSessionId.value
|
||||||
|
|
@ -63,6 +82,9 @@ class MentionSpanProvider(
|
||||||
type = MentionSpan.Type.USER,
|
type = MentionSpan.Type.USER,
|
||||||
backgroundColor = if (isCurrentUser) currentUserBackgroundColor else otherBackgroundColor,
|
backgroundColor = if (isCurrentUser) currentUserBackgroundColor else otherBackgroundColor,
|
||||||
textColor = if (isCurrentUser) currentUserTextColor else otherTextColor,
|
textColor = if (isCurrentUser) currentUserTextColor else otherTextColor,
|
||||||
|
startPadding = startPaddingPx,
|
||||||
|
endPadding = endPaddingPx,
|
||||||
|
typeface = typeface.value,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
text == "@room" && permalinkData is PermalinkData.FallbackLink -> {
|
text == "@room" && permalinkData is PermalinkData.FallbackLink -> {
|
||||||
|
|
@ -70,6 +92,9 @@ class MentionSpanProvider(
|
||||||
type = MentionSpan.Type.USER,
|
type = MentionSpan.Type.USER,
|
||||||
backgroundColor = otherBackgroundColor,
|
backgroundColor = otherBackgroundColor,
|
||||||
textColor = otherTextColor,
|
textColor = otherTextColor,
|
||||||
|
startPadding = startPaddingPx,
|
||||||
|
endPadding = endPaddingPx,
|
||||||
|
typeface = typeface.value,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
|
@ -77,6 +102,9 @@ class MentionSpanProvider(
|
||||||
type = MentionSpan.Type.ROOM,
|
type = MentionSpan.Type.ROOM,
|
||||||
backgroundColor = otherBackgroundColor,
|
backgroundColor = otherBackgroundColor,
|
||||||
textColor = otherTextColor,
|
textColor = otherTextColor,
|
||||||
|
startPadding = startPaddingPx,
|
||||||
|
endPadding = endPaddingPx,
|
||||||
|
typeface = typeface.value,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:8819c4ceeb21f96ba6d584ee78e4aca1a9cf2c87412f70e8f00eff09de61abc8
|
oid sha256:e541cfb32e9d3095d6499c4c25e4bb4158c10886d59accf6006290bda344e8b2
|
||||||
size 43788
|
size 43927
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:ffbb340bd78c7806dd52be9454057b5ed4a3f9831f9ecb1c99b10c0759ba7f85
|
oid sha256:06cd8d611bf8149d3c86b8d9a4aa5613dc9f32f89156081472f98d6410e98c4d
|
||||||
size 37091
|
size 37107
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue