Skip to content

fix(ui): unify reader overlays, empty/error states, and hit targets - #1198

Merged
everpcpc merged 1 commit into
mainfrom
fix/ui-review-batch-2
Oct 4, 2026
Merged

everpcpc merged 1 commit into
mainfrom
fix/ui-review-batch-2

Conversation

@everpcpc

@everpcpc everpcpc commented Oct 4, 2026

Copy link
Copy Markdown
Member

Stacked on #1197 — review that one first; this diff shrinks to batch-2 only once it merges.

Problem

Second batch from the UI review: the PDF reader overlay never received the chrome polish the DIVINA reader got, empty/error states had grown into four or five hand-drawn variants, and a sweep of plain buttons was only tappable on their glyphs (AGENTS.md rule 23).

  • PDF chrome visibility animated with a single .easeInOut + insertion transition while DIVINA rides a split curve/spring; PDF page numbers hard-cut instead of .numericText(); PDF scrims lacked location stops and the 120pt readability extension past the bars.
  • The DIVINA page-jump button stayed visibly tappable with no pages and silently did nothing.
  • EPUB in-page progress filled from the leading edge even for RTL publications, and its download detail hand-formatted megabytes.
  • Reader-level failures were drawn four different ways (NoPagesView with hardcoded white text, hand-rolled PDF and EPUB error rows, a one-line EPUB empty state), and app empty states used three different icon treatments; AdminRequiredView and the oneshot error state were hand-drawn too.
  • ~20 plain buttons/links/menus (search results, TOC disclosures, preset apply, offline task actions, protection chips, membership rows, settings links, saved-filter apply, edit-sheet trash buttons, heatmap cells, section-header menus) had hit areas far below 44pt, and several icon-only buttons read their SF Symbol names to VoiceOver.

Fix

  • Port the DIVINA chrome structure to the PDF overlay: opacity on .appCurve(0.3), bar slide on .appSpring, always-rendered bars driven by offset instead of insertion transitions, scrim stops with a 120pt extension, .numericText() page transitions, and .accessibilityHidden on hidden chrome.
  • Disable the DIVINA page-jump button when the book has no pages.
  • Mirror the EPUB in-page progress track for RTL publications and switch the EPUB download detail to ByteCountFormatter.
  • Converge all book-level reader failures on ReaderUnavailableView (now with an optional prominent Retry; Close demotes to bordered when Retry is present), deleting NoPagesView.
  • Render empty/error states through ContentUnavailableView everywhere: BrowseStateView internally (API unchanged), library list, server reading stats, admin-required, oneshot detail (with Retry), collection series query, picker-sheet no-results via ContentUnavailableView.search, and the PDF search sheet's three states.
  • Add .contentShape (inside labels, per rule 23), 44pt minimum frames, and accessibility labels across the swept buttons; heatmap cells keep their 13pt visuals but gain 28pt hit containers with compensated grid pitch.
  • Document the reader-level unavailable state and the empty/error state conventions in the repo-conventions skill.

Validation

  • make format
  • make build — iOS, macOS, tvOS all pass
  • make localize + misc/translate.py list — no missing keys (2 new keys translated for all 10 languages)

@everpcpc
everpcpc force-pushed the fix/ui-review-batch-2 branch from 70cd1b0 to be4a24c Compare October 4, 2026 09:43
@everpcpc
everpcpc merged commit 5d44d82 into main Oct 4, 2026
3 checks passed
@everpcpc
everpcpc deleted the fix/ui-review-batch-2 branch October 4, 2026 09:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant