Skip to content

Give every tab its own navigation stack and a floating glass tab bar - #120

Open
AndrewG828 wants to merge 1 commit into
user/andrewgao/feature/UI-UX-Lucid-Refactor-09-sell-tabfrom
user/andrewgao/feature/UI-UX-Lucid-Refactor-10-tab-navigation
Open

Give every tab its own navigation stack and a floating glass tab bar#120
AndrewG828 wants to merge 1 commit into
user/andrewgao/feature/UI-UX-Lucid-Refactor-09-sell-tabfrom
user/andrewgao/feature/UI-UX-Lucid-Refactor-10-tab-navigation

Conversation

@AndrewG828

@AndrewG828 AndrewG828 commented Sep 3, 2026

Copy link
Copy Markdown
Member

Stacked PR 10 of 15. Based on #119 — merge in order.
#111#112#113#114#115#116#117#118#119#120#121#122#123#124#125

Home / Explore / Sell / Messages / Profile, five tabs where there were three,
each with an independent navigation history.

The single app-wide NavigationStack meant pushing a listing from Home and
then switching to Messages left the listing on screen — there was one path and
every tab shared it. Router now holds one path per tab and exposes the active
one through the same path property, so push/pop/popToRoot and all their
call sites are unchanged. Router.Tab names the slots, because the indices
appear in the tab bar, the stack container and two unrelated screens.

The container is hand-rolled rather than a TabView. The system bar kept
drawing underneath the custom one and showed through the glass as a second
outline. Every stack stays mounted and is toggled by opacity so tab state
survives switching; the inactive ones are hidden from accessibility and hit
testing.

Fixes that come with the tab-count change:

  • ProductDetailsView sent you to selection = 2 when you tapped your own
    name on a listing. Slot 2 is now Sell, not Profile; both call sites use
    Router.Tab instead of a literal.
  • showsTabBar reacts to the route rather than to MessagesView.onDisappear,
    which fires after the pop animation and left the bar missing for a beat.
  • Bottom content inset is always in the tree, just zero-height when the bar is
    hidden. Adding and removing the safeAreaInset broke scroll insets after a
    push and often failed to restore them on pop.
  • The .reviewTesting destination pointed at a view deleted from main; the
    branch it came from still referenced it and did not compile.

The conversation toolbar picks up a Lucide calendar icon, which is what adds
lucide-icons-swift to the project (Profile and Availability use two more of
its glyphs in later commits). Four glyphs is a thin reason for a dependency —
worth revisiting if we don't reach for more of it. Its status dot is drawn only
when there actually is a confirmed meeting; unconditionally is how it started,
which made a badge that told you nothing and lost the hint explaining why the
button refuses to open the picker.

TabViewIcon is removed: it drew the old three-icon bar and has no other
caller.

Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_017R8mua9xepzF3mnRETtd6W

Home / Explore / Sell / Messages / Profile, five tabs where there were three,
each with an independent navigation history.

The single app-wide `NavigationStack` meant pushing a listing from Home and
then switching to Messages left the listing on screen — there was one path and
every tab shared it. `Router` now holds one path per tab and exposes the active
one through the same `path` property, so `push`/`pop`/`popToRoot` and all their
call sites are unchanged. `Router.Tab` names the slots, because the indices
appear in the tab bar, the stack container and two unrelated screens.

The container is hand-rolled rather than a `TabView`. The system bar kept
drawing underneath the custom one and showed through the glass as a second
outline. Every stack stays mounted and is toggled by opacity so tab state
survives switching; the inactive ones are hidden from accessibility and hit
testing.

Fixes that come with the tab-count change:

- `ProductDetailsView` sent you to `selection = 2` when you tapped your own
  name on a listing. Slot 2 is now Sell, not Profile; both call sites use
  `Router.Tab` instead of a literal.
- `showsTabBar` reacts to the route rather than to `MessagesView.onDisappear`,
  which fires after the pop animation and left the bar missing for a beat.
- Bottom content inset is always in the tree, just zero-height when the bar is
  hidden. Adding and removing the `safeAreaInset` broke scroll insets after a
  push and often failed to restore them on pop.
- The `.reviewTesting` destination pointed at a view deleted from main; the
  branch it came from still referenced it and did not compile.

The conversation toolbar picks up a Lucide calendar icon, which is what adds
`lucide-icons-swift` to the project (Profile and Availability use two more of
its glyphs in later commits). Four glyphs is a thin reason for a dependency —
worth revisiting if we don't reach for more of it. Its status dot is drawn only
when there actually is a confirmed meeting; unconditionally is how it started,
which made a badge that told you nothing and lost the hint explaining why the
button refuses to open the picker.

`TabViewIcon` is removed: it drew the old three-icon bar and has no other
caller.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017R8mua9xepzF3mnRETtd6W
@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 7c089a40-b1ad-4ba7-84f6-7fef68156009

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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