소스 검색

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 5 일 전
부모
커밋
ad585b8052
1개의 변경된 파일68개의 추가작업 그리고 46개의 파일을 삭제
  1. 68 46
      zoom_app/ViewController.swift

+ 68 - 46
zoom_app/ViewController.swift

@@ -26,8 +26,6 @@ class ViewController: NSViewController {
26 26
     private let chromeUnifiedBackground = NSColor(calibratedRed: 22 / 255, green: 23 / 255, blue: 26 / 255, alpha: 1)
27 27
     private let searchPillBackground = NSColor.white.withAlphaComponent(0.06)
28 28
     private let meetingCardBackground = NSColor(calibratedRed: 30 / 255, green: 34 / 255, blue: 42 / 255, alpha: 1)
29
-    private let titleBarControlBackground = NSColor.white.withAlphaComponent(0.04)
30
-    private let titleBarLightControlBackground = NSColor.white.withAlphaComponent(0.02)
31 29
     private let appShellCornerRadius: CGFloat = 20
32 30
     private let homeChromeHeaderHeight: CGFloat = 56
33 31
     private let nativeTrafficLightsLeading: CGFloat = 14
@@ -747,22 +745,35 @@ class ViewController: NSViewController {
747 745
         searchPill.layer?.cornerRadius = 10
748 746
         let search = makeLabel("Search (\u{2318}E)", size: 13, color: mutedText, weight: .regular, centered: true)
749 747
         
748
+        let backForwardCluster = NSStackView()
749
+        backForwardCluster.orientation = .horizontal
750
+        backForwardCluster.spacing = 4
751
+        backForwardCluster.alignment = .centerY
752
+        let backButton = makeNavGlyphButton(symbol: "chevron.left", action: #selector(topBarPlaceholderTapped), dimension: 14, pointSize: 7, toolTip: "Back")
753
+        let forwardButton = makeNavGlyphButton(symbol: "chevron.right", action: #selector(topBarPlaceholderTapped), dimension: 14, pointSize: 7, toolTip: "Forward")
754
+        [backButton, forwardButton].forEach { backForwardCluster.addArrangedSubview($0) }
755
+
750 756
         let leftTopBarCluster = NSStackView()
751 757
         leftTopBarCluster.orientation = .horizontal
752
-        leftTopBarCluster.spacing = 10
758
+        leftTopBarCluster.spacing = 0
753 759
         leftTopBarCluster.alignment = .centerY
754
-        let backButton = makeTopBarGlyphButton(symbol: "chevron.left", action: #selector(topBarPlaceholderTapped))
755
-        let forwardButton = makeTopBarGlyphButton(symbol: "chevron.right", action: #selector(topBarPlaceholderTapped))
756
-        let historyButton = makeTopBarGlyphButton(symbol: "clock.arrow.circlepath", action: #selector(topBarPlaceholderTapped))
757
-        [backButton, forwardButton, historyButton].forEach { leftTopBarCluster.addArrangedSubview($0) }
758
-        
760
+        let historyButton = makeNavGlyphButton(symbol: "clock.arrow.circlepath", action: #selector(topBarPlaceholderTapped), toolTip: "History")
761
+        let navHistoryGap = NSView()
762
+        navHistoryGap.translatesAutoresizingMaskIntoConstraints = false
763
+        navHistoryGap.widthAnchor.constraint(equalToConstant: 12).isActive = true
764
+        [backForwardCluster, navHistoryGap, historyButton].forEach { leftTopBarCluster.addArrangedSubview($0) }
765
+
766
+        let searchRow = NSStackView()
767
+        searchRow.orientation = .horizontal
768
+        searchRow.spacing = 14
769
+        searchRow.alignment = .centerY
770
+        [leftTopBarCluster, searchPill].forEach { searchRow.addArrangedSubview($0) }
771
+
759 772
         let rightTopBarCluster = NSStackView()
760 773
         rightTopBarCluster.orientation = .horizontal
761
-        rightTopBarCluster.spacing = 8
774
+        rightTopBarCluster.spacing = 10
762 775
         rightTopBarCluster.alignment = .centerY
763
-        let plusButton = makeTopBarGlyphButton(symbol: "plus", action: #selector(topBarPlaceholderTapped))
764
-        let notificationButton = makeTopBarGlyphButton(symbol: "bell", action: #selector(topBarPlaceholderTapped))
765
-        let appsButton = makeTopBarIconButton(symbol: "square.grid.2x2", action: #selector(topBarPlaceholderTapped))
776
+        let upgradeToProButton = makeUpgradeToProButton(action: #selector(topBarPlaceholderTapped))
766 777
 
767 778
         let profileChip = NSButton(title: String((profile?.name ?? "H").prefix(1)).uppercased(), target: self, action: #selector(logoutTapped))
768 779
         profileChip.isBordered = false
@@ -772,7 +783,7 @@ class ViewController: NSViewController {
772 783
         profileChip.contentTintColor = primaryText
773 784
         profileChip.font = .systemFont(ofSize: 14, weight: .bold)
774 785
         profileChip.toolTip = "Profile (click to logout)"
775
-        [plusButton, notificationButton, appsButton, profileChip].forEach { rightTopBarCluster.addArrangedSubview($0) }
786
+        [upgradeToProButton, profileChip].forEach { rightTopBarCluster.addArrangedSubview($0) }
776 787
 
777 788
         let welcome = makeLabel("Home", size: 15, color: secondaryText, weight: .medium, centered: false)
778 789
         let timeTitle = makeLabel("--:--", size: 56, color: primaryText, weight: .bold, centered: true)
@@ -829,14 +840,13 @@ class ViewController: NSViewController {
829 840
         content.addSubview(topBarDivider)
830 841
         content.addSubview(contentColumn)
831 842
 
832
-        [brandStack, leftTopBarCluster, rightTopBarCluster, searchPill, search].forEach {
843
+        [brandStack, searchRow, backForwardCluster, leftTopBarCluster, rightTopBarCluster, searchPill, search].forEach {
833 844
             $0.translatesAutoresizingMaskIntoConstraints = false
834 845
         }
835 846
         [brandStack].forEach {
836 847
             shell.addSubview($0)
837 848
         }
838
-        [leftTopBarCluster, rightTopBarCluster, searchPill, search].forEach {
839
-            $0.translatesAutoresizingMaskIntoConstraints = false
849
+        [searchRow, rightTopBarCluster, search].forEach {
840 850
             topBar.addSubview($0)
841 851
         }
842 852
         [welcome, timeTitle, dateTitle, actions, panel, panelHeader, meetingsStatus, noMeeting, meetingsScrollView, openRecordings].forEach {
@@ -850,9 +860,12 @@ class ViewController: NSViewController {
850 860
         meetingsScrollView.documentView = meetingsDocument
851 861
         meetingsDocument.addSubview(meetingsStack)
852 862
 
863
+        let searchRowCenterX = searchRow.centerXAnchor.constraint(equalTo: topBar.centerXAnchor)
864
+        searchRowCenterX.priority = .defaultHigh
865
+
853 866
         NSLayoutConstraint.activate([
854 867
             brandStack.leadingAnchor.constraint(equalTo: shell.leadingAnchor, constant: brandLeadingInset),
855
-            brandStack.trailingAnchor.constraint(lessThanOrEqualTo: leftTopBarCluster.leadingAnchor, constant: -12),
868
+            brandStack.trailingAnchor.constraint(lessThanOrEqualTo: searchRow.leadingAnchor, constant: -12),
856 869
             brandStack.centerYAnchor.constraint(equalTo: chromeHeader.centerYAnchor, constant: -1),
857 870
 
858 871
             topBar.topAnchor.constraint(equalTo: content.topAnchor),
@@ -869,18 +882,17 @@ class ViewController: NSViewController {
869 882
             contentColumn.leadingAnchor.constraint(equalTo: content.leadingAnchor, constant: 8),
870 883
             contentColumn.trailingAnchor.constraint(equalTo: content.trailingAnchor, constant: -8),
871 884
 
872
-            leftTopBarCluster.leadingAnchor.constraint(greaterThanOrEqualTo: topBar.leadingAnchor, constant: 40),
873
-            leftTopBarCluster.leadingAnchor.constraint(greaterThanOrEqualTo: brandStack.trailingAnchor, constant: 16),
874
-            leftTopBarCluster.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
885
+            searchRowCenterX,
886
+            searchRow.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
887
+            searchRow.leadingAnchor.constraint(greaterThanOrEqualTo: topBar.leadingAnchor, constant: 40),
888
+            searchRow.leadingAnchor.constraint(greaterThanOrEqualTo: brandStack.trailingAnchor, constant: 16),
889
+            searchRow.trailingAnchor.constraint(lessThanOrEqualTo: rightTopBarCluster.leadingAnchor, constant: -12),
890
+
875 891
             rightTopBarCluster.trailingAnchor.constraint(equalTo: topBar.trailingAnchor, constant: -12),
876 892
             rightTopBarCluster.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
877 893
 
878
-            searchPill.centerXAnchor.constraint(equalTo: topBar.centerXAnchor),
879
-            searchPill.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
880 894
             searchPill.heightAnchor.constraint(equalToConstant: 32),
881 895
             searchPill.widthAnchor.constraint(equalToConstant: 320),
882
-            searchPill.leadingAnchor.constraint(greaterThanOrEqualTo: leftTopBarCluster.trailingAnchor, constant: 12),
883
-            searchPill.trailingAnchor.constraint(lessThanOrEqualTo: rightTopBarCluster.leadingAnchor, constant: -12),
884 896
             search.leadingAnchor.constraint(equalTo: searchPill.leadingAnchor, constant: 12),
885 897
             search.trailingAnchor.constraint(equalTo: searchPill.trailingAnchor, constant: -12),
886 898
             search.centerYAnchor.constraint(equalTo: searchPill.centerYAnchor),
@@ -1061,37 +1073,47 @@ class ViewController: NSViewController {
1061 1073
         }
1062 1074
     }
1063 1075
 
1064
-    private func makeTopBarIconButton(symbol: String, action: Selector?) -> NSButton {
1065
-        let button = NSButton(title: "", target: action == nil ? nil : self, action: action)
1076
+    private func makeUpgradeToProButton(action: Selector?) -> NSButton {
1077
+        let title = "Upgrade to Pro"
1078
+        let button = NSButton(title: title, target: action == nil ? nil : self, action: action)
1066 1079
         button.isBordered = false
1080
+        button.focusRingType = .none
1067 1081
         button.wantsLayer = true
1068
-        button.layer?.backgroundColor = titleBarControlBackground.cgColor
1069
-        button.layer?.cornerRadius = 10
1070
-        button.layer?.borderWidth = 1
1071
-        button.layer?.borderColor = NSColor.white.withAlphaComponent(0.05).cgColor
1072
-        button.contentTintColor = secondaryText
1073
-        button.image = NSImage(systemSymbolName: symbol, accessibilityDescription: symbol)
1074
-        button.imageScaling = .scaleProportionallyUpOrDown
1082
+        button.layer?.backgroundColor = accentBlue.cgColor
1083
+        button.layer?.cornerRadius = 17
1084
+        let font = NSFont.systemFont(ofSize: 13, weight: .semibold)
1085
+        button.attributedTitle = NSAttributedString(string: title, attributes: [
1086
+            .foregroundColor: NSColor.white,
1087
+            .font: font
1088
+        ])
1089
+        button.toolTip = title
1075 1090
         button.translatesAutoresizingMaskIntoConstraints = false
1076
-        button.widthAnchor.constraint(equalToConstant: 30).isActive = true
1077
-        button.heightAnchor.constraint(equalToConstant: 30).isActive = true
1091
+        button.heightAnchor.constraint(equalToConstant: 34).isActive = true
1092
+        button.widthAnchor.constraint(greaterThanOrEqualToConstant: 152).isActive = true
1078 1093
         return button
1079 1094
     }
1080
-    
1081
-    private func makeTopBarGlyphButton(symbol: String, action: Selector?) -> NSButton {
1095
+
1096
+    /// Back / forward / history: icon-only, no background or border. Back/forward use smaller `dimension` / `pointSize` than history.
1097
+    private func makeNavGlyphButton(symbol: String, action: Selector?, dimension: CGFloat = 18, pointSize: CGFloat = 9, toolTip: String? = nil) -> NSButton {
1082 1098
         let button = NSButton(title: "", target: action == nil ? nil : self, action: action)
1083 1099
         button.isBordered = false
1084
-        button.wantsLayer = true
1085
-        button.layer?.backgroundColor = titleBarLightControlBackground.cgColor
1086
-        button.layer?.cornerRadius = 9
1087
-        button.layer?.borderWidth = 1
1088
-        button.layer?.borderColor = NSColor.white.withAlphaComponent(0.03).cgColor
1089
-        button.contentTintColor = secondaryText
1090
-        button.image = NSImage(systemSymbolName: symbol, accessibilityDescription: symbol)
1100
+        button.bezelStyle = .shadowlessSquare
1101
+        button.focusRingType = .none
1102
+        button.contentTintColor = NSColor(calibratedWhite: 0.84, alpha: 1)
1103
+        if let toolTip {
1104
+            button.toolTip = toolTip
1105
+        }
1106
+        let symbolConfig = NSImage.SymbolConfiguration(pointSize: pointSize, weight: .medium)
1107
+        if let base = NSImage(systemSymbolName: symbol, accessibilityDescription: symbol),
1108
+           let image = base.withSymbolConfiguration(symbolConfig) {
1109
+            image.isTemplate = true
1110
+            button.image = image
1111
+        }
1091 1112
         button.imageScaling = .scaleProportionallyUpOrDown
1113
+        button.imagePosition = .imageOnly
1092 1114
         button.translatesAutoresizingMaskIntoConstraints = false
1093
-        button.widthAnchor.constraint(equalToConstant: 26).isActive = true
1094
-        button.heightAnchor.constraint(equalToConstant: 26).isActive = true
1115
+        button.widthAnchor.constraint(equalToConstant: dimension).isActive = true
1116
+        button.heightAnchor.constraint(equalToConstant: dimension).isActive = true
1095 1117
         return button
1096 1118
     }
1097 1119