From 98ffebd7ae7622c7223a7f9919f59cf23c8902fa Mon Sep 17 00:00:00 2001 From: Jens Goldhammer Date: Sun, 12 Mar 2023 21:42:04 +0100 Subject: [PATCH] feat(events): allow to hide tentative events #515 - allows to show, hide or mark tentative events as inactive. Tentative events are maybe events where the recipient do not know if he will attend. --- .gitignore | 1 + MeetingBar/AppDelegate.swift | 1 + MeetingBar/Constants.swift | 7 ++++++ MeetingBar/EventStores/Event.swift | 15 +++++++++++ MeetingBar/Extensions/DefaultsKeys.swift | 4 +++ .../en.lproj/Localizable.strings | 1 + MeetingBar/StatusBarItemController.swift | 25 +++++++++++++++++++ .../Views/Preferences/AppearanceTab.swift | 20 +++++++++++---- 8 files changed, 69 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index c04d923d..501f24bd 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ MeetingBar.xcodeproj/xcuserdata/* MeetingBar.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/* Archive/* +build diff --git a/MeetingBar/AppDelegate.swift b/MeetingBar/AppDelegate.swift index 04a2a752..699a0ed0 100644 --- a/MeetingBar/AppDelegate.swift +++ b/MeetingBar/AppDelegate.swift @@ -124,6 +124,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele keys: .selectedCalendarIDs, .showEventsForPeriod, .disablePastEvents, .pastEventsAppereance, .declinedEventsAppereance, .showPendingEvents, + .showTentativeEvents, .allDayEvents, .nonAllDayEvents, .customRegexes, .personalEventsAppereance, .showEventsForPeriod, options: [] diff --git a/MeetingBar/Constants.swift b/MeetingBar/Constants.swift index e43ec026..36f5d955 100644 --- a/MeetingBar/Constants.swift +++ b/MeetingBar/Constants.swift @@ -84,6 +84,13 @@ enum PendingEventsAppereance: String, Codable, CaseIterable { case hide } +enum TentativeEventsAppereance: String, Codable, CaseIterable { + case show + case show_inactive + case show_underlined + case hide +} + enum PastEventsAppereance: String, Codable, CaseIterable { case show_active case show_inactive diff --git a/MeetingBar/EventStores/Event.swift b/MeetingBar/EventStores/Event.swift index 9e9e26f4..cdbff977 100644 --- a/MeetingBar/EventStores/Event.swift +++ b/MeetingBar/EventStores/Event.swift @@ -207,6 +207,16 @@ func filterEvents(_ events: [MBEvent]) -> [MBEvent] { continue // Skip this event } } + + // Filter tentative events + switch Defaults[.showTentativeEvents] { + case .show, .show_inactive, .show_underlined: + break + case .hide: + if calendarEvent.participationStatus == .tentative { + continue // Skip this event + } + } filteredCalendarEvents.append(calendarEvent) } @@ -261,6 +271,11 @@ func getNextEvent(events: [MBEvent]) -> MBEvent? { if event.participationStatus == .pending, Defaults[.showPendingEvents] == .hide || Defaults[.showPendingEvents] == .show_inactive { continue } + + // Skip event if pending events should be skipped + if event.participationStatus == .tentative, Defaults[.showTentativeEvents] == .hide || Defaults[.showTentativeEvents] == .show_inactive { + continue + } // Skip event if canceled if event.status == .canceled { diff --git a/MeetingBar/Extensions/DefaultsKeys.swift b/MeetingBar/Extensions/DefaultsKeys.swift index b3b485ca..8e221253 100644 --- a/MeetingBar/Extensions/DefaultsKeys.swift +++ b/MeetingBar/Extensions/DefaultsKeys.swift @@ -60,6 +60,10 @@ extension Defaults.Keys { // appearance of pending events should be shown in the statusbar and menu static let showPendingEvents = Key("showPendingEvents", default: PendingEventsAppereance.show) + // appearance of tentative events + static let showTentativeEvents = Key("showTentativeEvents", default: TentativeEventsAppereance.show) + + static let timeFormat = Key("timeFormat", default: .military) // Bookmarks diff --git a/MeetingBar/Resources /Localization /en.lproj/Localizable.strings b/MeetingBar/Resources /Localization /en.lproj/Localizable.strings index aa27f225..fb4b3103 100644 --- a/MeetingBar/Resources /Localization /en.lproj/Localizable.strings +++ b/MeetingBar/Resources /Localization /en.lproj/Localizable.strings @@ -79,6 +79,7 @@ "preferences_appearance_events_past_title" = "Past events:"; "preferences_appearance_events_pending_title" = "Pending events"; "preferences_appearance_events_declined_title" = "Declined events:"; +"preferences_appearance_events_tentative_title" = "Tentative events:"; "preferences_appearance_events_value_show" = "show"; "preferences_appearance_events_value_hide" = "hide"; "preferences_appearance_events_value_as_inactive" = "show as inactive"; diff --git a/MeetingBar/StatusBarItemController.swift b/MeetingBar/StatusBarItemController.swift index 9052dcf9..e99ab575 100644 --- a/MeetingBar/StatusBarItemController.swift +++ b/MeetingBar/StatusBarItemController.swift @@ -210,6 +210,10 @@ class StatusBarItemController { if nextEvent.participationStatus == .pending, Defaults[.showPendingEvents] == PendingEventsAppereance.show_underlined { styles[NSAttributedString.Key.underlineStyle] = NSUnderlineStyle.single.rawValue | NSUnderlineStyle.patternDot.rawValue | NSUnderlineStyle.byWord.rawValue } + + if nextEvent.participationStatus == .tentative, Defaults[.showTentativeEvents] == TentativeEventsAppereance.show_underlined { + styles[NSAttributedString.Key.underlineStyle] = NSUnderlineStyle.single.rawValue | NSUnderlineStyle.patternDot.rawValue | NSUnderlineStyle.byWord.rawValue + } menuTitle.append(NSAttributedString(string: eventTitle, attributes: styles)) } else { @@ -226,6 +230,12 @@ class StatusBarItemController { } else if nextEvent.participationStatus == .pending, Defaults[.showPendingEvents] == PendingEventsAppereance.show_underlined { styles[NSAttributedString.Key.underlineStyle] = NSUnderlineStyle.single.rawValue | NSUnderlineStyle.patternDot.rawValue | NSUnderlineStyle.byWord.rawValue } + + if nextEvent.participationStatus == .tentative, Defaults[.showTentativeEvents] == TentativeEventsAppereance.show_inactive { + styles[NSAttributedString.Key.foregroundColor] = NSColor.disabledControlTextColor + } else if nextEvent.participationStatus == .tentative, Defaults[.showTentativeEvents] == TentativeEventsAppereance.show_underlined { + styles[NSAttributedString.Key.underlineStyle] = NSUnderlineStyle.single.rawValue | NSUnderlineStyle.patternDot.rawValue | NSUnderlineStyle.byWord.rawValue + } menuTitle.append(NSAttributedString(string: title, attributes: styles)) @@ -434,6 +444,14 @@ class StatusBarItemController { styles[NSAttributedString.Key.underlineStyle] = NSUnderlineStyle.single.rawValue | NSUnderlineStyle.patternDot.rawValue | NSUnderlineStyle.byWord.rawValue } } + + if event.participationStatus == .tentative { + if Defaults[.showTentativeEvents] == TentativeEventsAppereance.show_inactive { + styles[NSAttributedString.Key.foregroundColor] = NSColor.disabledControlTextColor + } else if Defaults[.showTentativeEvents] == TentativeEventsAppereance.show_underlined { + styles[NSAttributedString.Key.underlineStyle] = NSUnderlineStyle.single.rawValue | NSUnderlineStyle.patternDot.rawValue | NSUnderlineStyle.byWord.rawValue + } + } if event.attendees.isEmpty, Defaults[.personalEventsAppereance] == .show_inactive { styles[NSAttributedString.Key.foregroundColor] = NSColor.disabledControlTextColor @@ -467,6 +485,13 @@ class StatusBarItemController { } else { styles[NSAttributedString.Key.font] = NSFont.systemFont(ofSize: 14) } + + if shouldShowAsActive, Defaults[.showTentativeEvents] != TentativeEventsAppereance.show_underlined { + // add the NSTextAttachment wrapper to our full string, then add some more text. + styles[NSAttributedString.Key.font] = NSFont.boldSystemFont(ofSize: 14) + } else { + styles[NSAttributedString.Key.font] = NSFont.systemFont(ofSize: 14) + } eventTitle.append(NSAttributedString(string: itemTitle, attributes: styles)) diff --git a/MeetingBar/Views/Preferences/AppearanceTab.swift b/MeetingBar/Views/Preferences/AppearanceTab.swift index 378c2e5c..8605ea0d 100644 --- a/MeetingBar/Views/Preferences/AppearanceTab.swift +++ b/MeetingBar/Views/Preferences/AppearanceTab.swift @@ -140,6 +140,7 @@ struct EventsSection: View { @Default(.allDayEvents) var allDayEvents @Default(.nonAllDayEvents) var nonAllDayEvents @Default(.showPendingEvents) var showPendingEvents + @Default(.showTentativeEvents) var showTentativeEvents @Default(.showEventsForPeriod) var showEventsForPeriod var body: some View { @@ -149,7 +150,13 @@ struct EventsSection: View { Picker("preferences_appearance_events_show_events_for_title".loco(), selection: $showEventsForPeriod) { Text("preferences_appearance_events_show_events_for_today_value".loco()).tag(ShowEventsForPeriod.today) Text("preferences_appearance_events_show_events_for_today_tomorrow_value".loco()).tag(ShowEventsForPeriod.today_n_tomorrow) - }.frame(width: 300) + } + + Picker("preferences_appearance_events_past_title".loco(), selection: $pastEventsAppereance) { + Text("preferences_appearance_events_value_show".loco()).tag(PastEventsAppereance.show_active) + Text("preferences_appearance_events_value_as_inactive".loco()).tag(PastEventsAppereance.show_inactive) + Text("preferences_appearance_events_value_hide".loco()).tag(PastEventsAppereance.hide) + } } HStack { @@ -172,11 +179,14 @@ struct EventsSection: View { Text("preferences_appearance_events_value_as_inactive".loco()).tag(PastEventsAppereance.show_inactive) Text("preferences_appearance_events_value_hide".loco()).tag(PastEventsAppereance.hide) } - Picker("preferences_appearance_events_past_title".loco(), selection: $pastEventsAppereance) { - Text("preferences_appearance_events_value_show".loco()).tag(PastEventsAppereance.show_active) - Text("preferences_appearance_events_value_as_inactive".loco()).tag(PastEventsAppereance.show_inactive) - Text("preferences_appearance_events_value_hide".loco()).tag(PastEventsAppereance.hide) + + Picker("preferences_appearance_events_tentative_title".loco(), selection: $showTentativeEvents) { + Text("preferences_appearance_events_value_show".loco()).tag(TentativeEventsAppereance.show) + Text("preferences_appearance_events_value_as_underlined".loco()).tag(TentativeEventsAppereance.show_underlined) + Text("preferences_appearance_events_value_as_inactive".loco()).tag(TentativeEventsAppereance.show_inactive) + Text("preferences_appearance_events_value_hide".loco()).tag(TentativeEventsAppereance.hide) } + } HStack { Picker("preferences_appearance_events_pending_title".loco(), selection: $showPendingEvents) {