|
@@ -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.
|