Procházet zdrojové kódy

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 před 5 dny
rodič
revize
a31a516cfe
1 změnil soubory, kde provedl 107 přidání a 10 odebrání
  1. 107 10
      zoom_app/ViewController.swift

+ 107 - 10
zoom_app/ViewController.swift

@@ -54,10 +54,20 @@ class ViewController: NSViewController {
54 54
     private weak var meetingsNextDayButton: NSButton?
55 55
     private weak var meetingsTodayButton: NSButton?
56 56
     private weak var refreshMeetingsButton: NSButton?
57
+    private weak var homeWelcomeLabel: NSTextField?
58
+    private weak var homeTimeLabelView: NSTextField?
59
+    private weak var homeDateLabelView: NSTextField?
60
+    private weak var homeActionsRow: NSView?
61
+    private weak var homeMeetingsPanel: NSView?
62
+    private weak var homePlaceholderLabel: NSTextField?
57 63
     private weak var homeSearchField: NSTextField?
58 64
     private weak var homeSearchPill: NSView?
59 65
     private var allScheduledMeetings: [ScheduledMeeting] = []
60 66
     private var selectedMeetingsDayStart: Date = Calendar.current.startOfDay(for: Date())
67
+    private var selectedHomeSidebarItem: String = "Home"
68
+    private var homeSidebarRowViews: [String: NSView] = [:]
69
+    private var homeSidebarIconViews: [String: NSImageView] = [:]
70
+    private var homeSidebarLabels: [String: NSTextField] = [:]
61 71
     private var searchTextObserver: NSObjectProtocol?
62 72
     private var searchShortcutMonitor: Any?
63 73
     private var searchOutsideClickMonitor: Any?
@@ -160,6 +170,8 @@ class ViewController: NSViewController {
160 170
         startClock()
161 171
         startMeetingsAutoRefresh()
162 172
         triggerMeetingsRefresh(force: true)
173
+        updateHomeSidebarHighlight()
174
+        updateSelectedHomeSectionUI()
163 175
     }
164 176
 
165 177
     private func isUserLoggedIn() -> Bool {
@@ -930,7 +942,10 @@ class ViewController: NSViewController {
930 942
         let chromeHeader = NSView()
931 943
         chromeHeader.wantsLayer = true
932 944
         chromeHeader.layer?.backgroundColor = chromeUnifiedBackground.cgColor
933
-        let sidebar = makeSidebar(items: ["Home", "Meetings", "Scheduler"], selected: "Home", style: .home)
945
+        homeSidebarRowViews = [:]
946
+        homeSidebarIconViews = [:]
947
+        homeSidebarLabels = [:]
948
+        let sidebar = makeSidebar(items: ["Home", "Meetings", "Scheduler"], selected: selectedHomeSidebarItem, style: .home)
934 949
         let content = NSView()
935 950
         content.wantsLayer = true
936 951
         content.layer?.backgroundColor = NSColor.clear.cgColor
@@ -1140,6 +1155,9 @@ class ViewController: NSViewController {
1140 1155
         refreshMeetingsButton.layer?.borderColor = NSColor.white.withAlphaComponent(0.07).cgColor
1141 1156
         self.refreshMeetingsButton = refreshMeetingsButton
1142 1157
 
1158
+        let placeholder = makeLabel("Coming soon", size: 22, color: secondaryText, weight: .semibold, centered: true)
1159
+        placeholder.isHidden = true
1160
+
1143 1161
         let contentColumn = NSView()
1144 1162
         contentColumn.translatesAutoresizingMaskIntoConstraints = false
1145 1163
         content.addSubview(topBar)
@@ -1158,7 +1176,7 @@ class ViewController: NSViewController {
1158 1176
         [searchIcon, searchField, searchHintLabel].forEach {
1159 1177
             searchPill.addSubview($0)
1160 1178
         }
1161
-        [welcome, timeTitle, dateTitle, actions, panel, panelHeader, meetingsStatus, meetingsDayNav, noMeeting, meetingsScrollView, refreshMeetingsButton].forEach {
1179
+        [welcome, timeTitle, dateTitle, actions, panel, panelHeader, meetingsStatus, meetingsDayNav, noMeeting, meetingsScrollView, refreshMeetingsButton, placeholder].forEach {
1162 1180
             $0.translatesAutoresizingMaskIntoConstraints = false
1163 1181
             contentColumn.addSubview($0)
1164 1182
         }
@@ -1261,11 +1279,20 @@ class ViewController: NSViewController {
1261 1279
             refreshMeetingsButton.leadingAnchor.constraint(equalTo: panel.leadingAnchor, constant: 14),
1262 1280
             refreshMeetingsButton.trailingAnchor.constraint(equalTo: panel.trailingAnchor, constant: -14),
1263 1281
             refreshMeetingsButton.bottomAnchor.constraint(equalTo: panel.bottomAnchor, constant: -12),
1264
-            refreshMeetingsButton.heightAnchor.constraint(equalToConstant: 40)
1282
+            refreshMeetingsButton.heightAnchor.constraint(equalToConstant: 40),
1283
+
1284
+            placeholder.centerXAnchor.constraint(equalTo: contentColumn.centerXAnchor),
1285
+            placeholder.centerYAnchor.constraint(equalTo: contentColumn.centerYAnchor)
1265 1286
         ])
1266 1287
 
1267 1288
         timeLabel = timeTitle
1268 1289
         dateLabel = dateTitle
1290
+        homeWelcomeLabel = welcome
1291
+        homeTimeLabelView = timeTitle
1292
+        homeDateLabelView = dateTitle
1293
+        homeActionsRow = actions
1294
+        homeMeetingsPanel = panel
1295
+        homePlaceholderLabel = placeholder
1269 1296
         meetingsDayHeaderLabel = panelHeader
1270 1297
         meetingsListStack = meetingsStack
1271 1298
         meetingsStatusLabel = meetingsStatus
@@ -1356,16 +1383,24 @@ class ViewController: NSViewController {
1356 1383
 
1357 1384
                 let iconView = NSImageView()
1358 1385
                 iconView.translatesAutoresizingMaskIntoConstraints = false
1359
-                iconView.contentTintColor = primaryText
1386
+                iconView.contentTintColor = selectedRow ? primaryText : secondaryText
1360 1387
                 iconView.imageScaling = .scaleProportionallyUpOrDown
1361 1388
                 iconView.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 20, weight: .regular)
1362
-                iconView.image = NSImage(systemSymbolName: sidebarSymbolName(for: item), accessibilityDescription: item)
1389
+                iconView.image = NSImage(systemSymbolName: sidebarSymbolName(for: item, filled: selectedRow), accessibilityDescription: item)
1363 1390
                 iconContainer.addSubview(iconView)
1364 1391
 
1365 1392
                 let label = makeLabel(item, size: 10, color: selectedRow ? primaryText : secondaryText, weight: .regular, centered: true)
1366 1393
                 label.translatesAutoresizingMaskIntoConstraints = false
1367 1394
                 row.addSubview(label)
1368 1395
 
1396
+                let hit = NSButton(title: "", target: self, action: #selector(homeSidebarItemTapped(_:)))
1397
+                hit.identifier = NSUserInterfaceItemIdentifier(item)
1398
+                hit.isBordered = false
1399
+                hit.bezelStyle = .shadowlessSquare
1400
+                hit.focusRingType = .none
1401
+                hit.translatesAutoresizingMaskIntoConstraints = false
1402
+                row.addSubview(hit, positioned: .above, relativeTo: nil)
1403
+
1369 1404
                 NSLayoutConstraint.activate([
1370 1405
                     iconContainer.topAnchor.constraint(equalTo: row.topAnchor, constant: 9),
1371 1406
                     iconContainer.centerXAnchor.constraint(equalTo: row.centerXAnchor),
@@ -1379,9 +1414,18 @@ class ViewController: NSViewController {
1379 1414
 
1380 1415
                     label.topAnchor.constraint(equalTo: iconContainer.bottomAnchor, constant: 6),
1381 1416
                     label.centerXAnchor.constraint(equalTo: row.centerXAnchor),
1382
-                    label.bottomAnchor.constraint(equalTo: row.bottomAnchor, constant: -8)
1417
+                    label.bottomAnchor.constraint(equalTo: row.bottomAnchor, constant: -8),
1418
+
1419
+                    hit.leadingAnchor.constraint(equalTo: row.leadingAnchor),
1420
+                    hit.trailingAnchor.constraint(equalTo: row.trailingAnchor),
1421
+                    hit.topAnchor.constraint(equalTo: row.topAnchor),
1422
+                    hit.bottomAnchor.constraint(equalTo: row.bottomAnchor)
1383 1423
                 ])
1384 1424
 
1425
+                homeSidebarRowViews[item] = row
1426
+                homeSidebarIconViews[item] = iconView
1427
+                homeSidebarLabels[item] = label
1428
+
1385 1429
                 if item == "Hub" {
1386 1430
                     let badge = makeSidebarBadge(text: "1")
1387 1431
                     badge.translatesAutoresizingMaskIntoConstraints = false
@@ -1491,15 +1535,68 @@ class ViewController: NSViewController {
1491 1535
         return sidebar
1492 1536
     }
1493 1537
 
1494
-    private func sidebarSymbolName(for item: String) -> String {
1538
+    @objc private func homeSidebarItemTapped(_ sender: NSButton) {
1539
+        guard let item = sender.identifier?.rawValue else { return }
1540
+        selectedHomeSidebarItem = item
1541
+        updateHomeSidebarHighlight()
1542
+        updateSelectedHomeSectionUI()
1543
+    }
1544
+
1545
+    @MainActor
1546
+    private func updateHomeSidebarHighlight() {
1547
+        for (item, row) in homeSidebarRowViews {
1548
+            let selected = item == selectedHomeSidebarItem
1549
+            row.layer?.backgroundColor = selected ? sidebarActiveBackground.withAlphaComponent(0.95).cgColor : NSColor.clear.cgColor
1550
+            homeSidebarLabels[item]?.textColor = selected ? primaryText : secondaryText
1551
+            homeSidebarIconViews[item]?.contentTintColor = selected ? primaryText : secondaryText
1552
+            let symbolName = sidebarSymbolName(for: item, filled: selected)
1553
+            if let image = NSImage(systemSymbolName: symbolName, accessibilityDescription: item) {
1554
+                homeSidebarIconViews[item]?.image = image
1555
+            }
1556
+        }
1557
+    }
1558
+
1559
+    @MainActor
1560
+    private func updateSelectedHomeSectionUI() {
1561
+        let isHome = selectedHomeSidebarItem == "Home"
1562
+        let title = selectedHomeSidebarItem
1563
+
1564
+        homeWelcomeLabel?.stringValue = title
1565
+
1566
+        let dashboardViews: [NSView?] = [
1567
+            homeTimeLabelView,
1568
+            homeDateLabelView,
1569
+            homeActionsRow,
1570
+            homeMeetingsPanel,
1571
+            meetingsDayHeaderLabel,
1572
+            meetingsStatusLabel,
1573
+            meetingsPrevDayButton,
1574
+            meetingsTodayButton,
1575
+            meetingsNextDayButton,
1576
+            emptyMeetingLabel,
1577
+            meetingsScrollView,
1578
+            refreshMeetingsButton
1579
+        ]
1580
+        dashboardViews.forEach { $0?.isHidden = isHome == false }
1581
+
1582
+        if isHome {
1583
+            homePlaceholderLabel?.isHidden = true
1584
+        } else {
1585
+            // Keep non-Home pages empty for now.
1586
+            homePlaceholderLabel?.isHidden = true
1587
+        }
1588
+    }
1589
+
1590
+    private func sidebarSymbolName(for item: String, filled: Bool = false) -> String {
1495 1591
         switch item {
1496 1592
         case "Home":
1497
-            return "house"
1593
+            return filled ? "house.fill" : "house"
1498 1594
         case "Meetings":
1499
-            return "video"
1595
+            return filled ? "video.fill" : "video"
1500 1596
         case "Chat":
1501
-            return "message"
1597
+            return filled ? "message.fill" : "message"
1502 1598
         case "Scheduler":
1599
+            // `calendar.badge.clock.fill` is not available on macOS; keep a stable symbol.
1503 1600
             return "calendar.badge.clock"
1504 1601
         case "Hub":
1505 1602
             return "square.grid.3x3"