Răsfoiți Sursa

Refine home top bar: nav cluster, search spacing, Upgrade to Pro

Group back, forward, and history with the search field and center the row;
keep the trailing actions pinned right. Replace the plus, bell, and grid
controls with a pill-shaped Upgrade to Pro button next to the profile chip.

Tune nav control sizes (smaller chevrons, history spacing, gap before search),
use transparent-style glyph buttons with tooltips on Back, Forward, and
History, and remove unused top-bar glyph helpers.

Made-with: Cursor
huzaifahayat12 3 luni în urmă
părinte
comite
ad585b8052
1 a modificat fișierele cu 68 adăugiri și 46 ștergeri
  1. 68 46
      zoom_app/ViewController.swift

+ 68 - 46
zoom_app/ViewController.swift

@@ -26,8 +26,6 @@ class ViewController: NSViewController {
     private let chromeUnifiedBackground = NSColor(calibratedRed: 22 / 255, green: 23 / 255, blue: 26 / 255, alpha: 1)
     private let searchPillBackground = NSColor.white.withAlphaComponent(0.06)
     private let meetingCardBackground = NSColor(calibratedRed: 30 / 255, green: 34 / 255, blue: 42 / 255, alpha: 1)
-    private let titleBarControlBackground = NSColor.white.withAlphaComponent(0.04)
-    private let titleBarLightControlBackground = NSColor.white.withAlphaComponent(0.02)
     private let appShellCornerRadius: CGFloat = 20
     private let homeChromeHeaderHeight: CGFloat = 56
     private let nativeTrafficLightsLeading: CGFloat = 14
@@ -747,22 +745,35 @@ class ViewController: NSViewController {
         searchPill.layer?.cornerRadius = 10
         let search = makeLabel("Search (\u{2318}E)", size: 13, color: mutedText, weight: .regular, centered: true)
         
+        let backForwardCluster = NSStackView()
+        backForwardCluster.orientation = .horizontal
+        backForwardCluster.spacing = 4
+        backForwardCluster.alignment = .centerY
+        let backButton = makeNavGlyphButton(symbol: "chevron.left", action: #selector(topBarPlaceholderTapped), dimension: 14, pointSize: 7, toolTip: "Back")
+        let forwardButton = makeNavGlyphButton(symbol: "chevron.right", action: #selector(topBarPlaceholderTapped), dimension: 14, pointSize: 7, toolTip: "Forward")
+        [backButton, forwardButton].forEach { backForwardCluster.addArrangedSubview($0) }
+
         let leftTopBarCluster = NSStackView()
         leftTopBarCluster.orientation = .horizontal
-        leftTopBarCluster.spacing = 10
+        leftTopBarCluster.spacing = 0
         leftTopBarCluster.alignment = .centerY
-        let backButton = makeTopBarGlyphButton(symbol: "chevron.left", action: #selector(topBarPlaceholderTapped))
-        let forwardButton = makeTopBarGlyphButton(symbol: "chevron.right", action: #selector(topBarPlaceholderTapped))
-        let historyButton = makeTopBarGlyphButton(symbol: "clock.arrow.circlepath", action: #selector(topBarPlaceholderTapped))
-        [backButton, forwardButton, historyButton].forEach { leftTopBarCluster.addArrangedSubview($0) }
-        
+        let historyButton = makeNavGlyphButton(symbol: "clock.arrow.circlepath", action: #selector(topBarPlaceholderTapped), toolTip: "History")
+        let navHistoryGap = NSView()
+        navHistoryGap.translatesAutoresizingMaskIntoConstraints = false
+        navHistoryGap.widthAnchor.constraint(equalToConstant: 12).isActive = true
+        [backForwardCluster, navHistoryGap, historyButton].forEach { leftTopBarCluster.addArrangedSubview($0) }
+
+        let searchRow = NSStackView()
+        searchRow.orientation = .horizontal
+        searchRow.spacing = 14
+        searchRow.alignment = .centerY
+        [leftTopBarCluster, searchPill].forEach { searchRow.addArrangedSubview($0) }
+
         let rightTopBarCluster = NSStackView()
         rightTopBarCluster.orientation = .horizontal
-        rightTopBarCluster.spacing = 8
+        rightTopBarCluster.spacing = 10
         rightTopBarCluster.alignment = .centerY
-        let plusButton = makeTopBarGlyphButton(symbol: "plus", action: #selector(topBarPlaceholderTapped))
-        let notificationButton = makeTopBarGlyphButton(symbol: "bell", action: #selector(topBarPlaceholderTapped))
-        let appsButton = makeTopBarIconButton(symbol: "square.grid.2x2", action: #selector(topBarPlaceholderTapped))
+        let upgradeToProButton = makeUpgradeToProButton(action: #selector(topBarPlaceholderTapped))
 
         let profileChip = NSButton(title: String((profile?.name ?? "H").prefix(1)).uppercased(), target: self, action: #selector(logoutTapped))
         profileChip.isBordered = false
@@ -772,7 +783,7 @@ class ViewController: NSViewController {
         profileChip.contentTintColor = primaryText
         profileChip.font = .systemFont(ofSize: 14, weight: .bold)
         profileChip.toolTip = "Profile (click to logout)"
-        [plusButton, notificationButton, appsButton, profileChip].forEach { rightTopBarCluster.addArrangedSubview($0) }
+        [upgradeToProButton, profileChip].forEach { rightTopBarCluster.addArrangedSubview($0) }
 
         let welcome = makeLabel("Home", size: 15, color: secondaryText, weight: .medium, centered: false)
         let timeTitle = makeLabel("--:--", size: 56, color: primaryText, weight: .bold, centered: true)
@@ -829,14 +840,13 @@ class ViewController: NSViewController {
         content.addSubview(topBarDivider)
         content.addSubview(contentColumn)
 
-        [brandStack, leftTopBarCluster, rightTopBarCluster, searchPill, search].forEach {
+        [brandStack, searchRow, backForwardCluster, leftTopBarCluster, rightTopBarCluster, searchPill, search].forEach {
             $0.translatesAutoresizingMaskIntoConstraints = false
         }
         [brandStack].forEach {
             shell.addSubview($0)
         }
-        [leftTopBarCluster, rightTopBarCluster, searchPill, search].forEach {
-            $0.translatesAutoresizingMaskIntoConstraints = false
+        [searchRow, rightTopBarCluster, search].forEach {
             topBar.addSubview($0)
         }
         [welcome, timeTitle, dateTitle, actions, panel, panelHeader, meetingsStatus, noMeeting, meetingsScrollView, openRecordings].forEach {
@@ -850,9 +860,12 @@ class ViewController: NSViewController {
         meetingsScrollView.documentView = meetingsDocument
         meetingsDocument.addSubview(meetingsStack)
 
+        let searchRowCenterX = searchRow.centerXAnchor.constraint(equalTo: topBar.centerXAnchor)
+        searchRowCenterX.priority = .defaultHigh
+
         NSLayoutConstraint.activate([
             brandStack.leadingAnchor.constraint(equalTo: shell.leadingAnchor, constant: brandLeadingInset),
-            brandStack.trailingAnchor.constraint(lessThanOrEqualTo: leftTopBarCluster.leadingAnchor, constant: -12),
+            brandStack.trailingAnchor.constraint(lessThanOrEqualTo: searchRow.leadingAnchor, constant: -12),
             brandStack.centerYAnchor.constraint(equalTo: chromeHeader.centerYAnchor, constant: -1),
 
             topBar.topAnchor.constraint(equalTo: content.topAnchor),
@@ -869,18 +882,17 @@ class ViewController: NSViewController {
             contentColumn.leadingAnchor.constraint(equalTo: content.leadingAnchor, constant: 8),
             contentColumn.trailingAnchor.constraint(equalTo: content.trailingAnchor, constant: -8),
 
-            leftTopBarCluster.leadingAnchor.constraint(greaterThanOrEqualTo: topBar.leadingAnchor, constant: 40),
-            leftTopBarCluster.leadingAnchor.constraint(greaterThanOrEqualTo: brandStack.trailingAnchor, constant: 16),
-            leftTopBarCluster.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
+            searchRowCenterX,
+            searchRow.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
+            searchRow.leadingAnchor.constraint(greaterThanOrEqualTo: topBar.leadingAnchor, constant: 40),
+            searchRow.leadingAnchor.constraint(greaterThanOrEqualTo: brandStack.trailingAnchor, constant: 16),
+            searchRow.trailingAnchor.constraint(lessThanOrEqualTo: rightTopBarCluster.leadingAnchor, constant: -12),
+
             rightTopBarCluster.trailingAnchor.constraint(equalTo: topBar.trailingAnchor, constant: -12),
             rightTopBarCluster.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
 
-            searchPill.centerXAnchor.constraint(equalTo: topBar.centerXAnchor),
-            searchPill.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
             searchPill.heightAnchor.constraint(equalToConstant: 32),
             searchPill.widthAnchor.constraint(equalToConstant: 320),
-            searchPill.leadingAnchor.constraint(greaterThanOrEqualTo: leftTopBarCluster.trailingAnchor, constant: 12),
-            searchPill.trailingAnchor.constraint(lessThanOrEqualTo: rightTopBarCluster.leadingAnchor, constant: -12),
             search.leadingAnchor.constraint(equalTo: searchPill.leadingAnchor, constant: 12),
             search.trailingAnchor.constraint(equalTo: searchPill.trailingAnchor, constant: -12),
             search.centerYAnchor.constraint(equalTo: searchPill.centerYAnchor),
@@ -1061,37 +1073,47 @@ class ViewController: NSViewController {
         }
     }
 
-    private func makeTopBarIconButton(symbol: String, action: Selector?) -> NSButton {
-        let button = NSButton(title: "", target: action == nil ? nil : self, action: action)
+    private func makeUpgradeToProButton(action: Selector?) -> NSButton {
+        let title = "Upgrade to Pro"
+        let button = NSButton(title: title, target: action == nil ? nil : self, action: action)
         button.isBordered = false
+        button.focusRingType = .none
         button.wantsLayer = true
-        button.layer?.backgroundColor = titleBarControlBackground.cgColor
-        button.layer?.cornerRadius = 10
-        button.layer?.borderWidth = 1
-        button.layer?.borderColor = NSColor.white.withAlphaComponent(0.05).cgColor
-        button.contentTintColor = secondaryText
-        button.image = NSImage(systemSymbolName: symbol, accessibilityDescription: symbol)
-        button.imageScaling = .scaleProportionallyUpOrDown
+        button.layer?.backgroundColor = accentBlue.cgColor
+        button.layer?.cornerRadius = 17
+        let font = NSFont.systemFont(ofSize: 13, weight: .semibold)
+        button.attributedTitle = NSAttributedString(string: title, attributes: [
+            .foregroundColor: NSColor.white,
+            .font: font
+        ])
+        button.toolTip = title
         button.translatesAutoresizingMaskIntoConstraints = false
-        button.widthAnchor.constraint(equalToConstant: 30).isActive = true
-        button.heightAnchor.constraint(equalToConstant: 30).isActive = true
+        button.heightAnchor.constraint(equalToConstant: 34).isActive = true
+        button.widthAnchor.constraint(greaterThanOrEqualToConstant: 152).isActive = true
         return button
     }
-    
-    private func makeTopBarGlyphButton(symbol: String, action: Selector?) -> NSButton {
+
+    /// Back / forward / history: icon-only, no background or border. Back/forward use smaller `dimension` / `pointSize` than history.
+    private func makeNavGlyphButton(symbol: String, action: Selector?, dimension: CGFloat = 18, pointSize: CGFloat = 9, toolTip: String? = nil) -> NSButton {
         let button = NSButton(title: "", target: action == nil ? nil : self, action: action)
         button.isBordered = false
-        button.wantsLayer = true
-        button.layer?.backgroundColor = titleBarLightControlBackground.cgColor
-        button.layer?.cornerRadius = 9
-        button.layer?.borderWidth = 1
-        button.layer?.borderColor = NSColor.white.withAlphaComponent(0.03).cgColor
-        button.contentTintColor = secondaryText
-        button.image = NSImage(systemSymbolName: symbol, accessibilityDescription: symbol)
+        button.bezelStyle = .shadowlessSquare
+        button.focusRingType = .none
+        button.contentTintColor = NSColor(calibratedWhite: 0.84, alpha: 1)
+        if let toolTip {
+            button.toolTip = toolTip
+        }
+        let symbolConfig = NSImage.SymbolConfiguration(pointSize: pointSize, weight: .medium)
+        if let base = NSImage(systemSymbolName: symbol, accessibilityDescription: symbol),
+           let image = base.withSymbolConfiguration(symbolConfig) {
+            image.isTemplate = true
+            button.image = image
+        }
         button.imageScaling = .scaleProportionallyUpOrDown
+        button.imagePosition = .imageOnly
         button.translatesAutoresizingMaskIntoConstraints = false
-        button.widthAnchor.constraint(equalToConstant: 26).isActive = true
-        button.heightAnchor.constraint(equalToConstant: 26).isActive = true
+        button.widthAnchor.constraint(equalToConstant: dimension).isActive = true
+        button.heightAnchor.constraint(equalToConstant: dimension).isActive = true
         return button
     }