Skip to content

Meetings without a meeting links can now be displayed in fullscreen notifications #812

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ For next releases info look here: <https://github.com/leits/MeetingBar/releases>
* Fix readability of the statusbar text in multi-screen setups (#354)
* Detect hidden menubar icon (#429)
* Added feature to snooze the notification
* Meetings without a meeting links can now be displayed in fullscreen notifications. A new setting has been added to control that behaviour.
* Preferences changes:
* Added a section "Notification"
* Added a new parameter related to full screen notification that you can disable to receives notification for meetings without links (Only for meetings with a link)
* In the fullscreen notification, don't show the Meeting Link button if there is no meeting link.


* Fix crash due to meeting attendees without an email address (#460)

## Version 3.10.0
Expand Down
15 changes: 6 additions & 9 deletions MeetingBar/ActionsOnEventStart.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,12 @@
}
//

if let nextEvent = getNextEvent(events: app.statusBarItem.events, linkRequired: true) {
let now = Date()
let fullscreenNotificationMeetingLinkOnly = Defaults[.fullscreenNotificationMeetingLinkOnly]

if let nextEvent = getNextEvent(events: app.statusBarItem.events, linkRequired: fullscreenNotificationMeetingLinkOnly) {
let now = Date()
let startEndRange = nextEvent.startDate ... nextEvent.endDate

let timeInterval = nextEvent.startDate.timeIntervalSince(now)

let allDayCandidate = nextEvent.isAllDay && startEndRange.contains(now)

/*
Expand All @@ -65,9 +64,9 @@
* ------------------------
*/
let actionTimeForFullscreenNotification = Double(Defaults[.fullscreenNotificationTime].rawValue)
let nonAlldayCandidateForFullscreenNotification = (timeInterval > -15 && timeInterval < actionTimeForFullscreenNotification)
let nonAllDayCandidateForFullscreenNotification = (timeInterval > -15 && timeInterval < actionTimeForFullscreenNotification)

Check warning

Code scanning / Tailor (reported by Codacy)

Initializer expression should not be enclosed within parentheses Warning

Initializer expression should not be enclosed within parentheses

if fullscreenNotificationActive && (nonAlldayCandidateForFullscreenNotification || allDayCandidate) {
if fullscreenNotificationActive && (nonAllDayCandidateForFullscreenNotification || allDayCandidate) {
var events = Defaults[.processedEventsForFullscreenNotification]

let matchedEvent = events.first { $0.id == nextEvent.ID }
Expand All @@ -76,9 +75,7 @@
// we will remove the the current event from the scheduled events, so that we can run the script again ->
// this is an edge case when the event was already notified for, but scheduled for a later time.
if matchedEvent == nil || matchedEvent?.lastModifiedDate != nextEvent.lastModifiedDate {
if nextEvent.meetingLink != nil {
app.openFullscreenNotificationWindow(event: nextEvent)
}
app.openFullscreenNotificationWindow(event: nextEvent)

// update the executed events
if matchedEvent != nil {
Expand Down
1 change: 1 addition & 0 deletions MeetingBar/Extensions/DefaultsKeys.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extension Defaults.Keys {
static let endOfEventNotificationTime = Key<TimeBeforeEventEnd>("endOfEventNotificationTime", default: .atEnd)

static let fullscreenNotification = Key<Bool>("fullscreenNotification", default: false)
static let fullscreenNotificationMeetingLinkOnly = Key<Bool>("fullscreenNotificationMeetingLinkOnly", default: false)
static let fullscreenNotificationTime = Key<TimeBeforeEvent>("fullscreenNotificationTime", default: .atStart)
static let processedEventsForFullscreenNotification = Key<[ProcessedEvent]>("processedEventsForFullscreenNotification", default: [])

Expand Down
6 changes: 3 additions & 3 deletions MeetingBar/Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -254,17 +254,17 @@ func openLinkFromClipboard() {
}
}

func generateFakeEvent() -> MBEvent {
func generateFakeEvent(includeMeetingLink: Bool) -> MBEvent {
let calendar = MBCalendar(title: "Fake calendar", ID: "fake_cal", source: nil, email: nil, color: .black)

let event = MBEvent(
ID: "test_event",
lastModifiedDate: nil,
title: "Test event",
title: includeMeetingLink ? "Test Event (with Meeting link)" : "Test Event (without Meeting link)",
status: .confirmed,
notes: nil,
location: nil,
url: URL(string: "https://zoom.us/j/5551112222")!,
url: includeMeetingLink ? URL(string: "https://zoom.us/j/5551112222")! : nil,
organizer: nil,
startDate: Calendar.current.date(byAdding: .minute, value: 3, to: Date())!,
endDate: Calendar.current.date(byAdding: .minute, value: 33, to: Date())!,
Expand Down
2 changes: 0 additions & 2 deletions MeetingBar/MeetingBar.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.usernotifications.time-sensitive</key>
<true/>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,10 @@

// MARK: - Shared

"preferences_notifications_section_title" = "Notifications";
"shared_send_notification_toggle" = "Send a system notification";
"shared_fullscreen_notification_toggle" = "Show a fullscreen notification";
"shared_fullscreen_notification_meeting_link_only_toggle" = "Only for meetings with a link";
"shared_send_notification_no_alert_style_tip" = "⚠️ Your macOS notification settings for MeetingBar are not set to alert. Do so if you want persistent notifications.";
"shared_send_notification_disabled_tip" = "⚠️ Your macOS notification settings for MeetingBar are off. Turn on notifications in the macOS system settings to keep track of meetings.";
"shared_automatic_event_join_toggle" = "Automatically join next event meeting";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@

// MARK: - Shared

"preferences_notifications_section_title" = "Notifications";
"shared_send_notification_toggle" = "Envoyer une notification système";
"shared_fullscreen_notification_toggle" = "Affiche une notification plein écran";
"shared_fullscreen_notification_meeting_link_only_toggle" = "Uniquement pour les évènement avec des liens de réunion";
"access_screen_access_granted_click_ok_title" = "Cliquez sur « OK » dans la fenêtre popup de macOS.";
"access_screen_access_screen_access_denied_go_to_title" = "Allez dans les";
"access_screen_access_denied_checkbox_title" = "et sélectionnez une case à cocher près de MeetingBar.";
Expand Down
5 changes: 5 additions & 0 deletions MeetingBar/Views/Changelog/Changelog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ struct ChangelogView: View {
Text("🌍 Translation into Slovak and Dutch")
}
}
if compareVersions("4.10.0", lastRevisedVersionInChangelog) {
Section(header: Text("Version 4.10")) {
Text("🖥️ Meetings without a meeting links can now be displayed in fullscreen notifications.")
}
}
}
}.listStyle(SidebarListStyle())
Button("general_close".loco(), action: close)
Expand Down
21 changes: 13 additions & 8 deletions MeetingBar/Views/FullscreenNotification.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,33 @@
Rectangle.semiOpaqueWindow()
VStack {
HStack {
Image(nsImage: getIconForMeetingService(event.meetingLink?.service))
.resizable().frame(width: 25, height: 25)
if event.meetingLink != nil {
Image(nsImage: getIconForMeetingService(event.meetingLink?.service))
.resizable().frame(width: 25, height: 25)
}
Text(event.title).font(.title)
}
VStack(spacing: 10) {
Text(getEventDateString(event))
}.padding(15)

// display location of the event, very useful if you
// have a lot of meetings in a building with a lot of meeting rooms
if let location = event.location {
VStack(spacing: 10) {
Text(location)
}.padding(15)
}

HStack(spacing: 30) {
Button(action: dismiss) {
Text("general_close".loco()).padding(.vertical, 5).padding(.horizontal, 20)
}
Button(action: joinEvent) {
Text("notifications_meetingbar_join_event_action".loco()).padding(.vertical, 5).padding(.horizontal, 25)
}.background(Color.accentColor).cornerRadius(5)
if event.meetingLink != nil {
Button(action: joinEvent) {
Text("notifications_meetingbar_join_event_action".loco()).padding(.vertical, 5).padding(.horizontal, 25)
}.background(Color.accentColor).cornerRadius(5)
}
}
}
}
Expand Down Expand Up @@ -81,5 +85,6 @@
}

#Preview {
FullscreenNotification(event: generateFakeEvent(), window: nil)
FullscreenNotification(event: generateFakeEvent(includeMeetingLink: true), window: nil)

Check warning on line 88 in MeetingBar/Views/FullscreenNotification.swift

View workflow job for this annotation

GitHub Actions / Tests

result of 'FullscreenNotification' initializer is unused

Check warning on line 88 in MeetingBar/Views/FullscreenNotification.swift

View workflow job for this annotation

GitHub Actions / Tests

result of 'FullscreenNotification' initializer is unused
FullscreenNotification(event: generateFakeEvent(includeMeetingLink: false), window: nil)

Check warning on line 89 in MeetingBar/Views/FullscreenNotification.swift

View workflow job for this annotation

GitHub Actions / Tests

result of 'FullscreenNotification' initializer is unused

Check warning on line 89 in MeetingBar/Views/FullscreenNotification.swift

View workflow job for this annotation

GitHub Actions / Tests

result of 'FullscreenNotification' initializer is unused
}
38 changes: 25 additions & 13 deletions MeetingBar/Views/Preferences/GeneralTab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ struct GeneralTab: View {
Section {
LaunchAtLoginANDPreferredLanguagePicker()
Divider()
JoinEventNotificationPicker()
FullscreenNotificationPicker()
NotificationsSection()
Divider()
}
Section {
Expand All @@ -30,25 +29,38 @@ struct GeneralTab: View {
}
}

struct NotificationsSection: View {
var body: some View {
Text("preferences_notifications_section_title".loco()).font(.headline).bold()
Section {
JoinEventNotificationPicker()
FullscreenNotificationPicker()
}.padding(.leading, 30)
}
}

struct ShortcutsSection: View {
@State var showingModal = false

var body: some View {
HStack {
Text("preferences_general_shortcut_create_meeting".loco())
KeyboardShortcuts.Recorder(for: .createMeetingShortcut)
Text("preferences_general_option_shortcuts".loco()).font(.headline).bold()
Section {
HStack {
Text("preferences_general_shortcut_create_meeting".loco())
KeyboardShortcuts.Recorder(for: .createMeetingShortcut)

Text("preferences_general_shortcut_join_next".loco())
KeyboardShortcuts.Recorder(for: .joinEventShortcut)
Text("preferences_general_shortcut_join_next".loco())
KeyboardShortcuts.Recorder(for: .joinEventShortcut)

Spacer()
Spacer()

Button(action: { self.showingModal.toggle() }) {
Text("preferences_general_all_shortcut".loco())
}.sheet(isPresented: $showingModal) {
ShortcutsModal()
Button(action: { self.showingModal.toggle() }) {
Text("preferences_general_all_shortcut".loco())
}.sheet(isPresented: $showingModal) {
ShortcutsModal()
}
}
}
}.padding(.leading, 30)
}
}

Expand Down
36 changes: 22 additions & 14 deletions MeetingBar/Views/Shared.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,23 @@ struct AutomaticEventJoinPicker: View {

struct FullscreenNotificationPicker: View {
@Default(.fullscreenNotification) var fullscreenNotification
@Default(.fullscreenNotificationMeetingLinkOnly) var fullscreenNotificationMeetingLinkOnly
@Default(.fullscreenNotificationTime) var fullscreenNotificationTime

var body: some View {
HStack {
Toggle("shared_fullscreen_notification_toggle".loco(), isOn: $fullscreenNotification)
Picker("", selection: $fullscreenNotificationTime) {
Text("general_when_event_starts".loco()).tag(TimeBeforeEvent.atStart)
Text("general_one_minute_before".loco()).tag(TimeBeforeEvent.minuteBefore)
Text("general_three_minute_before".loco()).tag(TimeBeforeEvent.threeMinuteBefore)
Text("general_five_minute_before".loco()).tag(TimeBeforeEvent.fiveMinuteBefore)
}.frame(width: 220, alignment: .leading).labelsHidden().disabled(!fullscreenNotification)
VStack(alignment: .leading, spacing: 15) {
HStack {
Toggle("shared_fullscreen_notification_toggle".loco(), isOn: $fullscreenNotification)
Picker("", selection: $fullscreenNotificationTime) {
Text("general_when_event_starts".loco()).tag(TimeBeforeEvent.atStart)
Text("general_one_minute_before".loco()).tag(TimeBeforeEvent.minuteBefore)
Text("general_three_minute_before".loco()).tag(TimeBeforeEvent.threeMinuteBefore)
Text("general_five_minute_before".loco()).tag(TimeBeforeEvent.fiveMinuteBefore)
}.frame(width: 220, alignment: .leading).labelsHidden().disabled(!fullscreenNotification)
}
Section {
Toggle("shared_fullscreen_notification_meeting_link_only_toggle".loco(), isOn: $fullscreenNotificationMeetingLinkOnly).disabled(!fullscreenNotification)
}.padding(.leading, 30)
}
}
}
Expand All @@ -74,13 +80,15 @@ struct JoinEventNotificationPicker: View {
}.frame(width: 220, alignment: .leading).labelsHidden().disabled(!joinEventNotification)
}

if noAlertStyle, !disabled, joinEventNotification {
Text("shared_send_notification_no_alert_style_tip".loco()).foregroundColor(.gray).font(.system(size: 12))
}
Section {
if noAlertStyle, !disabled, joinEventNotification {
Text("shared_send_notification_no_alert_style_tip".loco()).foregroundColor(.gray).font(.system(size: 12))
}

if disabled, joinEventNotification {
Text("shared_send_notification_disabled_tip".loco()).foregroundColor(.gray).font(.system(size: 12))
}
if disabled, joinEventNotification {
Text("shared_send_notification_disabled_tip".loco()).foregroundColor(.gray).font(.system(size: 12))
}
}.padding(.leading, 25)
}
}
struct endEventNotificationPicker: View {
Expand Down
Loading