Keep the home layout intact when the changelog is showing.

The subject grid no longer sits in a second scroller, so a tall what's-new card does not swallow scrolling or stretch the tiles.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
pepaskopec-blip 2026-10-07 14:31:44 +02:00
commit 3b4e7b283a
2 changed files with 31 additions and 39 deletions

View file

@ -61,6 +61,9 @@ struct MacFillGrid<Content: View>: View {
var minHeight: CGFloat = 148 var minHeight: CGFloat = 148
var spacing: CGFloat = 16 var spacing: CGFloat = 16
var inset: CGFloat = 28 var inset: CGFloat = 28
/// Home embeds the grid in its own scroll view. A second scroller here
/// swallows the wheel once a banner (the changelog) makes the page taller.
var scrolls = true
@ViewBuilder var content: (Int) -> Content @ViewBuilder var content: (Int) -> Content
var body: some View { var body: some View {
@ -74,32 +77,36 @@ struct MacFillGrid<Content: View>: View {
let tileH = max(minHeight, (gridH - spacing * CGFloat(max(rows - 1, 0))) / CGFloat(rows)) let tileH = max(minHeight, (gridH - spacing * CGFloat(max(rows - 1, 0))) / CGFloat(rows))
let tileW = (innerW - spacing * CGFloat(max(cols - 1, 0))) / CGFloat(max(cols, 1)) let tileW = (innerW - spacing * CGFloat(max(cols - 1, 0))) / CGFloat(max(cols, 1))
let lastCount = count - (rows - 1) * cols let lastCount = count - (rows - 1) * cols
ScrollView { let tiles = VStack(spacing: spacing) {
VStack(spacing: spacing) { ForEach(0..<rows, id: \.self) { row in
ForEach(0..<rows, id: \.self) { row in let stretch = row < rows - 1 || lastCount > 1
let stretch = row < rows - 1 || lastCount > 1 HStack(spacing: spacing) {
HStack(spacing: spacing) { ForEach(0..<cols, id: \.self) { col in
ForEach(0..<cols, id: \.self) { col in let index = row * cols + col
let index = row * cols + col if index < count {
if index < count { content(index)
content(index) .frame(
.frame( maxWidth: stretch ? .infinity : tileW,
maxWidth: stretch ? .infinity : tileW, minHeight: tileH,
minHeight: tileH, maxHeight: tileH,
maxHeight: tileH, alignment: .topLeading
alignment: .topLeading )
)
}
} }
} }
.frame(maxWidth: .infinity, alignment: .leading)
} }
.frame(maxWidth: .infinity, alignment: .leading)
} }
.frame(height: gridH, alignment: .top)
.padding(inset)
.frame(maxWidth: .infinity, minHeight: geo.size.height, alignment: .top)
} }
.scrollDisabled(floorH + inset * 2 <= geo.size.height + 1) .frame(height: gridH, alignment: .top)
.padding(inset)
.frame(maxWidth: .infinity, minHeight: scrolls ? geo.size.height : nil, alignment: .top)
if scrolls {
ScrollView { tiles }
.scrollDisabled(floorH + inset * 2 <= geo.size.height + 1)
} else {
tiles
}
} }
} }
} }

View file

@ -54,6 +54,7 @@ struct PracticeHome: View {
Text(vm.tr("subjects_title")) Text(vm.tr("subjects_title"))
.font(.title2.weight(.semibold)) .font(.title2.weight(.semibold))
} }
.fixedSize(horizontal: false, vertical: true)
.background { .background {
GeometryReader { proxy in GeometryReader { proxy in
Color.clear.preference(key: MacHeaderHeight.self, value: proxy.size.height) Color.clear.preference(key: MacHeaderHeight.self, value: proxy.size.height)
@ -64,7 +65,8 @@ struct PracticeHome: View {
minWidth: MacChrome.homeTileMin, minWidth: MacChrome.homeTileMin,
minHeight: MacChrome.homeTileHeight, minHeight: MacChrome.homeTileHeight,
spacing: 16, spacing: 16,
inset: 0 inset: 0,
scrolls: false
) { index in ) { index in
subjectTile(subjects[index]) subjectTile(subjects[index])
} }
@ -242,24 +244,7 @@ private struct ChangelogLines: View {
var body: some View { var body: some View {
VStack(alignment: .leading, spacing: 4) { VStack(alignment: .leading, spacing: 4) {
if index > 0 { Spacer().frame(height: 4) } if index > 0 { Spacer().frame(height: 4) }
#if os(macOS)
if lines.count >= 4 {
LazyVGrid(
columns: [
GridItem(.flexible(minimum: 240), spacing: 22, alignment: .topLeading),
GridItem(.flexible(minimum: 240), spacing: 22, alignment: .topLeading),
],
alignment: .leading,
spacing: 6
) {
lineList
}
} else {
VStack(alignment: .leading, spacing: 4) { lineList }
}
#else
VStack(alignment: .leading, spacing: 4) { lineList } VStack(alignment: .leading, spacing: 4) { lineList }
#endif
} }
} }