Skip to content

Commit

Permalink
Shorten menu bar event if notch is present
Browse files Browse the repository at this point in the history
  • Loading branch information
pakerwreah committed Apr 10, 2022
1 parent eea1f38 commit d957620
Show file tree
Hide file tree
Showing 19 changed files with 163 additions and 15 deletions.
12 changes: 10 additions & 2 deletions Calendr.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
34651F6E25E3171D00518C5A /* EventViewModelLinkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34651F6D25E3171D00518C5A /* EventViewModelLinkTests.swift */; };
34651F7425E3207200518C5A /* WorkspaceServiceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34651F7325E3207200518C5A /* WorkspaceServiceProvider.swift */; };
34651F7A25E325EA00518C5A /* MockWorkspaceServiceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34651F7925E325EA00518C5A /* MockWorkspaceServiceProvider.swift */; };
346E70C92802278E00A785FF /* ScreenProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346E70C82802278E00A785FF /* ScreenProvider.swift */; };
346E70CB2802289F00A785FF /* MockScreenProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346E70CA2802289F00A785FF /* MockScreenProvider.swift */; };
3470214A259DFF3000827AE7 /* CalendarServiceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34702149259DFF3000827AE7 /* CalendarServiceProvider.swift */; };
34702150259E163000827AE7 /* CalendarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3470214F259E163000827AE7 /* CalendarModel.swift */; };
34702168259E761100827AE7 /* Calendar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34702167259E761100827AE7 /* Calendar.swift */; };
Expand Down Expand Up @@ -190,6 +192,8 @@
34651F7325E3207200518C5A /* WorkspaceServiceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkspaceServiceProvider.swift; sourceTree = "<group>"; };
34651F7925E325EA00518C5A /* MockWorkspaceServiceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockWorkspaceServiceProvider.swift; sourceTree = "<group>"; };
34651F8925E4099700518C5A /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
346E70C82802278E00A785FF /* ScreenProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenProvider.swift; sourceTree = "<group>"; };
346E70CA2802289F00A785FF /* MockScreenProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockScreenProvider.swift; sourceTree = "<group>"; };
34702149259DFF3000827AE7 /* CalendarServiceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarServiceProvider.swift; sourceTree = "<group>"; };
3470214F259E163000827AE7 /* CalendarModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarModel.swift; sourceTree = "<group>"; };
34702167259E761100827AE7 /* Calendar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Calendar.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -533,6 +537,7 @@
children = (
34702149259DFF3000827AE7 /* CalendarServiceProvider.swift */,
34FD09D825AE269600AAAAE2 /* DateProvider.swift */,
346E70C82802278E00A785FF /* ScreenProvider.swift */,
34651F7325E3207200518C5A /* WorkspaceServiceProvider.swift */,
);
path = Providers;
Expand All @@ -547,6 +552,7 @@
3477F3D925FD44C1008EA888 /* MockEventListSettings.swift */,
34C72F9525E8A05700FD20FA /* MockNextEventSettings.swift */,
34C72F8725E88C0300FD20FA /* MockPopoverSettings.swift */,
346E70CA2802289F00A785FF /* MockScreenProvider.swift */,
34C72F8325E88B6600FD20FA /* MockStatusItemSettings.swift */,
34651F7925E325EA00518C5A /* MockWorkspaceServiceProvider.swift */,
);
Expand Down Expand Up @@ -829,6 +835,7 @@
34F96CEE25B523ED0020DEEA /* main.swift in Sources */,
348B8D0425B2925100E518FE /* SettingsViewModel.swift in Sources */,
34F128D125968044007DF31C /* Label.swift in Sources */,
346E70C92802278E00A785FF /* ScreenProvider.swift in Sources */,
34F128F22597C340007DF31C /* WeekDayCellView.swift in Sources */,
34C72F9C25E9847300FD20FA /* EventListViewModel.swift in Sources */,
3421DA142693E75A00056837 /* MockCalendarServiceProvider.swift in Sources */,
Expand Down Expand Up @@ -888,6 +895,7 @@
34C72F8825E88C0300FD20FA /* MockPopoverSettings.swift in Sources */,
34C2CF9125C2070400FC2CFF /* EventViewModelTests.swift in Sources */,
3477F3DA25FD44C1008EA888 /* MockEventListSettings.swift in Sources */,
346E70CB2802289F00A785FF /* MockScreenProvider.swift in Sources */,
34C72F7E25E844E500FD20FA /* NextEventViewModelTests.swift in Sources */,
348E703725C6173400B3B160 /* EventViewModelProgressTests.swift in Sources */,
3477F3D425FAF079008EA888 /* MockCalendarServiceProvider.swift in Sources */,
Expand Down Expand Up @@ -1101,7 +1109,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.5.0;
MARKETING_VERSION = 1.5.1;
PRODUCT_BUNDLE_IDENTIFIER = br.paker.Calendr;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Calendr/Config/Calendr-Bridging-Header.h";
Expand All @@ -1125,7 +1133,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.5.0;
MARKETING_VERSION = 1.5.1;
PRODUCT_BUNDLE_IDENTIFIER = br.paker.Calendr;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Calendr/Config/Calendr-Bridging-Header.h";
Expand Down
2 changes: 2 additions & 0 deletions Calendr/Assets/Generated/Strings.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ internal enum Strings {
internal enum MenuBar {
/// Date format
internal static var dateFormat: String { return Strings.tr("Localizable", "settings.menu_bar.date_format") }
/// Shorten if 'notch' is present
internal static var nextEventDetectNotch: String { return Strings.tr("Localizable", "settings.menu_bar.next_event_detect_notch") }
/// Width
internal static var nextEventLength: String { return Strings.tr("Localizable", "settings.menu_bar.next_event_length") }
/// Show date
Expand Down
1 change: 1 addition & 0 deletions Calendr/Assets/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"settings.menu_bar.date_format.info" = "In Systemeinstellungen konfigurieren";
"settings.menu_bar.show_next_event" = "Zeige nächsten Termin";
"settings.menu_bar.next_event_length" = "Breite";
"settings.menu_bar.next_event_detect_notch" = "Kürzen, wenn 'notch' vorhanden ist";

"settings.calendar" = "Kalender";
"settings.calendar.show_week_numbers" = "Zeige Kalenderwochen";
Expand Down
1 change: 1 addition & 0 deletions Calendr/Assets/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"settings.menu_bar.date_format.info" = "Configurable in System Preferences";
"settings.menu_bar.show_next_event" = "Show next event";
"settings.menu_bar.next_event_length" = "Width";
"settings.menu_bar.next_event_detect_notch" = "Shorten if 'notch' is present";

"settings.calendar" = "Calendar";
"settings.calendar.show_week_numbers" = "Show week numbers";
Expand Down
1 change: 1 addition & 0 deletions Calendr/Assets/es.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"settings.menu_bar.date_format.info" = "Configurable en Preferencias del Sistema";
"settings.menu_bar.show_next_event" = "Mostrar próximo evento";
"settings.menu_bar.next_event_length" = "Ancho";
"settings.menu_bar.next_event_detect_notch" = "Acortar si 'notch' está presente";

"settings.calendar" = "Calendario";
"settings.calendar.show_week_numbers" = "Mostrar número de semana";
Expand Down
1 change: 1 addition & 0 deletions Calendr/Assets/fr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"settings.menu_bar.date_format.info" = "Configurable dans les Préférences Système";
"settings.menu_bar.show_next_event" = "Afficher prochain événement";
"settings.menu_bar.next_event_length" = "Largeur";
"settings.menu_bar.next_event_detect_notch" = "Raccourcir si 'notch' est présent";

"settings.calendar" = "Calendrier";
"settings.calendar.show_week_numbers" = "Afficher les numéros des semaines";
Expand Down
1 change: 1 addition & 0 deletions Calendr/Assets/pt.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"settings.menu_bar.date_format.info" = "Configurável nas Preferências do Sistema";
"settings.menu_bar.show_next_event" = "Mostrar próximo evento";
"settings.menu_bar.next_event_length" = "Largura";
"settings.menu_bar.next_event_detect_notch" = "Encurtar se 'notch' estiver presente";

"settings.calendar" = "Calendário";
"settings.calendar.show_week_numbers" = "Mostrar números das semanas";
Expand Down
1 change: 1 addition & 0 deletions Calendr/Main/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
workspace: WorkspaceServiceProvider(),
calendarService: CalendarServiceProvider(),
dateProvider: DateProvider(calendar: .autoupdatingCurrent),
screenProvider: ScreenProvider(),
userDefaults: .standard,
notificationCenter: .default
)
Expand Down
4 changes: 3 additions & 1 deletion Calendr/Main/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class MainViewController: NSViewController {
workspace: WorkspaceServiceProviding,
calendarService: CalendarServiceProviding,
dateProvider: DateProviding,
screenProvider: ScreenProviding,
userDefaults: UserDefaults,
notificationCenter: NotificationCenter
) {
Expand Down Expand Up @@ -147,7 +148,8 @@ class MainViewController: NSViewController {
nextEventViewModel = NextEventViewModel(
settings: settingsViewModel,
eventsObservable: todayEventsObservable,
dateProvider: dateProvider
dateProvider: dateProvider,
screenProvider: screenProvider
)

nextEventView = NextEventView(viewModel: nextEventViewModel)
Expand Down
1 change: 1 addition & 0 deletions Calendr/Main/MockMainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class MockMainViewController: MainViewController {
workspace: WorkspaceServiceProvider(),
calendarService: MockCalendarServiceProvider(dateProvider: dateProvider),
dateProvider: dateProvider,
screenProvider: ScreenProvider(),
userDefaults: userDefaults,
notificationCenter: NotificationCenter()
)
Expand Down
13 changes: 12 additions & 1 deletion Calendr/MenuBar/NextEventView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Cocoa
import RxSwift

class NextEventView: NSView {
class NextEventView: NSView, NSWindowDelegate {

private let disposeBag = DisposeBag()

Expand Down Expand Up @@ -39,6 +39,17 @@ class NextEventView: NSView {
setUpBindings()
}

override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()

window?.delegate = self
}

func windowDidChangeScreen(_ notification: Notification) {

viewModel.didChangeScreen()
}

private func configureLayout() {

nextEventView.spacing = 4
Expand Down
38 changes: 29 additions & 9 deletions Calendr/MenuBar/NextEventViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,20 @@ class NextEventViewModel {
let hasEvent: Observable<Bool>
let event: Observable<EventModel?>

private let screenProvider: ScreenProviding
private let hasNotch: BehaviorSubject<Bool>

init(
settings: NextEventSettings,
eventsObservable: Observable<[EventModel]>,
dateProvider: DateProviding,
screenProvider: ScreenProviding,
scheduler: SchedulerType = MainScheduler.instance
) {

self.screenProvider = screenProvider
hasNotch = .init(value: screenProvider.hasNotch)

typealias NextEventTuple = (event: EventModel, isInProgress: Bool)

let nextEventObservable = Observable.combineLatest(settings.showEventStatusItem, eventsObservable)
Expand Down Expand Up @@ -63,15 +70,21 @@ class NextEventViewModel {
.skipNil()
.map { $0.isInProgress ? $0.event.calendar.color.withAlphaComponent(0.2): .clear }
.distinctUntilChanged()

title = Observable.combineLatest(
nextEventObservable
.skipNil()
.map(\.event.title),
settings.eventStatusItemLength
)
.map { $0.count > $1 ? "\($0.prefix($1).trimmed)..." : $0 }
.distinctUntilChanged()

let hasNotch = Observable
.combineLatest(settings.eventStatusItemDetectNotch, hasNotch)
.map { $0 && $1 }
.distinctUntilChanged()

let eventStatusItemLength = Observable
.combineLatest(hasNotch, settings.eventStatusItemLength)
.map { $0 ? min($1, Constants.compactMaxWidth) : $1 }

let nextEventTitle = nextEventObservable.skipNil().map(\.event.title)

title = Observable.combineLatest(nextEventTitle, eventStatusItemLength, hasNotch)
.map { $0.count > $1 ? "\($0.prefix($1).trimmed)\($2 ? "." : "...")": $0 }
.distinctUntilChanged()

let dateFormatter = DateComponentsFormatter()
dateFormatter.calendar = dateProvider.calendar
Expand Down Expand Up @@ -121,4 +134,11 @@ class NextEventViewModel {
.map(\.isNotNil)
.distinctUntilChanged()
}

func didChangeScreen() { hasNotch.onNext(screenProvider.hasNotch) }
}

private enum Constants {

static let compactMaxWidth = 15
}
19 changes: 19 additions & 0 deletions Calendr/Providers/ScreenProvider.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// ScreenProvider.swift
// Calendr
//
// Created by Paker on 09/04/22.
//

import AppKit.NSScreen

protocol ScreenProviding {
var hasNotch: Bool { get }
}

class ScreenProvider: ScreenProviding {
var hasNotch: Bool {
guard #available(macOS 12, *) else { return false }
return NSScreen.main?.auxiliaryTopRightArea != nil
}
}
16 changes: 15 additions & 1 deletion Calendr/Settings/GeneralSettingsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class GeneralSettingsViewController: NSViewController {
private let showMenuBarIconCheckbox = Checkbox(title: Strings.Settings.MenuBar.showIcon)
private let showMenuBarDateCheckbox = Checkbox(title: Strings.Settings.MenuBar.showDate)
private let showNextEventCheckbox = Checkbox(title: Strings.Settings.MenuBar.showNextEvent)
private let nextEventDetectNotchCheckbox = Checkbox(title: Strings.Settings.MenuBar.nextEventDetectNotch)
private let showWeekNumbersCheckbox = Checkbox(title: Strings.Settings.Calendar.showWeekNumbers)
private let fadePastEventsRadio = Radio(title: Strings.Settings.Events.Finished.fade)
private let hidePastEventsRadio = Radio(title: Strings.Settings.Events.Finished.hide)
Expand Down Expand Up @@ -70,12 +71,19 @@ class GeneralSettingsViewController: NSViewController {
nextEventLengthSlider
])

if #available(macOS 12, *) {
nextEventDetectNotchCheckbox.font = .systemFont(ofSize: 11, weight: .light)
} else {
nextEventDetectNotchCheckbox.isHidden = true
}

let checkboxes = NSStackView(views: [
NSStackView(views: [
showMenuBarIconCheckbox, showMenuBarDateCheckbox
]),
showNextEventCheckbox,
nextEventLengthView
nextEventLengthView,
nextEventDetectNotchCheckbox
])
.with(orientation: .vertical)

Expand Down Expand Up @@ -161,6 +169,12 @@ class GeneralSettingsViewController: NSViewController {
.bind(to: nextEventLengthSlider.rx.integerValue)
.disposed(by: disposeBag)

bind(
control: nextEventDetectNotchCheckbox,
observable: viewModel.eventStatusItemDetectNotch,
observer: viewModel.toggleEventStatusItemDetectNotch
)

nextEventLengthSlider.rx.value
.skip(1)
.map(Int.init)
Expand Down
1 change: 1 addition & 0 deletions Calendr/Settings/Prefs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ enum Prefs {
static let statusItemDateStyle = "status_item_date_style"
static let showEventStatusItem = "show_event_status_item"
static let eventStatusItemLength = "event_status_item_length"
static let eventStatusItemDetectNotch = "event_status_item_detect_notch"
static let showWeekNumbers = "show_week_numbers"
static let showPastEvents = "show_past_events"
static let transparencyLevel = "transparency_level"
Expand Down
14 changes: 14 additions & 0 deletions Calendr/Settings/SettingsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ protocol EventListSettings: PopoverSettings {
protocol NextEventSettings {
var showEventStatusItem: Observable<Bool> { get }
var eventStatusItemLength: Observable<Int> { get }
var eventStatusItemDetectNotch: Observable<Bool> { get }
}

class SettingsViewModel: StatusItemSettings, NextEventSettings, CalendarSettings, EventListSettings {
Expand All @@ -43,6 +44,7 @@ class SettingsViewModel: StatusItemSettings, NextEventSettings, CalendarSettings
let statusItemDateStyleObserver: AnyObserver<DateStyle>
let toggleEventStatusItem: AnyObserver<Bool>
let eventStatusItemLengthObserver: AnyObserver<Int>
let toggleEventStatusItemDetectNotch: AnyObserver<Bool>
let toggleWeekNumbers: AnyObserver<Bool>
let togglePastEvents: AnyObserver<Bool>
let transparencyObserver: AnyObserver<Int>
Expand All @@ -54,6 +56,7 @@ class SettingsViewModel: StatusItemSettings, NextEventSettings, CalendarSettings
var statusItemDateStyle: Observable<DateStyle>
let showEventStatusItem: Observable<Bool>
let eventStatusItemLength: Observable<Int>
let eventStatusItemDetectNotch: Observable<Bool>
let showWeekNumbers: Observable<Bool>
let showPastEvents: Observable<Bool>
let popoverTransparency: Observable<Int>
Expand All @@ -74,6 +77,7 @@ class SettingsViewModel: StatusItemSettings, NextEventSettings, CalendarSettings
Prefs.statusItemDateStyle: 1,
Prefs.showEventStatusItem: false,
Prefs.eventStatusItemLength: 18,
Prefs.eventStatusItemDetectNotch: false,
Prefs.showWeekNumbers: false,
Prefs.showPastEvents: true,
Prefs.transparencyLevel: 2,
Expand All @@ -95,6 +99,9 @@ class SettingsViewModel: StatusItemSettings, NextEventSettings, CalendarSettings
let eventStatusItemLengthBehavior = BehaviorSubject(
value: userDefaults.integer(forKey: Prefs.eventStatusItemLength)
)
let eventStatusItemDetectNotchBehavior = BehaviorSubject(
value: userDefaults.bool(forKey: Prefs.eventStatusItemDetectNotch)
)
let showWeekNumbersBehavior = BehaviorSubject(
value: userDefaults.bool(forKey: Prefs.showWeekNumbers)
)
Expand All @@ -113,6 +120,7 @@ class SettingsViewModel: StatusItemSettings, NextEventSettings, CalendarSettings
statusItemDateStyleObserver = statusItemDateStyleBehavior.asObserver()
toggleEventStatusItem = showEventStatusItemBehavior.asObserver()
eventStatusItemLengthObserver = eventStatusItemLengthBehavior.asObserver()
toggleEventStatusItemDetectNotch = eventStatusItemDetectNotchBehavior.asObserver()
toggleWeekNumbers = showWeekNumbersBehavior.asObserver()
togglePastEvents = showPastEventsBehavior.asObserver()
transparencyObserver = transparencyBehavior.asObserver()
Expand Down Expand Up @@ -155,6 +163,12 @@ class SettingsViewModel: StatusItemSettings, NextEventSettings, CalendarSettings
})
.share(replay: 1)

eventStatusItemDetectNotch = eventStatusItemDetectNotchBehavior
.do(onNext: {
userDefaults.setValue($0, forKey: Prefs.eventStatusItemDetectNotch)
})
.share(replay: 1)

showWeekNumbers = showWeekNumbersBehavior
.do(onNext: {
userDefaults.setValue($0, forKey: Prefs.showWeekNumbers)
Expand Down
4 changes: 4 additions & 0 deletions CalendrTests/Mocks/MockNextEventSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ class MockNextEventSettings: NextEventSettings {
var eventStatusItemLengthObserver: AnyObserver<Int>
var eventStatusItemLength: Observable<Int>

var toggleEventStatusItemDetectNotch: AnyObserver<Bool>
var eventStatusItemDetectNotch: Observable<Bool>

init() {
(showEventStatusItem, toggleStatusItem) = BehaviorSubject.pipe(value: true)
(eventStatusItemLength, eventStatusItemLengthObserver) = BehaviorSubject.pipe(value: 18)
(eventStatusItemDetectNotch, toggleEventStatusItemDetectNotch) = BehaviorSubject.pipe(value: false)
}
}
Loading

0 comments on commit d957620

Please sign in to comment.