Ver Fonte

Integrate the home top strip into the titlebar and remove duplicate traffic lights.

This unifies the left chrome and right top controls into a single titlebar-aligned header while preserving existing actions and visual theme.

Made-with: Cursor
huzaifahayat12 há 3 meses atrás
pai
commit
fafaf19cf8
1 ficheiros alterados com 101 adições e 54 exclusões
  1. 101 54
      zoom_app/ViewController.swift

+ 101 - 54
zoom_app/ViewController.swift

@@ -69,8 +69,14 @@ class ViewController: NSViewController {
 
     override func viewDidAppear() {
         super.viewDidAppear()
-        view.window?.setContentSize(NSSize(width: 1020, height: 690))
-        view.window?.title = "zoom Workplace"
+        if let window = view.window {
+            window.setContentSize(NSSize(width: 1020, height: 690))
+            // Use full-size content view so custom top chrome sits in the titlebar region.
+            window.titleVisibility = .hidden
+            window.titlebarAppearsTransparent = true
+            window.isMovableByWindowBackground = true
+            window.styleMask.insert(.fullSizeContentView)
+        }
         if isUserLoggedIn() {
             showHomeView(profile: nil)
         } else {
@@ -648,33 +654,69 @@ class ViewController: NSViewController {
         shell.layer?.cornerRadius = appShellCornerRadius
         shell.layer?.borderWidth = 1
         shell.layer?.borderColor = NSColor.white.withAlphaComponent(0.06).cgColor
+        let chromeColumn = NSView()
+        chromeColumn.wantsLayer = true
+        chromeColumn.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.03).cgColor
+        let chromeDivider = NSView()
+        chromeDivider.wantsLayer = true
+        chromeDivider.layer?.backgroundColor = NSColor.black.withAlphaComponent(0.32).cgColor
+        let chromeHeader = NSView()
+        chromeHeader.wantsLayer = true
+        chromeHeader.layer?.backgroundColor = NSColor.clear.cgColor
         let sidebar = makeSidebar(items: ["Home", "Meetings", "Chat", "Scheduler", "Hub", "More"], selected: "Home", style: .home)
         let content = NSView()
         content.wantsLayer = true
         content.layer?.backgroundColor = NSColor.clear.cgColor
 
         root.addSubview(shell)
-        shell.addSubview(sidebar)
+        shell.addSubview(chromeColumn)
         shell.addSubview(content)
+        chromeColumn.addSubview(chromeDivider)
+        chromeColumn.addSubview(chromeHeader)
+        chromeColumn.addSubview(sidebar)
         shell.translatesAutoresizingMaskIntoConstraints = false
+        chromeColumn.translatesAutoresizingMaskIntoConstraints = false
+        chromeDivider.translatesAutoresizingMaskIntoConstraints = false
+        chromeHeader.translatesAutoresizingMaskIntoConstraints = false
         sidebar.translatesAutoresizingMaskIntoConstraints = false
         content.translatesAutoresizingMaskIntoConstraints = false
 
         NSLayoutConstraint.activate([
-            shell.leadingAnchor.constraint(equalTo: root.leadingAnchor, constant: 10),
-            shell.trailingAnchor.constraint(equalTo: root.trailingAnchor, constant: -10),
-            shell.topAnchor.constraint(equalTo: root.topAnchor, constant: 10),
-            shell.bottomAnchor.constraint(equalTo: root.bottomAnchor, constant: -10),
-            sidebar.leadingAnchor.constraint(equalTo: shell.leadingAnchor),
-            sidebar.topAnchor.constraint(equalTo: shell.topAnchor),
-            sidebar.bottomAnchor.constraint(equalTo: shell.bottomAnchor),
-            sidebar.widthAnchor.constraint(equalToConstant: sidebarWidth),
-            content.leadingAnchor.constraint(equalTo: sidebar.trailingAnchor),
+            shell.leadingAnchor.constraint(equalTo: root.leadingAnchor, constant: 8),
+            shell.trailingAnchor.constraint(equalTo: root.trailingAnchor, constant: -8),
+            shell.topAnchor.constraint(equalTo: root.topAnchor, constant: 0),
+            shell.bottomAnchor.constraint(equalTo: root.bottomAnchor, constant: -8),
+            chromeColumn.leadingAnchor.constraint(equalTo: shell.leadingAnchor),
+            chromeColumn.topAnchor.constraint(equalTo: shell.topAnchor),
+            chromeColumn.bottomAnchor.constraint(equalTo: shell.bottomAnchor),
+            chromeColumn.widthAnchor.constraint(equalToConstant: 146),
+            chromeDivider.topAnchor.constraint(equalTo: chromeColumn.topAnchor),
+            chromeDivider.bottomAnchor.constraint(equalTo: chromeColumn.bottomAnchor),
+            chromeDivider.trailingAnchor.constraint(equalTo: chromeColumn.trailingAnchor),
+            chromeDivider.widthAnchor.constraint(equalToConstant: 1),
+            chromeHeader.topAnchor.constraint(equalTo: chromeColumn.topAnchor),
+            chromeHeader.leadingAnchor.constraint(equalTo: chromeColumn.leadingAnchor),
+            chromeHeader.trailingAnchor.constraint(equalTo: chromeColumn.trailingAnchor),
+            chromeHeader.heightAnchor.constraint(equalToConstant: 56),
+            sidebar.leadingAnchor.constraint(equalTo: chromeColumn.leadingAnchor),
+            sidebar.trailingAnchor.constraint(equalTo: chromeColumn.trailingAnchor),
+            sidebar.topAnchor.constraint(equalTo: chromeHeader.bottomAnchor, constant: 2),
+            sidebar.bottomAnchor.constraint(equalTo: chromeColumn.bottomAnchor),
+            content.leadingAnchor.constraint(equalTo: chromeColumn.trailingAnchor),
             content.trailingAnchor.constraint(equalTo: shell.trailingAnchor),
             content.topAnchor.constraint(equalTo: shell.topAnchor),
             content.bottomAnchor.constraint(equalTo: shell.bottomAnchor)
         ])
 
+        let brandStack = NSStackView()
+        brandStack.orientation = .vertical
+        brandStack.spacing = 0
+        brandStack.alignment = .leading
+        let brandTop = makeLabel("zoom", size: 14, color: primaryText, weight: .semibold, centered: false)
+        let brandBottom = makeLabel("Workplace", size: 27, color: primaryText, weight: .bold, centered: false)
+        brandBottom.font = .systemFont(ofSize: 14, weight: .bold)
+        [brandTop, brandBottom].forEach { brandStack.addArrangedSubview($0) }
+
         let topBar = NSView()
         topBar.wantsLayer = true
         topBar.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.03).cgColor
@@ -689,15 +731,6 @@ class ViewController: NSViewController {
         searchPill.layer?.cornerRadius = 10
         let search = makeLabel("Search (\u{2318}E)", size: 13, color: mutedText, weight: .regular, centered: true)
         
-        let brandStack = NSStackView()
-        brandStack.orientation = .vertical
-        brandStack.spacing = 0
-        brandStack.alignment = .leading
-        let brandTop = makeLabel("zoom", size: 14, color: primaryText, weight: .semibold, centered: false)
-        let brandBottom = makeLabel("Workplace", size: 27, color: primaryText, weight: .bold, centered: false)
-        brandBottom.font = .systemFont(ofSize: 14, weight: .bold)
-        [brandTop, brandBottom].forEach { brandStack.addArrangedSubview($0) }
-        
         let leftTopBarCluster = NSStackView()
         leftTopBarCluster.orientation = .horizontal
         leftTopBarCluster.spacing = 10
@@ -779,38 +812,65 @@ class ViewController: NSViewController {
         openRecordings.layer?.borderWidth = 1
         openRecordings.layer?.borderColor = NSColor.white.withAlphaComponent(0.07).cgColor
 
+        let contentPanel = NSView()
+        contentPanel.wantsLayer = true
+        contentPanel.layer?.backgroundColor = contentShellBackground.cgColor
+        contentPanel.layer?.cornerRadius = 12
+        contentPanel.layer?.borderWidth = 1
+        contentPanel.layer?.borderColor = NSColor.white.withAlphaComponent(0.04).cgColor
         let contentColumn = NSView()
         contentColumn.translatesAutoresizingMaskIntoConstraints = false
-        content.addSubview(contentColumn)
+        content.addSubview(topBar)
+        content.addSubview(topBarDivider)
+        content.addSubview(contentPanel)
+        contentPanel.addSubview(contentColumn)
 
-        [topBar, topBarDivider, brandStack, leftTopBarCluster, rightTopBarCluster, searchPill, search, welcome, timeTitle, dateTitle, actions, panel, panelHeaderStrip, panelHeader, meetingsStatus, noMeeting, meetingsScrollView, openRecordings].forEach {
+        [brandStack, leftTopBarCluster, rightTopBarCluster, searchPill, search].forEach {
+            $0.translatesAutoresizingMaskIntoConstraints = false
+        }
+        [brandStack].forEach {
+            chromeHeader.addSubview($0)
+        }
+        [leftTopBarCluster, rightTopBarCluster, searchPill, search].forEach {
+            $0.translatesAutoresizingMaskIntoConstraints = false
+            topBar.addSubview($0)
+        }
+        [welcome, timeTitle, dateTitle, actions, panel, panelHeaderStrip, panelHeader, meetingsStatus, noMeeting, meetingsScrollView, openRecordings].forEach {
             $0.translatesAutoresizingMaskIntoConstraints = false
             contentColumn.addSubview($0)
         }
+        topBar.translatesAutoresizingMaskIntoConstraints = false
+        topBarDivider.translatesAutoresizingMaskIntoConstraints = false
+        contentPanel.translatesAutoresizingMaskIntoConstraints = false
         meetingsDocument.translatesAutoresizingMaskIntoConstraints = false
         meetingsStack.translatesAutoresizingMaskIntoConstraints = false
         meetingsScrollView.documentView = meetingsDocument
         meetingsDocument.addSubview(meetingsStack)
 
         NSLayoutConstraint.activate([
-            contentColumn.topAnchor.constraint(equalTo: content.topAnchor),
-            contentColumn.bottomAnchor.constraint(equalTo: content.bottomAnchor),
-            contentColumn.leadingAnchor.constraint(equalTo: content.leadingAnchor),
-            contentColumn.trailingAnchor.constraint(equalTo: content.trailingAnchor),
-
-            topBar.topAnchor.constraint(equalTo: contentColumn.topAnchor),
-            topBar.leadingAnchor.constraint(equalTo: contentColumn.leadingAnchor),
-            topBar.trailingAnchor.constraint(equalTo: contentColumn.trailingAnchor),
-            topBar.heightAnchor.constraint(equalToConstant: 48),
+            brandStack.leadingAnchor.constraint(equalTo: chromeHeader.leadingAnchor, constant: 60),
+            brandStack.centerYAnchor.constraint(equalTo: chromeHeader.centerYAnchor),
+
+            topBar.topAnchor.constraint(equalTo: content.topAnchor),
+            topBar.leadingAnchor.constraint(equalTo: content.leadingAnchor),
+            topBar.trailingAnchor.constraint(equalTo: content.trailingAnchor),
+            topBar.heightAnchor.constraint(equalToConstant: 56),
             topBarDivider.topAnchor.constraint(equalTo: topBar.bottomAnchor),
-            topBarDivider.leadingAnchor.constraint(equalTo: contentColumn.leadingAnchor),
-            topBarDivider.trailingAnchor.constraint(equalTo: contentColumn.trailingAnchor),
+            topBarDivider.leadingAnchor.constraint(equalTo: content.leadingAnchor),
+            topBarDivider.trailingAnchor.constraint(equalTo: content.trailingAnchor),
             topBarDivider.heightAnchor.constraint(equalToConstant: 1),
 
-            brandStack.leadingAnchor.constraint(equalTo: topBar.leadingAnchor, constant: 12),
-            brandStack.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
+            contentPanel.topAnchor.constraint(equalTo: topBarDivider.bottomAnchor, constant: 6),
+            contentPanel.leadingAnchor.constraint(equalTo: content.leadingAnchor, constant: 8),
+            contentPanel.trailingAnchor.constraint(equalTo: content.trailingAnchor, constant: -8),
+            contentPanel.bottomAnchor.constraint(equalTo: content.bottomAnchor, constant: -8),
+
+            contentColumn.topAnchor.constraint(equalTo: contentPanel.topAnchor),
+            contentColumn.bottomAnchor.constraint(equalTo: contentPanel.bottomAnchor),
+            contentColumn.leadingAnchor.constraint(equalTo: contentPanel.leadingAnchor),
+            contentColumn.trailingAnchor.constraint(equalTo: contentPanel.trailingAnchor),
 
-            leftTopBarCluster.leadingAnchor.constraint(equalTo: brandStack.trailingAnchor, constant: 18),
+            leftTopBarCluster.leadingAnchor.constraint(equalTo: topBar.leadingAnchor, constant: 16),
             leftTopBarCluster.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
             rightTopBarCluster.trailingAnchor.constraint(equalTo: topBar.trailingAnchor, constant: -12),
             rightTopBarCluster.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
@@ -827,7 +887,7 @@ class ViewController: NSViewController {
             profileChip.widthAnchor.constraint(equalToConstant: 34),
             profileChip.heightAnchor.constraint(equalToConstant: 34),
 
-            welcome.topAnchor.constraint(equalTo: topBar.bottomAnchor, constant: 22),
+            welcome.topAnchor.constraint(equalTo: contentColumn.topAnchor, constant: 22),
             welcome.centerXAnchor.constraint(equalTo: contentColumn.centerXAnchor),
 
             timeTitle.topAnchor.constraint(equalTo: welcome.bottomAnchor, constant: 12),
@@ -845,7 +905,7 @@ class ViewController: NSViewController {
             panel.leadingAnchor.constraint(equalTo: contentColumn.leadingAnchor, constant: 26),
             panel.trailingAnchor.constraint(equalTo: contentColumn.trailingAnchor, constant: -26),
             panel.heightAnchor.constraint(equalToConstant: 316),
-            panel.bottomAnchor.constraint(lessThanOrEqualTo: contentColumn.bottomAnchor, constant: -20),
+            panel.bottomAnchor.constraint(lessThanOrEqualTo: contentColumn.bottomAnchor, constant: -24),
             
             panelHeaderStrip.topAnchor.constraint(equalTo: panel.topAnchor, constant: 10),
             panelHeaderStrip.leadingAnchor.constraint(equalTo: panel.leadingAnchor, constant: 10),
@@ -911,19 +971,6 @@ class ViewController: NSViewController {
         let sidebar = NSView()
         sidebar.wantsLayer = true
         sidebar.layer?.backgroundColor = (style == .home ? NSColor.white.withAlphaComponent(0.03) : sidebarBackground).cgColor
-        if style == .home {
-            let divider = NSView()
-            divider.wantsLayer = true
-            divider.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.06).cgColor
-            divider.translatesAutoresizingMaskIntoConstraints = false
-            sidebar.addSubview(divider)
-            NSLayoutConstraint.activate([
-                divider.topAnchor.constraint(equalTo: sidebar.topAnchor),
-                divider.bottomAnchor.constraint(equalTo: sidebar.bottomAnchor),
-                divider.trailingAnchor.constraint(equalTo: sidebar.trailingAnchor),
-                divider.widthAnchor.constraint(equalToConstant: 1)
-            ])
-        }
 
         let stack = NSStackView()
         stack.orientation = .vertical
@@ -981,7 +1028,7 @@ class ViewController: NSViewController {
         }
 
         NSLayoutConstraint.activate([
-            stack.topAnchor.constraint(equalTo: sidebar.topAnchor, constant: style == .home ? 16 : 18),
+            stack.topAnchor.constraint(equalTo: sidebar.topAnchor, constant: style == .home ? 8 : 18),
             stack.leadingAnchor.constraint(equalTo: sidebar.leadingAnchor, constant: 4),
             stack.trailingAnchor.constraint(equalTo: sidebar.trailingAnchor, constant: -4)
         ])
@@ -991,7 +1038,7 @@ class ViewController: NSViewController {
 
         return sidebar
     }
-    
+
     private func makeTopBarIconButton(symbol: String, action: Selector?) -> NSButton {
         let button = NSButton(title: "", target: action == nil ? nil : self, action: action)
         button.isBordered = false