|
|
@@ -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
|