better app icon

This commit is contained in:
sergeych committed 2026-05-23 16:12:45 +03:00
1 parent 02bde7e644
commit 75ba13bde2
39 files changed
+498 -142

No files matched your search

@@ -30,6 +30,7 @@ import kotlinx.coroutines.launch
private const val DefaultToastDurationMillis = 1_600L
private const val DeleteUndoDurationMillis = 5_000L
private const val BackgroundLibraryPageSize = 50
private data class AppToastData(
val id: Long,
@@ -151,7 +152,7 @@ private fun BookReaderApp(
durationMillis: Long,
) -> Unit,
) {
var state by remember { mutableStateOf<AppState>(AppState.LoadingLibrary) }
var state by remember { mutableStateOf<AppState>(AppState.LoadingStartup) }
var activeScan by remember { mutableStateOf<LibraryScanProgress?>(null) }
var scanJob by remember { mutableStateOf<Job?>(null) }
var pendingDelete by remember { mutableStateOf<PendingLibraryDelete?>(null) }
@@ -165,6 +166,34 @@ private fun BookReaderApp(
state = loadStartupState()
}
val activeBookState = when (val current = state) {
is AppState.Reader -> current.fileId to current.libraryItems.isEmpty()
is AppState.BookInfo -> current.fileId to current.libraryItems.isEmpty()
else -> null
}
LaunchedEffect(activeBookState?.first, activeBookState?.second) {
val (fileId, needsLibraryItems) = activeBookState ?: return@LaunchedEffect
if (!needsLibraryItems) return@LaunchedEffect
runCatching { loadLibraryItemsPage(BackgroundLibraryPageSize, 0) }
.onSuccess { items ->
state = when (val current = state) {
is AppState.Reader ->
if (current.fileId == fileId && current.libraryItems.isEmpty()) {
current.copy(libraryItems = items)
} else {
current
}
is AppState.BookInfo ->
if (current.fileId == fileId && current.libraryItems.isEmpty()) {
current.copy(libraryItems = items)
} else {
current
}
else -> current
}
}
}
fun commitPendingDelete(delete: PendingLibraryDelete) {
scope.launch {
val result = deleteLibraryBook(delete.request.fileId, delete.request.title)
@@ -238,18 +267,18 @@ private fun BookReaderApp(
)
is AppState.Reader -> {
scope.launch { saveActiveReadingFileId(null) }
AppState.Library(emptyList(), current.scanPath, current.message)
AppState.Library(current.libraryItems, current.scanPath, current.message)
}
is AppState.Scan -> AppState.Library(current.items, current.scanPath, current.message)
is AppState.Error -> AppState.LoadingLibrary
is AppState.Library, AppState.LoadingLibrary -> current
is AppState.Error -> AppState.LoadingStartup
is AppState.Library, AppState.LoadingStartup -> current
}
}
val navigationDepth = when (state) {
is AppState.BookInfo -> 2
is AppState.Error, is AppState.Reader, is AppState.Scan -> 1
is AppState.Library, AppState.LoadingLibrary -> 0
is AppState.Library, AppState.LoadingStartup -> 0
} + if (imageViewer != null) 1 else 0
PlatformBackHandler(
@@ -291,7 +320,7 @@ private fun BookReaderApp(
} else {
AppState.Library(current.items, path, message)
}
AppState.LoadingLibrary -> loadLibraryState(message, path)
AppState.LoadingStartup -> loadLibraryState(message, path)
is AppState.Reader -> current.copy(message = message)
is AppState.BookInfo -> current.copy(message = message)
is AppState.Error -> current
@@ -300,7 +329,7 @@ private fun BookReaderApp(
}
when (val current = state) {
AppState.LoadingLibrary -> LoadingScreen("Opening library")
AppState.LoadingStartup -> LoadingScreen("Opening book")
is AppState.Library -> LibraryScreen(
state = current,
activeScan = activeScan,
@@ -4,7 +4,7 @@ import net.sergeych.toread.fb2.Fb2Book
import net.sergeych.toread.fb2.Fb2Format
internal sealed interface AppState {
data object LoadingLibrary : AppState
data object LoadingStartup : AppState
data class Library(
val items: List<LibraryItem>,
val scanPath: String,
@@ -37,39 +37,40 @@ internal sealed interface AppState {
}
internal suspend fun loadStartupState(): AppState {
val library = loadLibraryState()
if (library !is AppState.Library) return library
val scanPath = try {
defaultLibraryScanPath().orEmpty()
} catch (t: Throwable) {
return AppState.Error(t.message ?: "Could not open library.")
}
loadPlatformOpenBookRequest()?.let { request ->
return runCatching {
AppState.Reader(
fileId = request.id,
book = Fb2Format.parse(request.bytes, request.displayName),
libraryItems = library.items,
scanPath = library.scanPath,
message = library.message,
libraryItems = emptyList(),
scanPath = scanPath,
)
}.getOrElse {
AppState.Library(library.items, library.scanPath, it.message ?: "Could not open ${request.displayName}.")
AppState.Library(emptyList(), scanPath, it.message ?: "Could not open ${request.displayName}.")
}
}
val activeFileId = loadActiveReadingFileId() ?: return library
val activeFileId = loadActiveReadingFileId() ?: return AppState.Library(emptyList(), scanPath)
val item = loadLibraryItem(activeFileId)
if (item == null) {
saveActiveReadingFileId(null)
return library
return AppState.Library(emptyList(), scanPath)
}
return runCatching {
val bytes = openLibraryBook(activeFileId) ?: error("Book file is not available.")
AppState.Reader(
fileId = activeFileId,
book = Fb2Format.parse(bytes, item.storageUri ?: item.title),
libraryItems = library.items,
scanPath = library.scanPath,
message = library.message,
libraryItems = emptyList(),
scanPath = scanPath,
)
}.getOrElse {
saveActiveReadingFileId(null)
AppState.Library(library.items, library.scanPath, it.message ?: "Could not reopen last book.")
AppState.Library(emptyList(), scanPath, it.message ?: "Could not reopen last book.")
}
}