Skip to content

Releases

Llunevie v0.5.1

Choose a tag to compare

@Llunatics Llunatics released this 07 Nov 14:35

Llunevie v0.5.1 — Stable (Version Code 70)

Changes since v0.4.1:

Two-page spread mode

  • The spread always renders at full size. A center tap no longer shrinks the book or toggles its chrome, and a stuck flip gesture can no longer leave the next spread peeking in at the edge.
  • Chrome moved to vertical side bars: the menu pill sits centered on the left edge, the title and translate pill centered on the right, Back and Bookmark stay raised at the top corners, and the notes and bookmarks tab is flush at the right-center edge.
  • The spread stays centered in landscape, and book covers on Home and Library have their soft elliptical shadow back.

Translation

  • Translations are cached per language and display mode, so switching the target language no longer produces mixed-language pages, and a failed translation is never stored or displayed as if it were one. Bilingual mode pairs every original page with its own translation, in spread and portrait alike, with no duplicated or missing pages.
  • On PDFs, translated text is fitted into the original text block: it scales down when the translation runs longer, never covers the printed footer, and never spills onto the facing page. Text blocks at the bottom of the page are translated too.
  • "Original" in the translation quick bar now genuinely returns to the original pages, and the quick bar no longer covers the first line of the text.
  • Catalog synopsis pages no longer mix languages or repeat paragraphs.

Reader and PDF fixes

  • Dark theme applies to PDF pages on the first render, exactly once per page. No more white first page in dark mode.
  • A blank page can no longer get stuck in the spread cache, external page jumps work again in Scroll and Webtoon modes, and the Back button closes overlays before leaving the reader.

Performance

  • R8 shrinking and about 8 MB of unused resources stripped from the APK. Reader bitmap caches are released when leaving a book (about 176 MB), in-book search runs off the main thread, and PDF rendering is pooled and cached along the hot path.

Safety and polish

  • Backup restore is sanitized against path traversal, EPUB import is capped so a crafted book cannot exhaust memory, network security is scoped, and signing keys live outside the build script.
  • The database is migrated to v9 with proper indices, reader icons gained content descriptions, and the notes handle now meets the 48dp touch target.

Release APK checksum (Llunevie-v0.5.1-release.apk)

  • MD5: eccb9d6668bd6a553522fb160c0f9126
  • SHA-256: fc33041e09a117d454c892b4c87bab55a97ea4db3cd4a0587008e33ba8a689fe

Debug APK checksum (Llunevie-v0.5.1-debug.apk)

  • MD5: 61f423dfbeede7699412d4870219a387
  • SHA-256: 4c8acc1eea6858ef2584475afc18d0db33d88101762bf9656ea442ec81360bfa

Llunevie v0.5.1-beta.7 (Hotfix)

Pre-release

Choose a tag to compare

@Llunatics Llunatics released this 07 Nov 12:33

Llunevie v0.5.1-beta.7 — Hotfix (Version Code 69)

Changes (2-Page Spread Mode Chrome Refinement)

  1. Left vertical menu pill (ReaderSpreadLeftVerticalBar): Decoupled from the top-left Back button container and restored to vertical center alignment (Alignment.CenterStart) so the menu pill (☰, ⌃, page indicator/slider, ⌄, Aa) remains centered vertically while the round Back button stays elevated in the top-left corner (Alignment.TopStart, top = 12.dp).
  2. Right vertical title & translate pill (ReaderSpreadRightVerticalBar): Decoupled from the top-right Bookmark button container and restored to vertical center alignment (Alignment.CenterEnd) while keeping the round Bookmark button elevated in the top-right corner (Alignment.TopEnd, top = 12.dp).
  3. Notes & bookmarks drawer handle tab (‹): Restored from bottom-center (Alignment.BottomCenter) back to flush right-center (Alignment.CenterEnd, 20.dp × 48.dp, zero gap from the right screen edge), matching portrait mode and restoring the full vertical book spread size (spreadTopPadDp / spreadBottomPadDp = 8.dp).
  4. Right chrome horizontal clearance: Shifted the right vertical title pill and top-right Bookmark button slightly left (end = 26.dp) with matching spreadSidePadDp (cutoutHorizontalMaxDp + 72.dp) so they do not collide with either the flush right-center ‹ handle tab or the book edge.

