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

Implement sidebar Home navigation and reset behavior

Show the job search dashboard only when Home is selected; other sidebar
items show a placeholder panel. Selecting Home clears the search field
and listings until the user searches again, scrolls results to the top,
and re-tapping Home while already selected repeats that reset.

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

+ 80 - 1
App for Indeed/Views/DashboardView.swift

@@ -53,6 +53,10 @@ final class DashboardView: NSView, NSTextFieldDelegate {
53 53
     /// Flipped so short result lists stay visually under the search bar instead of leaving a gap above the cards.
54 54
     private let jobListingsContainer = JobListingsDocumentView()
55 55
     private let jobListingsStack = NSStackView()
56
+    /// Shown when a sidebar item other than Home is selected.
57
+    private let nonHomeHost = NSView()
58
+    private let nonHomeTitleLabel = NSTextField(labelWithString: "")
59
+    private let nonHomeSubtitleLabel = NSTextField(wrappingLabelWithString: "")
56 60
 
57 61
     private var currentSidebarItems: [SidebarItem] = []
58 62
     private var selectedSidebarIndex: Int = 0
@@ -87,6 +91,7 @@ final class DashboardView: NSView, NSTextFieldDelegate {
87 91
         configureSidebar()
88 92
         catalogJobListings = data.jobListings
89 93
         configureJobListings([], noResultsForQuery: nil)
94
+        updateMainContentVisibility()
90 95
     }
91 96
 
92 97
     private func setupLayout() {
@@ -126,6 +131,8 @@ final class DashboardView: NSView, NSTextFieldDelegate {
126 131
         mainHost.setContentHuggingPriority(.defaultLow, for: .horizontal)
127 132
 
128 133
         mainHost.addSubview(mainOverlay)
134
+        configureNonHomePlaceholder()
135
+        mainHost.addSubview(nonHomeHost)
129 136
 
130 137
         mainOverlay.orientation = .vertical
131 138
         mainOverlay.spacing = 0
@@ -219,6 +226,11 @@ final class DashboardView: NSView, NSTextFieldDelegate {
219 226
             mainOverlay.topAnchor.constraint(equalTo: mainHost.topAnchor),
220 227
             mainOverlay.bottomAnchor.constraint(equalTo: mainHost.bottomAnchor, constant: -24),
221 228
 
229
+            nonHomeHost.leadingAnchor.constraint(equalTo: mainHost.leadingAnchor),
230
+            nonHomeHost.trailingAnchor.constraint(equalTo: mainHost.trailingAnchor),
231
+            nonHomeHost.topAnchor.constraint(equalTo: mainHost.topAnchor),
232
+            nonHomeHost.bottomAnchor.constraint(equalTo: mainHost.bottomAnchor, constant: -24),
233
+
222 234
             searchBarShadowHost.widthAnchor.constraint(equalTo: mainOverlay.widthAnchor, multiplier: 0.92),
223 235
             jobListingsScrollView.widthAnchor.constraint(equalTo: mainOverlay.widthAnchor, multiplier: 0.92),
224 236
 
@@ -485,6 +497,62 @@ final class DashboardView: NSView, NSTextFieldDelegate {
485 497
         )
486 498
     }
487 499
 
500
+    private func configureNonHomePlaceholder() {
501
+        nonHomeHost.translatesAutoresizingMaskIntoConstraints = false
502
+        nonHomeHost.wantsLayer = true
503
+        nonHomeHost.layer?.backgroundColor = Theme.mainHostBackground.cgColor
504
+        nonHomeHost.isHidden = true
505
+
506
+        nonHomeTitleLabel.font = .systemFont(ofSize: 22, weight: .bold)
507
+        nonHomeTitleLabel.textColor = Theme.primaryText
508
+        nonHomeTitleLabel.alignment = .center
509
+        nonHomeTitleLabel.maximumNumberOfLines = 1
510
+
511
+        nonHomeSubtitleLabel.font = .systemFont(ofSize: 14, weight: .regular)
512
+        nonHomeSubtitleLabel.textColor = Theme.secondaryText
513
+        nonHomeSubtitleLabel.alignment = .center
514
+        nonHomeSubtitleLabel.maximumNumberOfLines = 0
515
+        nonHomeSubtitleLabel.stringValue = "This area is not available in the preview build. Use Home to search jobs."
516
+
517
+        let stack = NSStackView(views: [nonHomeTitleLabel, nonHomeSubtitleLabel])
518
+        stack.orientation = .vertical
519
+        stack.spacing = 10
520
+        stack.alignment = .centerX
521
+        stack.translatesAutoresizingMaskIntoConstraints = false
522
+        nonHomeHost.addSubview(stack)
523
+        NSLayoutConstraint.activate([
524
+            stack.centerXAnchor.constraint(equalTo: nonHomeHost.centerXAnchor),
525
+            stack.centerYAnchor.constraint(equalTo: nonHomeHost.centerYAnchor),
526
+            stack.leadingAnchor.constraint(greaterThanOrEqualTo: nonHomeHost.leadingAnchor, constant: 32),
527
+            stack.trailingAnchor.constraint(lessThanOrEqualTo: nonHomeHost.trailingAnchor, constant: -32),
528
+            nonHomeSubtitleLabel.widthAnchor.constraint(lessThanOrEqualToConstant: 420)
529
+        ])
530
+    }
531
+
532
+    private func isHomeSidebarIndex(_ index: Int) -> Bool {
533
+        guard index >= 0, index < currentSidebarItems.count else { return false }
534
+        return currentSidebarItems[index].title == "Home"
535
+    }
536
+
537
+    private func updateMainContentVisibility() {
538
+        let home = isHomeSidebarIndex(selectedSidebarIndex)
539
+        mainOverlay.isHidden = !home
540
+        nonHomeHost.isHidden = home
541
+        if !home, selectedSidebarIndex < currentSidebarItems.count {
542
+            nonHomeTitleLabel.stringValue = currentSidebarItems[selectedSidebarIndex].title
543
+        }
544
+    }
545
+
546
+    /// Restores the main job-search experience: cleared query and no listings until the user searches again.
547
+    private func applyHomeState() {
548
+        jobKeywordsField.stringValue = ""
549
+        configureJobListings([], noResultsForQuery: nil)
550
+        window?.makeFirstResponder(nil)
551
+        if let doc = jobListingsScrollView.documentView {
552
+            doc.scroll(NSPoint(x: 0, y: 0))
553
+        }
554
+    }
555
+
488 556
     private func updateSearchBarShadowPath() {
489 557
         guard searchBarShadowHost.bounds.width > 0, searchBarShadowHost.bounds.height > 0 else { return }
490 558
         let r = searchBarShadowHost.bounds
@@ -726,9 +794,20 @@ final class DashboardView: NSView, NSTextFieldDelegate {
726 794
     }
727 795
 
728 796
     private func selectSidebarItem(at index: Int) {
729
-        guard index >= 0, index < currentSidebarItems.count, index != selectedSidebarIndex else { return }
797
+        guard index >= 0, index < currentSidebarItems.count else { return }
798
+        let selectingHome = isHomeSidebarIndex(index)
799
+        if index == selectedSidebarIndex {
800
+            if selectingHome {
801
+                applyHomeState()
802
+            }
803
+            return
804
+        }
730 805
         selectedSidebarIndex = index
731 806
         configureSidebar()
807
+        updateMainContentVisibility()
808
+        if selectingHome {
809
+            applyHomeState()
810
+        }
732 811
     }
733 812
 
734 813
 }