🛠️ MainState rework
* Non-null variables * Better, scalable structure
This commit is contained in:
parent
9561357f65
commit
3b287ff1a0
28 changed files with 206 additions and 197 deletions
|
|
@ -109,13 +109,13 @@ class Activity : AppCompatActivity() {
|
|||
|
||||
if (isLoaded.value) {
|
||||
BookStoryTheme(
|
||||
theme = state.value.theme!!,
|
||||
isDark = state.value.darkTheme!!.isDark(),
|
||||
isPureDark = state.value.pureDark!!.isPureDark(this),
|
||||
themeContrast = state.value.themeContrast!!
|
||||
theme = state.value.theme,
|
||||
isDark = state.value.darkTheme.isDark(),
|
||||
isPureDark = state.value.pureDark.isPureDark(this),
|
||||
themeContrast = state.value.themeContrast
|
||||
) {
|
||||
NavigationHost(
|
||||
startScreen = if (state.value.showStartScreen!!) Screen.Start
|
||||
startScreen = if (state.value.showStartScreen) Screen.Start
|
||||
else Screen.Library
|
||||
) {
|
||||
navigation(
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import android.os.Build
|
|||
import android.os.Parcelable
|
||||
import androidx.annotation.Keep
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import ua.acclorite.book_story.domain.util.Constants
|
||||
import ua.acclorite.book_story.domain.util.DataStoreConstants
|
||||
|
|
@ -37,169 +38,179 @@ import java.util.Locale
|
|||
@Parcelize
|
||||
data class MainState(
|
||||
// General Settings
|
||||
val language: String? = null,
|
||||
val theme: Theme? = null,
|
||||
val darkTheme: DarkTheme? = null,
|
||||
val pureDark: PureDark? = null,
|
||||
val themeContrast: ThemeContrast? = null,
|
||||
val showStartScreen: Boolean? = null,
|
||||
val checkForUpdates: Boolean? = null,
|
||||
val doublePressExit: Boolean? = null,
|
||||
val language: String = provideDefaultValue {
|
||||
val locale = Locale.getDefault().language.take(2)
|
||||
Constants.LANGUAGES.any { locale == it.first }.run {
|
||||
if (this) locale
|
||||
else "en"// Default language.
|
||||
}
|
||||
},
|
||||
val theme: Theme = provideDefaultValue {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Theme.DYNAMIC
|
||||
else Theme.BLUE
|
||||
},
|
||||
val darkTheme: DarkTheme = provideDefaultValue { DarkTheme.FOLLOW_SYSTEM },
|
||||
val pureDark: PureDark = provideDefaultValue { PureDark.OFF },
|
||||
val themeContrast: ThemeContrast = provideDefaultValue { ThemeContrast.STANDARD },
|
||||
val showStartScreen: Boolean = provideDefaultValue { true },
|
||||
val checkForUpdates: Boolean = provideDefaultValue { false },
|
||||
val doublePressExit: Boolean = provideDefaultValue { false },
|
||||
|
||||
// Reader Settings
|
||||
val fontFamily: String? = null,
|
||||
val isItalic: Boolean? = null,
|
||||
val fontSize: Int? = null,
|
||||
val lineHeight: Int? = null,
|
||||
val paragraphHeight: Int? = null,
|
||||
val paragraphIndentation: Boolean? = null,
|
||||
val sidePadding: Int? = null,
|
||||
val doubleClickTranslation: Boolean? = null,
|
||||
val fastColorPresetChange: Boolean? = null,
|
||||
val textAlignment: ReaderTextAlignment? = null,
|
||||
val letterSpacing: Int? = null,
|
||||
val fontFamily: String = provideDefaultValue { Constants.FONTS[0].id },
|
||||
val isItalic: Boolean = provideDefaultValue { false },
|
||||
val fontSize: Int = provideDefaultValue { 16 },
|
||||
val lineHeight: Int = provideDefaultValue { 4 },
|
||||
val paragraphHeight: Int = provideDefaultValue { 8 },
|
||||
val paragraphIndentation: Boolean = provideDefaultValue { false },
|
||||
val sidePadding: Int = provideDefaultValue { 6 },
|
||||
val doubleClickTranslation: Boolean = provideDefaultValue { false },
|
||||
val fastColorPresetChange: Boolean = provideDefaultValue { true },
|
||||
val textAlignment: ReaderTextAlignment = provideDefaultValue { ReaderTextAlignment.START },
|
||||
val letterSpacing: Int = provideDefaultValue { 0 },
|
||||
|
||||
// Browse Settings
|
||||
val browseFilesStructure: BrowseFilesStructure? = null,
|
||||
val browseLayout: BrowseLayout? = null,
|
||||
val browseAutoGridSize: Boolean? = null,
|
||||
val browseGridSize: Int? = null,
|
||||
val browsePinFavoriteDirectories: Boolean? = null,
|
||||
val browseSortOrder: BrowseSortOrder? = null,
|
||||
val browseSortOrderDescending: Boolean? = null,
|
||||
val browseIncludedFilterItems: List<String>? = null,
|
||||
val browseFilesStructure: BrowseFilesStructure = provideDefaultValue {
|
||||
BrowseFilesStructure.DIRECTORIES
|
||||
},
|
||||
val browseLayout: BrowseLayout = provideDefaultValue { BrowseLayout.LIST },
|
||||
val browseAutoGridSize: Boolean = provideDefaultValue { true },
|
||||
val browseGridSize: Int = provideDefaultValue { 0 },
|
||||
val browsePinFavoriteDirectories: Boolean = provideDefaultValue { true },
|
||||
val browseSortOrder: BrowseSortOrder = provideDefaultValue { BrowseSortOrder.LAST_MODIFIED },
|
||||
val browseSortOrderDescending: Boolean = provideDefaultValue { true },
|
||||
val browseIncludedFilterItems: List<String> = provideDefaultValue { emptyList() },
|
||||
) : Parcelable {
|
||||
companion object {
|
||||
/**
|
||||
* Initializes [MainState] by given [Map].
|
||||
* If no value provided in [data], assigns default value.
|
||||
*/
|
||||
fun initialize(data: Map<String, Any>): MainState {
|
||||
DataStoreConstants.apply {
|
||||
val language: String = data[LANGUAGE.name] as? String ?: if (
|
||||
Constants.LANGUAGES.any { Locale.getDefault().language.take(2) == it.first }
|
||||
) {
|
||||
Locale.getDefault().language.take(2)
|
||||
} else {
|
||||
"en"
|
||||
}
|
||||
val defaultState = MainState()
|
||||
fun <V, T> provideValue(
|
||||
key: Preferences.Key<T>,
|
||||
convert: T.() -> V = { this as V },
|
||||
default: MainState.() -> V
|
||||
): V {
|
||||
return (data[key.name] as? T)?.convert() ?: defaultState.default()
|
||||
}
|
||||
|
||||
val theme: String = data[THEME.name] as? String ?: if (
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||
) Theme.DYNAMIC.name else Theme.BLUE.name
|
||||
return DataStoreConstants.run {
|
||||
MainState(
|
||||
language = provideValue(
|
||||
LANGUAGE
|
||||
) { language },
|
||||
|
||||
val darkTheme: String = data[DARK_THEME.name] as? String
|
||||
?: DarkTheme.FOLLOW_SYSTEM.name
|
||||
theme = provideValue(
|
||||
THEME, convert = { toTheme() }
|
||||
) { theme },
|
||||
|
||||
val pureDark: String = data[PURE_DARK.name] as? String
|
||||
?: PureDark.OFF.name
|
||||
darkTheme = provideValue(
|
||||
DARK_THEME, convert = { toDarkTheme() }
|
||||
) { darkTheme },
|
||||
|
||||
val themeContrast: String = data[THEME_CONTRAST.name] as? String
|
||||
?: ThemeContrast.STANDARD.name
|
||||
pureDark = provideValue(
|
||||
PURE_DARK, convert = { toPureDark() }
|
||||
) { pureDark },
|
||||
|
||||
val showStartScreen: Boolean = data[SHOW_START_SCREEN.name] as? Boolean
|
||||
?: true
|
||||
themeContrast = provideValue(
|
||||
THEME_CONTRAST, convert = { toThemeContrast() }
|
||||
) { themeContrast },
|
||||
|
||||
val fontFamily: String = data[FONT.name] as? String
|
||||
?: Constants.FONTS[0].id
|
||||
showStartScreen = provideValue(
|
||||
SHOW_START_SCREEN
|
||||
) { showStartScreen },
|
||||
|
||||
val isItalic: Boolean = data[IS_ITALIC.name] as? Boolean
|
||||
?: false
|
||||
fontFamily = provideValue(
|
||||
FONT
|
||||
) { fontFamily },
|
||||
|
||||
val fontSize: Int = data[FONT_SIZE.name] as? Int
|
||||
?: 16
|
||||
isItalic = provideValue(
|
||||
IS_ITALIC
|
||||
) { isItalic },
|
||||
|
||||
val lineHeight: Int = data[LINE_HEIGHT.name] as? Int
|
||||
?: 4
|
||||
fontSize = provideValue(
|
||||
FONT_SIZE
|
||||
) { fontSize },
|
||||
|
||||
val paragraphHeight: Int = data[PARAGRAPH_HEIGHT.name] as? Int
|
||||
?: 8
|
||||
lineHeight = provideValue(
|
||||
LINE_HEIGHT
|
||||
) { lineHeight },
|
||||
|
||||
val paragraphIndentation: Boolean = data[PARAGRAPH_INDENTATION.name] as? Boolean
|
||||
?: false
|
||||
paragraphHeight = provideValue(
|
||||
PARAGRAPH_HEIGHT
|
||||
) { paragraphHeight },
|
||||
|
||||
val checkForUpdates: Boolean = data[CHECK_FOR_UPDATES.name] as? Boolean
|
||||
?: false
|
||||
paragraphIndentation = provideValue(
|
||||
PARAGRAPH_INDENTATION
|
||||
) { paragraphIndentation },
|
||||
|
||||
val sidePadding: Int = data[SIDE_PADDING.name] as? Int
|
||||
?: 6
|
||||
checkForUpdates = provideValue(
|
||||
CHECK_FOR_UPDATES
|
||||
) { checkForUpdates },
|
||||
|
||||
val doubleClickTranslation: Boolean =
|
||||
data[DOUBLE_CLICK_TRANSLATION.name] as? Boolean
|
||||
?: false
|
||||
sidePadding = provideValue(
|
||||
SIDE_PADDING
|
||||
) { sidePadding },
|
||||
|
||||
val fastColorPresetChange: Boolean =
|
||||
data[FAST_COLOR_PRESET_CHANGE.name] as? Boolean
|
||||
?: true
|
||||
doubleClickTranslation = provideValue(
|
||||
DOUBLE_CLICK_TRANSLATION
|
||||
) { doubleClickTranslation },
|
||||
|
||||
val browseFilesStructure: String = data[BROWSE_FILES_STRUCTURE.name] as? String
|
||||
?: BrowseFilesStructure.DIRECTORIES.name
|
||||
fastColorPresetChange = provideValue(
|
||||
FAST_COLOR_PRESET_CHANGE
|
||||
) { fastColorPresetChange },
|
||||
|
||||
val browseLayout: String = data[BROWSE_LAYOUT.name] as? String
|
||||
?: BrowseLayout.LIST.name
|
||||
browseFilesStructure = provideValue(
|
||||
BROWSE_FILES_STRUCTURE, convert = { toFilesStructure() }
|
||||
) { browseFilesStructure },
|
||||
|
||||
val browseAutoGridSize: Boolean =
|
||||
data[BROWSE_AUTO_GRID_SIZE.name] as? Boolean
|
||||
?: true
|
||||
browseLayout = provideValue(
|
||||
BROWSE_LAYOUT, convert = { toBrowseLayout() }
|
||||
) { browseLayout },
|
||||
|
||||
val browseGridSize: Int =
|
||||
data[BROWSE_GRID_SIZE.name] as? Int
|
||||
?: 0
|
||||
browseAutoGridSize = provideValue(
|
||||
BROWSE_AUTO_GRID_SIZE
|
||||
) { browseAutoGridSize },
|
||||
|
||||
val browsePinFavoriteDirectories: Boolean =
|
||||
data[BROWSE_PIN_FAVORITE_DIRECTORIES.name] as? Boolean
|
||||
?: true
|
||||
browseGridSize = provideValue(
|
||||
BROWSE_GRID_SIZE
|
||||
) { browseGridSize },
|
||||
|
||||
val browseSortOrder: String =
|
||||
data[BROWSE_SORT_ORDER.name] as? String
|
||||
?: BrowseSortOrder.LAST_MODIFIED.name
|
||||
browsePinFavoriteDirectories = provideValue(
|
||||
BROWSE_PIN_FAVORITE_DIRECTORIES
|
||||
) { browsePinFavoriteDirectories },
|
||||
|
||||
val browseSortOrderDescending: Boolean =
|
||||
data[BROWSE_SORT_ORDER_DESCENDING.name] as? Boolean
|
||||
?: true
|
||||
browseSortOrder = provideValue(
|
||||
BROWSE_SORT_ORDER, convert = { toBrowseSortOrder() }
|
||||
) { browseSortOrder },
|
||||
|
||||
val browseIncludedFilterItems =
|
||||
(data[BROWSE_INCLUDED_FILTER_ITEMS.name] as? Set<String>)?.toList()
|
||||
?: emptyList()
|
||||
browseSortOrderDescending = provideValue(
|
||||
BROWSE_SORT_ORDER_DESCENDING
|
||||
) { browseSortOrderDescending },
|
||||
|
||||
val textAlignment = data[TEXT_ALIGNMENT.name] as? String
|
||||
?: ReaderTextAlignment.START.name
|
||||
browseIncludedFilterItems = provideValue(
|
||||
BROWSE_INCLUDED_FILTER_ITEMS, convert = { toList() }
|
||||
) { browseIncludedFilterItems },
|
||||
|
||||
val doublePressExit = data[DOUBLE_PRESS_EXIT.name] as? Boolean
|
||||
?: false
|
||||
textAlignment = provideValue(
|
||||
TEXT_ALIGNMENT, convert = { toTextAlignment() }
|
||||
) { textAlignment },
|
||||
|
||||
val letterSpacing = data[LETTER_SPACING.name] as? Int
|
||||
?: 0
|
||||
doublePressExit = provideValue(
|
||||
DOUBLE_PRESS_EXIT
|
||||
) { doublePressExit },
|
||||
|
||||
return MainState(
|
||||
language = language,
|
||||
theme = theme.toTheme(),
|
||||
darkTheme = darkTheme.toDarkTheme(),
|
||||
pureDark = pureDark.toPureDark(),
|
||||
themeContrast = themeContrast.toThemeContrast(),
|
||||
showStartScreen = showStartScreen,
|
||||
fontFamily = fontFamily,
|
||||
isItalic = isItalic,
|
||||
fontSize = fontSize,
|
||||
lineHeight = lineHeight,
|
||||
paragraphHeight = paragraphHeight,
|
||||
paragraphIndentation = paragraphIndentation,
|
||||
checkForUpdates = checkForUpdates,
|
||||
sidePadding = sidePadding,
|
||||
doubleClickTranslation = doubleClickTranslation,
|
||||
fastColorPresetChange = fastColorPresetChange,
|
||||
browseFilesStructure = browseFilesStructure.toFilesStructure(),
|
||||
browseLayout = browseLayout.toBrowseLayout(),
|
||||
browseAutoGridSize = browseAutoGridSize,
|
||||
browseGridSize = browseGridSize,
|
||||
browsePinFavoriteDirectories = browsePinFavoriteDirectories,
|
||||
browseSortOrder = browseSortOrder.toBrowseSortOrder(),
|
||||
browseSortOrderDescending = browseSortOrderDescending,
|
||||
browseIncludedFilterItems = browseIncludedFilterItems,
|
||||
textAlignment = textAlignment.toTextAlignment(),
|
||||
doublePressExit = doublePressExit,
|
||||
letterSpacing = letterSpacing,
|
||||
letterSpacing = provideValue(
|
||||
LETTER_SPACING
|
||||
) { letterSpacing },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D> provideDefaultValue(calculation: () -> D): D {
|
||||
return calculation()
|
||||
}
|
||||
|
|
@ -318,7 +318,7 @@ class MainViewModel @Inject constructor(
|
|||
|
||||
is MainEvent.OnChangeBrowseIncludedFilterItem -> {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val set = _state.value.browseIncludedFilterItems!!.toMutableSet()
|
||||
val set = _state.value.browseIncludedFilterItems.toMutableSet()
|
||||
if (!set.add(event.item)) {
|
||||
set.remove(event.item)
|
||||
}
|
||||
|
|
@ -384,9 +384,9 @@ class MainViewModel @Inject constructor(
|
|||
val settings = getAllSettings.execute(viewModelScope)
|
||||
|
||||
// All additional execution
|
||||
changeLanguage.execute(settings.language!!)
|
||||
changeLanguage.execute(settings.language)
|
||||
|
||||
if (settings.checkForUpdates == true) {
|
||||
if (settings.checkForUpdates) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
checkForUpdates.execute(
|
||||
postNotification = true
|
||||
|
|
@ -394,9 +394,7 @@ class MainViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
updateStateWithSavedHandle {
|
||||
settings
|
||||
}
|
||||
updateStateWithSavedHandle { settings }
|
||||
isSettingsReady.update { true }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ private fun BrowseScreen(
|
|||
true -> {
|
||||
onEvent(
|
||||
BrowseEvent.OnSelectFile(
|
||||
includedFileFormats = mainState.value.browseIncludedFilterItems!!,
|
||||
includedFileFormats = mainState.value.browseIncludedFilterItems,
|
||||
file = selectableFile
|
||||
)
|
||||
)
|
||||
|
|
@ -194,7 +194,7 @@ private fun BrowseScreen(
|
|||
false -> {
|
||||
onEvent(
|
||||
BrowseEvent.OnSelectFile(
|
||||
includedFileFormats = mainState.value.browseIncludedFilterItems!!,
|
||||
includedFileFormats = mainState.value.browseIncludedFilterItems,
|
||||
file = selectableFile
|
||||
)
|
||||
)
|
||||
|
|
@ -211,7 +211,7 @@ private fun BrowseScreen(
|
|||
} else {
|
||||
onEvent(
|
||||
BrowseEvent.OnSelectFile(
|
||||
includedFileFormats = mainState.value.browseIncludedFilterItems!!,
|
||||
includedFileFormats = mainState.value.browseIncludedFilterItems,
|
||||
file = selectableFile
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ fun BrowseLayout(
|
|||
onFavoriteItemClick: (SelectableFile) -> Unit,
|
||||
onItemClick: (SelectableFile) -> Unit
|
||||
) {
|
||||
when (mainState.value.browseLayout!!) {
|
||||
when (mainState.value.browseLayout) {
|
||||
BrowseLayout.LIST -> {
|
||||
BrowseListLayout(
|
||||
state = state,
|
||||
|
|
@ -43,8 +43,8 @@ fun BrowseLayout(
|
|||
BrowseLayout.GRID -> {
|
||||
BrowseGridLayout(
|
||||
state = state,
|
||||
gridSize = mainState.value.browseGridSize!!,
|
||||
autoGridSize = mainState.value.browseAutoGridSize!!,
|
||||
gridSize = mainState.value.browseGridSize,
|
||||
autoGridSize = mainState.value.browseAutoGridSize,
|
||||
filteredFiles = filteredFiles,
|
||||
onLongItemClick = onLongItemClick,
|
||||
onFavoriteItemClick = onFavoriteItemClick,
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ fun BrowseTopBar(
|
|||
}
|
||||
val isScrolled = remember {
|
||||
derivedStateOf {
|
||||
when (mainState.value.browseLayout!!) {
|
||||
when (mainState.value.browseLayout) {
|
||||
BrowseLayout.LIST -> state.value.listState.canScrollBackward
|
||||
BrowseLayout.GRID -> state.value.gridState.canScrollBackward
|
||||
}
|
||||
|
|
@ -155,7 +155,7 @@ fun BrowseTopBar(
|
|||
contentDescription = R.string.filter_content_desc,
|
||||
disableOnClick = false,
|
||||
color = animateColorAsState(
|
||||
if (mainState.value.browseIncludedFilterItems!!.isNotEmpty()) {
|
||||
if (mainState.value.browseIncludedFilterItems.isNotEmpty()) {
|
||||
MaterialTheme.colorScheme.primary
|
||||
} else LocalContentColor.current,
|
||||
label = ""
|
||||
|
|
@ -195,7 +195,7 @@ fun BrowseTopBar(
|
|||
) {
|
||||
onEvent(
|
||||
BrowseEvent.OnSelectFiles(
|
||||
includedFileFormats = mainState.value.browseIncludedFilterItems!!,
|
||||
includedFileFormats = mainState.value.browseIncludedFilterItems,
|
||||
files = filteredFiles
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -601,7 +601,7 @@ class BrowseViewModel @Inject constructor(
|
|||
fun <T> thenCompareBy(
|
||||
selector: (T) -> Comparable<*>?
|
||||
): Comparator<T> {
|
||||
return if (mainState.browseSortOrderDescending!!) {
|
||||
return if (mainState.browseSortOrderDescending) {
|
||||
compareByDescending(selector)
|
||||
} else {
|
||||
compareBy(selector)
|
||||
|
|
@ -609,7 +609,7 @@ class BrowseViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun List<SelectableFile>.filterFiles(): List<SelectableFile> {
|
||||
if (mainState.browseIncludedFilterItems!!.isEmpty()) {
|
||||
if (mainState.browseIncludedFilterItems.isEmpty()) {
|
||||
return this
|
||||
}
|
||||
|
||||
|
|
@ -649,7 +649,7 @@ class BrowseViewModel @Inject constructor(
|
|||
if (
|
||||
Environment.getExternalStorageDirectory() == _state.value.selectedDirectory
|
||||
&& it.isFavorite
|
||||
&& mainState.browsePinFavoriteDirectories!!
|
||||
&& mainState.browsePinFavoriteDirectories
|
||||
) {
|
||||
return@filter true
|
||||
}
|
||||
|
|
@ -658,20 +658,20 @@ class BrowseViewModel @Inject constructor(
|
|||
}
|
||||
.sortedWith(
|
||||
compareByDescending<SelectableFile> {
|
||||
when (mainState.browsePinFavoriteDirectories!!) {
|
||||
when (mainState.browsePinFavoriteDirectories) {
|
||||
true -> it.isFavorite
|
||||
false -> true
|
||||
}
|
||||
}.then(
|
||||
compareByDescending {
|
||||
when (mainState.browseSortOrder!! != BrowseSortOrder.FILE_TYPE) {
|
||||
when (mainState.browseSortOrder != BrowseSortOrder.FILE_TYPE) {
|
||||
true -> it.isDirectory
|
||||
false -> true
|
||||
}
|
||||
}
|
||||
).then(
|
||||
thenCompareBy {
|
||||
when (mainState.browseSortOrder!!) {
|
||||
when (mainState.browseSortOrder) {
|
||||
BrowseSortOrder.NAME -> {
|
||||
it.fileOrDirectory.name.lowercase().trim()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ private fun LibraryScreen(
|
|||
return@BackHandler
|
||||
}
|
||||
|
||||
if (shouldExit || !mainState.value.doublePressExit!!) {
|
||||
if (shouldExit || !mainState.value.doublePressExit) {
|
||||
activity.finish()
|
||||
return@BackHandler
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,19 +211,19 @@ private fun ReaderScreen(
|
|||
mainState.value.fontSize,
|
||||
mainState.value.lineHeight
|
||||
) {
|
||||
(mainState.value.fontSize!! + mainState.value.lineHeight!!).sp
|
||||
(mainState.value.fontSize + mainState.value.lineHeight).sp
|
||||
}
|
||||
val letterSpacing = remember(mainState.value.letterSpacing) {
|
||||
(mainState.value.letterSpacing!! / 100f).em
|
||||
(mainState.value.letterSpacing / 100f).em
|
||||
}
|
||||
val sidePadding = remember(mainState.value.sidePadding) {
|
||||
(mainState.value.sidePadding!! * 3).dp
|
||||
(mainState.value.sidePadding * 3).dp
|
||||
}
|
||||
val paragraphHeight = remember(mainState.value.paragraphHeight) {
|
||||
(mainState.value.paragraphHeight!! * 3).dp
|
||||
(mainState.value.paragraphHeight * 3).dp
|
||||
}
|
||||
val fontStyle = remember(mainState.value.isItalic) {
|
||||
when (mainState.value.isItalic!!) {
|
||||
when (mainState.value.isItalic) {
|
||||
true -> FontStyle.Italic
|
||||
false -> FontStyle.Normal
|
||||
}
|
||||
|
|
@ -354,7 +354,7 @@ private fun ReaderScreen(
|
|||
}
|
||||
)
|
||||
.readerFastColorPresetChange(
|
||||
fastColorPresetChangeEnabled = mainState.value.fastColorPresetChange!!,
|
||||
fastColorPresetChangeEnabled = mainState.value.fastColorPresetChange,
|
||||
isLoading = state.value.loading,
|
||||
toolbarHidden = toolbarHidden,
|
||||
onSettingsEvent = onSettingsEvent,
|
||||
|
|
@ -389,12 +389,12 @@ private fun ReaderScreen(
|
|||
fontColor = fontColor.value,
|
||||
lineHeight = lineHeight,
|
||||
fontStyle = fontStyle,
|
||||
textAlignment = mainState.value.textAlignment!!,
|
||||
fontSize = mainState.value.fontSize!!.sp,
|
||||
textAlignment = mainState.value.textAlignment,
|
||||
fontSize = mainState.value.fontSize.sp,
|
||||
letterSpacing = letterSpacing,
|
||||
sidePadding = sidePadding,
|
||||
paragraphIndentation = mainState.value.paragraphIndentation!!,
|
||||
doubleClickTranslationEnabled = mainState.value.doubleClickTranslation!!,
|
||||
paragraphIndentation = mainState.value.paragraphIndentation,
|
||||
doubleClickTranslationEnabled = mainState.value.doubleClickTranslation,
|
||||
toolbarHidden = toolbarHidden,
|
||||
onEvent = onEvent
|
||||
)
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@ fun FastColorPresetChangeSetting(
|
|||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
SwitchWithTitle(
|
||||
selected = state.value.fastColorPresetChange!!,
|
||||
selected = state.value.fastColorPresetChange,
|
||||
title = stringResource(id = R.string.fast_color_preset_change_option),
|
||||
description = stringResource(id = R.string.fast_color_preset_change_option_desc),
|
||||
onClick = {
|
||||
onMainEvent(
|
||||
MainEvent.OnChangeFastColorPresetChange(
|
||||
!state.value.fastColorPresetChange!!
|
||||
!state.value.fastColorPresetChange
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ fun PureDarkSetting(
|
|||
state: State<MainState>,
|
||||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
ExpandingTransition(visible = state.value.darkTheme!!.isDark()) {
|
||||
ExpandingTransition(visible = state.value.darkTheme.isDark()) {
|
||||
SegmentedButtonWithTitle(
|
||||
title = stringResource(id = R.string.pure_dark_option),
|
||||
buttons = PureDark.entries.map {
|
||||
|
|
|
|||
|
|
@ -29,19 +29,19 @@ fun ThemeContrastSetting(
|
|||
state: State<MainState>,
|
||||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
val themeContrastTheme = remember { mutableStateOf(state.value.theme!!) }
|
||||
val themeContrastTheme = remember { mutableStateOf(state.value.theme) }
|
||||
|
||||
LaunchedEffect(state.value.theme) {
|
||||
if (themeContrastTheme.value != state.value.theme && state.value.theme != Theme.DYNAMIC) {
|
||||
themeContrastTheme.value = state.value.theme!!
|
||||
themeContrastTheme.value = state.value.theme
|
||||
}
|
||||
}
|
||||
|
||||
BookStoryTheme(
|
||||
theme = themeContrastTheme.value,
|
||||
isDark = state.value.darkTheme!!.isDark(),
|
||||
isPureDark = state.value.pureDark!!.isPureDark(context = LocalContext.current),
|
||||
themeContrast = state.value.themeContrast!!
|
||||
isDark = state.value.darkTheme.isDark(),
|
||||
isPureDark = state.value.pureDark.isPureDark(context = LocalContext.current),
|
||||
themeContrast = state.value.themeContrast
|
||||
) {
|
||||
ExpandingTransition(visible = state.value.theme != Theme.DYNAMIC) {
|
||||
SegmentedButtonWithTitle(
|
||||
|
|
|
|||
|
|
@ -91,9 +91,9 @@ fun ThemeSetting(
|
|||
|
||||
ThemeSettingItem(
|
||||
theme = themeEntry,
|
||||
darkTheme = state.value.darkTheme!!.isDark(),
|
||||
themeContrast = state.value.themeContrast!!,
|
||||
isPureDark = state.value.pureDark!!.isPureDark(context = LocalContext.current),
|
||||
darkTheme = state.value.darkTheme.isDark(),
|
||||
themeContrast = state.value.themeContrast,
|
||||
isPureDark = state.value.pureDark.isPureDark(context = LocalContext.current),
|
||||
selected = state.value.theme == themeEntry.first
|
||||
) {
|
||||
onMainEvent(MainEvent.OnChangeTheme(themeEntry.first.toString()))
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ fun LazyListScope.BrowseFilterSetting(
|
|||
customItems(Constants.EXTENSIONS, key = { it }) {
|
||||
FilterItem(
|
||||
item = it,
|
||||
isSelected = state.value.browseIncludedFilterItems!!.any { item ->
|
||||
isSelected = state.value.browseIncludedFilterItems.any { item ->
|
||||
item == it
|
||||
}
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ fun BrowseGridSizeSetting(
|
|||
) {
|
||||
ExpandingTransition(visible = state.value.browseLayout == BrowseLayout.GRID) {
|
||||
SliderWithTitle(
|
||||
value = state.value.browseGridSize!!
|
||||
value = state.value.browseGridSize
|
||||
to " ${stringResource(R.string.browse_grid_size_per_row)}",
|
||||
valuePlaceholder = stringResource(id = R.string.browse_grid_size_auto),
|
||||
showPlaceholder = state.value.browseAutoGridSize!!,
|
||||
showPlaceholder = state.value.browseAutoGridSize,
|
||||
fromValue = 0,
|
||||
toValue = 10,
|
||||
title = stringResource(id = R.string.browse_grid_size_option),
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ fun BrowsePinFavoriteDirectoriesSetting(
|
|||
) {
|
||||
ExpandingTransition(visible = state.value.browseFilesStructure == BrowseFilesStructure.DIRECTORIES) {
|
||||
SwitchWithTitle(
|
||||
selected = state.value.browsePinFavoriteDirectories!!,
|
||||
selected = state.value.browsePinFavoriteDirectories,
|
||||
title = stringResource(id = R.string.browse_pin_favorite_directories_option),
|
||||
description = stringResource(id = R.string.browse_pin_favorite_directories_option_desc)
|
||||
) {
|
||||
onMainEvent(
|
||||
MainEvent.OnChangeBrowsePinFavoriteDirectories(
|
||||
!state.value.browsePinFavoriteDirectories!!
|
||||
!state.value.browsePinFavoriteDirectories
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,13 +41,13 @@ fun LazyListScope.BrowseSortOrderSetting(
|
|||
customItems(BrowseSortOrder.entries, key = { it.name }) {
|
||||
SortItem(
|
||||
item = it,
|
||||
isSelected = state.value.browseSortOrder!! == it,
|
||||
isDescending = state.value.browseSortOrderDescending!!
|
||||
isSelected = state.value.browseSortOrder == it,
|
||||
isDescending = state.value.browseSortOrderDescending
|
||||
) {
|
||||
if (state.value.browseSortOrder!! == it) {
|
||||
if (state.value.browseSortOrder == it) {
|
||||
onMainEvent(
|
||||
MainEvent.OnChangeBrowseSortOrderDescending(
|
||||
!state.value.browseSortOrderDescending!!
|
||||
!state.value.browseSortOrderDescending
|
||||
)
|
||||
)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -59,13 +59,13 @@ fun CheckForUpdatesSetting(
|
|||
}
|
||||
|
||||
SwitchWithTitle(
|
||||
selected = state.value.checkForUpdates!!,
|
||||
selected = state.value.checkForUpdates,
|
||||
title = stringResource(id = R.string.check_for_updates_option),
|
||||
description = stringResource(id = R.string.check_for_updates_option_desc)
|
||||
) {
|
||||
onSettingsEvent(
|
||||
SettingsEvent.OnGeneralChangeCheckForUpdates(
|
||||
enable = !state.value.checkForUpdates!!,
|
||||
enable = !state.value.checkForUpdates,
|
||||
activity = activity,
|
||||
notificationsPermissionState = notificationsPermissionState,
|
||||
onChangeCheckForUpdates = {
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ fun DoublePressExitSetting(
|
|||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
SwitchWithTitle(
|
||||
selected = state.value.doublePressExit!!,
|
||||
selected = state.value.doublePressExit,
|
||||
title = stringResource(id = R.string.double_press_exit_option),
|
||||
description = stringResource(id = R.string.double_press_exit_option_desc)
|
||||
) {
|
||||
onMainEvent(
|
||||
MainEvent.OnChangeDoublePressExit(!state.value.doublePressExit!!)
|
||||
MainEvent.OnChangeDoublePressExit(!state.value.doublePressExit)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -18,13 +18,13 @@ fun DoubleClickTranslationSetting(
|
|||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
SwitchWithTitle(
|
||||
selected = state.value.doubleClickTranslation!!,
|
||||
selected = state.value.doubleClickTranslation,
|
||||
title = stringResource(id = R.string.double_click_translation_option),
|
||||
description = stringResource(id = R.string.double_click_translation_option_desc),
|
||||
onClick = {
|
||||
onMainEvent(
|
||||
MainEvent.OnChangeDoubleClickTranslation(
|
||||
!state.value.doubleClickTranslation!!
|
||||
!state.value.doubleClickTranslation
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ fun FontSizeSetting(
|
|||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
SliderWithTitle(
|
||||
value = state.value.fontSize!! to "pt",
|
||||
value = state.value.fontSize to "pt",
|
||||
fromValue = 10,
|
||||
toValue = 35,
|
||||
title = stringResource(id = R.string.font_size_option),
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ fun FontStyleSetting(
|
|||
fontFamily = fontFamily.font,
|
||||
fontStyle = FontStyle.Normal
|
||||
),
|
||||
selected = !state.value.isItalic!!
|
||||
selected = !state.value.isItalic
|
||||
),
|
||||
ButtonItem(
|
||||
id = "italic",
|
||||
|
|
@ -47,7 +47,7 @@ fun FontStyleSetting(
|
|||
fontFamily = fontFamily.font,
|
||||
fontStyle = FontStyle.Italic
|
||||
),
|
||||
selected = state.value.isItalic!!
|
||||
selected = state.value.isItalic
|
||||
),
|
||||
),
|
||||
onClick = {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ fun LetterSpacingSetting(
|
|||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
SliderWithTitle(
|
||||
value = state.value.letterSpacing!! to "pt",
|
||||
value = state.value.letterSpacing to "pt",
|
||||
fromValue = -8,
|
||||
toValue = 16,
|
||||
title = stringResource(id = R.string.letter_spacing_option),
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ fun LineHeightSetting(
|
|||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
SliderWithTitle(
|
||||
value = state.value.lineHeight!! to "pt",
|
||||
value = state.value.lineHeight to "pt",
|
||||
fromValue = 1,
|
||||
toValue = 24,
|
||||
title = stringResource(id = R.string.line_height_option),
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ fun ParagraphHeightSetting(
|
|||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
SliderWithTitle(
|
||||
value = state.value.paragraphHeight!! to "pt",
|
||||
value = state.value.paragraphHeight to "pt",
|
||||
fromValue = 0,
|
||||
toValue = 36,
|
||||
title = stringResource(id = R.string.paragraph_height_option),
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ fun ParagraphIndentationSetting(
|
|||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
SwitchWithTitle(
|
||||
selected = state.value.paragraphIndentation!!,
|
||||
selected = state.value.paragraphIndentation,
|
||||
title = stringResource(id = R.string.paragraph_indentation_option)
|
||||
) {
|
||||
onMainEvent(
|
||||
MainEvent.OnChangeParagraphIndentation(!state.value.paragraphIndentation!!)
|
||||
MainEvent.OnChangeParagraphIndentation(!state.value.paragraphIndentation)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ fun SidePaddingSetting(
|
|||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
SliderWithTitle(
|
||||
value = state.value.sidePadding!! to "pt",
|
||||
value = state.value.sidePadding to "pt",
|
||||
fromValue = 1,
|
||||
toValue = 20,
|
||||
title = stringResource(id = R.string.side_padding_option),
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ fun TextAlignmentSetting(
|
|||
ReaderTextAlignment.END -> stringResource(id = R.string.text_alignment_end)
|
||||
},
|
||||
textStyle = MaterialTheme.typography.labelLarge,
|
||||
selected = it == state.value.textAlignment!!
|
||||
selected = it == state.value.textAlignment
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue