|
|
@@ -69,8 +69,14 @@ class ViewController: NSViewController {
|
|
69
|
69
|
|
|
70
|
70
|
override func viewDidAppear() {
|
|
71
|
71
|
super.viewDidAppear()
|
|
72
|
|
- view.window?.setContentSize(NSSize(width: 1020, height: 690))
|
|
73
|
|
- view.window?.title = "zoom Workplace"
|
|
|
72
|
+ if let window = view.window {
|
|
|
73
|
+ window.setContentSize(NSSize(width: 1020, height: 690))
|
|
|
74
|
+ // Use full-size content view so custom top chrome sits in the titlebar region.
|
|
|
75
|
+ window.titleVisibility = .hidden
|
|
|
76
|
+ window.titlebarAppearsTransparent = true
|
|
|
77
|
+ window.isMovableByWindowBackground = true
|
|
|
78
|
+ window.styleMask.insert(.fullSizeContentView)
|
|
|
79
|
+ }
|
|
74
|
80
|
if isUserLoggedIn() {
|
|
75
|
81
|
showHomeView(profile: nil)
|
|
76
|
82
|
} else {
|
|
|
@@ -648,33 +654,69 @@ class ViewController: NSViewController {
|
|
648
|
654
|
shell.layer?.cornerRadius = appShellCornerRadius
|
|
649
|
655
|
shell.layer?.borderWidth = 1
|
|
650
|
656
|
shell.layer?.borderColor = NSColor.white.withAlphaComponent(0.06).cgColor
|
|
|
657
|
+ let chromeColumn = NSView()
|
|
|
658
|
+ chromeColumn.wantsLayer = true
|
|
|
659
|
+ chromeColumn.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.03).cgColor
|
|
|
660
|
+ let chromeDivider = NSView()
|
|
|
661
|
+ chromeDivider.wantsLayer = true
|
|
|
662
|
+ chromeDivider.layer?.backgroundColor = NSColor.black.withAlphaComponent(0.32).cgColor
|
|
|
663
|
+ let chromeHeader = NSView()
|
|
|
664
|
+ chromeHeader.wantsLayer = true
|
|
|
665
|
+ chromeHeader.layer?.backgroundColor = NSColor.clear.cgColor
|
|
651
|
666
|
let sidebar = makeSidebar(items: ["Home", "Meetings", "Chat", "Scheduler", "Hub", "More"], selected: "Home", style: .home)
|
|
652
|
667
|
let content = NSView()
|
|
653
|
668
|
content.wantsLayer = true
|
|
654
|
669
|
content.layer?.backgroundColor = NSColor.clear.cgColor
|
|
655
|
670
|
|
|
656
|
671
|
root.addSubview(shell)
|
|
657
|
|
- shell.addSubview(sidebar)
|
|
|
672
|
+ shell.addSubview(chromeColumn)
|
|
658
|
673
|
shell.addSubview(content)
|
|
|
674
|
+ chromeColumn.addSubview(chromeDivider)
|
|
|
675
|
+ chromeColumn.addSubview(chromeHeader)
|
|
|
676
|
+ chromeColumn.addSubview(sidebar)
|
|
659
|
677
|
shell.translatesAutoresizingMaskIntoConstraints = false
|
|
|
678
|
+ chromeColumn.translatesAutoresizingMaskIntoConstraints = false
|
|
|
679
|
+ chromeDivider.translatesAutoresizingMaskIntoConstraints = false
|
|
|
680
|
+ chromeHeader.translatesAutoresizingMaskIntoConstraints = false
|
|
660
|
681
|
sidebar.translatesAutoresizingMaskIntoConstraints = false
|
|
661
|
682
|
content.translatesAutoresizingMaskIntoConstraints = false
|
|
662
|
683
|
|
|
663
|
684
|
NSLayoutConstraint.activate([
|
|
664
|
|
- shell.leadingAnchor.constraint(equalTo: root.leadingAnchor, constant: 10),
|
|
665
|
|
- shell.trailingAnchor.constraint(equalTo: root.trailingAnchor, constant: -10),
|
|
666
|
|
- shell.topAnchor.constraint(equalTo: root.topAnchor, constant: 10),
|
|
667
|
|
- shell.bottomAnchor.constraint(equalTo: root.bottomAnchor, constant: -10),
|
|
668
|
|
- sidebar.leadingAnchor.constraint(equalTo: shell.leadingAnchor),
|
|
669
|
|
- sidebar.topAnchor.constraint(equalTo: shell.topAnchor),
|
|
670
|
|
- sidebar.bottomAnchor.constraint(equalTo: shell.bottomAnchor),
|
|
671
|
|
- sidebar.widthAnchor.constraint(equalToConstant: sidebarWidth),
|
|
672
|
|
- content.leadingAnchor.constraint(equalTo: sidebar.trailingAnchor),
|
|
|
685
|
+ shell.leadingAnchor.constraint(equalTo: root.leadingAnchor, constant: 8),
|
|
|
686
|
+ shell.trailingAnchor.constraint(equalTo: root.trailingAnchor, constant: -8),
|
|
|
687
|
+ shell.topAnchor.constraint(equalTo: root.topAnchor, constant: 0),
|
|
|
688
|
+ shell.bottomAnchor.constraint(equalTo: root.bottomAnchor, constant: -8),
|
|
|
689
|
+ chromeColumn.leadingAnchor.constraint(equalTo: shell.leadingAnchor),
|
|
|
690
|
+ chromeColumn.topAnchor.constraint(equalTo: shell.topAnchor),
|
|
|
691
|
+ chromeColumn.bottomAnchor.constraint(equalTo: shell.bottomAnchor),
|
|
|
692
|
+ chromeColumn.widthAnchor.constraint(equalToConstant: 146),
|
|
|
693
|
+ chromeDivider.topAnchor.constraint(equalTo: chromeColumn.topAnchor),
|
|
|
694
|
+ chromeDivider.bottomAnchor.constraint(equalTo: chromeColumn.bottomAnchor),
|
|
|
695
|
+ chromeDivider.trailingAnchor.constraint(equalTo: chromeColumn.trailingAnchor),
|
|
|
696
|
+ chromeDivider.widthAnchor.constraint(equalToConstant: 1),
|
|
|
697
|
+ chromeHeader.topAnchor.constraint(equalTo: chromeColumn.topAnchor),
|
|
|
698
|
+ chromeHeader.leadingAnchor.constraint(equalTo: chromeColumn.leadingAnchor),
|
|
|
699
|
+ chromeHeader.trailingAnchor.constraint(equalTo: chromeColumn.trailingAnchor),
|
|
|
700
|
+ chromeHeader.heightAnchor.constraint(equalToConstant: 56),
|
|
|
701
|
+ sidebar.leadingAnchor.constraint(equalTo: chromeColumn.leadingAnchor),
|
|
|
702
|
+ sidebar.trailingAnchor.constraint(equalTo: chromeColumn.trailingAnchor),
|
|
|
703
|
+ sidebar.topAnchor.constraint(equalTo: chromeHeader.bottomAnchor, constant: 2),
|
|
|
704
|
+ sidebar.bottomAnchor.constraint(equalTo: chromeColumn.bottomAnchor),
|
|
|
705
|
+ content.leadingAnchor.constraint(equalTo: chromeColumn.trailingAnchor),
|
|
673
|
706
|
content.trailingAnchor.constraint(equalTo: shell.trailingAnchor),
|
|
674
|
707
|
content.topAnchor.constraint(equalTo: shell.topAnchor),
|
|
675
|
708
|
content.bottomAnchor.constraint(equalTo: shell.bottomAnchor)
|
|
676
|
709
|
])
|
|
677
|
710
|
|
|
|
711
|
+ let brandStack = NSStackView()
|
|
|
712
|
+ brandStack.orientation = .vertical
|
|
|
713
|
+ brandStack.spacing = 0
|
|
|
714
|
+ brandStack.alignment = .leading
|
|
|
715
|
+ let brandTop = makeLabel("zoom", size: 14, color: primaryText, weight: .semibold, centered: false)
|
|
|
716
|
+ let brandBottom = makeLabel("Workplace", size: 27, color: primaryText, weight: .bold, centered: false)
|
|
|
717
|
+ brandBottom.font = .systemFont(ofSize: 14, weight: .bold)
|
|
|
718
|
+ [brandTop, brandBottom].forEach { brandStack.addArrangedSubview($0) }
|
|
|
719
|
+
|
|
678
|
720
|
let topBar = NSView()
|
|
679
|
721
|
topBar.wantsLayer = true
|
|
680
|
722
|
topBar.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.03).cgColor
|
|
|
@@ -689,15 +731,6 @@ class ViewController: NSViewController {
|
|
689
|
731
|
searchPill.layer?.cornerRadius = 10
|
|
690
|
732
|
let search = makeLabel("Search (\u{2318}E)", size: 13, color: mutedText, weight: .regular, centered: true)
|
|
691
|
733
|
|
|
692
|
|
- let brandStack = NSStackView()
|
|
693
|
|
- brandStack.orientation = .vertical
|
|
694
|
|
- brandStack.spacing = 0
|
|
695
|
|
- brandStack.alignment = .leading
|
|
696
|
|
- let brandTop = makeLabel("zoom", size: 14, color: primaryText, weight: .semibold, centered: false)
|
|
697
|
|
- let brandBottom = makeLabel("Workplace", size: 27, color: primaryText, weight: .bold, centered: false)
|
|
698
|
|
- brandBottom.font = .systemFont(ofSize: 14, weight: .bold)
|
|
699
|
|
- [brandTop, brandBottom].forEach { brandStack.addArrangedSubview($0) }
|
|
700
|
|
-
|
|
701
|
734
|
let leftTopBarCluster = NSStackView()
|
|
702
|
735
|
leftTopBarCluster.orientation = .horizontal
|
|
703
|
736
|
leftTopBarCluster.spacing = 10
|
|
|
@@ -779,38 +812,65 @@ class ViewController: NSViewController {
|
|
779
|
812
|
openRecordings.layer?.borderWidth = 1
|
|
780
|
813
|
openRecordings.layer?.borderColor = NSColor.white.withAlphaComponent(0.07).cgColor
|
|
781
|
814
|
|
|
|
815
|
+ let contentPanel = NSView()
|
|
|
816
|
+ contentPanel.wantsLayer = true
|
|
|
817
|
+ contentPanel.layer?.backgroundColor = contentShellBackground.cgColor
|
|
|
818
|
+ contentPanel.layer?.cornerRadius = 12
|
|
|
819
|
+ contentPanel.layer?.borderWidth = 1
|
|
|
820
|
+ contentPanel.layer?.borderColor = NSColor.white.withAlphaComponent(0.04).cgColor
|
|
782
|
821
|
let contentColumn = NSView()
|
|
783
|
822
|
contentColumn.translatesAutoresizingMaskIntoConstraints = false
|
|
784
|
|
- content.addSubview(contentColumn)
|
|
|
823
|
+ content.addSubview(topBar)
|
|
|
824
|
+ content.addSubview(topBarDivider)
|
|
|
825
|
+ content.addSubview(contentPanel)
|
|
|
826
|
+ contentPanel.addSubview(contentColumn)
|
|
785
|
827
|
|
|
786
|
|
- [topBar, topBarDivider, brandStack, leftTopBarCluster, rightTopBarCluster, searchPill, search, welcome, timeTitle, dateTitle, actions, panel, panelHeaderStrip, panelHeader, meetingsStatus, noMeeting, meetingsScrollView, openRecordings].forEach {
|
|
|
828
|
+ [brandStack, leftTopBarCluster, rightTopBarCluster, searchPill, search].forEach {
|
|
|
829
|
+ $0.translatesAutoresizingMaskIntoConstraints = false
|
|
|
830
|
+ }
|
|
|
831
|
+ [brandStack].forEach {
|
|
|
832
|
+ chromeHeader.addSubview($0)
|
|
|
833
|
+ }
|
|
|
834
|
+ [leftTopBarCluster, rightTopBarCluster, searchPill, search].forEach {
|
|
|
835
|
+ $0.translatesAutoresizingMaskIntoConstraints = false
|
|
|
836
|
+ topBar.addSubview($0)
|
|
|
837
|
+ }
|
|
|
838
|
+ [welcome, timeTitle, dateTitle, actions, panel, panelHeaderStrip, panelHeader, meetingsStatus, noMeeting, meetingsScrollView, openRecordings].forEach {
|
|
787
|
839
|
$0.translatesAutoresizingMaskIntoConstraints = false
|
|
788
|
840
|
contentColumn.addSubview($0)
|
|
789
|
841
|
}
|
|
|
842
|
+ topBar.translatesAutoresizingMaskIntoConstraints = false
|
|
|
843
|
+ topBarDivider.translatesAutoresizingMaskIntoConstraints = false
|
|
|
844
|
+ contentPanel.translatesAutoresizingMaskIntoConstraints = false
|
|
790
|
845
|
meetingsDocument.translatesAutoresizingMaskIntoConstraints = false
|
|
791
|
846
|
meetingsStack.translatesAutoresizingMaskIntoConstraints = false
|
|
792
|
847
|
meetingsScrollView.documentView = meetingsDocument
|
|
793
|
848
|
meetingsDocument.addSubview(meetingsStack)
|
|
794
|
849
|
|
|
795
|
850
|
NSLayoutConstraint.activate([
|
|
796
|
|
- contentColumn.topAnchor.constraint(equalTo: content.topAnchor),
|
|
797
|
|
- contentColumn.bottomAnchor.constraint(equalTo: content.bottomAnchor),
|
|
798
|
|
- contentColumn.leadingAnchor.constraint(equalTo: content.leadingAnchor),
|
|
799
|
|
- contentColumn.trailingAnchor.constraint(equalTo: content.trailingAnchor),
|
|
800
|
|
-
|
|
801
|
|
- topBar.topAnchor.constraint(equalTo: contentColumn.topAnchor),
|
|
802
|
|
- topBar.leadingAnchor.constraint(equalTo: contentColumn.leadingAnchor),
|
|
803
|
|
- topBar.trailingAnchor.constraint(equalTo: contentColumn.trailingAnchor),
|
|
804
|
|
- topBar.heightAnchor.constraint(equalToConstant: 48),
|
|
|
851
|
+ brandStack.leadingAnchor.constraint(equalTo: chromeHeader.leadingAnchor, constant: 60),
|
|
|
852
|
+ brandStack.centerYAnchor.constraint(equalTo: chromeHeader.centerYAnchor),
|
|
|
853
|
+
|
|
|
854
|
+ topBar.topAnchor.constraint(equalTo: content.topAnchor),
|
|
|
855
|
+ topBar.leadingAnchor.constraint(equalTo: content.leadingAnchor),
|
|
|
856
|
+ topBar.trailingAnchor.constraint(equalTo: content.trailingAnchor),
|
|
|
857
|
+ topBar.heightAnchor.constraint(equalToConstant: 56),
|
|
805
|
858
|
topBarDivider.topAnchor.constraint(equalTo: topBar.bottomAnchor),
|
|
806
|
|
- topBarDivider.leadingAnchor.constraint(equalTo: contentColumn.leadingAnchor),
|
|
807
|
|
- topBarDivider.trailingAnchor.constraint(equalTo: contentColumn.trailingAnchor),
|
|
|
859
|
+ topBarDivider.leadingAnchor.constraint(equalTo: content.leadingAnchor),
|
|
|
860
|
+ topBarDivider.trailingAnchor.constraint(equalTo: content.trailingAnchor),
|
|
808
|
861
|
topBarDivider.heightAnchor.constraint(equalToConstant: 1),
|
|
809
|
862
|
|
|
810
|
|
- brandStack.leadingAnchor.constraint(equalTo: topBar.leadingAnchor, constant: 12),
|
|
811
|
|
- brandStack.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
|
|
|
863
|
+ contentPanel.topAnchor.constraint(equalTo: topBarDivider.bottomAnchor, constant: 6),
|
|
|
864
|
+ contentPanel.leadingAnchor.constraint(equalTo: content.leadingAnchor, constant: 8),
|
|
|
865
|
+ contentPanel.trailingAnchor.constraint(equalTo: content.trailingAnchor, constant: -8),
|
|
|
866
|
+ contentPanel.bottomAnchor.constraint(equalTo: content.bottomAnchor, constant: -8),
|
|
|
867
|
+
|
|
|
868
|
+ contentColumn.topAnchor.constraint(equalTo: contentPanel.topAnchor),
|
|
|
869
|
+ contentColumn.bottomAnchor.constraint(equalTo: contentPanel.bottomAnchor),
|
|
|
870
|
+ contentColumn.leadingAnchor.constraint(equalTo: contentPanel.leadingAnchor),
|
|
|
871
|
+ contentColumn.trailingAnchor.constraint(equalTo: contentPanel.trailingAnchor),
|
|
812
|
872
|
|
|
813
|
|
- leftTopBarCluster.leadingAnchor.constraint(equalTo: brandStack.trailingAnchor, constant: 18),
|
|
|
873
|
+ leftTopBarCluster.leadingAnchor.constraint(equalTo: topBar.leadingAnchor, constant: 16),
|
|
814
|
874
|
leftTopBarCluster.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
|
|
815
|
875
|
rightTopBarCluster.trailingAnchor.constraint(equalTo: topBar.trailingAnchor, constant: -12),
|
|
816
|
876
|
rightTopBarCluster.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
|
|
|
@@ -827,7 +887,7 @@ class ViewController: NSViewController {
|
|
827
|
887
|
profileChip.widthAnchor.constraint(equalToConstant: 34),
|
|
828
|
888
|
profileChip.heightAnchor.constraint(equalToConstant: 34),
|
|
829
|
889
|
|
|
830
|
|
- welcome.topAnchor.constraint(equalTo: topBar.bottomAnchor, constant: 22),
|
|
|
890
|
+ welcome.topAnchor.constraint(equalTo: contentColumn.topAnchor, constant: 22),
|
|
831
|
891
|
welcome.centerXAnchor.constraint(equalTo: contentColumn.centerXAnchor),
|
|
832
|
892
|
|
|
833
|
893
|
timeTitle.topAnchor.constraint(equalTo: welcome.bottomAnchor, constant: 12),
|
|
|
@@ -845,7 +905,7 @@ class ViewController: NSViewController {
|
|
845
|
905
|
panel.leadingAnchor.constraint(equalTo: contentColumn.leadingAnchor, constant: 26),
|
|
846
|
906
|
panel.trailingAnchor.constraint(equalTo: contentColumn.trailingAnchor, constant: -26),
|
|
847
|
907
|
panel.heightAnchor.constraint(equalToConstant: 316),
|
|
848
|
|
- panel.bottomAnchor.constraint(lessThanOrEqualTo: contentColumn.bottomAnchor, constant: -20),
|
|
|
908
|
+ panel.bottomAnchor.constraint(lessThanOrEqualTo: contentColumn.bottomAnchor, constant: -24),
|
|
849
|
909
|
|
|
850
|
910
|
panelHeaderStrip.topAnchor.constraint(equalTo: panel.topAnchor, constant: 10),
|
|
851
|
911
|
panelHeaderStrip.leadingAnchor.constraint(equalTo: panel.leadingAnchor, constant: 10),
|
|
|
@@ -911,19 +971,6 @@ class ViewController: NSViewController {
|
|
911
|
971
|
let sidebar = NSView()
|
|
912
|
972
|
sidebar.wantsLayer = true
|
|
913
|
973
|
sidebar.layer?.backgroundColor = (style == .home ? NSColor.white.withAlphaComponent(0.03) : sidebarBackground).cgColor
|
|
914
|
|
- if style == .home {
|
|
915
|
|
- let divider = NSView()
|
|
916
|
|
- divider.wantsLayer = true
|
|
917
|
|
- divider.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.06).cgColor
|
|
918
|
|
- divider.translatesAutoresizingMaskIntoConstraints = false
|
|
919
|
|
- sidebar.addSubview(divider)
|
|
920
|
|
- NSLayoutConstraint.activate([
|
|
921
|
|
- divider.topAnchor.constraint(equalTo: sidebar.topAnchor),
|
|
922
|
|
- divider.bottomAnchor.constraint(equalTo: sidebar.bottomAnchor),
|
|
923
|
|
- divider.trailingAnchor.constraint(equalTo: sidebar.trailingAnchor),
|
|
924
|
|
- divider.widthAnchor.constraint(equalToConstant: 1)
|
|
925
|
|
- ])
|
|
926
|
|
- }
|
|
927
|
974
|
|
|
928
|
975
|
let stack = NSStackView()
|
|
929
|
976
|
stack.orientation = .vertical
|
|
|
@@ -981,7 +1028,7 @@ class ViewController: NSViewController {
|
|
981
|
1028
|
}
|
|
982
|
1029
|
|
|
983
|
1030
|
NSLayoutConstraint.activate([
|
|
984
|
|
- stack.topAnchor.constraint(equalTo: sidebar.topAnchor, constant: style == .home ? 16 : 18),
|
|
|
1031
|
+ stack.topAnchor.constraint(equalTo: sidebar.topAnchor, constant: style == .home ? 8 : 18),
|
|
985
|
1032
|
stack.leadingAnchor.constraint(equalTo: sidebar.leadingAnchor, constant: 4),
|
|
986
|
1033
|
stack.trailingAnchor.constraint(equalTo: sidebar.trailingAnchor, constant: -4)
|
|
987
|
1034
|
])
|
|
|
@@ -991,7 +1038,7 @@ class ViewController: NSViewController {
|
|
991
|
1038
|
|
|
992
|
1039
|
return sidebar
|
|
993
|
1040
|
}
|
|
994
|
|
-
|
|
|
1041
|
+
|
|
995
|
1042
|
private func makeTopBarIconButton(symbol: String, action: Selector?) -> NSButton {
|
|
996
|
1043
|
let button = NSButton(title: "", target: action == nil ? nil : self, action: action)
|
|
997
|
1044
|
button.isBordered = false
|