Просмотр исходного кода

Fix dashboard scroll: only job list uses NSScrollView

Remove the full-window scroll view so the chrome, welcome block, and
search bar stay fixed. Wrap job cards in a dedicated vertical
NSScrollView with document layout tied to the clip view.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 недель назад: 3
Родитель
Сommit
6b4c5b3f4e
1 измененных файлов с 21 добавлено и 35 удалено
  1. 21 35
      App for Indeed/Views/DashboardView.swift

+ 21 - 35
App for Indeed/Views/DashboardView.swift

@@ -35,7 +35,6 @@ final class DashboardView: NSView, NSTextFieldDelegate {
35
     }
35
     }
36
 
36
 
37
     private let contentStack = NSStackView()
37
     private let contentStack = NSStackView()
38
-    private let documentContainer = NSView()
39
     private let chromeContainer = NSView()
38
     private let chromeContainer = NSView()
40
     private let sidebar = NSStackView()
39
     private let sidebar = NSStackView()
41
     private let mainHost = NSView()
40
     private let mainHost = NSView()
@@ -50,7 +49,7 @@ final class DashboardView: NSView, NSTextFieldDelegate {
50
     private let findJobsCTAHost = NSView()
49
     private let findJobsCTAHost = NSView()
51
     private let findJobsCTAChrome = NSView()
50
     private let findJobsCTAChrome = NSView()
52
     private var findJobsCTAGradientLayer: CAGradientLayer?
51
     private var findJobsCTAGradientLayer: CAGradientLayer?
53
-    private let scrollView = NSScrollView()
52
+    private let jobListingsScrollView = NSScrollView()
54
     private let jobListingsContainer = NSView()
53
     private let jobListingsContainer = NSView()
55
     private let jobListingsStack = NSStackView()
54
     private let jobListingsStack = NSStackView()
56
 
55
 
@@ -69,7 +68,6 @@ final class DashboardView: NSView, NSTextFieldDelegate {
69
 
68
 
70
     override func layout() {
69
     override func layout() {
71
         super.layout()
70
         super.layout()
72
-        updateDocumentLayout()
73
         updateSearchBarShadowPath()
71
         updateSearchBarShadowPath()
74
         findJobsCTAGradientLayer?.frame = findJobsCTAChrome.bounds
72
         findJobsCTAGradientLayer?.frame = findJobsCTAChrome.bounds
75
         updateFindJobsCTAShadowPath()
73
         updateFindJobsCTAShadowPath()
@@ -85,18 +83,12 @@ final class DashboardView: NSView, NSTextFieldDelegate {
85
         }
83
         }
86
         configureSidebar()
84
         configureSidebar()
87
         configureJobListings(data.jobListings)
85
         configureJobListings(data.jobListings)
88
-        updateDocumentLayout()
89
     }
86
     }
90
 
87
 
91
     private func setupLayout() {
88
     private func setupLayout() {
92
         wantsLayer = true
89
         wantsLayer = true
93
         layer?.backgroundColor = Theme.pageBackground.cgColor
90
         layer?.backgroundColor = Theme.pageBackground.cgColor
94
 
91
 
95
-        scrollView.translatesAutoresizingMaskIntoConstraints = false
96
-        scrollView.hasVerticalScroller = true
97
-        scrollView.drawsBackground = false
98
-        addSubview(scrollView)
99
-
100
         contentStack.orientation = .horizontal
92
         contentStack.orientation = .horizontal
101
         contentStack.spacing = 20
93
         contentStack.spacing = 20
102
         contentStack.distribution = .fill
94
         contentStack.distribution = .fill
@@ -104,16 +96,12 @@ final class DashboardView: NSView, NSTextFieldDelegate {
104
         contentStack.alignment = .height
96
         contentStack.alignment = .height
105
         contentStack.edgeInsets = NSEdgeInsets(top: 24, left: 24, bottom: 24, right: 24)
97
         contentStack.edgeInsets = NSEdgeInsets(top: 24, left: 24, bottom: 24, right: 24)
106
 
98
 
107
-        documentContainer.translatesAutoresizingMaskIntoConstraints = true
108
-        documentContainer.autoresizingMask = [.width]
109
-        documentContainer.frame = NSRect(x: 0, y: 0, width: 1040, height: 900)
110
         chromeContainer.translatesAutoresizingMaskIntoConstraints = false
99
         chromeContainer.translatesAutoresizingMaskIntoConstraints = false
111
         chromeContainer.wantsLayer = true
100
         chromeContainer.wantsLayer = true
112
         chromeContainer.layer?.backgroundColor = Theme.chromeBackground.cgColor
101
         chromeContainer.layer?.backgroundColor = Theme.chromeBackground.cgColor
113
         chromeContainer.layer?.cornerRadius = 0
102
         chromeContainer.layer?.cornerRadius = 0
114
-        documentContainer.addSubview(chromeContainer)
103
+        addSubview(chromeContainer)
115
         chromeContainer.addSubview(contentStack)
104
         chromeContainer.addSubview(contentStack)
116
-        scrollView.documentView = documentContainer
117
 
105
 
118
         sidebar.orientation = .vertical
106
         sidebar.orientation = .vertical
119
         sidebar.spacing = 10
107
         sidebar.spacing = 10
@@ -188,32 +176,31 @@ final class DashboardView: NSView, NSTextFieldDelegate {
188
             jobListingsStack.bottomAnchor.constraint(equalTo: jobListingsContainer.bottomAnchor)
176
             jobListingsStack.bottomAnchor.constraint(equalTo: jobListingsContainer.bottomAnchor)
189
         ])
177
         ])
190
 
178
 
191
-        let overlayBottomSpacer = NSView()
192
-        overlayBottomSpacer.translatesAutoresizingMaskIntoConstraints = false
193
-        overlayBottomSpacer.setContentHuggingPriority(.defaultLow, for: .vertical)
194
-        overlayBottomSpacer.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
179
+        jobListingsScrollView.translatesAutoresizingMaskIntoConstraints = false
180
+        jobListingsScrollView.hasVerticalScroller = true
181
+        jobListingsScrollView.hasHorizontalScroller = false
182
+        jobListingsScrollView.autohidesScrollers = true
183
+        jobListingsScrollView.drawsBackground = false
184
+        jobListingsScrollView.borderType = .noBorder
185
+        jobListingsScrollView.documentView = jobListingsContainer
186
+        jobListingsScrollView.setContentHuggingPriority(.defaultLow, for: .vertical)
187
+        jobListingsScrollView.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
195
 
188
 
196
         mainOverlay.addArrangedSubview(topInset)
189
         mainOverlay.addArrangedSubview(topInset)
197
         mainOverlay.addArrangedSubview(titleBlock)
190
         mainOverlay.addArrangedSubview(titleBlock)
198
         mainOverlay.addArrangedSubview(midSpacer)
191
         mainOverlay.addArrangedSubview(midSpacer)
199
         mainOverlay.addArrangedSubview(searchBarShadowHost)
192
         mainOverlay.addArrangedSubview(searchBarShadowHost)
200
         mainOverlay.addArrangedSubview(listingsTopSpacer)
193
         mainOverlay.addArrangedSubview(listingsTopSpacer)
201
-        mainOverlay.addArrangedSubview(jobListingsContainer)
202
-        mainOverlay.addArrangedSubview(overlayBottomSpacer)
194
+        mainOverlay.addArrangedSubview(jobListingsScrollView)
203
 
195
 
204
         contentStack.addArrangedSubview(sidebar)
196
         contentStack.addArrangedSubview(sidebar)
205
         contentStack.addArrangedSubview(mainHost)
197
         contentStack.addArrangedSubview(mainHost)
206
 
198
 
207
         NSLayoutConstraint.activate([
199
         NSLayoutConstraint.activate([
208
-            scrollView.leadingAnchor.constraint(equalTo: leadingAnchor),
209
-            scrollView.trailingAnchor.constraint(equalTo: trailingAnchor),
210
-            scrollView.topAnchor.constraint(equalTo: topAnchor),
211
-            scrollView.bottomAnchor.constraint(equalTo: bottomAnchor),
212
-
213
-            chromeContainer.leadingAnchor.constraint(equalTo: documentContainer.leadingAnchor),
214
-            chromeContainer.trailingAnchor.constraint(equalTo: documentContainer.trailingAnchor),
215
-            chromeContainer.topAnchor.constraint(equalTo: documentContainer.topAnchor),
216
-            chromeContainer.bottomAnchor.constraint(equalTo: documentContainer.bottomAnchor),
200
+            chromeContainer.leadingAnchor.constraint(equalTo: leadingAnchor),
201
+            chromeContainer.trailingAnchor.constraint(equalTo: trailingAnchor),
202
+            chromeContainer.topAnchor.constraint(equalTo: topAnchor),
203
+            chromeContainer.bottomAnchor.constraint(equalTo: bottomAnchor),
217
 
204
 
218
             contentStack.leadingAnchor.constraint(equalTo: chromeContainer.leadingAnchor),
205
             contentStack.leadingAnchor.constraint(equalTo: chromeContainer.leadingAnchor),
219
             contentStack.trailingAnchor.constraint(equalTo: chromeContainer.trailingAnchor),
206
             contentStack.trailingAnchor.constraint(equalTo: chromeContainer.trailingAnchor),
@@ -229,7 +216,11 @@ final class DashboardView: NSView, NSTextFieldDelegate {
229
             mainOverlay.bottomAnchor.constraint(equalTo: mainHost.bottomAnchor, constant: -24),
216
             mainOverlay.bottomAnchor.constraint(equalTo: mainHost.bottomAnchor, constant: -24),
230
 
217
 
231
             searchBarShadowHost.widthAnchor.constraint(equalTo: mainOverlay.widthAnchor, multiplier: 0.92),
218
             searchBarShadowHost.widthAnchor.constraint(equalTo: mainOverlay.widthAnchor, multiplier: 0.92),
232
-            jobListingsContainer.widthAnchor.constraint(equalTo: mainOverlay.widthAnchor, multiplier: 0.92),
219
+            jobListingsScrollView.widthAnchor.constraint(equalTo: mainOverlay.widthAnchor, multiplier: 0.92),
220
+
221
+            jobListingsContainer.topAnchor.constraint(equalTo: jobListingsScrollView.contentView.topAnchor),
222
+            jobListingsContainer.leadingAnchor.constraint(equalTo: jobListingsScrollView.contentView.leadingAnchor),
223
+            jobListingsContainer.widthAnchor.constraint(equalTo: jobListingsScrollView.contentView.widthAnchor),
233
 
224
 
234
             greetingLabel.leadingAnchor.constraint(equalTo: mainOverlay.leadingAnchor, constant: 24),
225
             greetingLabel.leadingAnchor.constraint(equalTo: mainOverlay.leadingAnchor, constant: 24),
235
             greetingLabel.trailingAnchor.constraint(equalTo: mainOverlay.trailingAnchor, constant: -24),
226
             greetingLabel.trailingAnchor.constraint(equalTo: mainOverlay.trailingAnchor, constant: -24),
@@ -699,11 +690,6 @@ final class DashboardView: NSView, NSTextFieldDelegate {
699
         configureSidebar()
690
         configureSidebar()
700
     }
691
     }
701
 
692
 
702
-    private func updateDocumentLayout() {
703
-        documentContainer.layoutSubtreeIfNeeded()
704
-        let fittingHeight = max(chromeContainer.fittingSize.height, bounds.height)
705
-        documentContainer.frame = NSRect(x: 0, y: 0, width: bounds.width, height: fittingHeight)
706
-    }
707
 }
693
 }
708
 
694
 
709
 /// Captures clicks for the full sidebar pill so icon, label, and padding behave as one tab.
695
 /// Captures clicks for the full sidebar pill so icon, label, and padding behave as one tab.