preparing the publication
This commit is contained in:
1 parent
bad1e89c26
commit
128275402e
18 files changed
+242
-22
No files matched your search
@@ -51,6 +51,7 @@ private data class PendingLibraryDelete(
|
||||
fun App() {
|
||||
var themeMode by remember { mutableStateOf(ThemeMode.SYSTEM) }
|
||||
var systemDark by remember { mutableStateOf(isPlatformDarkTheme()) }
|
||||
var localePreferenceLoaded by remember { mutableStateOf(false) }
|
||||
var toast by remember { mutableStateOf<AppToastData?>(null) }
|
||||
var nextToastId by remember { mutableStateOf(0L) }
|
||||
val scope = rememberCoroutineScope()
|
||||
@@ -78,6 +79,13 @@ fun App() {
|
||||
themeMode = loadThemeMode()
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
selectedAppLocaleTag = loadAppLocaleTag()?.takeIf { saved ->
|
||||
availableAppLanguages.any { it.localeTag == saved }
|
||||
}
|
||||
localePreferenceLoaded = true
|
||||
}
|
||||
|
||||
LaunchedEffect(toast?.id) {
|
||||
val current = toast ?: return@LaunchedEffect
|
||||
delay(current.durationMillis)
|
||||
@@ -89,17 +97,21 @@ fun App() {
|
||||
MaterialTheme(colorScheme = if (useDark) darkReaderColorScheme() else lightReaderColorScheme()) {
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
|
||||
BookReaderApp(
|
||||
onThemeToggle = {
|
||||
val next = themeMode.next()
|
||||
themeMode = next
|
||||
showToast(strings.themeChanged(next))
|
||||
scope.launch {
|
||||
saveThemeMode(next)
|
||||
}
|
||||
},
|
||||
onShowToast = ::showToast,
|
||||
)
|
||||
if (localePreferenceLoaded) {
|
||||
BookReaderApp(
|
||||
onThemeToggle = {
|
||||
val next = themeMode.next()
|
||||
themeMode = next
|
||||
showToast(strings.themeChanged(next))
|
||||
scope.launch {
|
||||
saveThemeMode(next)
|
||||
}
|
||||
},
|
||||
onShowToast = ::showToast,
|
||||
)
|
||||
} else {
|
||||
LoadingScreen(strings.loadingOpeningBook)
|
||||
}
|
||||
}
|
||||
AppToast(toast, modifier = Modifier.align(Alignment.BottomCenter))
|
||||
}
|
||||
|
||||
@@ -145,6 +145,10 @@ expect suspend fun loadScanDownloadsAutomatically(): Boolean
|
||||
|
||||
expect suspend fun saveScanDownloadsAutomatically(enabled: Boolean)
|
||||
|
||||
expect suspend fun loadAppLocaleTag(): String?
|
||||
|
||||
expect suspend fun saveAppLocaleTag(localeTag: String?)
|
||||
|
||||
expect suspend fun loadDownloadsWasScanned(): Boolean
|
||||
|
||||
expect suspend fun saveDownloadsWasScanned(scanned: Boolean)
|
||||
|
||||
@@ -24,7 +24,9 @@ import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.Favorite
|
||||
import androidx.compose.material.icons.filled.KeyboardArrowDown
|
||||
@@ -101,6 +103,7 @@ internal fun LibraryScreen(
|
||||
var recentlyAddedItems by remember(state.items) { mutableStateOf<List<LibraryItem>>(emptyList()) }
|
||||
var wasScanning by remember { mutableStateOf(false) }
|
||||
var settingsMenuOpen by remember { mutableStateOf(false) }
|
||||
var localeMenuOpen by remember { mutableStateOf(false) }
|
||||
var autoScanDownloads by remember { mutableStateOf(true) }
|
||||
var autoScanSettingLoaded by remember { mutableStateOf(false) }
|
||||
var backgroundDownloadsRescanStarted by remember { mutableStateOf(false) }
|
||||
@@ -221,6 +224,7 @@ internal fun LibraryScreen(
|
||||
|
||||
fun rescanAllLibrary() {
|
||||
settingsMenuOpen = false
|
||||
localeMenuOpen = false
|
||||
scope.launch {
|
||||
busy = true
|
||||
message = strings.rescanningLibrary
|
||||
@@ -282,7 +286,10 @@ internal fun LibraryScreen(
|
||||
}
|
||||
|
||||
LaunchedEffect(searchFocused) {
|
||||
if (searchFocused) settingsMenuOpen = false
|
||||
if (searchFocused) {
|
||||
settingsMenuOpen = false
|
||||
localeMenuOpen = false
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(searchActive, loadingPage, endReached, libraryItems, recentlyAdded) {
|
||||
@@ -366,7 +373,13 @@ internal fun LibraryScreen(
|
||||
IconButton(onClick = { settingsMenuOpen = true }) {
|
||||
Icon(Icons.Filled.MoreVert, contentDescription = strings.libraryOptions)
|
||||
}
|
||||
DropdownMenu(expanded = settingsMenuOpen, onDismissRequest = { settingsMenuOpen = false }) {
|
||||
DropdownMenu(
|
||||
expanded = settingsMenuOpen,
|
||||
onDismissRequest = {
|
||||
settingsMenuOpen = false
|
||||
localeMenuOpen = false
|
||||
},
|
||||
) {
|
||||
// DropdownMenuItem(
|
||||
// text = { Text("Rescan all library") },
|
||||
// enabled = !busy && activeScan == null,
|
||||
@@ -385,6 +398,56 @@ internal fun LibraryScreen(
|
||||
scope.launch { saveScanDownloadsAutomatically(next) }
|
||||
},
|
||||
)
|
||||
HorizontalDivider()
|
||||
Box {
|
||||
DropdownMenuItem(
|
||||
text = { Text(strings.locale) },
|
||||
trailingIcon = {
|
||||
Icon(Icons.AutoMirrored.Filled.KeyboardArrowRight, contentDescription = null)
|
||||
},
|
||||
onClick = { localeMenuOpen = true },
|
||||
)
|
||||
DropdownMenu(expanded = localeMenuOpen, onDismissRequest = { localeMenuOpen = false }) {
|
||||
availableAppLanguages.forEach { language ->
|
||||
val checked = selectedAppLocaleTag == language.localeTag
|
||||
DropdownMenuItem(
|
||||
leadingIcon = {
|
||||
if (checked) {
|
||||
Icon(Icons.Filled.Check, contentDescription = null)
|
||||
}
|
||||
},
|
||||
text = { Text(strings.appLanguageName(language)) },
|
||||
onClick = {
|
||||
selectedAppLocaleTag = language.localeTag
|
||||
localeMenuOpen = false
|
||||
settingsMenuOpen = false
|
||||
scope.launch { saveAppLocaleTag(language.localeTag) }
|
||||
},
|
||||
)
|
||||
}
|
||||
HorizontalDivider()
|
||||
DropdownMenuItem(
|
||||
leadingIcon = {
|
||||
if (selectedAppLocaleTag == null) {
|
||||
Icon(Icons.Filled.Check, contentDescription = null)
|
||||
}
|
||||
},
|
||||
text = { Text(strings.systemLocale) },
|
||||
onClick = {
|
||||
selectedAppLocaleTag = null
|
||||
localeMenuOpen = false
|
||||
settingsMenuOpen = false
|
||||
scope.launch { saveAppLocaleTag(null) }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
HorizontalDivider()
|
||||
DropdownMenuItem(
|
||||
text = { Text(strings.appVersion(AppVersionDisplay)) },
|
||||
enabled = false,
|
||||
onClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
package net.sergeych.toread
|
||||
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import net.sergeych.toread.storage.BookReadingStatus
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
internal enum class AppLanguage {
|
||||
English,
|
||||
Russian,
|
||||
internal enum class AppLanguage(val localeTag: String) {
|
||||
English("en"),
|
||||
Russian("ru"),
|
||||
}
|
||||
|
||||
internal val availableAppLanguages: List<AppLanguage> = AppLanguage.entries
|
||||
|
||||
internal var selectedAppLocaleTag: String? by mutableStateOf(null)
|
||||
|
||||
internal val appLanguage: AppLanguage
|
||||
get() = if (platformLocaleTags().any { it.isRussianLanguageTag() }) {
|
||||
get() = if (effectiveAppLocaleTags().any { it.isRussianLanguageTag() }) {
|
||||
AppLanguage.Russian
|
||||
} else {
|
||||
AppLanguage.English
|
||||
@@ -23,6 +30,9 @@ internal val strings: AppStrings
|
||||
|
||||
internal expect fun platformLocaleTags(): List<String>
|
||||
|
||||
private fun effectiveAppLocaleTags(): List<String> =
|
||||
selectedAppLocaleTag?.let(::listOf) ?: platformLocaleTags()
|
||||
|
||||
private fun String.isRussianLanguageTag(): Boolean =
|
||||
substringBefore('-').substringBefore('_').equals("ru", ignoreCase = true)
|
||||
|
||||
@@ -53,6 +63,9 @@ internal open class AppStrings {
|
||||
|
||||
open val libraryOptions = "Library options"
|
||||
open val scanDownloadsAutomatically = "Scan Downloads automatically"
|
||||
open val locale = "Locale"
|
||||
open val systemLocale = "Default"
|
||||
open fun appVersion(version: String): String = "Version $version"
|
||||
open val scanFolder = "Scan folder"
|
||||
open val chooseLibraryFilter = "Choose library filter"
|
||||
open val searchLibrary = "Search library"
|
||||
@@ -197,6 +210,11 @@ internal open class AppStrings {
|
||||
open fun couldNotRead(name: String): String = "Could not read $name"
|
||||
open fun progressLabel(progress: Double?): String =
|
||||
progress?.let { "Progress ${(it * 100).roundToInt()}%" } ?: "Progress not recorded"
|
||||
open fun appLanguageName(language: AppLanguage): String =
|
||||
when (language) {
|
||||
AppLanguage.English -> "English"
|
||||
AppLanguage.Russian -> "Russian"
|
||||
}
|
||||
open fun sectionFallback(index: Int): String = "Section ${index + 1}"
|
||||
open fun readingStatus(status: BookReadingStatus): String =
|
||||
when (status) {
|
||||
@@ -237,6 +255,9 @@ internal object RussianStrings : AppStrings() {
|
||||
|
||||
override val libraryOptions = "Параметры библиотеки"
|
||||
override val scanDownloadsAutomatically = "Автоматически сканировать Загрузки"
|
||||
override val locale = "Локализация"
|
||||
override val systemLocale = "Системная"
|
||||
override fun appVersion(version: String): String = "Версия $version"
|
||||
override val scanFolder = "Сканировать папку"
|
||||
override val chooseLibraryFilter = "Выбрать фильтр библиотеки"
|
||||
override val searchLibrary = "Поиск"
|
||||
@@ -384,6 +405,11 @@ internal object RussianStrings : AppStrings() {
|
||||
override fun couldNotRead(name: String): String = "Не удалось прочитать $name"
|
||||
override fun progressLabel(progress: Double?): String =
|
||||
progress?.let { "Прогресс ${(it * 100).roundToInt()}%" } ?: "Прогресс не записан"
|
||||
override fun appLanguageName(language: AppLanguage): String =
|
||||
when (language) {
|
||||
AppLanguage.English -> "Английский"
|
||||
AppLanguage.Russian -> "Русский"
|
||||
}
|
||||
override fun sectionFallback(index: Int): String = "Раздел ${index + 1}"
|
||||
override fun readingStatus(status: BookReadingStatus): String =
|
||||
when (status) {
|
||||
|
||||
Reference in new issue
Block a user