mirror of https://github.com/Ashinch/ReadYou.git
fix(ui): apply "any-RTL" algorithm for correct text direction on some `Text`s (#732)
* fix(ui): apply "any-RTL" algorithm for correct direction on some `Text`s * Update Type.kt
This commit is contained in:
parent
0d0477e4ff
commit
3c8e11f086
|
@ -30,7 +30,7 @@ import androidx.compose.foundation.rememberScrollState
|
|||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.ClickableText
|
||||
import androidx.compose.foundation.text.selection.DisableSelection
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
|
@ -46,6 +46,7 @@ import androidx.compose.ui.text.font.FontStyle
|
|||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.BaselineShift
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.text.style.TextDirection
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.size.Precision
|
||||
|
@ -54,6 +55,8 @@ import coil.size.pxOrElse
|
|||
import me.ash.reader.R
|
||||
import me.ash.reader.infrastructure.preference.LocalReadingImageMaximize
|
||||
import me.ash.reader.ui.component.base.RYAsyncImage
|
||||
import me.ash.reader.ui.ext.requiresBidi
|
||||
import me.ash.reader.ui.theme.applyTextDirection
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.helper.StringUtil
|
||||
import org.jsoup.nodes.Element
|
||||
|
@ -96,6 +99,8 @@ private fun LazyListScope.formatBody(
|
|||
val composer = TextComposer { paragraphBuilder ->
|
||||
item {
|
||||
val paragraph = paragraphBuilder.toAnnotatedString()
|
||||
val requiresBidi = paragraph.toString().requiresBidi()
|
||||
val textStyle = bodyStyle().applyTextDirection(requiresBidi = requiresBidi)
|
||||
|
||||
// ClickableText prevents taps from deselecting selected text
|
||||
// So use regular Text if possible
|
||||
|
@ -104,7 +109,7 @@ private fun LazyListScope.formatBody(
|
|||
) {
|
||||
ClickableText(
|
||||
text = paragraph,
|
||||
style = bodyStyle(),
|
||||
style = textStyle,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = textHorizontalPadding().dp)
|
||||
.width(MAX_CONTENT_WIDTH.dp)
|
||||
|
@ -118,7 +123,7 @@ private fun LazyListScope.formatBody(
|
|||
} else {
|
||||
Text(
|
||||
text = paragraph,
|
||||
style = bodyStyle(),
|
||||
style = textStyle,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = textHorizontalPadding().dp)
|
||||
.width(MAX_CONTENT_WIDTH.dp)
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.text.Html
|
|||
import android.util.Base64
|
||||
import java.math.BigInteger
|
||||
import java.security.MessageDigest
|
||||
import java.text.Bidi
|
||||
|
||||
object MimeType {
|
||||
|
||||
|
@ -47,6 +48,9 @@ fun String?.decodeHTML(): String? = this?.run { Html.fromHtml(this).toString() }
|
|||
fun String?.orNotEmpty(l: (value: String) -> String): String =
|
||||
if (this.isNullOrBlank()) "" else l(this)
|
||||
|
||||
|
||||
fun String.requiresBidi(): Boolean = Bidi.requiresBidi(this.toCharArray(), 0, this.length)
|
||||
|
||||
fun String?.extractDomain(): String {
|
||||
if (this.isNullOrBlank()) return ""
|
||||
val urlMatchResult = Regex("(?<=://)([\\w\\d.-]+)").find(this)
|
||||
|
@ -56,4 +60,4 @@ fun String?.extractDomain(): String {
|
|||
val domainRegex = Regex("[\\w\\d.-]+\\.[\\w\\d.-]+")
|
||||
val domainMatchResult = domainRegex.find(this)
|
||||
return domainMatchResult?.value ?: ""
|
||||
}
|
||||
}
|
|
@ -60,10 +60,10 @@ import androidx.compose.ui.platform.LocalLayoutDirection
|
|||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.DpOffset
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.size.Precision
|
||||
import coil.size.Scale
|
||||
|
@ -84,9 +84,11 @@ import me.ash.reader.ui.component.FeedIcon
|
|||
import me.ash.reader.ui.component.base.RYAsyncImage
|
||||
import me.ash.reader.ui.component.base.SIZE_1000
|
||||
import me.ash.reader.ui.component.menu.AnimatedDropdownMenu
|
||||
import me.ash.reader.ui.ext.requiresBidi
|
||||
import me.ash.reader.ui.ext.surfaceColorAtElevation
|
||||
import me.ash.reader.ui.page.settings.color.flow.generateArticleWithFeedPreview
|
||||
import me.ash.reader.ui.theme.Shape20
|
||||
import me.ash.reader.ui.theme.applyTextDirection
|
||||
import me.ash.reader.ui.theme.palette.onDark
|
||||
|
||||
@Composable
|
||||
|
@ -230,7 +232,7 @@ fun ArticleItem(
|
|||
Text(
|
||||
text = title,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
style = MaterialTheme.typography.titleMedium.applyTextDirection(title.requiresBidi()),
|
||||
maxLines = if (articleListDesc.value) 2 else 4,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
@ -241,7 +243,9 @@ fun ArticleItem(
|
|||
modifier = Modifier.padding(top = 4.dp),
|
||||
text = shortDescription,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
style = MaterialTheme.typography.bodySmall.applyTextDirection(
|
||||
shortDescription.requiresBidi()
|
||||
),
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
|
|
@ -11,11 +11,15 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import me.ash.reader.infrastructure.preference.*
|
||||
import me.ash.reader.ui.component.reader.bodyStyle
|
||||
import me.ash.reader.ui.ext.formatAsString
|
||||
import me.ash.reader.ui.ext.openURL
|
||||
import me.ash.reader.ui.ext.requiresBidi
|
||||
import me.ash.reader.ui.ext.roundClick
|
||||
import me.ash.reader.ui.theme.applyTextDirection
|
||||
import java.util.*
|
||||
|
||||
@Composable
|
||||
|
@ -65,6 +69,8 @@ fun Metadata(
|
|||
style = MaterialTheme.typography.headlineLarge.copy(
|
||||
fontFamily = LocalReadingFonts.current.asFontFamily(context),
|
||||
fontWeight = if (titleBold.value) FontWeight.SemiBold else FontWeight.Normal,
|
||||
).applyTextDirection(
|
||||
requiresBidi = title.requiresBidi()
|
||||
),
|
||||
textAlign = titleAlign.toTextAlign(),
|
||||
)
|
||||
|
|
|
@ -5,6 +5,7 @@ import androidx.compose.ui.text.TextStyle
|
|||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextDirection
|
||||
import androidx.compose.ui.unit.sp
|
||||
import java.text.Bidi
|
||||
|
||||
// TODO: Rename file to Typography.kt and add @Stable
|
||||
|
||||
|
@ -101,7 +102,16 @@ val SystemTypography = Typography(
|
|||
),
|
||||
)
|
||||
|
||||
internal fun TextStyle.applyTextDirection() = this.copy(textDirection = TextDirection.Content)
|
||||
internal fun TextStyle.applyTextDirection(textDirection: TextDirection = TextDirection.Content) =
|
||||
this.copy(textDirection = textDirection)
|
||||
|
||||
/**
|
||||
* Resolve the text to Rtl if the text requires BiDirectional
|
||||
* @see [android.view.View.TEXT_DIRECTION_ANY_RTL]
|
||||
* @see [Bidi.requiresBidi]
|
||||
*/
|
||||
fun TextStyle.applyTextDirection(requiresBidi: Boolean) =
|
||||
this.applyTextDirection(textDirection = if (requiresBidi) TextDirection.Rtl else TextDirection.Ltr)
|
||||
|
||||
internal fun Typography.applyTextDirection() = this.copy(
|
||||
displayLarge = displayLarge.applyTextDirection(),
|
||||
|
|
Loading…
Reference in New Issue