support dark mode in android web reader

This commit is contained in:
Satindar Dhillon
2022-12-31 15:31:38 -08:00
parent 8fc5e608c5
commit 30ed2405e4
8 changed files with 26 additions and 15 deletions

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,7 @@ package app.omnivore.omnivore.ui.reader
import android.util.Log
import androidx.compose.foundation.clickable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.rememberScrollState
@ -42,7 +43,7 @@ fun WebPreferencesDialog(onDismiss: () -> Unit, webReaderViewModel: WebReaderVie
@Composable
fun WebPreferencesView(webReaderViewModel: WebReaderViewModel) {
val currentWebPreferences = webReaderViewModel.storedWebPreferences()
val currentWebPreferences = webReaderViewModel.storedWebPreferences(isSystemInDarkTheme())
val isFontListExpanded = remember { mutableStateOf(false) }
val highContrastTextSwitchState = remember { mutableStateOf(currentWebPreferences.prefersHighContrastText) }
val selectedWebFontRawValue = remember { mutableStateOf(currentWebPreferences.fontFamily.rawValue) }

View File

@ -10,6 +10,7 @@ import android.view.*
import android.webkit.JavascriptInterface
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.TopAppBar
@ -21,6 +22,7 @@ import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
@ -85,7 +87,7 @@ fun WebReaderLoadingContainer(slug: String, webReaderViewModel: WebReaderViewMod
.requiredHeight(height = maxToolbarHeight)
) {
}
WebReader(webReaderParams!!, webReaderViewModel.storedWebPreferences(), webReaderViewModel)
WebReader(webReaderParams!!, webReaderViewModel.storedWebPreferences(isSystemInDarkTheme()), webReaderViewModel)
}
TopAppBar(
@ -162,15 +164,18 @@ fun WebReader(
val webReaderContent = WebReaderContent(
preferences = preferences,
item = params.item,
themeKey = "LightGray",
articleContent = params.articleContent,
)
val styledContent = webReaderContent.styledContent()
val isInDarkMode = isSystemInDarkTheme()
Box {
AndroidView(factory = {
OmnivoreWebView(it).apply {
if (isInDarkMode) {
setBackgroundColor(Color.Transparent.hashCode())
}
viewModel = webReaderViewModel
layoutParams = ViewGroup.LayoutParams(

View File

@ -1,5 +1,6 @@
package app.omnivore.omnivore.ui.reader
import android.util.Log
import app.omnivore.omnivore.models.Highlight
import app.omnivore.omnivore.models.LinkedItem
import com.google.gson.Gson
@ -39,7 +40,6 @@ data class ArticleContent(
data class WebReaderContent(
val preferences: WebPreferences,
val item: LinkedItem,
val themeKey: String,
val articleContent: ArticleContent,
) {
fun styledContent(): String {
@ -49,7 +49,9 @@ data class WebReaderContent(
val publishedAt =
"new Date().toISOString()" //if (item.publishDate != null) "new Date((item.publishDate!.timeIntervalSince1970 * 1000)).toISOString()" else "undefined"
val textFontSize = preferences.textFontSize
val highlightCssFilePath = "highlight${if (themeKey == "Gray") "-dark" else ""}.css"
val highlightCssFilePath = "highlight${if (preferences.themeKey == "Gray") "-dark" else ""}.css"
Log.d("theme", "current theme is: ${preferences.themeKey}")
return """
<!DOCTYPE html>
@ -92,12 +94,12 @@ data class WebReaderContent(
highlights: ${articleContent.highlightsJSONString()},
}
window.themeKey = "${preferences.themeKey}"
window.fontSize = $textFontSize
window.fontFamily = "${preferences.fontFamily.rawValue}"
window.maxWidthPercentage = $preferences.maxWidthPercentage
window.lineHeight = $preferences.lineHeight
window.localStorage.setItem("theme", "$themeKey")
window.prefersHighContrastFont = $preferences.prefersHighContrastText
window.maxWidthPercentage = ${preferences.maxWidthPercentage}
window.lineHeight = ${preferences.lineHeight}
window.prefersHighContrastFont = ${preferences.prefersHighContrastText}
window.enableHighlightBar = false
</script>
<script src="bundle.js"></script>

View File

@ -175,7 +175,7 @@ class WebReaderViewModel @Inject constructor(
javascriptActionLoopUUIDLiveData.value = UUID.randomUUID()
}
fun storedWebPreferences(): WebPreferences = runBlocking {
fun storedWebPreferences(isDarkMode: Boolean): WebPreferences = runBlocking {
val storedFontSize = datastoreRepo.getInt(DatastoreKeys.preferredWebFontSize)
val storedLineHeight = datastoreRepo.getInt(DatastoreKeys.preferredWebLineHeight)
val storedMaxWidth = datastoreRepo.getInt(DatastoreKeys.preferredWebMaxWidthPercentage)
@ -189,7 +189,7 @@ class WebReaderViewModel @Inject constructor(
textFontSize = storedFontSize ?: 12,
lineHeight = storedLineHeight ?: 150,
maxWidthPercentage = storedMaxWidth ?: 100,
themeKey = "LightGray", // TODO: match system value
themeKey = if (isDarkMode) "Gray" else "LightGray",
fontFamily = storedWebFont,
prefersHighContrastText = prefersHighContrastFont
)

File diff suppressed because one or more lines are too long

View File

@ -15,6 +15,7 @@ declare global {
intercomSettings: IntercomSettings
analytics?: Analytics
AndroidWebKitMessenger?: AndroidWebKitMessenger
themeKey?: string
}
}

View File

@ -33,7 +33,7 @@ export function updateThemeLocally(themeId: string): void {
ThemeId.Darker,
ThemeId.Lighter,
ThemeId.Sepia,
ThemeId.Charcoal,
ThemeId.Charcoal
)
document.body.classList.add(themeId)
}
@ -70,7 +70,9 @@ export function applyStoredTheme(syncWithServer = true): ThemeId | undefined {
return undefined
}
const theme = window.localStorage.getItem(themeKey) as ThemeId | undefined
const theme = (window.themeKey || window.localStorage.getItem(themeKey)) as
| ThemeId
| undefined
if (theme && Object.values(ThemeId).includes(theme)) {
syncWithServer ? updateTheme(theme) : updateThemeLocally(theme)
}