Release APK checksum (Llunevie-v0.5.1-beta.7-release.apk)

  • MD5: 1fd611c630ae9cb8944dd5b64e29addd
  • SHA-256: 156d46dbe278a25b54bbb317c826bb0a395771742c42384f0c8c09b8724bbc3d

Debug APK checksum (Llunevie-v0.5.1-beta.7-debug.apk)

  • MD5: f8d6192af53261859546ba317790c490
  • SHA-256: e2354ba342f5a0e6a300345eb974c8f5ebf0cfc774d8c4bfc3523ae7da9b4074

Llunevie v0.5.1-beta.6 (Hotfix)

Pre-release

Choose a tag to compare

@Llunatics Llunatics released this 07 Nov 11:08

Llunevie v0.5.1-beta.6 — Hotfix (Version Code 68)

Changes

  1. PDF translation (Replace mode) — bottom-of-page text: Removed the hard cut-off footerGuardBottomPx = outBmp.height * 0.872f in PdfNativeRenderer.renderTranslatedPdfPageBitmap, which blocked the erase/draw pass for paragraph blocks below 87.2% of the page height (y ≈ 0.869–0.895). The footer filter in extractPdfPageParagraphBlocks now only drops pure page numbers or isolated footer lines at the bottom edge, and the [[PARA_SPLIT]] separator in TranslationRepository accepts full-width brackets. Body text at the bottom of a page is now translated together with its paragraph instead of being left untranslated or stranded at the foot of the page.

  2. Spread mode side chrome: The left and right side chrome groups (ReaderSpreadLeftVerticalBar, ReaderSpreadRightVerticalBar) moved to Alignment.TopStart / Alignment.TopEnd (top = 12.dp, start/end = 10.dp, width 42.dp), putting the round Back and Bookmark buttons much higher in the top corners, and the book's horizontal safety margin widened (spreadSidePadDp = cutoutHorizontalMaxDp + 64.dp) so the chrome no longer crowds the book's edges.

  3. Notes/bookmark handle tab (‹) in spread mode: Moved from the bottom right to the bottom center of the screen (Alignment.BottomCenter, 48.dp × 20.dp), with a matching bottom safety margin for the book (spreadBottomPadDp = 26.dp).

  4. Notes/bookmark handle tab (‹) in page-turn/portrait mode: Removed the .minimumInteractiveComponentSize() wrapper from the tab's Surface(onClick = ...), which had left a ~14.dp gap from the screen edge; the tab now sits fully flush (0px) at the right-center edge (Alignment.CenterEnd).

  5. Soft book shadow (spread and portrait): Fixed the .clipToBounds() / .padding(...) order on the spread book container, which had clipped the top and bottom shadow into a hard, flat edge. The hard shadow is replaced with Modifier.softBookShadow — 16 layers of soft Gaussian feathering around the book in spread and portrait modes, in light and dark themes — and the center spine gradient is smoother.


Release APK checksum (Llunevie-v0.5.1-beta.6-release.apk)

  • MD5: de488615c0dfd914fd15b0413c8adc6b
  • SHA-256: d5e25f1766930448e22322005056fb03fc7aa15dc36201cd694073c8fcb63b14

Debug APK checksum (Llunevie-v0.5.1-beta.6-debug.apk)

  • MD5: 6ae82fef07252e807b4d3b743efef448
  • SHA-256: 5e62a97159a56b9824212383c89359aa67e2290ce469397a758144a256b22037

Llunevie v0.5.1-beta.5

Pre-release

Choose a tag to compare

@Llunatics Llunatics released this 07 Nov 09:26

Beta release: hotfix for on-device test findings in v0.5.1-beta.4 — two-page mode redesign, PDF dark theme on first render, translated overlay bounds, and Original mode.

