|
|
@@ -35,7 +35,6 @@ final class DashboardView: NSView, NSTextFieldDelegate {
|
|
35
|
35
|
}
|
|
36
|
36
|
|
|
37
|
37
|
private let contentStack = NSStackView()
|
|
38
|
|
- private let documentContainer = NSView()
|
|
39
|
38
|
private let chromeContainer = NSView()
|
|
40
|
39
|
private let sidebar = NSStackView()
|
|
41
|
40
|
private let mainHost = NSView()
|
|
|
@@ -50,7 +49,7 @@ final class DashboardView: NSView, NSTextFieldDelegate {
|
|
50
|
49
|
private let findJobsCTAHost = NSView()
|
|
51
|
50
|
private let findJobsCTAChrome = NSView()
|
|
52
|
51
|
private var findJobsCTAGradientLayer: CAGradientLayer?
|
|
53
|
|
- private let scrollView = NSScrollView()
|
|
|
52
|
+ private let jobListingsScrollView = NSScrollView()
|
|
54
|
53
|
private let jobListingsContainer = NSView()
|
|
55
|
54
|
private let jobListingsStack = NSStackView()
|
|
56
|
55
|
|
|
|
@@ -69,7 +68,6 @@ final class DashboardView: NSView, NSTextFieldDelegate {
|
|
69
|
68
|
|
|
70
|
69
|
override func layout() {
|
|
71
|
70
|
super.layout()
|
|
72
|
|
- updateDocumentLayout()
|
|
73
|
71
|
updateSearchBarShadowPath()
|
|
74
|
72
|
findJobsCTAGradientLayer?.frame = findJobsCTAChrome.bounds
|
|
75
|
73
|
updateFindJobsCTAShadowPath()
|
|
|
@@ -85,18 +83,12 @@ final class DashboardView: NSView, NSTextFieldDelegate {
|
|
85
|
83
|
}
|
|
86
|
84
|
configureSidebar()
|
|
87
|
85
|
configureJobListings(data.jobListings)
|
|
88
|
|
- updateDocumentLayout()
|
|
89
|
86
|
}
|
|
90
|
87
|
|
|
91
|
88
|
private func setupLayout() {
|
|
92
|
89
|
wantsLayer = true
|
|
93
|
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
|
92
|
contentStack.orientation = .horizontal
|
|
101
|
93
|
contentStack.spacing = 20
|
|
102
|
94
|
contentStack.distribution = .fill
|
|
|
@@ -104,16 +96,12 @@ final class DashboardView: NSView, NSTextFieldDelegate {
|
|
104
|
96
|
contentStack.alignment = .height
|
|
105
|
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
|
99
|
chromeContainer.translatesAutoresizingMaskIntoConstraints = false
|
|
111
|
100
|
chromeContainer.wantsLayer = true
|
|
112
|
101
|
chromeContainer.layer?.backgroundColor = Theme.chromeBackground.cgColor
|
|
113
|
102
|
chromeContainer.layer?.cornerRadius = 0
|
|
114
|
|
- documentContainer.addSubview(chromeContainer)
|
|
|
103
|
+ addSubview(chromeContainer)
|
|
115
|
104
|
chromeContainer.addSubview(contentStack)
|
|
116
|
|
- scrollView.documentView = documentContainer
|
|
117
|
105
|
|
|
118
|
106
|
sidebar.orientation = .vertical
|
|
119
|
107
|
sidebar.spacing = 10
|
|
|
@@ -188,32 +176,31 @@ final class DashboardView: NSView, NSTextFieldDelegate {
|
|
188
|
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
|
189
|
mainOverlay.addArrangedSubview(topInset)
|
|
197
|
190
|
mainOverlay.addArrangedSubview(titleBlock)
|
|
198
|
191
|
mainOverlay.addArrangedSubview(midSpacer)
|
|
199
|
192
|
mainOverlay.addArrangedSubview(searchBarShadowHost)
|
|
200
|
193
|
mainOverlay.addArrangedSubview(listingsTopSpacer)
|
|
201
|
|
- mainOverlay.addArrangedSubview(jobListingsContainer)
|
|
202
|
|
- mainOverlay.addArrangedSubview(overlayBottomSpacer)
|
|
|
194
|
+ mainOverlay.addArrangedSubview(jobListingsScrollView)
|
|
203
|
195
|
|
|
204
|
196
|
contentStack.addArrangedSubview(sidebar)
|
|
205
|
197
|
contentStack.addArrangedSubview(mainHost)
|
|
206
|
198
|
|
|
207
|
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
|
205
|
contentStack.leadingAnchor.constraint(equalTo: chromeContainer.leadingAnchor),
|
|
219
|
206
|
contentStack.trailingAnchor.constraint(equalTo: chromeContainer.trailingAnchor),
|
|
|
@@ -229,7 +216,11 @@ final class DashboardView: NSView, NSTextFieldDelegate {
|
|
229
|
216
|
mainOverlay.bottomAnchor.constraint(equalTo: mainHost.bottomAnchor, constant: -24),
|
|
230
|
217
|
|
|
231
|
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
|
225
|
greetingLabel.leadingAnchor.constraint(equalTo: mainOverlay.leadingAnchor, constant: 24),
|
|
235
|
226
|
greetingLabel.trailingAnchor.constraint(equalTo: mainOverlay.trailingAnchor, constant: -24),
|
|
|
@@ -699,11 +690,6 @@ final class DashboardView: NSView, NSTextFieldDelegate {
|
|
699
|
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
|
695
|
/// Captures clicks for the full sidebar pill so icon, label, and padding behave as one tab.
|