fix: Render hashtags, mentions, and initial paras correctly in RTL (#906)

Previous code didn't set the textDirection for the status content, so
the first para of RTL text might be rendered incorrectly.

In addition, mentions and tags weren't BIDI wrapped, so would appear as
"foo@" and "foo#" in RTL statuses, instead of "@foo" and "#foo".

Fix both of these issues.

Fixes #870
This commit is contained in:
Nik Clayton 2024-08-28 17:46:39 +02:00 committed by GitHub
parent c9cf078939
commit 766dc1f907
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 13 additions and 4 deletions

View File

@ -9,7 +9,8 @@
android:clipChildren="false" android:clipChildren="false"
android:clipToPadding="false" android:clipToPadding="false"
android:paddingStart="12dp" android:paddingStart="12dp"
android:paddingEnd="14dp"> android:paddingEnd="14dp"
android:textDirection="anyRtl">
<TextView <TextView
android:id="@+id/conversation_name" android:id="@+id/conversation_name"

View File

@ -8,7 +8,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clipChildren="false" android:clipChildren="false"
android:clipToPadding="false" android:clipToPadding="false"
android:focusable="true"> android:focusable="true"
android:textDirection="anyRtl">
<TextView <TextView
android:id="@+id/status_info" android:id="@+id/status_info"

View File

@ -7,7 +7,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clipChildren="false" android:clipChildren="false"
android:clipToPadding="false"> android:clipToPadding="false"
android:textDirection="anyRtl">
<ImageView <ImageView
android:id="@+id/status_avatar" android:id="@+id/status_avatar"

View File

@ -29,6 +29,7 @@ import android.widget.TextView
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import androidx.core.net.toUri import androidx.core.net.toUri
import app.pachli.core.activity.EmojiSpan import app.pachli.core.activity.EmojiSpan
import app.pachli.core.common.string.unicodeWrap
import app.pachli.core.network.model.HashTag import app.pachli.core.network.model.HashTag
import app.pachli.core.network.model.Status.Mention import app.pachli.core.network.model.Status.Mention
import com.mikepenz.iconics.IconicsColor import com.mikepenz.iconics.IconicsColor
@ -142,7 +143,11 @@ fun setClickableText(
val start = getSpanStart(span) val start = getSpanStart(span)
val end = getSpanEnd(span) val end = getSpanEnd(span)
val flags = getSpanFlags(span) val flags = getSpanFlags(span)
val text = subSequence(start, end) val text = subSequence(start, end)
// Wrap the text so that "@foo" or "#foo" is rendered that way in RTL text, and
// not "foo@" or "foo#".
val wrappedText = text.unicodeWrap()
val customSpan = when (text[0]) { val customSpan = when (text[0]) {
'#' -> getCustomSpanForTag(text, tags, span, listener) '#' -> getCustomSpanForTag(text, tags, span, listener)
@ -153,7 +158,8 @@ fun setClickableText(
} }
removeSpan(span) removeSpan(span)
setSpan(customSpan, start, end, flags) replace(start, end, wrappedText)
setSpan(customSpan, start, end + 1, flags)
} }
@VisibleForTesting @VisibleForTesting