Browse Source

Preserve chat when returning to Home; add Clear chat control

Stop resetting chat history from applyHomeState() so sidebar Home and
re-selecting Home no longer wipe the thread. Add a Clear chat button
above the transcript that calls resetChatState(); disable it while a
search request is in flight to avoid races with late completions.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 3 weeks ago
parent
commit
cf8cbc4f1f
1 changed files with 30 additions and 1 deletions
  1. 30 1
      App for Indeed/Views/DashboardView.swift

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

@@ -102,6 +102,7 @@ final class DashboardView: NSView, NSTextFieldDelegate {
102 102
         WelcomeSparkleClusterView(iconWell: Theme.welcomeHeroIconWell, tint: Theme.welcomeHeroHeadingBlue)
103 103
     }()
104 104
     private let featureCardsRow = NSStackView()
105
+    private let clearChatButton = NSButton(title: "Clear chat", target: nil, action: nil)
105 106
     private let chatScrollView = NSScrollView()
106 107
     private let chatDocumentView = JobListingsDocumentView()
107 108
     private let chatStack = NSStackView()
@@ -322,6 +323,26 @@ final class DashboardView: NSView, NSTextFieldDelegate {
322 323
         mainOverlay.addArrangedSubview(featureCardsRow)
323 324
         mainOverlay.addArrangedSubview(midSpacer)
324 325
         mainOverlay.addArrangedSubview(chatTopSpacer)
326
+
327
+        let chatHeaderRow = NSStackView()
328
+        chatHeaderRow.orientation = .horizontal
329
+        chatHeaderRow.spacing = 8
330
+        chatHeaderRow.alignment = .centerY
331
+        chatHeaderRow.distribution = .fill
332
+        chatHeaderRow.translatesAutoresizingMaskIntoConstraints = false
333
+        let chatHeaderLeadingSpacer = NSView()
334
+        chatHeaderLeadingSpacer.translatesAutoresizingMaskIntoConstraints = false
335
+        chatHeaderLeadingSpacer.setContentHuggingPriority(.defaultLow, for: .horizontal)
336
+        clearChatButton.translatesAutoresizingMaskIntoConstraints = false
337
+        clearChatButton.bezelStyle = .rounded
338
+        clearChatButton.font = .systemFont(ofSize: 12, weight: .medium)
339
+        clearChatButton.target = self
340
+        clearChatButton.action = #selector(didTapClearChat)
341
+        clearChatButton.toolTip = "Remove all messages and start a new conversation"
342
+        clearChatButton.setContentHuggingPriority(.required, for: .horizontal)
343
+        chatHeaderRow.addArrangedSubview(chatHeaderLeadingSpacer)
344
+        chatHeaderRow.addArrangedSubview(clearChatButton)
345
+        mainOverlay.addArrangedSubview(chatHeaderRow)
325 346
         mainOverlay.addArrangedSubview(chatScrollView)
326 347
         mainOverlay.addArrangedSubview(chatBottomSpacer)
327 348
         mainOverlay.addArrangedSubview(searchBarShadowHost)
@@ -368,6 +389,7 @@ final class DashboardView: NSView, NSTextFieldDelegate {
368 389
 
369 390
             searchBarShadowHost.widthAnchor.constraint(equalTo: mainOverlay.widthAnchor, multiplier: 0.92),
370 391
             featureCardsRow.widthAnchor.constraint(equalTo: mainOverlay.widthAnchor, multiplier: 0.92),
392
+            chatHeaderRow.widthAnchor.constraint(equalTo: mainOverlay.widthAnchor, multiplier: 0.92),
371 393
             chatScrollView.widthAnchor.constraint(equalTo: mainOverlay.widthAnchor, multiplier: 0.92),
372 394
 
373 395
             welcomeHeroHost.leadingAnchor.constraint(equalTo: mainOverlay.leadingAnchor),
@@ -1562,9 +1584,14 @@ final class DashboardView: NSView, NSTextFieldDelegate {
1562 1584
         }
1563 1585
     }
1564 1586
 
1565
-    /// Restores the main job-search experience: cleared query and a fresh chat history.
1587
+    /// Restores the main job-search field when returning to Home; chat history is kept until the user chooses **Clear chat**.
1566 1588
     private func applyHomeState() {
1567 1589
         jobKeywordsField.stringValue = ""
1590
+        window?.makeFirstResponder(nil)
1591
+    }
1592
+
1593
+    @objc private func didTapClearChat() {
1594
+        guard !isAwaitingResponse else { return }
1568 1595
         resetChatState()
1569 1596
         window?.makeFirstResponder(nil)
1570 1597
     }
@@ -2092,6 +2119,8 @@ final class DashboardView: NSView, NSTextFieldDelegate {
2092 2119
         jobKeywordsField.isEnabled = enabled
2093 2120
         findJobsButton.isEnabled = enabled
2094 2121
         findJobsButton.alphaValue = enabled ? 1 : 0.65
2122
+        clearChatButton.isEnabled = enabled
2123
+        clearChatButton.alphaValue = enabled ? 1 : 0.65
2095 2124
         trailingLoadMoreJobsButton?.isEnabled = enabled
2096 2125
         trailingLoadMoreJobsButton?.alphaValue = enabled ? 1 : 0.65
2097 2126
     }