Skip to content

Commit 8f4fda7

Browse files
author
Fredrik Hallin
committed
Fix watch Gutenberg review issues
1 parent f77ab61 commit 8f4fda7

4 files changed

Lines changed: 27 additions & 31 deletions

File tree

app/src/main/kotlin/com/fredapp/wbooks/data/changelog/Changelog.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ val CHANGELOG: List<ChangelogEntry> = listOf(
5353
"Books-finished counter, daily reading totals (30-day rolling window), and last-50 WPM samples now persisted on the watch and exposed over a new /wbooks/stats Wear Data Layer path.",
5454
"Phone companion gains a stats dashboard: Today / Total / Finished cards, a 30-day bar chart of reading minutes, and a WPM-trend line chart (both pure Compose Canvas).",
5555
"Sentry SDK wired into both APKs; DSN sourced from local.properties so the project builds without an account.",
56-
"Phone-side Project Gutenberg browser: search the OPDS catalogue and stream a downloaded book straight to the watch via ChannelClient — no intermediate temp file.",
56+
"Phone-side Project Gutenberg browser: search the OPDS catalogue and stream a downloaded book straight to the watch via ChannelClient - no intermediate temp file.",
5757
"Release builds run through R8 + resource shrinking for both modules.",
5858
),
5959
),
@@ -63,15 +63,15 @@ val CHANGELOG: List<ChangelogEntry> = listOf(
6363
notes = listOf(
6464
"Phone companion app (separate APK). Mirrors the watch's library; SAF picker sends books to the watch over the Wear Data Layer (no IP / PIN). Material 3, dark-mode aware, minSdk 24.",
6565
"Watch-side BookReceiverService accepts uploads via ChannelClient and list / delete via MessageClient.sendRequest. Scope is cancelled on service teardown; binder thread is no longer blocked.",
66-
"LAN upload server (NanoHTTPD) stays as an additive transport — companion is an alternative, not a replacement.",
66+
"LAN upload server (NanoHTTPD) stays as an additive transport - companion is an alternative, not a replacement.",
6767
),
6868
),
6969
ChangelogEntry(
7070
version = "0.2.0",
7171
date = "2026-05-19",
7272
notes = listOf(
7373
"DOCX and ODT support (Office Open XML, OpenDocument Text). Headings split into chapters, inline bold / italic / underline preserved, unsupported elements (tables, images, frames, ...) silently dropped.",
74-
"Two new bundled seed books: Stevenson's Jekyll & Hyde (DOCX) and Wells's The Time Machine (ODT) — pandoc-converted from Project Gutenberg, header / license boilerplate stripped.",
74+
"Two new bundled seed books: Stevenson's Jekyll & Hyde (DOCX) and Wells's The Time Machine (ODT) - pandoc-converted from Project Gutenberg, header / license boilerplate stripped.",
7575
"Upload server hardened: PIN now checked before multipart body is spooled; sliding-window rate limiter (10 wrong PINs / 60s -> 429); constant-time PIN compare; HTML escaping on the library listing.",
7676
"Repo housekeeping: GPLv3 LICENSE at root, GitHub Actions CI (assembleDebug + JVM unit tests for the parsers).",
7777
),

app/src/main/kotlin/com/fredapp/wbooks/ui/library/LibraryScreen.kt

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -468,14 +468,6 @@ private fun ConfirmDeleteScreen(
468468
modifier = Modifier.fillMaxWidth(),
469469
)
470470
}
471-
item(key = "cancel") {
472-
Chip(
473-
label = { Text("Cancel") },
474-
onClick = onCancel,
475-
colors = ChipDefaults.secondaryChipColors(),
476-
modifier = Modifier.fillMaxWidth(),
477-
)
478-
}
479471
}
480472
}
481473
}
@@ -661,14 +653,6 @@ private fun FolderActionsScreen(
661653
modifier = Modifier.fillMaxWidth(),
662654
)
663655
}
664-
item(key = "cancel") {
665-
Chip(
666-
label = { Text("Cancel") },
667-
onClick = onCancel,
668-
colors = ChipDefaults.secondaryChipColors(),
669-
modifier = Modifier.fillMaxWidth(),
670-
)
671-
}
672656
}
673657
}
674658
}

