Fixing Right To Left Text

This commit is contained in:
Vitor Pamplona
2023-07-13 19:23:26 -04:00
parent 9b62cf563a
commit 0d9399a1a4
2 changed files with 51 additions and 31 deletions

View File

@@ -30,9 +30,11 @@ data class RichTextViewerState(
val imagesForPager: ImmutableMap<String, ZoomableUrlContent>,
val imageList: ImmutableList<ZoomableUrlContent>,
val customEmoji: ImmutableMap<String, String>,
val paragraphs: ImmutableList<ImmutableList<Segment>>
val paragraphs: ImmutableList<ParagraphState>
)
data class ParagraphState(val words: ImmutableList<Segment>, val isRTL: Boolean)
object CachedRichTextParser {
val richTextCache = LruCache<String, RichTextViewerState>(200)
@@ -108,13 +110,15 @@ class RichTextParser() {
)
}
private fun findTextSegments(content: String, images: Set<String>, urls: Set<String>, emojis: Map<String, String>, tags: ImmutableListOfLists<String>): ImmutableList<ImmutableList<Segment>> {
var paragraphSegments = persistentListOf<ImmutableList<Segment>>()
private fun findTextSegments(content: String, images: Set<String>, urls: Set<String>, emojis: Map<String, String>, tags: ImmutableListOfLists<String>): ImmutableList<ParagraphState> {
var paragraphSegments = persistentListOf<ParagraphState>()
content.split('\n').forEach { paragraph ->
var segments = persistentListOf<Segment>()
var isDirty = false
val isRTL = isArabic(paragraph)
val wordList = paragraph.split(' ')
wordList.forEach { word ->
val wordSegment = wordIdentifier(word, images, urls, emojis, tags)
@@ -125,13 +129,9 @@ class RichTextParser() {
}
val newSegments = if (isDirty) {
if (isArabic(paragraph)) {
segments.asReversed().toImmutableList()
} else {
segments
}
ParagraphState(segments, isRTL)
} else {
persistentListOf<Segment>(RegularTextSegment(paragraph))
ParagraphState(persistentListOf<Segment>(RegularTextSegment(paragraph)), isRTL)
}
paragraphSegments = paragraphSegments.add(newSegments)

View File

@@ -17,16 +17,19 @@ import androidx.compose.material.ProvideTextStyle
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.takeOrElse
import androidx.compose.ui.layout.SubcomposeLayout
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.*
import androidx.compose.ui.text.style.TextDirection
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.em
import androidx.lifecycle.distinctUntilChanged
import androidx.lifecycle.map
@@ -136,7 +139,6 @@ private fun RenderRegular(
val currentTextStyle = LocalTextStyle.current
val textStyle = currentTextStyle.copy(
textDirection = TextDirection.Content,
lineHeight = 1.4.em,
color = currentTextStyle.color.takeOrElse {
LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
@@ -144,36 +146,54 @@ private fun RenderRegular(
)
MeasureSpaceWidth() { spaceWidth ->
Column {
Column() {
if (canPreview) {
// FlowRow doesn't work well with paragraphs. So we need to split them
state.paragraphs.forEach { paragraph ->
FlowRow(horizontalArrangement = Arrangement.spacedBy(spaceWidth)) {
paragraph.forEach { word ->
RenderWordWithPreview(
word,
state,
backgroundColor,
textStyle,
accountViewModel,
nav
)
val direction = if (paragraph.isRTL) {
LayoutDirection.Rtl
} else LayoutDirection.Ltr
CompositionLocalProvider(LocalLayoutDirection provides direction) {
FlowRow(
modifier = Modifier.align(if (paragraph.isRTL) Alignment.End else Alignment.Start),
horizontalArrangement = Arrangement.spacedBy(spaceWidth)
) {
paragraph.words.forEach { word ->
RenderWordWithPreview(
word,
state,
backgroundColor,
textStyle,
accountViewModel,
nav
)
}
}
}
}
} else {
// FlowRow doesn't work well with paragraphs. So we need to split them
state.paragraphs.forEach { paragraph ->
FlowRow(horizontalArrangement = Arrangement.spacedBy(spaceWidth)) {
paragraph.forEach { word ->
RenderWordWithoutPreview(
word,
state,
backgroundColor,
textStyle,
accountViewModel,
nav
)
val direction = if (paragraph.isRTL) {
LayoutDirection.Rtl
} else LayoutDirection.Ltr
CompositionLocalProvider(LocalLayoutDirection provides direction) {
FlowRow(
horizontalArrangement = Arrangement.spacedBy(spaceWidth),
modifier = Modifier.align(if (paragraph.isRTL) Alignment.End else Alignment.Start),
) {
paragraph.words.forEach { word ->
RenderWordWithoutPreview(
word,
state,
backgroundColor,
textStyle,
accountViewModel,
nav
)
}
}
}
}