Two-page (spread) mode:

  • Tapping the center no longer shrinks the spread: the "minimize" state came from the spread stage padding following the chrome visibility toggle, which also shrank the book through its aspect-ratio sizing. The spread now always renders full-size in two-page mode, the center tap no longer toggles chrome there, and a stuck flip gesture can no longer leave the next spread's edge peeking in on the right (release detection fixed, and the drag state is now always reset when a gesture ends or is cancelled).
  • Chrome moved to the sides: the left vertical bar gains the Back button above the existing navigation pill, and a new right vertical bar carries the Bookmark button, a rotated book title (tap opens the table of contents), and the Translate button. The top-center title pill and the top corner buttons are hidden in spread mode; the translation quick bar still appears at the top while active. Single-page and portrait chrome are unchanged.

PDF dark theme:

  • Fixed pages rendering white on the first spread in dark mode even with the apply-theme-to-PDF option enabled: the theme color filter was applied once while composing the spread bitmap and a second time while drawing it idle, which inverted the dark paper back to light; a swipe redrew without the second pass, which is why it only looked correct after swiping. The filter now applies exactly once per page, and the theme and filter state is part of the bitmap and snapshot cache keys, so a wrongly filtered page can no longer be cached and reused.

Translated PDF overlay:

  • Translations are laid out per original text block with a fitted layout: text is erased and drawn only inside its own block's box, every block is clipped to that box, the font scales down (with tighter line spacing and end truncation as a last resort) when a translation runs longer than the original, and a footer guard keeps translated text above the printed footer zone. A translation can no longer overflow past the page bottom, cover the footer, or spill onto the facing page or its illustrations.

Original mode:

  • Tapping "Original" in the translation quick bar now actually switches the translation mode and re-renders from the original pages: previously it only set a peek flag that the PDF bitmap producers ignored, so translated bitmaps stayed on screen. The footer overlap visible in that state was the last translated line overrunning the footer on the stuck render; it is fixed both by this mode switch and by the overlay bounds above.

Known issue: one pre-existing unit test (PDF chapter title deduplication, "the" vs "The") still fails on an assertion mismatch that predates the audit batches; the code it covers is untouched. Test run otherwise matches the pre-batch baseline exactly (4 of 5 passing, no new failures).

Build: versionCode 67, clean build (assembleDebug + assembleRelease, R8 + shrinkResources).
Release APK (17,215,222 bytes) — MD5: ca70ed478c0cadc78c1faef96272b24f
SHA-256: 1d51f4c0ff81339eceea7eac9f011918533eec9e233f06d42cc9860d77614fed

Llunevie v0.5.1-beta.4

Pre-release

Choose a tag to compare

@Llunatics Llunatics released this 07 Nov 07:35

Beta release: hotfix for on-device test findings in v0.5.1-beta.3 — translation display isolation, bilingual duplication, spread layout, and 3D cover shadow.

Translation rendering (reader):

  • Page translations are now keyed per target language, and the EPUB snapshot cache key carries the text version (original/translated/partial), the display mode (Original/Replace/Bilingual), and the target language. A spread whose translation is still incomplete is rendered with no cache key at all, so a partial or mixed-language render can never be stored and reused later. Switching target language, display mode, or translation on/off now evicts the whole snapshot cache.
  • The translation repository no longer falls back to the source text when a request fails: previously a failed single-paragraph translation returned the original text as its own "translation" and cached it to disk, which is why Bilingual mode could show the same paragraph twice (once as body text, once as the grey translation block). Failed translations now yield no pair, cached entries identical to the source or containing API error text are rejected and cleaned on read, the paragraph-split marker match is case-insensitive, AI-engine failures fall back to the free engine, and the MyMemory language pair no longer uses autodetect. The bilingual block also refuses to render a "translation" that is identical to the original, and a page without a valid pair triggers its translation load.
  • Catalog synopsis pages no longer mix languages or repeat paragraphs: the intro sentence language is detected from the synopsis text itself (it previously followed the UI language), the left/right synopsis pages split without overlap, and books whose stored synopsis chapters were generated with the old duplication are rebuilt when opened.

