Skip to content

fix: Android UI polish — safe-area, headers, review filter, log - #28

Merged
damarals merged 5 commits into
mainfrom
fix/ui-polish
May 10, 2026
Merged

damarals merged 5 commits into
mainfrom
fix/ui-polish

Conversation

@damarals

Copy link
Copy Markdown
Owner

Summary

  • Library home FAB was hiding behind the Android nav bar; absolute positioning ignores SafeAreaView padding, so NewDeckFAB now reads useSafeAreaInsets().bottom directly. Library SafeAreaView also gained the 'bottom' edge.
  • Native Stack header rendered under the status bar on first mount (corrected itself on resume). Root SafeAreaProvider now initialized with initialWindowMetrics so insets are available synchronously at mount instead of after the first layout pass.
  • Removed custom components/ui/screen-header.tsx — it duplicated the native Stack header above it (double-header smell). 5 screens migrated: deck/[id], import, export/[id], card/[deckId]/[isrc], review/[id]. Per-screen titles set in _layout.tsx; review uses a per-screen <Stack.Screen options> for its dynamic subtitle + Export PDF action.
  • app/generate.tsx placeholder back to a short format hint (https://...) — was duplicating the helper text below and wrapping at the path separator on Android. Added numberOfLines={1} to suppress the EditText hint wrap.
  • app/review/[id].tsx kept/skipped pills are now Pressable filter toggles (accessibilityState.selected set). Inactive pill fades to opacity 0.4. Skipped pill gained a tinted Dot to match the kept pill's composition; the green pill lost the inline ✓ (third redundant green signal next to lime tone + lime Dot). User-facing copy unified: "dropped" → "skipped".
  • app/resolving.tsx live log: dropped the second stats row (X dropped + X% duplicated the first), swapped mono font for display font (Nunito_600SemiBold 13px), removed inline → arrow and ✓/skipped text. Year now joined by middle dot: Artist — Title · 1975. Skipped tracks render red without the explicit label.

Test plan

  • npm run typecheck clean
  • Library home: FAB visible above Android nav bar
  • Open inner screen (deck, import, export, card preview, review) on first mount — back chevron and title respect status bar without minimize/restore
  • Review: tap green pill → filters to kept; tap again → all; tap red pill → filters to skipped
  • Resolving: log shows Artist — Title · 1975 (no arrows/checkmarks); skipped tracks in red
  • Generate input: placeholder reads https://..., single line on narrow phones

damarals added 5 commits May 11, 2026 00:51
The bottom FAB on the library home was hiding behind the Android
navigation bar, and the native Stack header rendered under the
status bar on first mount (corrected itself on app resume).

- NewDeckFAB now reads useSafeAreaInsets().bottom for its offset;
  absolute positioning ignores SafeAreaView padding, so the inset
  must be applied directly.
- LibraryScreen SafeAreaView now includes the 'bottom' edge so
  flow children sit above the nav bar.
- RootLayout's SafeAreaProvider is now initialized with
  initialWindowMetrics so insets are available synchronously on
  first render — react-navigation's header reads insets at mount
  and was getting top=0 before the layout pass settled.
The custom ScreenHeader sat inside the screen body even though
the native Stack header was already rendered above it — a
"double header" smell that wasted vertical space and split title
ownership across two components.

- Set per-screen titles in _layout.tsx for deck/[id] ("Deck"),
  export/[id] ("Export"), card/[deckId]/[isrc] ("Card preview"),
  and import ("Import deck"). review/[id] uses an in-screen
  <Stack.Screen options> because its headerTitle (subtitle is
  dynamic) and headerRight (Export PDF) depend on local state.
- Brand-style the global headerTitleStyle: Nunito 900 Black 18px
  in navy50, matching the prior ScreenHeader visual.
- Delete components/ui/screen-header.tsx and remove all imports.
The placeholder text duplicated the helper text below the field
(both showing the example URL), and on Android the long URL
wrapped at the path separator since the EditText hint doesn't
honor single-line by default.

- Drop the placeholder back to a short format hint ("https://...")
  per Material/Baymard guidance: placeholders carry the shape of
  the value, not the value itself.
- Add numberOfLines={1} so Android stops wrapping the hint.
- Helper text below the field continues to show the full example
  URL — that's where elaboration belongs.
The pills above the review list were status-only — useful as a
glance but inert. Make them functional filter chips so the user
can isolate either bucket. Also unify wording.

- Wrap each pill in a Pressable that toggles a FilterKind state
  ('all' | 'kept' | 'dropped'). Tapping the active pill clears
  the filter; tapping the other switches to it.
- Inactive pill fades to opacity 0.4 to signal the filter state.
- Add a red Dot to the skipped pill so both pills share the same
  composition (Dot + label) — the green pill loses the inline ✓,
  which was a third redundant green signal next to the lime tone
  and lime Dot.
- Rename "dropped" → "skipped" in user-facing copy (header
  subtitle + pill text). The domain term ("dropped"/DroppedTrack)
  stays in code; the user-facing word is friendlier.
- accessibilityState={{ selected }} announces the active filter.
The log felt CLI-ish: mono font, arrows, checkmarks, and a
second stats row that duplicated the first.

- Drop the second stats row (the "X dropped" + "X%" line).
  The kept count is in the header subtitle and the bar already
  conveys percentage visually; explicit numbers were redundant.
- Replace mono font (JetBrainsMono 11px) with display font
  (Nunito_600SemiBold 13px) so the ticker reads as polished UI
  rather than terminal output.
- Drop the inline arrow + checkmark glyphs. The year is now
  joined by a middle-dot separator: "Artist — Title · 1975".
  Skipped tracks omit the year and use the red text color
  alone to signal state — no "skipped" label needed.
@damarals
damarals merged commit 628d37b into main May 10, 2026
1 check passed
@damarals
damarals deleted the fix/ui-polish branch May 10, 2026 23:03
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