Kaynağa Gözat

Add sidebar navigation state

Make Home sidebar items clickable with stronger selected styling, and hide Home dashboard widgets on Meetings/Scheduler.

Made-with: Cursor
huzaifahayat12 3 ay önce
ebeveyn
işleme
a31a516cfe
1 değiştirilmiş dosya ile 107 ekleme ve 10 silme
  1. 107 10
      zoom_app/ViewController.swift

+ 107 - 10
zoom_app/ViewController.swift

@@ -54,10 +54,20 @@ class ViewController: NSViewController {
     private weak var meetingsNextDayButton: NSButton?
     private weak var meetingsTodayButton: NSButton?
     private weak var refreshMeetingsButton: NSButton?
+    private weak var homeWelcomeLabel: NSTextField?
+    private weak var homeTimeLabelView: NSTextField?
+    private weak var homeDateLabelView: NSTextField?
+    private weak var homeActionsRow: NSView?
+    private weak var homeMeetingsPanel: NSView?
+    private weak var homePlaceholderLabel: NSTextField?
     private weak var homeSearchField: NSTextField?
     private weak var homeSearchPill: NSView?
     private var allScheduledMeetings: [ScheduledMeeting] = []
     private var selectedMeetingsDayStart: Date = Calendar.current.startOfDay(for: Date())
+    private var selectedHomeSidebarItem: String = "Home"
+    private var homeSidebarRowViews: [String: NSView] = [:]
+    private var homeSidebarIconViews: [String: NSImageView] = [:]
+    private var homeSidebarLabels: [String: NSTextField] = [:]
     private var searchTextObserver: NSObjectProtocol?
     private var searchShortcutMonitor: Any?
     private var searchOutsideClickMonitor: Any?
@@ -160,6 +170,8 @@ class ViewController: NSViewController {
         startClock()
         startMeetingsAutoRefresh()
         triggerMeetingsRefresh(force: true)
+        updateHomeSidebarHighlight()
+        updateSelectedHomeSectionUI()
     }
 
     private func isUserLoggedIn() -> Bool {
@@ -930,7 +942,10 @@ class ViewController: NSViewController {
         let chromeHeader = NSView()
         chromeHeader.wantsLayer = true
         chromeHeader.layer?.backgroundColor = chromeUnifiedBackground.cgColor
-        let sidebar = makeSidebar(items: ["Home", "Meetings", "Scheduler"], selected: "Home", style: .home)
+        homeSidebarRowViews = [:]
+        homeSidebarIconViews = [:]
+        homeSidebarLabels = [:]
+        let sidebar = makeSidebar(items: ["Home", "Meetings", "Scheduler"], selected: selectedHomeSidebarItem, style: .home)
         let content = NSView()
         content.wantsLayer = true
         content.layer?.backgroundColor = NSColor.clear.cgColor
@@ -1140,6 +1155,9 @@ class ViewController: NSViewController {
         refreshMeetingsButton.layer?.borderColor = NSColor.white.withAlphaComponent(0.07).cgColor
         self.refreshMeetingsButton = refreshMeetingsButton
 
+        let placeholder = makeLabel("Coming soon", size: 22, color: secondaryText, weight: .semibold, centered: true)
+        placeholder.isHidden = true
+
         let contentColumn = NSView()
         contentColumn.translatesAutoresizingMaskIntoConstraints = false
         content.addSubview(topBar)
@@ -1158,7 +1176,7 @@ class ViewController: NSViewController {
         [searchIcon, searchField, searchHintLabel].forEach {
             searchPill.addSubview($0)
         }
-        [welcome, timeTitle, dateTitle, actions, panel, panelHeader, meetingsStatus, meetingsDayNav, noMeeting, meetingsScrollView, refreshMeetingsButton].forEach {
+        [welcome, timeTitle, dateTitle, actions, panel, panelHeader, meetingsStatus, meetingsDayNav, noMeeting, meetingsScrollView, refreshMeetingsButton, placeholder].forEach {
             $0.translatesAutoresizingMaskIntoConstraints = false
             contentColumn.addSubview($0)
         }
@@ -1261,11 +1279,20 @@ class ViewController: NSViewController {
             refreshMeetingsButton.leadingAnchor.constraint(equalTo: panel.leadingAnchor, constant: 14),
             refreshMeetingsButton.trailingAnchor.constraint(equalTo: panel.trailingAnchor, constant: -14),
             refreshMeetingsButton.bottomAnchor.constraint(equalTo: panel.bottomAnchor, constant: -12),
-            refreshMeetingsButton.heightAnchor.constraint(equalToConstant: 40)
+            refreshMeetingsButton.heightAnchor.constraint(equalToConstant: 40),
+
+            placeholder.centerXAnchor.constraint(equalTo: contentColumn.centerXAnchor),
+            placeholder.centerYAnchor.constraint(equalTo: contentColumn.centerYAnchor)
         ])
 
         timeLabel = timeTitle
         dateLabel = dateTitle
+        homeWelcomeLabel = welcome
+        homeTimeLabelView = timeTitle
+        homeDateLabelView = dateTitle
+        homeActionsRow = actions
+        homeMeetingsPanel = panel
+        homePlaceholderLabel = placeholder
         meetingsDayHeaderLabel = panelHeader
         meetingsListStack = meetingsStack
         meetingsStatusLabel = meetingsStatus
@@ -1356,16 +1383,24 @@ class ViewController: NSViewController {
 
                 let iconView = NSImageView()
                 iconView.translatesAutoresizingMaskIntoConstraints = false
-                iconView.contentTintColor = primaryText
+                iconView.contentTintColor = selectedRow ? primaryText : secondaryText
                 iconView.imageScaling = .scaleProportionallyUpOrDown
                 iconView.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 20, weight: .regular)
-                iconView.image = NSImage(systemSymbolName: sidebarSymbolName(for: item), accessibilityDescription: item)
+                iconView.image = NSImage(systemSymbolName: sidebarSymbolName(for: item, filled: selectedRow), accessibilityDescription: item)
                 iconContainer.addSubview(iconView)
 
                 let label = makeLabel(item, size: 10, color: selectedRow ? primaryText : secondaryText, weight: .regular, centered: true)
                 label.translatesAutoresizingMaskIntoConstraints = false
                 row.addSubview(label)
 
+                let hit = NSButton(title: "", target: self, action: #selector(homeSidebarItemTapped(_:)))
+                hit.identifier = NSUserInterfaceItemIdentifier(item)
+                hit.isBordered = false
+                hit.bezelStyle = .shadowlessSquare
+                hit.focusRingType = .none
+                hit.translatesAutoresizingMaskIntoConstraints = false
+                row.addSubview(hit, positioned: .above, relativeTo: nil)
+
                 NSLayoutConstraint.activate([
                     iconContainer.topAnchor.constraint(equalTo: row.topAnchor, constant: 9),
                     iconContainer.centerXAnchor.constraint(equalTo: row.centerXAnchor),
@@ -1379,9 +1414,18 @@ class ViewController: NSViewController {
 
                     label.topAnchor.constraint(equalTo: iconContainer.bottomAnchor, constant: 6),
                     label.centerXAnchor.constraint(equalTo: row.centerXAnchor),
-                    label.bottomAnchor.constraint(equalTo: row.bottomAnchor, constant: -8)
+                    label.bottomAnchor.constraint(equalTo: row.bottomAnchor, constant: -8),
+
+                    hit.leadingAnchor.constraint(equalTo: row.leadingAnchor),
+                    hit.trailingAnchor.constraint(equalTo: row.trailingAnchor),
+                    hit.topAnchor.constraint(equalTo: row.topAnchor),
+                    hit.bottomAnchor.constraint(equalTo: row.bottomAnchor)
                 ])
 
+                homeSidebarRowViews[item] = row
+                homeSidebarIconViews[item] = iconView
+                homeSidebarLabels[item] = label
+
                 if item == "Hub" {
                     let badge = makeSidebarBadge(text: "1")
                     badge.translatesAutoresizingMaskIntoConstraints = false
@@ -1491,15 +1535,68 @@ class ViewController: NSViewController {
         return sidebar
     }
 
-    private func sidebarSymbolName(for item: String) -> String {
+    @objc private func homeSidebarItemTapped(_ sender: NSButton) {
+        guard let item = sender.identifier?.rawValue else { return }
+        selectedHomeSidebarItem = item
+        updateHomeSidebarHighlight()
+        updateSelectedHomeSectionUI()
+    }
+
+    @MainActor
+    private func updateHomeSidebarHighlight() {
+        for (item, row) in homeSidebarRowViews {
+            let selected = item == selectedHomeSidebarItem
+            row.layer?.backgroundColor = selected ? sidebarActiveBackground.withAlphaComponent(0.95).cgColor : NSColor.clear.cgColor
+            homeSidebarLabels[item]?.textColor = selected ? primaryText : secondaryText
+            homeSidebarIconViews[item]?.contentTintColor = selected ? primaryText : secondaryText
+            let symbolName = sidebarSymbolName(for: item, filled: selected)
+            if let image = NSImage(systemSymbolName: symbolName, accessibilityDescription: item) {
+                homeSidebarIconViews[item]?.image = image
+            }
+        }
+    }
+
+    @MainActor
+    private func updateSelectedHomeSectionUI() {
+        let isHome = selectedHomeSidebarItem == "Home"
+        let title = selectedHomeSidebarItem
+
+        homeWelcomeLabel?.stringValue = title
+
+        let dashboardViews: [NSView?] = [
+            homeTimeLabelView,
+            homeDateLabelView,
+            homeActionsRow,
+            homeMeetingsPanel,
+            meetingsDayHeaderLabel,
+            meetingsStatusLabel,
+            meetingsPrevDayButton,
+            meetingsTodayButton,
+            meetingsNextDayButton,
+            emptyMeetingLabel,
+            meetingsScrollView,
+            refreshMeetingsButton
+        ]
+        dashboardViews.forEach { $0?.isHidden = isHome == false }
+
+        if isHome {
+            homePlaceholderLabel?.isHidden = true
+        } else {
+            // Keep non-Home pages empty for now.
+            homePlaceholderLabel?.isHidden = true
+        }
+    }
+
+    private func sidebarSymbolName(for item: String, filled: Bool = false) -> String {
         switch item {
         case "Home":
-            return "house"
+            return filled ? "house.fill" : "house"
         case "Meetings":
-            return "video"
+            return filled ? "video.fill" : "video"
         case "Chat":
-            return "message"
+            return filled ? "message.fill" : "message"
         case "Scheduler":
+            // `calendar.badge.clock.fill` is not available on macOS; keep a stable symbol.
             return "calendar.badge.clock"
         case "Hub":
             return "square.grid.3x3"