Reader chrome and layout:

  • Two-page spread is centered again in landscape: the flipbook, non-flipbook, and fade-transition containers now center their content instead of defaulting to top-start, which had glued the book to the left half of the screen.
  • The top center pill shows the book title again in spread mode: a spread-only branch that rendered just a translate icon has been removed, so the pill carries the title (wider cap in spread), a divider, and the translate button, and still swaps to the translation quick bar while that is active.

3D book covers (Home / Library):

  • The bottom shadow is a true soft ellipse again: it is drawn with elliptical gradients rotated to the cover's bottom tilt and fading fully to transparent, replacing a circular radial gradient clipped by a flat oval that produced a hard grey bar detached from the book. The 3D front cover also paints its opaque backing color again (a Batch 4C regression), so the shadow can no longer bleed through an unloaded cover.

Checked and intentionally unchanged: the white box around the printed page number "115" in a dark-mode PDF is a dark badge from the source document's own typesetting, inverted by the dark theme color filter — not an app artifact.

Known issue: one pre-existing unit test (PDF chapter title deduplication, "the" vs "The") still fails on an assertion mismatch that predates the audit batches; the code it covers is untouched. Test run otherwise matches the pre-batch baseline exactly (4 of 5 passing, no new failures).

Build: versionCode 66, clean build (assembleDebug + assembleRelease, R8 + shrinkResources).
Release APK (17,198,828 bytes) — MD5: 6c4e17372ed476397fcf26663b054a04
SHA-256: eaa1974715a7a0efe4b80095318b289d0e8b9461d80f28951c45944691c466fa

Llunevie v0.5.1-beta.3

Pre-release

Choose a tag to compare

@Llunatics Llunatics released this 06 Nov 12:08

Beta release: Audit Batch 4 — full fix pass over Audit #2 findings (all 17 new findings plus the remaining open items from Audit #1), plus two bugs found in on-device testing of beta.2.

Batch 4A (critical/high fixes):

  • PDF spread mode can no longer cache a permanently blank page; external page jumps in Scroll/Webtoon modes work again; Back button priority in the reader is back in the right order (overlays first, exit last).
  • Backup restore is sanitized: book ids / paths in a backup can no longer escape the app folder (path traversal could previously delete the whole app data directory), and EPUB import is bounded by a total byte budget so a crafted book can no longer OOM the app.

On-device test fixes:

  • T1 — Bilingual spread mode: pagination now comes only from the original text; each bilingual page is exactly one original page plus its own translation fitted into the same box, page numbers follow the original, and switching modes no longer leaves a mixed original/translation stream. Left and right pages can no longer show unrelated passages or two translations side by side.
  • T2 — The translation quick bar (Replace | Bilingual | JA | x) no longer covers the first line of text: reader content is inset by the bar height plus margin in every mode whenever the bar is visible.

Batch 4B (performance/memory):

  • Stripped unused BouncyCastle post-quantum .properties resources from the APK (about 8 MB), translation requests no longer duplicate via a fallback Elvis chain, fit-scale results are reused instead of recomputed, a center tap no longer also fires the highlight action, reader bitmap caches are evicted on exit instead of lingering (~176 MB), and in-book search runs off the main thread.

Batch 4C (remaining items):

  • Security: scoped network security config and backup/data-extraction rules added; signing credentials moved out of the build script into a gitignored keystore.properties with identical values; stray prototype/release artifacts moved to a gitignored archive/ folder (nothing deleted).
  • Room: indices on createdAtMillis and shelf with a proper MIGRATION_8_9 (database version 9); reader highlights/bookmarks now use per-book DAO queries.
  • Auto-import folder scan has a 60-second cooldown and all HttpURLConnection calls are cancellable (connection disconnects when the coroutine is cancelled).
  • Animated root blur replaced with a static blur while modals/sheets are open (no per-frame RenderEffect rebuild); accessibility: content descriptions on reader icons and a >=48dp touch target for the quick-notes handle; several recomposition hot spots remembered/hoisted.
  • Dead code removed (~1,200 net lines, including 427 lines of dead snapshot renderers) and duplicated chapter CRUD / path helpers deduplicated.
  • Skipped by design (recorded in the run report): mechanically splitting LlunevieViewModel / PdfNativeRenderer — too tightly coupled to private mutex/state; deferred rather than risking reader stability.