app/src/main/kotlin/com/fredapp/wbooks/ui/library/WatchGutenbergScreen.kt

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ fun WatchGutenbergScreen(onBack: () -> Unit, onLibraryChanged: () -> Unit) {
107107

108108
fun refreshAddedFilenames() {
109109
val files = app.booksDir
110-
.listFiles()
111-
?.filter { it.isFile }
112-
?: emptySet()
110+
.walkTopDown()
111+
.filter { it.isFile && BookFormat.fromExtension(it.extension) != null }
112+
.toList()
113113
addedFilenames = files.mapTo(mutableSetOf()) { it.name.normalizedFilename() }
114114
addedTitleKeys = files.mapTo(mutableSetOf()) { it.nameWithoutExtension.normalizedTitleKey() }
115115
}
@@ -161,6 +161,15 @@ fun WatchGutenbergScreen(onBack: () -> Unit, onLibraryChanged: () -> Unit) {
161161
}
162162

163163
fun loadMore(target: GutenbergTarget) {
164+
val currentCount = when (target) {
165+
GutenbergTarget.POPULAR -> popular.size
166+
GutenbergTarget.RECENT -> recent.size
167+
GutenbergTarget.SEARCH -> results.size
168+
}
169+
if (currentCount >= MAX_LIST_ITEMS) {
170+
error = "Showing the maximum $MAX_LIST_ITEMS Gutenberg results for this list."
171+
return
172+
}
164173
scope.launch {
165174
loading = true
166175
error = null
@@ -178,16 +187,19 @@ fun WatchGutenbergScreen(onBack: () -> Unit, onLibraryChanged: () -> Unit) {
178187
}.onSuccess { page ->
179188
when (target) {
180189
GutenbergTarget.POPULAR -> {
181-
popular = mergeBooks(popular, page)
182-
popularHasMore = page.hasMore
190+
val merged = mergeBooks(popular, page)
191+
popular = merged
192+
popularHasMore = page.hasMore && merged.size < MAX_LIST_ITEMS
183193
}
184194
GutenbergTarget.RECENT -> {
185-
recent = mergeBooks(recent, page)
186-
recentHasMore = page.hasMore
195+
val merged = mergeBooks(recent, page)
196+
recent = merged
197+
recentHasMore = page.hasMore && merged.size < MAX_LIST_ITEMS
187198
}
188199
GutenbergTarget.SEARCH -> {
189-
results = mergeBooks(results, page)
190-
searchHasMore = page.hasMore
200+
val merged = mergeBooks(results, page)
201+
results = merged
202+
searchHasMore = page.hasMore && merged.size < MAX_LIST_ITEMS
191203
}
192204
}
193205
}.onFailure { error = it.message ?: "Load more failed" }
@@ -421,7 +433,7 @@ private fun GutenbergSearchInput(
421433
) {
422434
if (value.isBlank()) {
423435
Text(
424-
"Text search",
436+
"Search Gutenberg",
425437
color = onSurface.copy(alpha = 0.5f),
426438
fontSize = 14.sp,
427439
maxLines = 1,

companion/src/main/kotlin/com/fredapp/wbooksutil/CompanionChangelog.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ object CompanionChangelog {
4949
"Large folder sets now stay in a half-screen scroll area so Root remains visible below them, while small folder sets shrink upward dynamically.",
5050
"Books in an expanded folder now render directly under that folder's chip; Root sits below the folder list and scrolls to centre as folder count grows.",
5151
"Rename-folder dialog (edit icon next to the delete icon).",
52-
"Project Gutenberg search works again search results now synthesise the EPUB download URL from the book id, and the keyboard Enter key submits.",
52+
"Project Gutenberg search works again - search results now synthesise the EPUB download URL from the book id, and the keyboard Enter key submits.",
5353
"Library and settings auto-refresh every 5 s while the screen is on stage; the manual refresh icon is gone.",
5454
"Upload flow shows a modal with a progress bar while the bytes are in flight.",
5555
"Watch settings page gained Changelog and About sections at the bottom.",
@@ -68,7 +68,7 @@ object CompanionChangelog {
6868
version = "0.3.0",
6969
date = "2026-05-19",
7070
notes = listOf(
71-
"Initial phone companion. SAF file picker Wear Data Layer upload to the watch. Material 3, dark-mode aware.",
71+
"Initial phone companion. SAF file picker sends books through Wear Data Layer upload to the watch. Material 3, dark-mode aware.",
7272
"Folder organisation: create, expand, delete, drag-and-drop assignment.",
7373
),
7474
),

0 commit comments

Comments
 (0)