diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts
index 44f111b..1ee37bb 100644
--- a/composeApp/build.gradle.kts
+++ b/composeApp/build.gradle.kts
@@ -101,6 +101,19 @@ compose.desktop {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "net.sergeych.toread"
packageVersion = "1.0.0"
+
+ macOS {
+ iconFile.set(project.file("src/jvmMain/resources/icons/icon.icns"))
+ }
+ windows {
+ iconFile.set(project.file("src/jvmMain/resources/icons/icon.ico"))
+ shortcut = true
+ menu = true
+ }
+ linux {
+ iconFile.set(project.file("src/jvmMain/resources/icons/icon.png"))
+ shortcut = true
+ }
}
}
}
diff --git a/composeApp/src/androidMain/ic_launcher-playstore.png b/composeApp/src/androidMain/ic_launcher-playstore.png
new file mode 100644
index 0000000..63eb80d
Binary files /dev/null and b/composeApp/src/androidMain/ic_launcher-playstore.png differ
diff --git a/composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml b/composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml
deleted file mode 100644
index 66ffb4b..0000000
--- a/composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/composeApp/src/androidMain/res/drawable/ic_launcher_foreground.xml b/composeApp/src/androidMain/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..44548a2
--- /dev/null
+++ b/composeApp/src/androidMain/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml b/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml
index bbd3e02..6f2acb4 100644
--- a/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml b/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml
index bbd3e02..6f2acb4 100644
--- a/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ b/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png b/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index f69e95f..0000000
Binary files a/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.webp b/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..2a23c19
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_background.webp b/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_background.webp
new file mode 100644
index 0000000..cfce887
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_background.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png b/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png
deleted file mode 100644
index f69e95f..0000000
Binary files a/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ
diff --git a/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.webp b/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..aad71ef
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png b/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 2257963..0000000
Binary files a/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.webp b/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..c473c12
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_background.webp b/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_background.webp
new file mode 100644
index 0000000..a7be543
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_background.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png b/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png
deleted file mode 100644
index 2257963..0000000
Binary files a/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ
diff --git a/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.webp b/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..f398e66
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png b/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 7b53c00..0000000
Binary files a/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.webp b/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..664fed5
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_background.webp b/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_background.webp
new file mode 100644
index 0000000..afa1395
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_background.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png b/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png
deleted file mode 100644
index 7b53c00..0000000
Binary files a/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.webp b/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..93f125c
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png b/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 568881a..0000000
Binary files a/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.webp b/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..23177c4
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_background.webp b/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_background.webp
new file mode 100644
index 0000000..7ddedea
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_background.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png b/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png
deleted file mode 100644
index 568881a..0000000
Binary files a/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.webp b/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..7a5565c
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png b/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index e0eac22..0000000
Binary files a/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.webp b/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..9caf290
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_background.webp b/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_background.webp
new file mode 100644
index 0000000..4e478bd
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_background.webp differ
diff --git a/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png b/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png
deleted file mode 100644
index e0eac22..0000000
Binary files a/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.webp b/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..4af6941
Binary files /dev/null and b/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/composeApp/src/commonMain/kotlin/net/sergeych/toread/App.kt b/composeApp/src/commonMain/kotlin/net/sergeych/toread/App.kt
index 732e78a..9c2ea56 100644
--- a/composeApp/src/commonMain/kotlin/net/sergeych/toread/App.kt
+++ b/composeApp/src/commonMain/kotlin/net/sergeych/toread/App.kt
@@ -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.LoadingLibrary) }
+ var state by remember { mutableStateOf(AppState.LoadingStartup) }
var activeScan by remember { mutableStateOf(null) }
var scanJob by remember { mutableStateOf(null) }
var pendingDelete by remember { mutableStateOf(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,
diff --git a/composeApp/src/commonMain/kotlin/net/sergeych/toread/AppState.kt b/composeApp/src/commonMain/kotlin/net/sergeych/toread/AppState.kt
index 636c015..9665adc 100644
--- a/composeApp/src/commonMain/kotlin/net/sergeych/toread/AppState.kt
+++ b/composeApp/src/commonMain/kotlin/net/sergeych/toread/AppState.kt
@@ -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,
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.")
}
}
diff --git a/composeApp/src/jvmMain/resources/icons/icon.icns b/composeApp/src/jvmMain/resources/icons/icon.icns
new file mode 100644
index 0000000..9868b43
Binary files /dev/null and b/composeApp/src/jvmMain/resources/icons/icon.icns differ
diff --git a/composeApp/src/jvmMain/resources/icons/icon.ico b/composeApp/src/jvmMain/resources/icons/icon.ico
new file mode 100644
index 0000000..0b1363a
Binary files /dev/null and b/composeApp/src/jvmMain/resources/icons/icon.ico differ
diff --git a/composeApp/src/jvmMain/resources/icons/icon.png b/composeApp/src/jvmMain/resources/icons/icon.png
new file mode 100644
index 0000000..a9d7e14
Binary files /dev/null and b/composeApp/src/jvmMain/resources/icons/icon.png differ
diff --git a/image_src/icon-app-large.svg b/image_src/icon-app-large.svg
new file mode 100644
index 0000000..f447c37
--- /dev/null
+++ b/image_src/icon-app-large.svg
@@ -0,0 +1,59 @@
+
+
+
diff --git a/image_src/icon-app.svg b/image_src/icon-app.svg
index 96896f3..a1d3aaf 100644
--- a/image_src/icon-app.svg
+++ b/image_src/icon-app.svg
@@ -1,65 +1,264 @@
-
-