Known issue: one pre-existing unit test (PDF chapter title deduplication, "the" vs "The") still fails on an assertion mismatch that predates the audit batches; the code it covers is untouched. Test run otherwise matches the pre-batch baseline exactly (4 of 5 passing, no new failures).

Build: versionCode 65, clean build (assembleDebug + assembleRelease, R8 + shrinkResources).
Release APK (17,198,828 bytes) — MD5: 1e8173ad3e1d79d9d3c9a7b8f883dd2d
SHA-256: 533516a4ce5f8faa26d1cb00e7259afe320d7d9f83a7de28854b639667cde7cc

Llunevie v0.5.1-beta.2

Pre-release

Choose a tag to compare

@Llunatics Llunatics released this 06 Nov 07:31

Beta release: Audit Batch 3 — reader hot-path performance and modularization.

  • EPUB rendering: page snapshots now actually go through the snapshot cache (byte-sized LRU) and render off the main thread, page-fit scaling uses binary search instead of a linear probe loop, and two-page spread snapshots no longer re-render pages quadratically. This removes the ~31 MB of bitmap work that previously ran on the main thread for every page turn.
  • Flipbook: page-curl state is now read in the draw phase instead of forcing recomposition every frame, and Path/Paint/RectF objects are reused across frames instead of being allocated 30-60 times per frame.
  • Page scrubber: dragging the slider no longer re-renders the target page on every tick; the jump commits once when the drag ends.
  • PDF: a single pooled PdfRenderer + file descriptor session is kept per book and closed through the Batch 2 lifecycle hook when leaving the reader; the aspect-ratio cache is now thread-safe (ConcurrentHashMap), and paginated/scroll modes share one bitmap cache key space instead of duplicating every page.
  • Scroll & Webtoon modes: saved progress now follows the first visible item instead of lagging behind, page jumps land on the exact page (chapter headers and dividers are accounted for in the index mapping), page content receives the real chapter/page indices, and pinch-to-zoom is available in both modes.
  • Reader chrome & structure: tapping the center of the page toggles the reader chrome, the Back button dismisses in-reader overlays (search, language dropdown, scrubber, quote popover, text selection) before exiting, and ReaderScreen.kt was mechanically split from 8,153 lines into a 1,353-line core plus 9 focused component files (top chrome, bottom dock, search overlay, typography sheet, TOC drawer, notes drawer, illustration viewer, page content, EPUB snapshot renderer) with no behavior change intended.

Known issue: one pre-existing unit test (PDF chapter title deduplication, "the" vs "The") still fails on an assertion mismatch that predates the audit batches; the code it covers is untouched. Test run otherwise matches the pre-batch baseline exactly (4 of 5 passing, no new failures).

Build: versionCode 64, clean build (assembleDebug + assembleRelease).
Release APK (21,320,286 bytes) — MD5: 8ad90a5f99dfe4e46bc7a8c9e7a7f932
SHA-256: 4abdb5f11a131d47405662a369224543306ea6900123ff61d0f2befbb367be9e

Llunevie v0.5.1-beta.1

Pre-release

Choose a tag to compare

@Llunatics Llunatics released this 06 Nov 04:34

