diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebPreferencesDialog.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebPreferencesDialog.kt index 3a967f554..a0b55f298 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebPreferencesDialog.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebPreferencesDialog.kt @@ -1,47 +1,31 @@ package app.omnivore.omnivore.ui.reader import android.util.Log -import androidx.compose.foundation.clickable +import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.rememberLazyListState + import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.Switch import androidx.compose.material.Text -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Check -import androidx.compose.material.icons.filled.KeyboardArrowDown -import androidx.compose.material.icons.filled.KeyboardArrowRight -import androidx.compose.material3.Divider -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.Surface -import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember +import androidx.compose.material3.* +import androidx.compose.runtime.* 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.text.TextStyle +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.Dialog +import androidx.compose.ui.unit.sp import app.omnivore.omnivore.R import app.omnivore.omnivore.ui.components.SegmentedControl - -@Composable -fun WebPreferencesDialog(onDismiss: () -> Unit, webReaderViewModel: WebReaderViewModel) { - Dialog(onDismissRequest = { onDismiss() }) { - Surface( - shape = RoundedCornerShape(16.dp), - color = Color.White, - modifier = Modifier - .height(350.dp) - ) { - WebPreferencesView(webReaderViewModel) - } - } -} +import app.omnivore.omnivore.ui.theme.OmnivoreTheme @Composable fun WebPreferencesView(webReaderViewModel: WebReaderViewModel) { @@ -54,125 +38,207 @@ fun WebPreferencesView(webReaderViewModel: WebReaderViewModel) { val selectedWebFontRawValue = remember { mutableStateOf(currentWebPreferences.fontFamily.rawValue) } + + 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 themeListState = rememberLazyListState() + + OmnivoreTheme() { Column( modifier = Modifier - .padding(top = 6.dp, start = 6.dp, end = 6.dp, bottom = 6.dp) + .padding(horizontal = 15.dp) + .verticalScroll(rememberScrollState()) ) { Row( modifier = Modifier .fillMaxWidth() - .padding(top = 12.dp, bottom = 12.dp), - horizontalArrangement = Arrangement.Center + .padding(bottom = 15.dp), + verticalAlignment = Alignment.CenterVertically, ) { - Text("Web Preferences") - } - - Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) - ) { - Stepper( - label = "Font Size:", - onIncrease = { webReaderViewModel.updateFontSize(isIncrease = true) }, - onDecrease = { webReaderViewModel.updateFontSize(isIncrease = false) } - ) - - Stepper( - label = "Margin:", - onIncrease = { webReaderViewModel.updateMaxWidthPercentage(isIncrease = false) }, - onDecrease = { webReaderViewModel.updateMaxWidthPercentage(isIncrease = true) } - ) - - Stepper( - label = "Line Spacing:", - onIncrease = { webReaderViewModel.updateLineSpacing(isIncrease = true) }, - onDecrease = { webReaderViewModel.updateLineSpacing(isIncrease = false) } - ) - - Row(verticalAlignment = Alignment.CenterVertically) { - Text("High Contrast Text") - Spacer(modifier = Modifier.weight(1.0F)) - Switch( - checked = highContrastTextSwitchState.value, - onCheckedChange = { - highContrastTextSwitchState.value = it - webReaderViewModel.updateHighContrastTextPreference(it) - } - ) - } - - Row(verticalAlignment = Alignment.CenterVertically) { - Text("Justify Text") - Spacer(modifier = Modifier.weight(1.0F)) - Switch( - checked = justifyTextSwitchState.value, - onCheckedChange = { - justifyTextSwitchState.value = it - webReaderViewModel.updateJustifyText(it) - } - ) - } - - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .padding(vertical = 4.dp) - ) { - Text("Theme:") - Spacer(modifier = Modifier.weight(1.0F)) - SegmentedControl( - items = webReaderViewModel.systemThemeKeys, - initialSelectedItemIndex = webReaderViewModel.systemThemeKeys.indexOf(currentWebPreferences.storedThemePreference) + 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 { + OutlinedButton( + shape = RoundedCornerShape(4.dp), + onClick = { isFontListExpanded.value = true }, + colors = ButtonDefaults.buttonColors( + contentColor = Color(red = 137, green = 137, blue = 137), + // containerColor = Color.Transparent, + ), ) { - webReaderViewModel.updateStoredThemePreference(it, isDark) + Text(selectedWebFontRawValue.value) } - } - - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .clickable(onClick = { isFontListExpanded.value = !isFontListExpanded.value }) - ) { - Text("Font Family") - Spacer(modifier = Modifier.weight(1.0F)) - Icon( - imageVector = - if (isFontListExpanded.value) - Icons.Filled.KeyboardArrowDown - else - Icons.Filled.KeyboardArrowRight, - contentDescription = null - ) - } - - if (isFontListExpanded.value) { - WebFont.values().forEach { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .clickable(onClick = { - webReaderViewModel.applyWebFont(it) - selectedWebFontRawValue.value = it.rawValue - }) + if (isFontListExpanded.value) { + DropdownMenu( + expanded = isFontListExpanded.value, + onDismissRequest = { isFontListExpanded.value = false } ) { - Text( - it.displayText, - modifier = Modifier - .padding(top = 6.dp, start = 6.dp, end = 6.dp, bottom = 6.dp) - ) - Spacer(modifier = Modifier.weight(1.0F)) - if (it.rawValue == selectedWebFontRawValue.value) { - Icon( - imageVector = Icons.Filled.Check, - contentDescription = null + WebFont.values().forEach { + DropdownMenuItem( + text = { Text(it.displayText) }, + onClick = { + webReaderViewModel.applyWebFont(it) + selectedWebFontRawValue.value = it.rawValue + isFontListExpanded.value = false + }, + colors = MenuDefaults.itemColors( + textColor = Color(red = 137, green = 137, blue = 137), + ) ) } } } } } + + Text("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 = 10, + valueRange = 8f..28f, + ) + + Text("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 = 4, + valueRange = 60f..100f, + ) + + Text("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 = 8, + valueRange = 100f..300f, + ) + + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .padding(vertical = 4.dp) + ) { + Text("Theme:", style = TextStyle( + fontSize = 15.sp, + fontWeight = FontWeight.Normal, + color = Color(red = 137, green = 137, blue = 137) + )) + Spacer(modifier = Modifier.weight(1.0F)) + Text("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", isDark) + } else { + val newThemeKey = if (isDark) "Black" else "Light" + themeState.value = newThemeKey + webReaderViewModel.updateStoredThemePreference(newThemeKey, isDark) + } + }) + } + 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, isDark) + }, + 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("High Contrast 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("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) + } + ) + } } } +} @Composable fun Stepper(label: String, onIncrease: () -> Unit, onDecrease: () -> Unit) { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt index 7d64466ce..e08adbea8 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt @@ -11,12 +11,14 @@ import androidx.activity.viewModels import androidx.compose.foundation.background import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.* -import androidx.compose.material.TopAppBar +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.Home import androidx.compose.material.icons.filled.Menu import androidx.compose.material.icons.filled.Settings +import androidx.compose.material3.* import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme @@ -25,6 +27,7 @@ import androidx.compose.runtime.* import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity @@ -42,9 +45,8 @@ import app.omnivore.omnivore.ui.theme.OmnivoreTheme import com.google.accompanist.systemuicontroller.rememberSystemUiController import dagger.hilt.android.AndroidEntryPoint import kotlin.math.roundToInt -import androidx.navigation.compose.rememberNavController -import app.omnivore.omnivore.Routes import app.omnivore.omnivore.ui.notebook.NotebookActivity +import kotlinx.coroutines.launch @AndroidEntryPoint @@ -105,6 +107,7 @@ class WebReaderLoadingContainerActivity: ComponentActivity() { } } +@OptIn(ExperimentalMaterialApi::class) @Composable fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null, onLibraryIconTap: (() -> Unit)? = null, webReaderViewModel: WebReaderViewModel) { val onBackPressedDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher @@ -112,6 +115,10 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null, o var isMenuExpanded by remember { mutableStateOf(false) } var showWebPreferencesDialog by remember { mutableStateOf(false ) } + val isDark = isSystemInDarkTheme() + val currentWebPreferences = webReaderViewModel.storedWebPreferences(isDark) + val currentTheme = Themes.values().find { it.themeKey == currentWebPreferences.themeKey } + val webReaderParams: WebReaderParams? by webReaderViewModel.webReaderParamsLiveData.observeAsState(null) val annotation: String? by webReaderViewModel.annotationLiveData.observeAsState(null) val shouldPopView: Boolean by webReaderViewModel.shouldPopViewLiveData.observeAsState(false) @@ -123,6 +130,7 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null, o webReaderViewModel.loadItem(slug = slug, requestID = requestID) val context = LocalContext.current + val coroutineScope = rememberCoroutineScope() val styledContent = webReaderParams?.let { val webReaderContent = WebReaderContent( @@ -133,111 +141,169 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null, o webReaderContent.styledContent() } ?: null - Box( - modifier = Modifier - .fillMaxSize() - .systemBarsPadding() - .background(color = backgroundColor) - ) { - if (styledContent != null) { - WebReader( - preferences = webReaderViewModel.storedWebPreferences(isSystemInDarkTheme()), - styledContent = styledContent, - webReaderViewModel = webReaderViewModel - ) + val modalBottomSheetState = rememberModalBottomSheetState( + ModalBottomSheetValue.Hidden, + ) - TopAppBar( - modifier = Modifier - .height(height = with(LocalDensity.current) { - toolbarHeightPx.roundToInt().toDp() - }), - backgroundColor = MaterialTheme.colorScheme.surfaceVariant, - title = {}, - navigationIcon = { - IconButton(onClick = { - onBackPressedDispatcher?.onBackPressed() - }) { - Icon( - imageVector = androidx.compose.material.icons.Icons.Filled.ArrowBack, - modifier = Modifier, - contentDescription = "Back" - ) - } - }, - actions = { - if (onLibraryIconTap != null) { - IconButton(onClick = { onLibraryIconTap() }) { - Icon( - imageVector = Icons.Default.Home, - contentDescription = null - ) - } - } - webReaderParams?.let { + ModalBottomSheetLayout( + modifier = Modifier.statusBarsPadding(), + sheetBackgroundColor = Color.Transparent, + sheetState = modalBottomSheetState, + sheetContent = { + if (showWebPreferencesDialog) { + BottomSheetUI("Reader Preferences") { + WebPreferencesView(webReaderViewModel) + } + } + Spacer(modifier = Modifier.weight(1.0F)) + } + ) { + Box( + modifier = Modifier + .fillMaxSize() + .systemBarsPadding() + .background(color = backgroundColor) + ) { + if (styledContent != null) { + WebReader( + preferences = webReaderViewModel.storedWebPreferences(isSystemInDarkTheme()), + styledContent = styledContent, + webReaderViewModel = webReaderViewModel + ) + + TopAppBar( + modifier = Modifier + .height(height = with(LocalDensity.current) { + toolbarHeightPx.roundToInt().toDp() + }), + backgroundColor = Color(currentTheme?.backgroundColor ?: 0xFFFFFFFF), // MaterialTheme.colorScheme.surfaceVariant, + title = {}, + navigationIcon = { IconButton(onClick = { - val intent = Intent(context, NotebookActivity::class.java) - intent.putExtra("SAVED_ITEM_ID", it.item.savedItemId) - context.startActivity(intent) + onBackPressedDispatcher?.onBackPressed() }) { Icon( - painter = painterResource(id = R.drawable.notebook), + imageVector = Icons.Filled.ArrowBack, + modifier = Modifier, + contentDescription = "Back" + ) + } + }, + actions = { + if (onLibraryIconTap != null) { + IconButton(onClick = { onLibraryIconTap() }) { + Icon( + imageVector = Icons.Default.Home, + contentDescription = null + ) + } + } + webReaderParams?.let { + IconButton(onClick = { + val intent = Intent(context, NotebookActivity::class.java) + intent.putExtra("SAVED_ITEM_ID", it.item.savedItemId) + context.startActivity(intent) + }) { + Icon( + painter = painterResource(id = R.drawable.notebook), + contentDescription = null + ) + } + } + IconButton(onClick = { + showWebPreferencesDialog = true + coroutineScope.launch { + modalBottomSheetState.show() + } + }) { + Icon( + painter = painterResource(id = R.drawable.format_letter_case), contentDescription = null ) } - } - IconButton(onClick = { showWebPreferencesDialog = true }) { - Icon( - painter = painterResource(id = R.drawable.format_letter_case), - contentDescription = null - ) - } - IconButton(onClick = { isMenuExpanded = true }) { - Icon( - painter = painterResource(id = R.drawable.dots_horizontal), - contentDescription = null - ) - } - SavedItemContextMenu( - isExpanded = isMenuExpanded, - isArchived = webReaderParams!!.item.isArchived, - onDismiss = { isMenuExpanded = false }, - actionHandler = { - webReaderViewModel.handleSavedItemAction( - webReaderParams!!.item.savedItemId, - it + IconButton(onClick = { isMenuExpanded = true }) { + Icon( + painter = painterResource(id = R.drawable.dots_horizontal), + contentDescription = null ) } + SavedItemContextMenu( + isExpanded = isMenuExpanded, + isArchived = webReaderParams!!.item.isArchived, + onDismiss = { isMenuExpanded = false }, + actionHandler = { + webReaderViewModel.handleSavedItemAction( + webReaderParams!!.item.savedItemId, + it + ) + } + ) + } + ) + + if (annotation != null) { + AnnotationEditView( + initialAnnotation = annotation!!, + onSave = { + webReaderViewModel.saveAnnotation(it) + }, + onCancel = { + webReaderViewModel.cancelAnnotationEdit() + } ) } - ) - if (showWebPreferencesDialog) { - WebPreferencesDialog( - onDismiss = { - showWebPreferencesDialog = false - }, - webReaderViewModel = webReaderViewModel - ) + WebReaderLabelsSelectionSheet(webReaderViewModel) } - if (annotation != null) { - AnnotationEditView( - initialAnnotation = annotation!!, - onSave = { - webReaderViewModel.saveAnnotation(it) - }, - onCancel = { - webReaderViewModel.cancelAnnotationEdit() - } - ) - } - - WebReaderLabelsSelectionSheet(webReaderViewModel) - } - - LaunchedEffect(shouldPopView) { - if (shouldPopView) { - onBackPressedDispatcher?.onBackPressed() + LaunchedEffect(shouldPopView) { + if (shouldPopView) { + onBackPressedDispatcher?.onBackPressed() + } + } + } + } +} + +@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class) +@Composable +fun BottomSheetUI(title: String?, content: @Composable () -> Unit) { + val onBackPressedDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher + + Box( + modifier = Modifier + .wrapContentHeight() + .fillMaxWidth() + .clip(RoundedCornerShape(topEnd = 20.dp, topStart = 20.dp)) + .background(Color.White) + .statusBarsPadding() + ) { + Scaffold( + topBar = { + TopAppBar( + title = { Text(title ?: "") }, + modifier = Modifier.statusBarsPadding(), + colors = TopAppBarDefaults.topAppBarColors( + containerColor = MaterialTheme.colorScheme.background + ), +// navigationIcon = { +// IconButton(onClick = { +// onBackPressedDispatcher?.onBackPressed() +// }) { +// Icon( +// imageVector = Icons.Filled.ArrowBack, +// modifier = Modifier, +// contentDescription = "Back" +// ) +// } +// } + ) + } + ) { paddingValues -> + Box(modifier = Modifier + .padding(paddingValues) + .fillMaxSize()) { + content() } } } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt index 9689656fc..ec6470a39 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt @@ -37,6 +37,15 @@ data class AnnotationWebViewMessage( val annotation: String? ) +enum class Themes(val themeKey: String, val backgroundColor: Long) { + SYSTEM("System", 0xFFFFFFFF), + LIGHT("Light", 0xFF000000), + SEPIA("Sepia", 0xFFFBF0D9), + DARK("Dark", 0xFF2a2a2a), + APOLLO("Apollo", 0xFF6A6968), + BLACK("Black", 0xFFFFFFFF), +} + @HiltViewModel class WebReaderViewModel @Inject constructor( private val datastoreRepo: DatastoreRepository, @@ -56,9 +65,6 @@ class WebReaderViewModel @Inject constructor( val showLabelsSelectionSheetLiveData = MutableLiveData(false) val savedItemLabelsLiveData = dataService.db.savedItemLabelDao().getSavedItemLabelsLiveData() - // "Sepia", "Apollo", - val systemThemeKeys = listOf("Light", "Black", "System") - var hasTappedExistingHighlight = false var lastTapCoordinates: TapCoordinates? = null private var isLoading = false @@ -288,59 +294,37 @@ class WebReaderViewModel @Inject constructor( return storedThemePreference } - fun updateStoredThemePreference(index: Int, isDarkMode: Boolean) { - val newThemeKey = themeKey(isDarkMode, systemThemeKeys[index]) + fun updateStoredThemePreference(newThemeKey: String, isDarkMode: Boolean) { Log.d("theme", "Setting theme key: ${newThemeKey}") runBlocking { - datastoreRepo.putString(DatastoreKeys.preferredTheme, systemThemeKeys[index]) + datastoreRepo.putString(DatastoreKeys.preferredTheme, newThemeKey) } val script = "var event = new Event('updateTheme');event.themeName = '$newThemeKey';document.dispatchEvent(event);" enqueueScript(script) } - fun updateFontSize(isIncrease: Boolean) { - val delta = if (isIncrease) 2 else -2 - var newFontSize: Int - + fun setFontSize(newFontSize: Int) { runBlocking { - val storedFontSize = datastoreRepo.getInt(DatastoreKeys.preferredWebFontSize) - newFontSize = ((storedFontSize ?: 12) + delta).coerceIn(8, 28) datastoreRepo.putInt(DatastoreKeys.preferredWebFontSize, newFontSize) } - - // Get value from data store and then update it val script = "var event = new Event('updateFontSize');event.fontSize = '$newFontSize';document.dispatchEvent(event);" enqueueScript(script) } - fun updateMaxWidthPercentage(isIncrease: Boolean) { - val delta = if (isIncrease) 10 else -10 - var newMaxWidthPercentageValue: Int - + fun setMaxWidthPercentage(newMaxWidthPercentageValue: Int) { runBlocking { - val storedWidth = datastoreRepo.getInt(DatastoreKeys.preferredWebMaxWidthPercentage) - newMaxWidthPercentageValue = ((storedWidth ?: 100) + delta).coerceIn(40, 100) datastoreRepo.putInt(DatastoreKeys.preferredWebMaxWidthPercentage, newMaxWidthPercentageValue) } - - // Get value from data store and then update it val script = "var event = new Event('updateMaxWidthPercentage');event.maxWidthPercentage = '$newMaxWidthPercentageValue';document.dispatchEvent(event);" enqueueScript(script) } - fun updateLineSpacing(isIncrease: Boolean) { - val delta = if (isIncrease) 25 else -25 - var newLineHeight: Int - + fun setLineHeight(newLineHeight: Int) { runBlocking { - val storedHeight = datastoreRepo.getInt(DatastoreKeys.preferredWebLineHeight) - newLineHeight = ((storedHeight ?: 150) + delta).coerceIn(100, 300) datastoreRepo.putInt(DatastoreKeys.preferredWebLineHeight, newLineHeight) } - - // Get value from data store and then update it val script = "var event = new Event('updateLineHeight');event.lineHeight = '$newLineHeight';document.dispatchEvent(event);" enqueueScript(script) }