|
|
@@ -74,7 +74,7 @@ final class ViewController: NSViewController {
|
|
74
|
74
|
private var scheduleFilter: ScheduleFilter = .all
|
|
75
|
75
|
private weak var scheduleDateHeadingLabel: NSTextField?
|
|
76
|
76
|
private weak var scheduleCardsStack: NSStackView?
|
|
77
|
|
- private weak var scheduleFilterLabel: NSTextField?
|
|
|
77
|
+ private weak var scheduleFilterDropdown: NSPopUpButton?
|
|
78
|
78
|
|
|
79
|
79
|
/// In-app browser navigation: `.allowAll` or `.whitelist(hostSuffixes:)` (e.g. `["google.com"]` matches `meet.google.com`).
|
|
80
|
80
|
private let inAppBrowserDefaultPolicy: InAppBrowserURLPolicy = .allowAll
|
|
|
@@ -1807,45 +1807,39 @@ private extension ViewController {
|
|
1807
|
1807
|
connectButton.action = #selector(scheduleConnectButtonPressed(_:))
|
|
1808
|
1808
|
row.addArrangedSubview(connectButton)
|
|
1809
|
1809
|
|
|
1810
|
|
- let filter = roundedContainer(cornerRadius: 8, color: palette.inputBackground)
|
|
1811
|
|
- filter.translatesAutoresizingMaskIntoConstraints = false
|
|
1812
|
|
- filter.widthAnchor.constraint(equalToConstant: 156).isActive = true
|
|
1813
|
|
- filter.heightAnchor.constraint(equalToConstant: 34).isActive = true
|
|
1814
|
|
- styleSurface(filter, borderColor: palette.inputBorder, borderWidth: 1, shadow: false)
|
|
1815
|
|
- let filterText = textLabel(scheduleFilterTitle(scheduleFilter), font: typography.filterText, color: palette.textSecondary)
|
|
1816
|
|
- scheduleFilterLabel = filterText
|
|
1817
|
|
- let arrow = textLabel("▾", font: typography.filterArrow, color: palette.textMuted)
|
|
1818
|
|
- filterText.translatesAutoresizingMaskIntoConstraints = false
|
|
1819
|
|
- arrow.translatesAutoresizingMaskIntoConstraints = false
|
|
1820
|
|
- filter.addSubview(filterText)
|
|
1821
|
|
- filter.addSubview(arrow)
|
|
|
1810
|
+ row.addArrangedSubview(makeScheduleFilterDropdown())
|
|
|
1811
|
+ row.widthAnchor.constraint(greaterThanOrEqualToConstant: 780).isActive = true
|
|
|
1812
|
+ return row
|
|
|
1813
|
+ }
|
|
1822
|
1814
|
|
|
1823
|
|
- NSLayoutConstraint.activate([
|
|
1824
|
|
- filterText.leadingAnchor.constraint(equalTo: filter.leadingAnchor, constant: 12),
|
|
1825
|
|
- filterText.centerYAnchor.constraint(equalTo: filter.centerYAnchor),
|
|
1826
|
|
- arrow.trailingAnchor.constraint(equalTo: filter.trailingAnchor, constant: -10),
|
|
1827
|
|
- arrow.centerYAnchor.constraint(equalTo: filter.centerYAnchor)
|
|
1828
|
|
- ])
|
|
|
1815
|
+ private func makeScheduleFilterDropdown() -> NSPopUpButton {
|
|
|
1816
|
+ let button = NSPopUpButton(frame: .zero, pullsDown: false)
|
|
|
1817
|
+ button.translatesAutoresizingMaskIntoConstraints = false
|
|
|
1818
|
+ button.autoenablesItems = false
|
|
|
1819
|
+ button.wantsLayer = true
|
|
|
1820
|
+ button.layer?.cornerRadius = 8
|
|
|
1821
|
+ button.layer?.backgroundColor = palette.inputBackground.cgColor
|
|
|
1822
|
+ button.layer?.borderColor = palette.inputBorder.cgColor
|
|
|
1823
|
+ button.layer?.borderWidth = 1
|
|
|
1824
|
+ button.font = typography.filterText
|
|
|
1825
|
+ button.contentTintColor = palette.textSecondary
|
|
|
1826
|
+ button.target = self
|
|
|
1827
|
+ button.action = #selector(scheduleFilterDropdownChanged(_:))
|
|
|
1828
|
+ button.heightAnchor.constraint(equalToConstant: 34).isActive = true
|
|
|
1829
|
+ button.widthAnchor.constraint(equalToConstant: 156).isActive = true
|
|
1829
|
1830
|
|
|
1830
|
|
- let filterHit = HoverTrackingView()
|
|
1831
|
|
- filterHit.translatesAutoresizingMaskIntoConstraints = false
|
|
1832
|
|
- filterHit.addSubview(filter)
|
|
1833
|
|
- NSLayoutConstraint.activate([
|
|
1834
|
|
- filterHit.widthAnchor.constraint(equalToConstant: 156),
|
|
1835
|
|
- filterHit.heightAnchor.constraint(equalToConstant: 34),
|
|
1836
|
|
- filter.leadingAnchor.constraint(equalTo: filterHit.leadingAnchor),
|
|
1837
|
|
- filter.trailingAnchor.constraint(equalTo: filterHit.trailingAnchor),
|
|
1838
|
|
- filter.topAnchor.constraint(equalTo: filterHit.topAnchor),
|
|
1839
|
|
- filter.bottomAnchor.constraint(equalTo: filterHit.bottomAnchor)
|
|
1840
|
|
- ])
|
|
1841
|
|
- filterHit.onClick = { [weak self, weak filterHit] in
|
|
1842
|
|
- guard let self, let anchor = filterHit else { return }
|
|
1843
|
|
- self.showScheduleFilterMenu(anchor: anchor)
|
|
|
1831
|
+ button.removeAllItems()
|
|
|
1832
|
+ button.addItems(withTitles: ["All", "Today", "This week"])
|
|
|
1833
|
+ button.selectItem(at: scheduleFilter.rawValue)
|
|
|
1834
|
+
|
|
|
1835
|
+ if let menu = button.menu {
|
|
|
1836
|
+ for (index, item) in menu.items.enumerated() {
|
|
|
1837
|
+ item.tag = index
|
|
|
1838
|
+ }
|
|
1844
|
1839
|
}
|
|
1845
|
1840
|
|
|
1846
|
|
- row.addArrangedSubview(filterHit)
|
|
1847
|
|
- row.widthAnchor.constraint(greaterThanOrEqualToConstant: 780).isActive = true
|
|
1848
|
|
- return row
|
|
|
1841
|
+ scheduleFilterDropdown = button
|
|
|
1842
|
+ return button
|
|
1849
|
1843
|
}
|
|
1850
|
1844
|
|
|
1851
|
1845
|
private func makeSchedulePillButton(title: String) -> NSButton {
|
|
|
@@ -2552,36 +2546,15 @@ private extension ViewController {
|
|
2552
|
2546
|
googleOAuth.loadTokens() == nil ? "Connect Google to see meetings" : "Loading…"
|
|
2553
|
2547
|
}
|
|
2554
|
2548
|
|
|
2555
|
|
- private func scheduleFilterTitle(_ filter: ScheduleFilter) -> String {
|
|
2556
|
|
- switch filter {
|
|
2557
|
|
- case .all: return "All"
|
|
2558
|
|
- case .today: return "Today"
|
|
2559
|
|
- case .week: return "This week"
|
|
2560
|
|
- }
|
|
2561
|
|
- }
|
|
2562
|
|
-
|
|
2563
|
|
- private func showScheduleFilterMenu(anchor: NSView) {
|
|
2564
|
|
- let menu = NSMenu()
|
|
2565
|
|
- let items: [(ScheduleFilter, String)] = [
|
|
2566
|
|
- (.all, "All"),
|
|
2567
|
|
- (.today, "Today"),
|
|
2568
|
|
- (.week, "This week")
|
|
2569
|
|
- ]
|
|
2570
|
|
- for (filter, title) in items {
|
|
2571
|
|
- let item = NSMenuItem(title: title, action: #selector(scheduleFilterSelected(_:)), keyEquivalent: "")
|
|
2572
|
|
- item.target = self
|
|
2573
|
|
- item.tag = filter.rawValue
|
|
2574
|
|
- item.state = (filter == scheduleFilter) ? .on : .off
|
|
2575
|
|
- menu.addItem(item)
|
|
2576
|
|
- }
|
|
2577
|
|
- let loc = NSPoint(x: 8, y: anchor.bounds.height + 2)
|
|
2578
|
|
- menu.popUp(positioning: nil, at: loc, in: anchor)
|
|
|
2549
|
+ @objc func scheduleFilterDropdownChanged(_ sender: NSPopUpButton) {
|
|
|
2550
|
+ guard let selectedItem = sender.selectedItem,
|
|
|
2551
|
+ let filter = ScheduleFilter(rawValue: selectedItem.tag) else { return }
|
|
|
2552
|
+ applyScheduleFilter(filter)
|
|
2579
|
2553
|
}
|
|
2580
|
2554
|
|
|
2581
|
|
- @objc func scheduleFilterSelected(_ sender: NSMenuItem) {
|
|
2582
|
|
- guard let filter = ScheduleFilter(rawValue: sender.tag) else { return }
|
|
|
2555
|
+ private func applyScheduleFilter(_ filter: ScheduleFilter) {
|
|
2583
|
2556
|
scheduleFilter = filter
|
|
2584
|
|
- scheduleFilterLabel?.stringValue = scheduleFilterTitle(filter)
|
|
|
2557
|
+ scheduleFilterDropdown?.selectItem(at: filter.rawValue)
|
|
2585
|
2558
|
Task { [weak self] in
|
|
2586
|
2559
|
await self?.loadSchedule()
|
|
2587
|
2560
|
}
|