diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/ReaderPreferencesView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/ReaderPreferencesView.kt index de19c8193..7809a56a1 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/ReaderPreferencesView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/ReaderPreferencesView.kt @@ -2,8 +2,14 @@ package app.omnivore.omnivore.feature.reader import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.* - +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.verticalScroll @@ -11,300 +17,289 @@ import androidx.compose.material.Switch import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowDropDown -import androidx.compose.material3.* -import androidx.compose.runtime.* +import androidx.compose.material3.AssistChip +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Checkbox +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.Icon +import androidx.compose.material3.Slider +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.colorResource -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import app.omnivore.omnivore.R +import app.omnivore.omnivore.core.designsystem.component.SwitchPreferenceWidget import app.omnivore.omnivore.feature.theme.OmnivoreTheme @Composable -fun ReaderPreferencesView(webReaderViewModel: WebReaderViewModel) { - val isDark = isSystemInDarkTheme() - val currentWebPreferences = webReaderViewModel.storedWebPreferences(isDark) - val isFontListExpanded = remember { mutableStateOf(false) } - val highContrastTextSwitchState = remember { mutableStateOf(currentWebPreferences.prefersHighContrastText) } +fun ReaderPreferencesView( + webReaderViewModel: WebReaderViewModel +) { + val isDark = isSystemInDarkTheme() + val currentWebPreferences = webReaderViewModel.storedWebPreferences(isDark) + val isFontListExpanded = remember { mutableStateOf(false) } + val highContrastTextSwitchState = + remember { mutableStateOf(currentWebPreferences.prefersHighContrastText) } - val justifyTextSwitchState = remember { mutableStateOf(currentWebPreferences.prefersJustifyText) } + val justifyTextSwitchState = + remember { mutableStateOf(currentWebPreferences.prefersJustifyText) } - val selectedWebFontName = remember { mutableStateOf(currentWebPreferences.fontFamily.displayText) } + val selectedWebFontName = + remember { mutableStateOf(currentWebPreferences.fontFamily.displayText) } - var fontSizeSliderValue by remember { mutableStateOf(currentWebPreferences.textFontSize.toFloat()) } - var marginSliderValue by remember { mutableStateOf(currentWebPreferences.maxWidthPercentage.toFloat()) } - var lineSpacingSliderValue by remember { mutableStateOf(currentWebPreferences.lineHeight.toFloat()) } + var fontSizeSliderValue by remember { mutableStateOf(currentWebPreferences.textFontSize.toFloat()) } + var marginSliderValue by remember { mutableStateOf(currentWebPreferences.maxWidthPercentage.toFloat()) } + var lineSpacingSliderValue by remember { mutableStateOf(currentWebPreferences.lineHeight.toFloat()) } - val themeState = remember { mutableStateOf(currentWebPreferences.storedThemePreference) } + val themeState = remember { mutableStateOf(currentWebPreferences.storedThemePreference) } - val volumeForScrollState = remember { mutableStateOf(currentWebPreferences.shouldUseVolumeRockerForScroll) } - OmnivoreTheme { - Column( - modifier = Modifier - .padding(horizontal = 15.dp) - .padding(vertical = 35.dp) - .verticalScroll(rememberScrollState()) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 15.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Text("Font", style = TextStyle( - fontSize = 15.sp, - fontWeight = FontWeight.Normal, - color = Color(red = 137, green = 137, blue = 137) - )) - Spacer(modifier = Modifier.weight(1.0F)) - Box { - AssistChip( - onClick = { isFontListExpanded.value = true }, - label = { Text(selectedWebFontName.value, color = Color(red = 137, green = 137, blue = 137)) }, - trailingIcon = { - Icon( - Icons.Default.ArrowDropDown, - contentDescription = "Choose the Reader font", - tint = Color(red = 137, green = 137, blue = 137) - ) - }, - ) - if (isFontListExpanded.value) { - DropdownMenu( - expanded = isFontListExpanded.value, - onDismissRequest = { isFontListExpanded.value = false }, - ) { - WebFont.values().forEach { - DropdownMenuItem( - text = { - Text(it.displayText, style = TextStyle( - fontSize = 15.sp, - fontWeight = FontWeight.Normal, - color = Color(red = 137, green = 137, blue = 137) - )) - }, - onClick = { - webReaderViewModel.applyWebFont(it) - selectedWebFontName.value = it.displayText - isFontListExpanded.value = false - }, - ) + val volumeForScrollState by webReaderViewModel.volumeRockerForScrollState.collectAsStateWithLifecycle() + + OmnivoreTheme { + // Temporary wrapping for margin while migrating components to design system + Column( + modifier = Modifier + .padding(vertical = 35.dp) + .verticalScroll(rememberScrollState()) + ) { + Column( + modifier = Modifier + .padding(horizontal = 15.dp) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 15.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + "Font", style = TextStyle( + fontSize = 15.sp, + fontWeight = FontWeight.Normal, + color = Color(red = 137, green = 137, blue = 137) + ) + ) + Spacer(modifier = Modifier.weight(1.0F)) + Box { + AssistChip( + onClick = { isFontListExpanded.value = true }, + label = { + Text( + selectedWebFontName.value, + color = Color(red = 137, green = 137, blue = 137) + ) + }, + trailingIcon = { + Icon( + Icons.Default.ArrowDropDown, + contentDescription = "Choose the Reader font", + tint = Color(red = 137, green = 137, blue = 137) + ) + }, + ) + if (isFontListExpanded.value) { + DropdownMenu( + expanded = isFontListExpanded.value, + onDismissRequest = { isFontListExpanded.value = false }, + ) { + WebFont.values().forEach { + DropdownMenuItem( + text = { + Text( + it.displayText, style = TextStyle( + fontSize = 15.sp, + fontWeight = FontWeight.Normal, + color = Color(red = 137, green = 137, blue = 137) + ) + ) + }, + onClick = { + webReaderViewModel.applyWebFont(it) + selectedWebFontName.value = it.displayText + isFontListExpanded.value = false + }, + ) + } + } + } + } + } + + Text( + stringResource(R.string.reader_preferences_view_font_size), style = TextStyle( + fontSize = 15.sp, + fontWeight = FontWeight.Normal, + color = Color(red = 137, green = 137, blue = 137) + ) + ) + Slider( + value = fontSizeSliderValue, + onValueChange = { + fontSizeSliderValue = it + webReaderViewModel.setFontSize(it.toInt()) + }, + steps = 40, + valueRange = 10f..50f, + ) + + Text( + stringResource(R.string.reader_preferences_view_margin), style = TextStyle( + fontSize = 15.sp, + fontWeight = FontWeight.Normal, + color = Color(red = 137, green = 137, blue = 137) + ) + ) + Slider( + value = marginSliderValue, + onValueChange = { + marginSliderValue = it + webReaderViewModel.setMaxWidthPercentage(it.toInt()) + }, + steps = 40, + valueRange = 60f..100f, + ) + + Text( + stringResource(R.string.reader_preferences_view_line_spacing), style = TextStyle( + fontSize = 15.sp, + fontWeight = FontWeight.Normal, + color = Color(red = 137, green = 137, blue = 137) + ) + ) + Slider( + value = lineSpacingSliderValue, + onValueChange = { + lineSpacingSliderValue = it + webReaderViewModel.setLineHeight(it.toInt()) + }, + steps = 50, + valueRange = 100f..300f, + ) + + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(vertical = 4.dp) + ) { + Text( + stringResource(R.string.reader_preferences_view_theme), style = TextStyle( + fontSize = 15.sp, + fontWeight = FontWeight.Normal, + color = Color(red = 137, green = 137, blue = 137) + ) + ) + Spacer(modifier = Modifier.weight(1.0F)) + Text( + stringResource(R.string.reader_preferences_view_auto), style = TextStyle( + fontSize = 10.sp, + fontWeight = FontWeight.Normal, + color = Color(red = 137, green = 137, blue = 137) + ) + ) + Checkbox(checked = themeState.value == "System", onCheckedChange = { + if (it) { + themeState.value = "System" + webReaderViewModel.updateStoredThemePreference("System") + } else { + val newThemeKey = if (isDark) "Black" else "Light" + themeState.value = newThemeKey + webReaderViewModel.updateStoredThemePreference(newThemeKey) + } + }) + } + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.Start, + ) { + for (theme in Themes.values()) { + if (theme.themeKey != "System") { + val isSelected = theme.themeKey == themeState.value + Button( + onClick = { + themeState.value = theme.themeKey + webReaderViewModel.updateStoredThemePreference(theme.themeKey) + }, + shape = CircleShape, + border = BorderStroke( + 3.dp, + if (isSelected) colorResource(R.color.cta_yellow) else Color.Transparent + ), + modifier = Modifier.size(35.dp), + colors = ButtonDefaults.buttonColors( + + containerColor = Color(theme.backgroundColor) + ) + ) { + + } + Spacer(modifier = Modifier.weight(0.1F)) + } + + } + Spacer(modifier = Modifier.weight(2.0F)) + } + + Row(verticalAlignment = Alignment.CenterVertically) { + Text( + stringResource(R.string.reader_preferences_view_high_constrast_text), + style = TextStyle( + fontSize = 15.sp, + fontWeight = FontWeight.Normal, + color = Color(red = 137, green = 137, blue = 137) + ) + ) + Spacer(modifier = Modifier.weight(1.0F)) + Switch(checked = highContrastTextSwitchState.value, onCheckedChange = { + highContrastTextSwitchState.value = it + webReaderViewModel.updateHighContrastTextPreference(it) + }) + } + + Row(verticalAlignment = Alignment.CenterVertically) { + Text( + stringResource(R.string.reader_preferences_view_justify_text), + style = TextStyle( + fontSize = 15.sp, + fontWeight = FontWeight.Normal, + color = Color(red = 137, green = 137, blue = 137) + ) + ) + Spacer(modifier = Modifier.weight(1.0F)) + Switch(checked = justifyTextSwitchState.value, onCheckedChange = { + justifyTextSwitchState.value = it + webReaderViewModel.updateJustifyText(it) + }) + } } - } - } - } - } - - Text(stringResource(R.string.reader_preferences_view_font_size), style = TextStyle( - fontSize = 15.sp, - fontWeight = FontWeight.Normal, - color = Color(red = 137, green = 137, blue = 137) - )) - Slider( - value = fontSizeSliderValue, - onValueChange = { - fontSizeSliderValue = it - webReaderViewModel.setFontSize(it.toInt()) - }, - steps = 40, - valueRange = 10f..50f, - ) - - Text(stringResource(R.string.reader_preferences_view_margin), style = TextStyle( - fontSize = 15.sp, - fontWeight = FontWeight.Normal, - color = Color(red = 137, green = 137, blue = 137) - )) - Slider( - value = marginSliderValue, - onValueChange = { - marginSliderValue = it - webReaderViewModel.setMaxWidthPercentage(it.toInt()) - }, - steps = 40, - valueRange = 60f..100f, - ) - - Text(stringResource(R.string.reader_preferences_view_line_spacing), style = TextStyle( - fontSize = 15.sp, - fontWeight = FontWeight.Normal, - color = Color(red = 137, green = 137, blue = 137) - )) - Slider( - value = lineSpacingSliderValue, - onValueChange = { - lineSpacingSliderValue = it - webReaderViewModel.setLineHeight(it.toInt()) - }, - steps = 50, - valueRange = 100f..300f, - ) - - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .padding(vertical = 4.dp) - ) { - Text(stringResource(R.string.reader_preferences_view_theme), style = TextStyle( - fontSize = 15.sp, - fontWeight = FontWeight.Normal, - color = Color(red = 137, green = 137, blue = 137) - )) - Spacer(modifier = Modifier.weight(1.0F)) - Text(stringResource(R.string.reader_preferences_view_auto), style = TextStyle( - fontSize = 10.sp, - fontWeight = FontWeight.Normal, - color = Color(red = 137, green = 137, blue = 137) - )) - Checkbox( - checked = themeState.value == "System", - onCheckedChange = { - if (it) { - themeState.value = "System" - webReaderViewModel.updateStoredThemePreference("System") - } else { - val newThemeKey = if (isDark) "Black" else "Light" - themeState.value = newThemeKey - webReaderViewModel.updateStoredThemePreference(newThemeKey) - } - }) - } - Row( - modifier = Modifier - .fillMaxWidth(), - horizontalArrangement = Arrangement.Start, - ) { - for(theme in Themes.values()) { - if (theme.themeKey != "System") { - val isSelected = theme.themeKey == themeState.value - Button( - onClick = { - themeState.value = theme.themeKey - webReaderViewModel.updateStoredThemePreference(theme.themeKey) - }, - shape = CircleShape, - border = BorderStroke(3.dp, if (isSelected) colorResource(R.color.cta_yellow) else Color.Transparent), - modifier = Modifier.size(35.dp), - colors = ButtonDefaults.buttonColors( - - containerColor = Color(theme.backgroundColor) + SwitchPreferenceWidget( + title = stringResource(R.string.reader_preferences_view_volume_scroll), + checked = volumeForScrollState, + onCheckedChanged = { webReaderViewModel.setVolumeRockerForScrollState(it) }, ) - ) { - - } - Spacer(modifier = Modifier.weight(0.1F)) } - - } - Spacer(modifier = Modifier.weight(2.0F)) } - - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - stringResource(R.string.reader_preferences_view_high_constrast_text), - style = TextStyle( - fontSize = 15.sp, - fontWeight = FontWeight.Normal, - color = Color(red = 137, green = 137, blue = 137) - )) - Spacer(modifier = Modifier.weight(1.0F)) - Switch( - checked = highContrastTextSwitchState.value, - onCheckedChange = { - highContrastTextSwitchState.value = it - webReaderViewModel.updateHighContrastTextPreference(it) - } - ) - } - - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - stringResource(R.string.reader_preferences_view_justify_text), - style = TextStyle( - fontSize = 15.sp, - fontWeight = FontWeight.Normal, - color = Color(red = 137, green = 137, blue = 137)) - ) - Spacer(modifier = Modifier.weight(1.0F)) - Switch( - checked = justifyTextSwitchState.value, - onCheckedChange = { - justifyTextSwitchState.value = it - webReaderViewModel.updateJustifyText(it) - } - ) - } - - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - stringResource(R.string.reader_preferences_view_volume_scroll), - style = TextStyle( - fontSize = 15.sp, - fontWeight = FontWeight.Normal, - color = Color(red = 137, green = 137, blue = 137)) - ) - Spacer(modifier = Modifier.weight(1.0F)) - Switch ( - checked = volumeForScrollState.value, - onCheckedChange = { - volumeForScrollState.value = it - webReaderViewModel.updateVolumeRockerForScroll(it) - } - ) - } - } -} -} - -@Composable -fun Stepper(label: String, onIncrease: () -> Unit, onDecrease: () -> Unit) { - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = label, - modifier = Modifier - .padding(bottom = 6.dp) - ) - - Spacer(modifier = Modifier.weight(1.0F)) - - IconButton(onClick = { onDecrease() }) { - Icon( - painter = painterResource(id = R.drawable.minus), - contentDescription = null - ) - } - - Divider( - color = Color.Black, - modifier = Modifier - .height(20.dp) - .width(1.dp) - ) - - IconButton(onClick = { onIncrease() }) { - Icon( - painter = painterResource(id = R.drawable.plus), - contentDescription = null - ) - } - } } data class WebPreferences( - val textFontSize: Int, - val lineHeight: Int, - val maxWidthPercentage: Int, - val themeKey: String, - val storedThemePreference: String, - val fontFamily: WebFont, - val prefersHighContrastText: Boolean, - val prefersJustifyText: Boolean, - var shouldUseVolumeRockerForScroll: Boolean + val textFontSize: Int, + val lineHeight: Int, + val maxWidthPercentage: Int, + val themeKey: String, + val storedThemePreference: String, + val fontFamily: WebFont, + val prefersHighContrastText: Boolean, + val prefersJustifyText: Boolean ) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReader.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReader.kt index e56d10853..3e89a456c 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReader.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReader.kt @@ -22,6 +22,7 @@ import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.viewinterop.AndroidView +import androidx.lifecycle.compose.collectAsStateWithLifecycle import app.omnivore.omnivore.R import com.google.gson.Gson import kotlinx.coroutines.CoroutineScope @@ -32,7 +33,9 @@ import java.util.* @SuppressLint("SetJavaScriptEnabled") @Composable fun WebReader( - styledContent: String, webReaderViewModel: WebReaderViewModel, currentTheme: Themes? + styledContent: String, + webReaderViewModel: WebReaderViewModel, + currentTheme: Themes? ) { val javascriptActionLoopUUID: UUID by webReaderViewModel.javascriptActionLoopUUIDLiveData.observeAsState( UUID.randomUUID() @@ -41,6 +44,8 @@ fun WebReader( WebView.setWebContentsDebuggingEnabled(true) + val volumeForScrollState by webReaderViewModel.volumeRockerForScrollState.collectAsStateWithLifecycle() + Box { AndroidView(factory = { OmnivoreWebView(it).apply { @@ -170,7 +175,7 @@ fun WebReader( if (event.action == KeyEvent.ACTION_DOWN) { when (keyCode) { KeyEvent.KEYCODE_VOLUME_UP -> { - if (!webReaderViewModel.shouldUseVolumeRockerForScroll) { + if (!volumeForScrollState) { return@setOnKeyListener false } scrollVertically(OmnivoreWebView.Direction.UP) @@ -178,7 +183,7 @@ fun WebReader( } KeyEvent.KEYCODE_VOLUME_DOWN -> { - if (!webReaderViewModel.shouldUseVolumeRockerForScroll) { + if (!volumeForScrollState) { return@setOnKeyListener false } scrollVertically(OmnivoreWebView.Direction.DOWN) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderViewModel.kt index 78d03ad51..e5483272f 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderViewModel.kt @@ -28,6 +28,7 @@ import app.omnivore.omnivore.core.database.dao.SavedItemDao import app.omnivore.omnivore.core.database.entities.SavedItem import app.omnivore.omnivore.core.database.entities.SavedItemLabel import app.omnivore.omnivore.core.datastore.DatastoreRepository +import app.omnivore.omnivore.core.datastore.followingTabActive import app.omnivore.omnivore.core.datastore.preferredTheme import app.omnivore.omnivore.core.datastore.preferredWebFontFamily import app.omnivore.omnivore.core.datastore.preferredWebFontSize @@ -35,6 +36,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.volumeForScroll import app.omnivore.omnivore.core.network.Networker import app.omnivore.omnivore.core.network.createNewLabel import app.omnivore.omnivore.core.network.saveUrl @@ -42,14 +44,16 @@ import app.omnivore.omnivore.core.network.savedItem import app.omnivore.omnivore.feature.components.HighlightColor import app.omnivore.omnivore.feature.library.SavedItemAction import app.omnivore.omnivore.graphql.generated.type.CreateLabelInput -import app.omnivore.omnivore.utils.DatastoreKeys import com.apollographql.apollo3.api.Optional.Companion.presentIfNotNull import com.google.gson.Gson import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext @@ -83,7 +87,7 @@ enum class Themes( @HiltViewModel class WebReaderViewModel @Inject constructor( - private val datastoreRepo: DatastoreRepository, + private val datastoreRepository: DatastoreRepository, private val dataService: DataService, private val networker: Networker, private val eventTracker: EventTracker, @@ -457,28 +461,27 @@ class WebReaderViewModel @Inject constructor( javascriptActionLoopUUIDLiveData.value = UUID.randomUUID() } - val currentThemeKey: LiveData = datastoreRepo + val currentThemeKey: LiveData = datastoreRepository .themeKeyFlow .distinctUntilChanged() .asLiveData() fun storedWebPreferences(isDarkMode: Boolean): WebPreferences = runBlocking { - val storedFontSize = datastoreRepo.getInt(preferredWebFontSize) - val storedLineHeight = datastoreRepo.getInt(preferredWebLineHeight) - val storedMaxWidth = datastoreRepo.getInt(preferredWebMaxWidthPercentage) + val storedFontSize = datastoreRepository.getInt(preferredWebFontSize) + val storedLineHeight = datastoreRepository.getInt(preferredWebLineHeight) + val storedMaxWidth = datastoreRepository.getInt(preferredWebMaxWidthPercentage) val storedFontFamily = - datastoreRepo.getString(preferredWebFontFamily) ?: WebFont.SYSTEM.rawValue + datastoreRepository.getString(preferredWebFontFamily) ?: WebFont.SYSTEM.rawValue val storedThemePreference = - datastoreRepo.getString(preferredTheme) ?: "System" + datastoreRepository.getString(preferredTheme) ?: "System" val storedWebFont = WebFont.entries.firstOrNull { it.rawValue == storedFontFamily } ?: WebFont.entries .first() val prefersHighContrastFont = - datastoreRepo.getString(prefersWebHighContrastText) == "true" - val prefersJustifyText = datastoreRepo.getString(DatastoreKeys.prefersJustifyText) == "true" - val shouldUseVolumeRockerForScroll = datastoreRepo.getString(DatastoreKeys.volumeForScroll) != "false" + datastoreRepository.getString(prefersWebHighContrastText) == "true" + val prefersJustifyText = datastoreRepository.getString(prefersJustifyText) == "true" WebPreferences( textFontSize = storedFontSize ?: 12, @@ -488,8 +491,7 @@ class WebReaderViewModel @Inject constructor( storedThemePreference = storedThemePreference, fontFamily = storedWebFont, prefersHighContrastText = prefersHighContrastFont, - prefersJustifyText = prefersJustifyText, - shouldUseVolumeRockerForScroll = shouldUseVolumeRockerForScroll + prefersJustifyText = prefersJustifyText ) } @@ -505,7 +507,7 @@ class WebReaderViewModel @Inject constructor( Log.d("theme", "Setting theme key: $newThemeKey") runBlocking { - datastoreRepo.putString(preferredTheme, newThemeKey) + datastoreRepository.putString(preferredTheme, newThemeKey) } val script = @@ -515,7 +517,7 @@ class WebReaderViewModel @Inject constructor( fun setFontSize(newFontSize: Int) { runBlocking { - datastoreRepo.putInt(preferredWebFontSize, newFontSize) + datastoreRepository.putInt(preferredWebFontSize, newFontSize) } val script = "var event = new Event('updateFontSize');event.fontSize = '$newFontSize';document.dispatchEvent(event);" @@ -524,7 +526,7 @@ class WebReaderViewModel @Inject constructor( fun setMaxWidthPercentage(newMaxWidthPercentageValue: Int) { runBlocking { - datastoreRepo.putInt( + datastoreRepository.putInt( preferredWebMaxWidthPercentage, newMaxWidthPercentageValue ) @@ -536,7 +538,7 @@ class WebReaderViewModel @Inject constructor( fun setLineHeight(newLineHeight: Int) { runBlocking { - datastoreRepo.putInt(preferredWebLineHeight, newLineHeight) + datastoreRepository.putInt(preferredWebLineHeight, newLineHeight) } val script = "var event = new Event('updateLineHeight');event.lineHeight = '$newLineHeight';document.dispatchEvent(event);" @@ -545,7 +547,7 @@ class WebReaderViewModel @Inject constructor( fun updateHighContrastTextPreference(prefersHighContrastText: Boolean) { runBlocking { - datastoreRepo.putString( + datastoreRepository.putString( prefersWebHighContrastText, prefersHighContrastText.toString() ) @@ -558,23 +560,30 @@ class WebReaderViewModel @Inject constructor( fun updateJustifyText(justifyText: Boolean) { runBlocking { - datastoreRepo.putString(prefersJustifyText, justifyText.toString()) + datastoreRepository.putString(prefersJustifyText, justifyText.toString()) } val script = "var event = new Event('updateJustifyText');event.justifyText = $justifyText;document.dispatchEvent(event);" enqueueScript(script) } - fun updateVolumeRockerForScroll(shouldUseVolumeRockerForScroll: Boolean) { - runBlocking { - datastoreRepo.putString(DatastoreKeys.volumeForScroll, shouldUseVolumeRockerForScroll.toString()) + val volumeRockerForScrollState: StateFlow = datastoreRepository.getBoolean( + volumeForScroll + ).stateIn( + scope = viewModelScope, + started = SharingStarted.Lazily, + initialValue = false + ) + + fun setVolumeRockerForScrollState(value: Boolean) { + viewModelScope.launch { + datastoreRepository.putBoolean(volumeForScroll, value) } - this.shouldUseVolumeRockerForScroll = shouldUseVolumeRockerForScroll } fun applyWebFont(font: WebFont) { runBlocking { - datastoreRepo.putString(preferredWebFontFamily, font.rawValue) + datastoreRepository.putString(preferredWebFontFamily, font.rawValue) } val script =