Skip to content

refactor(ui): InsetHeaderScrollView, shared tab swipes#535

Open
pwltr wants to merge 1 commit intomasterfrom
fix/sticky-nav
Open

refactor(ui): InsetHeaderScrollView, shared tab swipes#535
pwltr wants to merge 1 commit intomasterfrom
fix/sticky-nav

Conversation

@pwltr
Copy link
Copy Markdown
Contributor

@pwltr pwltr commented May 4, 2026

Description

  • add a reusable InsetHeaderScrollView with measured top safeAreaInset header + scroll content minHeight to fill the viewport below. To be used on scrollable screens with headers like AllActivity, MainSettings, ShopDiscover.
  • add swipeSegmentedTabs for AllActivity, MainSettings, and ShopDiscover segmented controls (horizontal swipe to change tabs).
  • refactor Card views
  • fix "lightbulb" figure image

Screenshot / Video

Simulator.Screen.Recording.-.iPhone.17.-.2026-05-04.at.23.44.27.mov

QA Notes

Make sure changed screens look polished and suggestion/shop cards still work as expected.

@pwltr pwltr self-assigned this May 4, 2026
@pwltr pwltr added this to the 2.3.0 milestone May 4, 2026
@pwltr pwltr marked this pull request as ready for review May 4, 2026 21:46
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a8e3162b57

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Bitkit/Assets.xcassets/icons/lightbulb.imageset/Contents.json Outdated
@pwltr pwltr force-pushed the fix/sticky-nav branch from a8e3162 to 09fe376 Compare May 5, 2026 06:42

/// Before the first header measurement, use full height so `minHeight` is non-negative.
private func contentMinHeight(in geo: GeometryProxy) -> CGFloat {
let insetTop = headerHeight > 0 ? headerHeight : geo.size.height
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: contentMinHeight fallback returns 0 instead of the full viewport height

The conditional is inverted. When headerHeight == 0 (before the first preference propagation), insetTop is set to geo.size.height, so the method returns max(0, geo.size.height - geo.size.height) = 0. This contradicts the doc comment — "use full height so minHeight is non-negative" — and causes scroll content to collapse to zero minimum height on first render, producing a visible layout flash. SupportScreen, which previously used geometry.size.height for frame(minHeight:) to pin footer content at the bottom, will regress.

Context:

/// Before the first header measurement, use full height so `minHeight` is non-negative.
private func contentMinHeight(in geo: GeometryProxy) -> CGFloat {
let insetTop = headerHeight > 0 ? headerHeight : geo.size.height
return max(0, geo.size.height - insetTop)
}

The fix is to swap the fallback: when headerHeight is not yet known, subtract 0 so the content gets the full geometry height as its minimum.

Suggested change
let insetTop = headerHeight > 0 ? headerHeight : geo.size.height
let insetTop = headerHeight > 0 ? headerHeight : 0

import SwiftUI

/// Shared gradient tile used by suggestions widget and shop discover
struct Card: View {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLAUDE.md: name Card violates the descriptive-names rule

CLAUDE.md states:

Use descriptive names (e.g., UserProfileCard not Card)

Card is the exact anti-example cited in the rule. The doc comment already describes a specific semantic role ("Shared gradient tile used by suggestions widget and shop discover"), so a more descriptive name is straightforward — e.g. SuggestionTileCard or GradientTileCard.

Context:

/// Shared gradient tile used by suggestions widget and shop discover
struct Card: View {
let title: String

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