Skip to content

Commit

Permalink
Add option to choose the native calendar view mode
Browse files Browse the repository at this point in the history
  • Loading branch information
pakerwreah committed Oct 13, 2024
1 parent 83869ff commit 9de7fa0
Show file tree
Hide file tree
Showing 19 changed files with 142 additions and 20 deletions.
8 changes: 8 additions & 0 deletions Calendr/Assets/Strings.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,14 @@ internal enum Strings {
internal static let transparency = Strings.tr("Localizable", "settings.appearance.transparency", fallback: "Transparency")
}
internal enum Calendar {
/// Calendar app view mode
internal static let calendarAppViewMode = Strings.tr("Localizable", "settings.calendar.calendar_app_view_mode", fallback: "Calendar app view mode")
/// Hold ⌥ to peek at hovered dates
internal static let dateHoverOption = Strings.tr("Localizable", "settings.calendar.date_hover_option", fallback: "Hold ⌥ to peek at hovered dates")
/// day
internal static let day = Strings.tr("Localizable", "settings.calendar.day", fallback: "day")
/// month
internal static let month = Strings.tr("Localizable", "settings.calendar.month", fallback: "month")
/// Preserve selected date on hide
internal static let preserveSelectedDate = Strings.tr("Localizable", "settings.calendar.preserve_selected_date", fallback: "Preserve selected date on hide")
/// Show declined events
Expand All @@ -149,6 +155,8 @@ internal enum Strings {
internal static let showDeclinedEventsTooltip = Strings.tr("Localizable", "settings.calendar.show_declined_events_tooltip", fallback: "This only works if it is also enabled in the native Calendar app.")
/// Show week numbers
internal static let showWeekNumbers = Strings.tr("Localizable", "settings.calendar.show_week_numbers", fallback: "Show week numbers")
/// week
internal static let week = Strings.tr("Localizable", "settings.calendar.week", fallback: "week")
}
internal enum Events {
/// Show finished events
Expand Down
4 changes: 4 additions & 0 deletions Calendr/Assets/cs.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
"settings.calendar.show_declined_events" = "Zobrazit odmítnuté události";
"settings.calendar.show_declined_events_tooltip" = "Funguje pouze tehdy, pokud je také zapnuto v nativní aplikaci Kalendář.";
//"settings.calendar.date_hover_option" = "Hold ⌥ to peek at hovered dates";
//"settings.calendar.calendar_app_view_mode" = "Calendar app view mode";
//"settings.calendar.month" = "month";
//"settings.calendar.week" = "week";
//"settings.calendar.day" = "day";

"settings.events" = "Události";
//"settings.events.show_map" = "Show map and weather";
Expand Down
4 changes: 4 additions & 0 deletions Calendr/Assets/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
"settings.calendar.show_declined_events" = "Abgelehnte Ereignisse anzeigen";
"settings.calendar.show_declined_events_tooltip" = "Dies funktioniert nur, wenn es auch in der nativen Kalender-App aktiviert ist.";
//"settings.calendar.date_hover_option" = "Hold ⌥ to peek at hovered dates";
//"settings.calendar.calendar_app_view_mode" = "Calendar app view mode";
//"settings.calendar.month" = "month";
//"settings.calendar.week" = "week";
//"settings.calendar.day" = "day";

"settings.events" = "Termine";
"settings.events.show_map" = "Karte und Wetter anzeigen";
Expand Down
4 changes: 4 additions & 0 deletions Calendr/Assets/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
"settings.calendar.show_declined_events" = "Show declined events";
"settings.calendar.show_declined_events_tooltip" = "This only works if it is also enabled in the native Calendar app.";
"settings.calendar.date_hover_option" = "Hold ⌥ to peek at hovered dates";
"settings.calendar.calendar_app_view_mode" = "Calendar app view mode";
"settings.calendar.month" = "month";
"settings.calendar.week" = "week";
"settings.calendar.day" = "day";

"settings.events" = "Events";
"settings.events.show_map" = "Show map and weather";
Expand Down
4 changes: 4 additions & 0 deletions Calendr/Assets/es.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
"settings.calendar.show_declined_events" = "Mostrar eventos rechazados";
"settings.calendar.show_declined_events_tooltip" = "Esto solo funciona si también está habilitado en la aplicación Calendario nativa.";
//"settings.calendar.date_hover_option" = "Hold ⌥ to peek at hovered dates";
//"settings.calendar.calendar_app_view_mode" = "Calendar app view mode";
//"settings.calendar.month" = "month";
//"settings.calendar.week" = "week";
//"settings.calendar.day" = "day";

"settings.events" = "Eventos";
"settings.events.show_map" = "Mostrar mapa y clima";
Expand Down
4 changes: 4 additions & 0 deletions Calendr/Assets/fr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
"settings.calendar.show_declined_events" = "Afficher les événements refusés";
"settings.calendar.show_declined_events_tooltip" = "Cela ne fonctionne que s'il est également activé dans l'application Calendrier native.";
//"settings.calendar.date_hover_option" = "Hold ⌥ to peek at hovered dates";
//"settings.calendar.calendar_app_view_mode" = "Calendar app view mode";
//"settings.calendar.month" = "month";
//"settings.calendar.week" = "week";
//"settings.calendar.day" = "day";

"settings.events" = "Événements";
"settings.events.show_map" = "Afficher la carte et la météo";
Expand Down
4 changes: 4 additions & 0 deletions Calendr/Assets/it.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
"settings.calendar.show_declined_events" = "Mostra eventi rifiutati";
"settings.calendar.show_declined_events_tooltip" = "Funziona solo se è abilitato anche nell'app Calendario nativa.";
//"settings.calendar.date_hover_option" = "Hold ⌥ to peek at hovered dates";
//"settings.calendar.calendar_app_view_mode" = "Calendar app view mode";
//"settings.calendar.month" = "month";
//"settings.calendar.week" = "week";
//"settings.calendar.day" = "day";

"settings.events" = "Eventi";
"settings.events.show_map" = "Mostra mappa e meteo";
Expand Down
4 changes: 4 additions & 0 deletions Calendr/Assets/pt.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
"settings.calendar.show_declined_events" = "Mostrar eventos recusados";
"settings.calendar.show_declined_events_tooltip" = "Isso só funciona se também estiver ativado no aplicativo Calendário nativo.";
"settings.calendar.date_hover_option" = "Segure ⌥ para espiar datas sob o cursor";
//"settings.calendar.calendar_app_view_mode" = "Calendar app view mode";
//"settings.calendar.month" = "month";
//"settings.calendar.week" = "week";
//"settings.calendar.day" = "day";

"settings.events" = "Eventos";
"settings.events.show_map" = "Mostrar mapa e clima";
Expand Down
4 changes: 4 additions & 0 deletions Calendr/Assets/sk.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
"settings.calendar.show_declined_events" = "Zobraziť odmietnuté udalosti";
"settings.calendar.show_declined_events_tooltip" = "Funguje, len ak je to povolené aj v natívnej aplikácii Kalendár.";
//"settings.calendar.date_hover_option" = "Hold ⌥ to peek at hovered dates";
//"settings.calendar.calendar_app_view_mode" = "Calendar app view mode";
//"settings.calendar.month" = "month";
//"settings.calendar.week" = "week";
//"settings.calendar.day" = "day";

"settings.events" = "Udalosti";
"settings.events.show_map" = "Zobraziť mapu a počasie";
Expand Down
4 changes: 4 additions & 0 deletions Calendr/Assets/sv.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
"settings.calendar.show_declined_events" = "Visa avböjda händelser";
"settings.calendar.show_declined_events_tooltip" = "Detta fungerar bara om det också är aktiverat i den inbyggda kalenderappen.";
//"settings.calendar.date_hover_option" = "Hold ⌥ to peek at hovered dates";
//"settings.calendar.calendar_app_view_mode" = "Calendar app view mode";
//"settings.calendar.month" = "month";
//"settings.calendar.week" = "week";
//"settings.calendar.day" = "day";

"settings.events" = "Händelser";
//"settings.events.show_map" = "Show map and weather";
Expand Down
4 changes: 4 additions & 0 deletions Calendr/Assets/zh-Hans.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
"settings.calendar.show_declined_events" = "显示拒绝的日程";
"settings.calendar.show_declined_events_tooltip" = "此功能需在原生日历应用中同样启用。";
//"settings.calendar.date_hover_option" = "Hold ⌥ to peek at hovered dates";
//"settings.calendar.calendar_app_view_mode" = "Calendar app view mode";
//"settings.calendar.month" = "month";
//"settings.calendar.week" = "week";
//"settings.calendar.day" = "day";

"settings.events" = "日程";
//"settings.events.show_map" = "Show map and weather";
Expand Down
7 changes: 1 addition & 6 deletions Calendr/Automation/CalendarScript.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,13 @@ class CalendarScript {
self.workspace = workspace
}

enum CalendarViewMode: String {
case day
case month
}

func openCalendar(at date: Date, mode: CalendarViewMode) {
Task {
do {
try await runScript("""
tell application "Calendar"
switch view to \(mode) view
view calendar at date ("\(formatter.string(from: date))")
switch view to \(mode) view
activate
end tell
""")
Expand Down
12 changes: 9 additions & 3 deletions Calendr/Main/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,15 @@ class MainViewController: NSViewController {
.disposed(by: disposeBag)

calendarBtn.rx.tap
.withLatestFrom(selectedDate)
.bind { date in
calendarScript.openCalendar(at: date, mode: .month)
.withLatestFrom(
Observable.combineLatest(selectedDate, settingsViewModel.calendarAppViewMode)
)
.bind { [dateProvider] date, mode in
var date = date
if mode == .week, let week = dateProvider.calendar.dateInterval(of: .weekOfYear, for: date) {
date = week.start
}
calendarScript.openCalendar(at: date, mode: mode)
}
.disposed(by: disposeBag)

Expand Down
2 changes: 2 additions & 0 deletions Calendr/Mocks/MockCalendarSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class MockCalendarSettings: CalendarSettings {
let showDeclinedEvents: Observable<Bool>
let preserveSelectedDate: Observable<Bool>
let dateHoverOption: Observable<Bool>
let calendarAppViewMode: Observable<CalendarViewMode>

init(
calendarScaling: Double = 1,
Expand All @@ -38,6 +39,7 @@ class MockCalendarSettings: CalendarSettings {
self.preserveSelectedDate = .just(false)
self.showDeclinedEvents = .just(false)
self.dateHoverOption = .just(false)
self.calendarAppViewMode = .just(.month)
}
}

Expand Down
33 changes: 32 additions & 1 deletion Calendr/Settings/GeneralSettingsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class GeneralSettingsViewController: NSViewController, SettingsUI {
private let showDeclinedEventsCheckbox = Checkbox(title: Strings.Settings.Calendar.showDeclinedEvents)
private let preserveSelectedDateCheckbox = Checkbox(title: Strings.Settings.Calendar.preserveSelectedDate)
private let dateHoverOptionCheckbox = Checkbox(title: Strings.Settings.Calendar.dateHoverOption)
private let calendarAppViewModeLabel = Label(text: Strings.Settings.Calendar.calendarAppViewMode)
private let calendarAppViewModeDropdown = Dropdown()

// Events
private let showMapCheckbox = Checkbox(title: Strings.Settings.Events.showMap)
Expand Down Expand Up @@ -203,14 +205,19 @@ class GeneralSettingsViewController: NSViewController, SettingsUI {
firstWeekdayPrev.setContentHuggingPriority(.fittingSizeCompression, for: .horizontal)
firstWeekdayNext.setContentHuggingPriority(.fittingSizeCompression, for: .horizontal)

calendarAppViewModeDropdown.isBordered = false
calendarAppViewModeDropdown.setContentHuggingPriority(.required, for: .horizontal)

return NSStackView(views: [
NSStackView(views: [firstWeekdayPrev, highlightedWeekdaysButtons, firstWeekdayNext])
.with(distribution: .fillProportionally),
.dummy,
showWeekNumbersCheckbox,
NSStackView(views: [showDeclinedEventsCheckbox, showDeclinedEventsTooltip]),
preserveSelectedDateCheckbox,
dateHoverOptionCheckbox
dateHoverOptionCheckbox,
.dummy,
NSStackView(views: [calendarAppViewModeLabel, calendarAppViewModeDropdown])
])
.with(orientation: .vertical)
}()
Expand Down Expand Up @@ -270,6 +277,8 @@ class GeneralSettingsViewController: NSViewController, SettingsUI {
setUpIconStyle()

setUpDateFormat()

setUpCalendarAppViewMode()
}

private func setUpIconStyle() {
Expand Down Expand Up @@ -372,6 +381,28 @@ class GeneralSettingsViewController: NSViewController, SettingsUI {
.disposed(by: disposeBag)
}

private func setUpCalendarAppViewMode() {

let calendarAppViewModeControl = calendarAppViewModeDropdown.rx.controlProperty(
getter: \.indexOfSelectedItem,
setter: { $0.selectItem(at: $1) }
)

let options = viewModel.calendarAppViewModeOptions
calendarAppViewModeDropdown.addItems(withTitles: options.map { "\($0.title) " })

calendarAppViewModeControl
.skip(1)
.map { options[$0].mode }
.bind(to: viewModel.calendarAppViewModeObserver)
.disposed(by: disposeBag)

viewModel.calendarAppViewMode
.compactMap(options.map(\.mode).firstIndex(of:))
.bind(to: calendarAppViewModeControl)
.disposed(by: disposeBag)
}

private func setUpCalendar() {

setUpfirstWeekday()
Expand Down
7 changes: 7 additions & 0 deletions Calendr/Settings/Prefs+UserDefaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ enum Prefs {
static let showDeclinedEvents = "show_declined_events"
static let preserveSelectedDate = "preserve_selected_date"
static let dateHoverOption = "date_hover_option"
static let calendarAppViewMode = "calendar_app_view_mode"

// Event Details
static let showMap = "show_map"
Expand Down Expand Up @@ -83,6 +84,7 @@ func registerDefaultPrefs(in userDefaults: UserDefaults, calendar: Calendar = .c
Prefs.showDeclinedEvents: false,
Prefs.preserveSelectedDate: false,
Prefs.dateHoverOption: false,
Prefs.calendarAppViewMode: CalendarViewMode.month.rawValue,

// Event Details
Prefs.showMap: true,
Expand Down Expand Up @@ -210,6 +212,11 @@ extension UserDefaults {
set { set(newValue, forKey: Prefs.dateHoverOption) }
}

@objc dynamic var calendarAppViewMode: String {
get { string(forKey: Prefs.calendarAppViewMode) ?? "" }
set { set(newValue, forKey: Prefs.calendarAppViewMode) }
}

// Event Details

@objc dynamic var showMap: Bool {
Expand Down
33 changes: 31 additions & 2 deletions Calendr/Settings/SettingsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ extension PopoverMaterial {
}
}

enum CalendarViewMode: String, CaseIterable {
case month
case week
case day
}

enum StatusItemIconStyle: String, CaseIterable {
case calendar
case date
Expand All @@ -57,6 +63,7 @@ protocol CalendarSettings {
var showDeclinedEvents: Observable<Bool> { get }
var preserveSelectedDate: Observable<Bool> { get }
var dateHoverOption: Observable<Bool> { get }
var calendarAppViewMode: Observable<CalendarViewMode> { get }
}

protocol AppearanceSettings {
Expand Down Expand Up @@ -101,6 +108,11 @@ class SettingsViewModel:
let title: String
}

struct CalendarViewModeOption: Equatable {
let mode: CalendarViewMode
let title: String
}

// Observers
let toggleAutoLaunch: AnyObserver<Bool>
let toggleStatusItemIcon: AnyObserver<Bool>
Expand Down Expand Up @@ -129,6 +141,7 @@ class SettingsViewModel:
let transparencyObserver: AnyObserver<Int>
let textScalingObserver: AnyObserver<Double>
let calendarTextScalingObserver: AnyObserver<Double>
let calendarAppViewModeObserver: AnyObserver<CalendarViewMode>

// Observables
let autoLaunch: Observable<Bool>
Expand Down Expand Up @@ -163,9 +176,23 @@ class SettingsViewModel:
let popoverMaterial: Observable<PopoverMaterial>
let textScaling: Observable<Double>
let calendarTextScaling: Observable<Double>
let calendarAppViewMode: Observable<CalendarViewMode>

let isPresented = BehaviorSubject(value: false)

let calendarAppViewModeOptions = CalendarViewMode.allCases.map {
let title = switch $0 {
case .month:
Strings.Settings.Calendar.month
case .week:
Strings.Settings.Calendar.week
case .day:
Strings.Settings.Calendar.day
}

return CalendarViewModeOption(mode: $0, title: title)
}

let dateFormatPlaceholder = AppConstants.defaultCustomDateFormat

private let autoLauncher: AutoLauncher
Expand Down Expand Up @@ -207,6 +234,7 @@ class SettingsViewModel:
transparencyObserver = userDefaults.rx.observer(for: \.transparencyLevel)
textScalingObserver = userDefaults.rx.observer(for: \.textScaling)
calendarTextScalingObserver = userDefaults.rx.observer(for: \.calendarTextScaling)
calendarAppViewModeObserver = userDefaults.rx.observer(for: \.calendarAppViewMode).mapObserver(\.rawValue)

// MARK: - Observables

Expand All @@ -226,8 +254,8 @@ class SettingsViewModel:
/* ----------------------- */

showStatusItemBackground = userDefaults.rx.observe(\.statusItemBackgroundEnabled)
statusItemIconStyle = userDefaults.rx.observe(\.statusItemIconStyle).map { StatusItemIconStyle(rawValue: $0) ?? .calendar }
statusItemDateStyle = userDefaults.rx.observe(\.statusItemDateStyle).map { StatusItemDateStyle(rawValue: $0) ?? .none }
statusItemIconStyle = userDefaults.rx.observe(\.statusItemIconStyle).map { .init(rawValue: $0) ?? .calendar }
statusItemDateStyle = userDefaults.rx.observe(\.statusItemDateStyle).map { .init(rawValue: $0) ?? .none }
statusItemDateFormat = userDefaults.rx.observe(\.statusItemDateFormat)
showEventStatusItem = userDefaults.rx.observe(\.showEventStatusItem)
eventStatusItemFontSize = userDefaults.rx.observe(\.eventStatusItemFontSize)
Expand All @@ -248,6 +276,7 @@ class SettingsViewModel:
popoverTransparency = userDefaults.rx.observe(\.transparencyLevel)
textScaling = userDefaults.rx.observe(\.textScaling)
calendarTextScaling = userDefaults.rx.observe(\.calendarTextScaling)
calendarAppViewMode = userDefaults.rx.observe(\.calendarAppViewMode).map { .init(rawValue: $0) ?? .month }

let localeChangeObservable = notificationCenter.rx
.notification(NSLocale.currentLocaleDidChangeNotification)
Expand Down
3 changes: 3 additions & 0 deletions CalendrTests/Mocks/MockCalendarSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class MockCalendarSettings: CalendarSettings {

let preserveSelectedDate: Observable<Bool>

let calendarAppViewMode: Observable<CalendarViewMode>

let calendarScaling: Observable<Double>
let textScaling: Observable<Double>
let calendarTextScaling: Observable<Double>
Expand All @@ -38,6 +40,7 @@ class MockCalendarSettings: CalendarSettings {
(showDeclinedEvents, toggleDeclinedEvents) = BehaviorSubject.pipe(value: false)
(dateHoverOption, toggleDateHoverOption) = BehaviorSubject.pipe(value: false)
preserveSelectedDate = .just(false)
calendarAppViewMode = .just(.month)
calendarScaling = .just(1)
textScaling = .just(1)
calendarTextScaling = .just(1)
Expand Down
Loading

0 comments on commit 9de7fa0

Please sign in to comment.