|
@@ -265,6 +265,10 @@ class ViewController: NSViewController {
|
|
265
|
// Reserved for future titlebar control actions.
|
265
|
// Reserved for future titlebar control actions.
|
|
266
|
}
|
266
|
}
|
|
267
|
|
267
|
|
|
|
|
268
|
+ @objc private func refreshMeetingsTapped() {
|
|
|
|
269
|
+ triggerMeetingsRefresh(force: true)
|
|
|
|
270
|
+ }
|
|
|
|
271
|
+
|
|
268
|
private func startMeetingsAutoRefresh() {
|
272
|
private func startMeetingsAutoRefresh() {
|
|
269
|
meetingsRefreshTimer?.invalidate()
|
273
|
meetingsRefreshTimer?.invalidate()
|
|
270
|
// Poll Zoom meetings periodically so newly scheduled meetings appear automatically.
|
274
|
// Poll Zoom meetings periodically so newly scheduled meetings appear automatically.
|
|
@@ -1079,15 +1083,24 @@ class ViewController: NSViewController {
|
|
1079
|
// Keep meeting cards pinned to the top of the scroll content.
|
1083
|
// Keep meeting cards pinned to the top of the scroll content.
|
|
1080
|
meetingsStack.setContentHuggingPriority(.required, for: .vertical)
|
1084
|
meetingsStack.setContentHuggingPriority(.required, for: .vertical)
|
|
1081
|
meetingsStack.setContentCompressionResistancePriority(.required, for: .vertical)
|
1085
|
meetingsStack.setContentCompressionResistancePriority(.required, for: .vertical)
|
|
1082
|
- let openRecordings = NSButton(title: "Open recordings", target: nil, action: nil)
|
|
|
|
1083
|
- openRecordings.isBordered = false
|
|
|
|
1084
|
- openRecordings.font = .systemFont(ofSize: 14, weight: .semibold)
|
|
|
|
1085
|
- openRecordings.contentTintColor = primaryText
|
|
|
|
1086
|
- openRecordings.wantsLayer = true
|
|
|
|
1087
|
- openRecordings.layer?.backgroundColor = NSColor(calibratedRed: 36 / 255, green: 39 / 255, blue: 46 / 255, alpha: 1).cgColor
|
|
|
|
1088
|
- openRecordings.layer?.cornerRadius = 11
|
|
|
|
1089
|
- openRecordings.layer?.borderWidth = 1
|
|
|
|
1090
|
- openRecordings.layer?.borderColor = NSColor.white.withAlphaComponent(0.07).cgColor
|
|
|
|
|
|
1086
|
+ let refreshMeetingsButton = NSButton(title: "Refresh", target: self, action: #selector(refreshMeetingsTapped))
|
|
|
|
1087
|
+ refreshMeetingsButton.isBordered = false
|
|
|
|
1088
|
+ refreshMeetingsButton.font = .systemFont(ofSize: 14, weight: .semibold)
|
|
|
|
1089
|
+ refreshMeetingsButton.contentTintColor = primaryText
|
|
|
|
1090
|
+ let refreshSymbolConfig = NSImage.SymbolConfiguration(pointSize: 13, weight: .semibold)
|
|
|
|
1091
|
+ if let base = NSImage(systemSymbolName: "arrow.clockwise", accessibilityDescription: "Refresh"),
|
|
|
|
1092
|
+ let image = base.withSymbolConfiguration(refreshSymbolConfig) {
|
|
|
|
1093
|
+ image.isTemplate = true
|
|
|
|
1094
|
+ refreshMeetingsButton.image = image
|
|
|
|
1095
|
+ refreshMeetingsButton.imagePosition = .imageLeading
|
|
|
|
1096
|
+ refreshMeetingsButton.imageHugsTitle = true
|
|
|
|
1097
|
+ refreshMeetingsButton.imageScaling = .scaleNone
|
|
|
|
1098
|
+ }
|
|
|
|
1099
|
+ refreshMeetingsButton.wantsLayer = true
|
|
|
|
1100
|
+ refreshMeetingsButton.layer?.backgroundColor = NSColor(calibratedRed: 36 / 255, green: 39 / 255, blue: 46 / 255, alpha: 1).cgColor
|
|
|
|
1101
|
+ refreshMeetingsButton.layer?.cornerRadius = 11
|
|
|
|
1102
|
+ refreshMeetingsButton.layer?.borderWidth = 1
|
|
|
|
1103
|
+ refreshMeetingsButton.layer?.borderColor = NSColor.white.withAlphaComponent(0.07).cgColor
|
|
1091
|
|
1104
|
|
|
1092
|
let contentColumn = NSView()
|
1105
|
let contentColumn = NSView()
|
|
1093
|
contentColumn.translatesAutoresizingMaskIntoConstraints = false
|
1106
|
contentColumn.translatesAutoresizingMaskIntoConstraints = false
|
|
@@ -1107,7 +1120,7 @@ class ViewController: NSViewController {
|
|
1107
|
[searchIcon, searchField, searchHintLabel].forEach {
|
1120
|
[searchIcon, searchField, searchHintLabel].forEach {
|
|
1108
|
searchPill.addSubview($0)
|
1121
|
searchPill.addSubview($0)
|
|
1109
|
}
|
1122
|
}
|
|
1110
|
- [welcome, timeTitle, dateTitle, actions, panel, panelHeader, meetingsStatus, meetingsDayNav, noMeeting, meetingsScrollView, openRecordings].forEach {
|
|
|
|
|
|
1123
|
+ [welcome, timeTitle, dateTitle, actions, panel, panelHeader, meetingsStatus, meetingsDayNav, noMeeting, meetingsScrollView, refreshMeetingsButton].forEach {
|
|
1111
|
$0.translatesAutoresizingMaskIntoConstraints = false
|
1124
|
$0.translatesAutoresizingMaskIntoConstraints = false
|
|
1112
|
contentColumn.addSubview($0)
|
1125
|
contentColumn.addSubview($0)
|
|
1113
|
}
|
1126
|
}
|
|
@@ -1199,7 +1212,7 @@ class ViewController: NSViewController {
|
|
1199
|
meetingsScrollView.topAnchor.constraint(equalTo: panelHeader.bottomAnchor, constant: 12),
|
1212
|
meetingsScrollView.topAnchor.constraint(equalTo: panelHeader.bottomAnchor, constant: 12),
|
|
1200
|
meetingsScrollView.leadingAnchor.constraint(equalTo: panel.leadingAnchor, constant: 14),
|
1213
|
meetingsScrollView.leadingAnchor.constraint(equalTo: panel.leadingAnchor, constant: 14),
|
|
1201
|
meetingsScrollView.trailingAnchor.constraint(equalTo: panel.trailingAnchor, constant: -14),
|
1214
|
meetingsScrollView.trailingAnchor.constraint(equalTo: panel.trailingAnchor, constant: -14),
|
|
1202
|
- meetingsScrollView.bottomAnchor.constraint(equalTo: openRecordings.topAnchor, constant: -14),
|
|
|
|
|
|
1215
|
+ meetingsScrollView.bottomAnchor.constraint(equalTo: refreshMeetingsButton.topAnchor, constant: -14),
|
|
1203
|
|
1216
|
|
|
1204
|
meetingsDocument.widthAnchor.constraint(equalTo: meetingsScrollView.contentView.widthAnchor),
|
1217
|
meetingsDocument.widthAnchor.constraint(equalTo: meetingsScrollView.contentView.widthAnchor),
|
|
1205
|
meetingsStack.topAnchor.constraint(equalTo: meetingsDocument.topAnchor),
|
1218
|
meetingsStack.topAnchor.constraint(equalTo: meetingsDocument.topAnchor),
|
|
@@ -1207,10 +1220,10 @@ class ViewController: NSViewController {
|
|
1207
|
meetingsStack.trailingAnchor.constraint(equalTo: meetingsDocument.trailingAnchor),
|
1220
|
meetingsStack.trailingAnchor.constraint(equalTo: meetingsDocument.trailingAnchor),
|
|
1208
|
meetingsStack.bottomAnchor.constraint(lessThanOrEqualTo: meetingsDocument.bottomAnchor),
|
1221
|
meetingsStack.bottomAnchor.constraint(lessThanOrEqualTo: meetingsDocument.bottomAnchor),
|
|
1209
|
|
1222
|
|
|
1210
|
- openRecordings.leadingAnchor.constraint(equalTo: panel.leadingAnchor, constant: 14),
|
|
|
|
1211
|
- openRecordings.trailingAnchor.constraint(equalTo: panel.trailingAnchor, constant: -14),
|
|
|
|
1212
|
- openRecordings.bottomAnchor.constraint(equalTo: panel.bottomAnchor, constant: -12),
|
|
|
|
1213
|
- openRecordings.heightAnchor.constraint(equalToConstant: 40)
|
|
|
|
|
|
1223
|
+ refreshMeetingsButton.leadingAnchor.constraint(equalTo: panel.leadingAnchor, constant: 14),
|
|
|
|
1224
|
+ refreshMeetingsButton.trailingAnchor.constraint(equalTo: panel.trailingAnchor, constant: -14),
|
|
|
|
1225
|
+ refreshMeetingsButton.bottomAnchor.constraint(equalTo: panel.bottomAnchor, constant: -12),
|
|
|
|
1226
|
+ refreshMeetingsButton.heightAnchor.constraint(equalToConstant: 40)
|
|
1214
|
])
|
1227
|
])
|
|
1215
|
|
1228
|
|
|
1216
|
timeLabel = timeTitle
|
1229
|
timeLabel = timeTitle
|