|
@@ -3084,6 +3084,8 @@ private extension ViewController {
|
|
|
titleRowSpacer.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
|
titleRowSpacer.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
|
|
|
|
|
|
|
titleRow.addArrangedSubview(titleLabel)
|
|
titleRow.addArrangedSubview(titleLabel)
|
|
|
|
|
+ titleRow.addArrangedSubview(makeSchedulePageAddButton())
|
|
|
|
|
+ titleRow.setCustomSpacing(12, after: titleLabel)
|
|
|
titleRow.addArrangedSubview(titleRowSpacer)
|
|
titleRow.addArrangedSubview(titleRowSpacer)
|
|
|
container.addArrangedSubview(titleRow)
|
|
container.addArrangedSubview(titleRow)
|
|
|
|
|
|
|
@@ -3428,6 +3430,40 @@ private extension ViewController {
|
|
|
return button
|
|
return button
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private func makeSchedulePageAddButton() -> NSButton {
|
|
|
|
|
+ let diameter: CGFloat = 30
|
|
|
|
|
+ let button = HoverButton(title: "", target: self, action: #selector(schedulePageAddMeetingPressed(_:)))
|
|
|
|
|
+ button.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
|
+ button.isBordered = false
|
|
|
|
|
+ button.bezelStyle = .regularSquare
|
|
|
|
|
+ button.wantsLayer = true
|
|
|
|
|
+ button.layer?.cornerRadius = diameter / 2
|
|
|
|
|
+ button.layer?.masksToBounds = true
|
|
|
|
|
+ button.layer?.backgroundColor = palette.inputBackground.cgColor
|
|
|
|
|
+ button.layer?.borderColor = palette.inputBorder.cgColor
|
|
|
|
|
+ button.layer?.borderWidth = 1
|
|
|
|
|
+ button.setButtonType(.momentaryChange)
|
|
|
|
|
+ button.contentTintColor = palette.textSecondary
|
|
|
|
|
+ button.image = NSImage(systemSymbolName: "plus", accessibilityDescription: "Schedule meeting")
|
|
|
|
|
+ button.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 14, weight: .semibold)
|
|
|
|
|
+ button.imagePosition = .imageOnly
|
|
|
|
|
+ button.imageScaling = .scaleProportionallyDown
|
|
|
|
|
+ button.focusRingType = .none
|
|
|
|
|
+ button.heightAnchor.constraint(equalToConstant: diameter).isActive = true
|
|
|
|
|
+ button.widthAnchor.constraint(equalToConstant: diameter).isActive = true
|
|
|
|
|
+ let baseColor = palette.inputBackground
|
|
|
|
|
+ let baseBorder = palette.inputBorder
|
|
|
|
|
+ let hoverBlend = darkModeEnabled ? NSColor.white : NSColor.black
|
|
|
|
|
+ let hoverColor = baseColor.blended(withFraction: 0.10, of: hoverBlend) ?? baseColor
|
|
|
|
|
+ let hoverBorder = baseBorder.blended(withFraction: 0.16, of: hoverBlend) ?? baseBorder
|
|
|
|
|
+ button.onHoverChanged = { [weak button] hovering in
|
|
|
|
|
+ button?.layer?.backgroundColor = (hovering ? hoverColor : baseColor).cgColor
|
|
|
|
|
+ button?.layer?.borderColor = (hovering ? hoverBorder : baseBorder).cgColor
|
|
|
|
|
+ }
|
|
|
|
|
+ button.onHoverChanged?(false)
|
|
|
|
|
+ return button
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private func makeScheduleRefreshButton() -> NSButton {
|
|
private func makeScheduleRefreshButton() -> NSButton {
|
|
|
let diameter: CGFloat = 30
|
|
let diameter: CGFloat = 30
|
|
|
let button = HoverButton(title: "", target: self, action: #selector(scheduleReloadButtonPressed(_:)))
|
|
let button = HoverButton(title: "", target: self, action: #selector(scheduleReloadButtonPressed(_:)))
|
|
@@ -5606,6 +5642,33 @@ private extension ViewController {
|
|
|
applySchedulePageFiltersAndRender()
|
|
applySchedulePageFiltersAndRender()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @objc func schedulePageAddMeetingPressed(_ sender: NSButton) {
|
|
|
|
|
+ guard requireGoogleLoginForCalendarScheduling() else { return }
|
|
|
|
|
+
|
|
|
|
|
+ let accessory = NSView(frame: NSRect(x: 0, y: 0, width: 230, height: 28))
|
|
|
|
|
+
|
|
|
|
|
+ let datePicker = NSDatePicker(frame: accessory.bounds)
|
|
|
|
|
+ datePicker.autoresizingMask = [.width, .height]
|
|
|
|
|
+ datePicker.datePickerMode = .single
|
|
|
|
|
+ datePicker.datePickerStyle = .textFieldAndStepper
|
|
|
|
|
+ datePicker.datePickerElements = [.yearMonthDay]
|
|
|
|
|
+ datePicker.dateValue = Calendar.current.startOfDay(for: Date())
|
|
|
|
|
+ accessory.addSubview(datePicker)
|
|
|
|
|
+
|
|
|
|
|
+ let alert = NSAlert()
|
|
|
|
|
+ alert.messageText = "Select date"
|
|
|
|
|
+ alert.informativeText = "Choose a date to schedule your meeting."
|
|
|
|
|
+ alert.alertStyle = .informational
|
|
|
|
|
+ alert.accessoryView = accessory
|
|
|
|
|
+ alert.addButton(withTitle: "Continue")
|
|
|
|
|
+ alert.addButton(withTitle: "Cancel")
|
|
|
|
|
+
|
|
|
|
|
+ guard alert.runModal() == .alertFirstButtonReturn else { return }
|
|
|
|
|
+
|
|
|
|
|
+ calendarPageSelectedDate = Calendar.current.startOfDay(for: datePicker.dateValue)
|
|
|
|
|
+ presentCreateMeetingPopover(relativeTo: sender)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private func scheduleTimeText(for meeting: ScheduledMeeting) -> String {
|
|
private func scheduleTimeText(for meeting: ScheduledMeeting) -> String {
|
|
|
if meeting.isAllDay { return "All day" }
|
|
if meeting.isAllDay { return "All day" }
|
|
|
let f = DateFormatter()
|
|
let f = DateFormatter()
|