|
@@ -100,6 +100,7 @@ final class DashboardView: NSView, NSTextFieldDelegate, NSSharingServicePickerDe
|
|
|
private let welcomeLogoWell = NSView()
|
|
private let welcomeLogoWell = NSView()
|
|
|
private let welcomeLogoView = IndeedLogoView(displayHeight: 40, variant: .compact)
|
|
private let welcomeLogoView = IndeedLogoView(displayHeight: 40, variant: .compact)
|
|
|
private let featureCardsRow = NSStackView()
|
|
private let featureCardsRow = NSStackView()
|
|
|
|
|
+ private enum FeatureShortcut: Int { case role = 0, company = 1, skill = 2 }
|
|
|
private let clearChatButton = NSButton(title: "Clear chat", target: nil, action: nil)
|
|
private let clearChatButton = NSButton(title: "Clear chat", target: nil, action: nil)
|
|
|
private let chatScrollView = NSScrollView()
|
|
private let chatScrollView = NSScrollView()
|
|
|
private let chatDocumentView = JobListingsDocumentView()
|
|
private let chatDocumentView = JobListingsDocumentView()
|
|
@@ -1813,17 +1814,27 @@ final class DashboardView: NSView, NSTextFieldDelegate, NSSharingServicePickerDe
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@objc private func didTapFeatureRole() {
|
|
@objc private func didTapFeatureRole() {
|
|
|
|
|
+ selectFeatureShortcut(.role)
|
|
|
focusSearchField(seed: "Find roles similar to: ")
|
|
focusSearchField(seed: "Find roles similar to: ")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@objc private func didTapFeatureCompany() {
|
|
@objc private func didTapFeatureCompany() {
|
|
|
|
|
+ selectFeatureShortcut(.company)
|
|
|
focusSearchField(seed: "Find jobs at company: ")
|
|
focusSearchField(seed: "Find jobs at company: ")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@objc private func didTapFeatureSkill() {
|
|
@objc private func didTapFeatureSkill() {
|
|
|
|
|
+ selectFeatureShortcut(.skill)
|
|
|
focusSearchField(seed: "Find jobs that require skill: ")
|
|
focusSearchField(seed: "Find jobs that require skill: ")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private func selectFeatureShortcut(_ shortcut: FeatureShortcut) {
|
|
|
|
|
+ for (index, view) in featureCardsRow.arrangedSubviews.enumerated() {
|
|
|
|
|
+ guard let card = view as? FeatureShortcutCardView else { continue }
|
|
|
|
|
+ card.isSelected = (index == shortcut.rawValue)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@objc private func didTapShareApp(_ sender: NSButton) {
|
|
@objc private func didTapShareApp(_ sender: NSButton) {
|
|
|
presentAppShareMenu(anchoredTo: sender)
|
|
presentAppShareMenu(anchoredTo: sender)
|
|
|
}
|
|
}
|
|
@@ -3167,6 +3178,9 @@ private final class WelcomeHeroBackgroundView: NSView {
|
|
|
/// Home welcome row: three tappable shortcuts that seed the main search field (reference: white cards, pastel icon well, arrow at bottom trailing).
|
|
/// Home welcome row: three tappable shortcuts that seed the main search field (reference: white cards, pastel icon well, arrow at bottom trailing).
|
|
|
private final class FeatureShortcutCardView: NSView {
|
|
private final class FeatureShortcutCardView: NSView {
|
|
|
private static let cardCornerRadius: CGFloat = 14
|
|
private static let cardCornerRadius: CGFloat = 14
|
|
|
|
|
+ private static let primaryBlue = NSColor(srgbRed: 0, green: 82 / 255, blue: 204 / 255, alpha: 1)
|
|
|
|
|
+ private static let defaultBorderColor = NSColor(srgbRed: 237 / 255, green: 242 / 255, blue: 247 / 255, alpha: 1)
|
|
|
|
|
+ var isSelected = false { didSet { updateSelectionAppearance() } }
|
|
|
private weak var actionTarget: AnyObject?
|
|
private weak var actionTarget: AnyObject?
|
|
|
private var actionSelector: Selector
|
|
private var actionSelector: Selector
|
|
|
|
|
|
|
@@ -3182,16 +3196,13 @@ private final class FeatureShortcutCardView: NSView {
|
|
|
}
|
|
}
|
|
|
layer?.backgroundColor = NSColor.white.cgColor
|
|
layer?.backgroundColor = NSColor.white.cgColor
|
|
|
layer?.masksToBounds = false
|
|
layer?.masksToBounds = false
|
|
|
- layer?.borderWidth = 1
|
|
|
|
|
- // `#EDF2F7` — light card stroke.
|
|
|
|
|
- layer?.borderColor = NSColor(srgbRed: 237 / 255, green: 242 / 255, blue: 247 / 255, alpha: 1).cgColor
|
|
|
|
|
layer?.shadowColor = NSColor.black.withAlphaComponent(0.06).cgColor
|
|
layer?.shadowColor = NSColor.black.withAlphaComponent(0.06).cgColor
|
|
|
layer?.shadowOffset = CGSize(width: 0, height: 2)
|
|
layer?.shadowOffset = CGSize(width: 0, height: 2)
|
|
|
layer?.shadowRadius = 12
|
|
layer?.shadowRadius = 12
|
|
|
layer?.shadowOpacity = 1
|
|
layer?.shadowOpacity = 1
|
|
|
|
|
+ updateSelectionAppearance()
|
|
|
|
|
|
|
|
- // `#0052CC` — primary title / icons / arrow (matches welcome hero reference).
|
|
|
|
|
- let primaryBlue = NSColor(srgbRed: 0, green: 82 / 255, blue: 204 / 255, alpha: 1)
|
|
|
|
|
|
|
+ let primaryBlue = Self.primaryBlue
|
|
|
// `#EBF2FF` — circular icon well.
|
|
// `#EBF2FF` — circular icon well.
|
|
|
let iconWellColor = NSColor(srgbRed: 235 / 255, green: 242 / 255, blue: 255 / 255, alpha: 1)
|
|
let iconWellColor = NSColor(srgbRed: 235 / 255, green: 242 / 255, blue: 255 / 255, alpha: 1)
|
|
|
// `#5D6D7E` — muted description.
|
|
// `#5D6D7E` — muted description.
|
|
@@ -3284,6 +3295,20 @@ private final class FeatureShortcutCardView: NSView {
|
|
|
setAccessibilityLabel("\(title). \(subtitle)")
|
|
setAccessibilityLabel("\(title). \(subtitle)")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private func updateSelectionAppearance() {
|
|
|
|
|
+ guard let layer else { return }
|
|
|
|
|
+ if isSelected {
|
|
|
|
|
+ layer.borderWidth = 2
|
|
|
|
|
+ layer.borderColor = Self.primaryBlue.cgColor
|
|
|
|
|
+ layer.shadowOpacity = 0.1
|
|
|
|
|
+ } else {
|
|
|
|
|
+ layer.borderWidth = 1
|
|
|
|
|
+ layer.borderColor = Self.defaultBorderColor.cgColor
|
|
|
|
|
+ layer.shadowOpacity = 1
|
|
|
|
|
+ }
|
|
|
|
|
+ setAccessibilitySelected(isSelected)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@available(*, unavailable)
|
|
@available(*, unavailable)
|
|
|
required init?(coder: NSCoder) {
|
|
required init?(coder: NSCoder) {
|
|
|
fatalError("init(coder:) has not been implemented")
|
|
fatalError("init(coder:) has not been implemented")
|