Beta release: Audit Batch 2 — correctness, persistence, and memory bounds.

  • Translator: fixed the feedback loop that kept wiping the page translation cache and re-rendering flipbook bitmaps (up to 6x per page turn); in-flight page translations are now deduplicated, the current-page translation uses the correct global page index, and single-page mode next/previous bitmaps now use the translation cache — no more untranslated flash before a page settles.
  • Text parsing: chapter text sanitizing no longer strips <...> tags from LitRPG/Sci-Fi novels (the Html.fromHtml pass is gone, entities are decoded directly, regexes are pre-compiled); EPUB illustrations keep their document order; the PDF "bulan kabur" watermark filter is restricted to the header/footer margins so it cannot eat body text.
  • Memory: all bitmap caches are now byte-sized with hard caps (PDF pages 48 MB, translated PDF pages 32 MB, high-res illustrations 24 MB, EPUB images 24 MB), the cached PDF document is closed when leaving the reader, and onTrimMemory evicts bitmap caches under system memory pressure.
  • Backup & restore: backups now include all tables and reading progress; restoring updates books in place instead of clobbering existing EPUB/PDF chapters, highlights, and bookmarks; export uses the system file picker (SAF CreateDocument); v1 backup files still restore.
  • Stats: the reading session timer pauses/flushes on lifecycle changes without losing sub-minute progress or double-counting; weekly minutes and reading streaks on Home/Stats are computed over real calendar days; the library spine-width formula now matches the row renderer.

Known issue: one pre-existing unit test (PDF chapter title deduplication, "the" vs "The") still fails on an assertion mismatch that predates the audit batches; the code it covers is untouched. Test run otherwise matches the pre-batch baseline exactly (4 of 5 passing, no new failures).

Build: versionCode 63, clean build (assembleDebug + assembleRelease).
Release APK (21,303,893 bytes) — MD5: 88f84b49c81d9297c2ed28caa3a7243f
SHA-256: c5a2ab687f634609e1e398e1edbf240dca803fb540cfa8d9982284c22349f8ce

Llunevie v0.4.2-beta.1

Pre-release

Choose a tag to compare

@Llunatics Llunatics released this 06 Nov 04:02

Beta release: Audit Batch 1 — zero-risk size, startup, and leak fixes.

  • APK size down 42.8% (37.2 MB -> 21.3 MB): R8 minification and resource shrinking are now enabled for release builds, 7 duplicate/unused font files were removed from assets, and the unused palette-ktx and ui-text-google-fonts dependencies were dropped (material-icons-extended stays — it is genuinely used by the UI).
  • CameraX leak fixed in the ISBN scanner: the camera is now unbound when the scanner screen closes, so it no longer stays active in the background.
  • Lighter cold start: the dead cover-cache pre-warm is gone, and the orphan file sweep now runs before the auto-import folder scan.
  • Heavy I/O no longer runs on the main thread: opening books, deleting books, importing photos, the Settings avatar crop, and backup export were moved to background dispatchers.
  • Icons: vector paths are cached instead of re-parsed on every recomposition, tappable icons got proper content descriptions and minimum touch targets.
  • Minimal ProGuard keep rules added for PDFBox reflection paths.

Known issue: one pre-existing unit test (PDF chapter title deduplication, "the" vs "The") fails on an assertion mismatch that predates this batch; the code it covers is untouched here.

Build: versionCode 62, clean build (assembleDebug + assembleRelease).
Release APK (21,287,537 bytes) — MD5: f901ec142453e31b4911e6986daa57e6
SHA-256: 27b0a2b49f914d95aae9170ab46bae3abff9651128aede011fc4d55bf76383a5

Llunevie v0.4.1

Choose a tag to compare

@Llunatics Llunatics released this 05 Nov 11:35

Stable release: translator language selection fixes and the redesigned language picker.

  • Fixed the translator language choice lagging one step behind (choosing Japanese showed Korean): translated-PDF cache keys now include the normalized target language and mode in a dedicated cache, finished translations appear immediately via a reactive revision counter, stale flipbook bitmaps are cleared, and language codes are passed explicitly (zh -> zh-CN).
  • Canonical translation language catalog: 5 defaults (Indonesian, English, Japanese, Korean, Simplified Chinese) with native labels plus 14 additional languages; compact redesigned Top Pill language dropdown; Settings language manager with "+ Add More Languages" — custom languages persist and appear in both Settings and the reader dropdown.
  • The language selector no longer uses a Material3 DropdownMenu popup (it anchored to the whole Top Pill's left edge and had a heavy shadow halo): it is now a shadow-free card centered directly below the Top Pill, with a tap-outside catcher and auto-close.

Build: versionCode 61, clean build (assembleDebug + assembleRelease).