add right to left text support

This commit is contained in:
Stefano Sansone 2024-06-24 01:25:31 +02:00
parent d40701f918
commit d61c3916f9
7 changed files with 51 additions and 18 deletions

View file

@ -18,3 +18,4 @@ const val lastUsedSavedItemSortFilter = "lastUsedSavedItemSortFilter"
const val preferredTheme = "preferredTheme"
const val followingTabActive = "followingTabActive"
const val volumeForScroll = "volumeForScroll"
const val rtlText = "rtlText"

View file

@ -46,7 +46,7 @@ import app.omnivore.omnivore.feature.components.SliderWithPlusMinus
import app.omnivore.omnivore.feature.theme.OmnivoreTheme
@Composable
fun ReaderPreferencesView(
fun ReaderPreferencesSheet(
webReaderViewModel: WebReaderViewModel
) {
val isDark = isSystemInDarkTheme()
@ -74,6 +74,8 @@ fun ReaderPreferencesView(
val volumeForScrollState by webReaderViewModel.volumeRockerForScrollState.collectAsStateWithLifecycle()
val rtlTextState by webReaderViewModel.rtlTextState.collectAsStateWithLifecycle()
OmnivoreTheme {
// Temporary wrapping for margin while migrating components to design system
Column(
@ -282,6 +284,11 @@ fun ReaderPreferencesView(
checked = volumeForScrollState,
onCheckedChanged = { webReaderViewModel.setVolumeRockerForScrollState(it) },
)
SwitchPreferenceWidget(
title = stringResource(R.string.reader_preferences_view_use_rtl),
checked = rtlTextState,
onCheckedChanged = { webReaderViewModel.setRtlTextState(it) },
)
}
}
}

View file

@ -168,6 +168,7 @@ fun WebReader(
"utf-8",
null
)
Log.d("HTMLContent", styledContent)
requestFocus()
setOnKeyListener { _, keyCode, event ->
if (event.action == KeyEvent.ACTION_DOWN) {

View file

@ -7,32 +7,25 @@ import com.google.gson.Gson
enum class WebFont(val displayText: String, val rawValue: String) {
INTER("Inter", "Inter"), SYSTEM("System Default", "system-ui"), OPEN_DYSLEXIC(
"Open Dyslexic",
"OpenDyslexic"
"Open Dyslexic", "OpenDyslexic"
),
MERRIWEATHER("Merriweather", "Merriweather"), LORA("Lora", "Lora"), OPEN_SANS(
"Open Sans",
"Open Sans"
"Open Sans", "Open Sans"
),
ROBOTO("Roboto", "Roboto"), CRIMSON_TEXT(
"Crimson Text",
"Crimson Text"
"Crimson Text", "Crimson Text"
),
SOURCE_SERIF_PRO("Source Serif Pro", "Source Serif Pro"), NEWSREADER(
"Newsreader",
"Newsreader"
"Newsreader", "Newsreader"
),
LEXEND("Lexend", "Lexend"), LXGWWENKAI(
"LXGW WenKai",
"LXGWWenKai"
"LXGW WenKai", "LXGWWenKai"
),
ATKINSON_HYPERLEGIBLE(
"Atkinson Hyperlegible",
"AtkinsonHyperlegible"
"Atkinson Hyperlegible", "AtkinsonHyperlegible"
),
SOURCE_SANS_PRO("Source Sans Pro", "SourceSansPro"), IBM_PLEX_SANS(
"IBM Plex Sans",
"IBMPlexSans"
"IBM Plex Sans", "IBMPlexSans"
),
LITERATA("Literata", "Literata"), FRAUNCES("Fraunces", "Fraunces"),
}
@ -55,6 +48,7 @@ data class ArticleContent(
data class WebReaderContent(
val preferences: WebPreferences,
val rtlText: Boolean,
val item: SavedItem,
val articleContent: ArticleContent,
) {
@ -68,6 +62,17 @@ data class WebReaderContent(
val highlightCssFilePath =
"highlight${if (preferences.themeKey == "Dark" || preferences.themeKey == "Black") "-dark" else ""}.css"
val rtlCss = if (rtlText) {
"""
body, html, #_omnivore-htmlContent, p, a, div, span {
direction: rtl;
text-align: right;
}
"""
} else {
""
}
Log.d("theme", "current theme is: ${preferences.themeKey}")
Log.d("sync", "HIGHLIGHTS JSON: ${articleContent.highlightsJSONString()}")
@ -80,6 +85,7 @@ data class WebReaderContent(
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no' />
<style>
@import url("$highlightCssFilePath");
$rtlCss
</style>
</head>
<body>

View file

@ -161,20 +161,22 @@ fun WebReaderLoadingContainer(
val darkTheme = isSystemInDarkTheme()
val rtlTextState by webReaderViewModel.rtlTextState.collectAsStateWithLifecycle()
val styledContent by remember {
derivedStateOf {
webReaderParams?.let {
val webReaderContent = WebReaderContent(
preferences = webReaderViewModel.storedWebPreferences(darkTheme),
rtlText = rtlTextState,
item = it.item,
articleContent = it.articleContent,
articleContent = it.articleContent
)
webReaderContent.styledContent()
}
}
}
val modalBottomSheetState = rememberModalBottomSheetState(
initialValue = ModalBottomSheetValue.Hidden,
skipHalfExpanded = bottomSheetState == BottomSheetState.EDITNOTE || bottomSheetState == BottomSheetState.HIGHLIGHTNOTE,
@ -217,7 +219,7 @@ fun WebReaderLoadingContainer(
when (bottomSheetState) {
BottomSheetState.PREFERENCES -> {
BottomSheetUI {
ReaderPreferencesView(webReaderViewModel)
ReaderPreferencesSheet(webReaderViewModel)
}
}

View file

@ -32,6 +32,7 @@ import app.omnivore.omnivore.core.datastore.preferredWebLineHeight
import app.omnivore.omnivore.core.datastore.preferredWebMaxWidthPercentage
import app.omnivore.omnivore.core.datastore.prefersJustifyText
import app.omnivore.omnivore.core.datastore.prefersWebHighContrastText
import app.omnivore.omnivore.core.datastore.rtlText
import app.omnivore.omnivore.core.datastore.volumeForScroll
import app.omnivore.omnivore.core.network.Networker
import app.omnivore.omnivore.core.network.createNewLabel
@ -132,6 +133,14 @@ class WebReaderViewModel @Inject constructor(
}
}
val rtlTextState: StateFlow<Boolean> = datastoreRepository.getBoolean(
rtlText
).stateIn(
scope = viewModelScope,
started = SharingStarted.Eagerly,
initialValue = false
)
fun showNavBar() {
onScrollChange(maxToolbarHeightPx)
}
@ -581,6 +590,12 @@ class WebReaderViewModel @Inject constructor(
}
}
fun setRtlTextState(value: Boolean) {
viewModelScope.launch {
datastoreRepository.putBoolean(rtlText, value)
}
}
fun applyWebFont(font: WebFont) {
runBlocking {
datastoreRepository.putString(preferredWebFontFamily, font.rawValue)

View file

@ -154,6 +154,7 @@
<string name="reader_preferences_view_high_constrast_text">High Contrast Text</string>
<string name="reader_preferences_view_justify_text">Justify Text</string>
<string name="reader_preferences_view_volume_scroll">Use Volume Rocker to scroll</string>
<string name="reader_preferences_view_use_rtl">Right-to-left text</string>
<!-- WebReaderLoadingContainer -->
<string name="web_reader_loading_container_error_msg">We were unable to fetch your content.</string>