Skip to content

Commit

Permalink
Merge pull request #137 from jgoldhammer/feat/105-custom-url-new-meet…
Browse files Browse the repository at this point in the history
…ings

feat(create-meeting): custom url for new meetings
  • Loading branch information
leits authored Jan 15, 2021
2 parents d86fee4 + a230bfc commit c7f81b3
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 14 deletions.
10 changes: 6 additions & 4 deletions MeetingBar.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
40DC7053250E5E1000217DD9 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; };
40E60312250E81EA005986C7 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
E249D533259BBC3800429BF1 /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
E2AE715525AA54A600D3C7CF /* DevTeamOverride.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DevTeamOverride.xcconfig; sourceTree = "<group>"; };
E4DD0F0A2529D0D20029E395 /* Project-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Project-Release.xcconfig"; sourceTree = "<group>"; };
E4DD0F0B2529D0D20029E395 /* Project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Project.xcconfig; sourceTree = "<group>"; };
E4DD0F0C2529D0D20029E395 /* Project-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Project-Debug.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -229,6 +230,7 @@
E4DD0F092529D0D20029E395 /* XCConfig */ = {
isa = PBXGroup;
children = (
E2AE715525AA54A600D3C7CF /* DevTeamOverride.xcconfig */,
E4DD0F0B2529D0D20029E395 /* Project.xcconfig */,
E4DD0F0A2529D0D20029E395 /* Project-Release.xcconfig */,
E4DD0F0C2529D0D20029E395 /* Project-Debug.xcconfig */,
Expand Down Expand Up @@ -540,7 +542,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = MeetingBar/MeetingBar.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 108;
Expand All @@ -566,7 +568,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = MeetingBar/MeetingBar.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 108;
Expand All @@ -592,7 +594,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = AutoLauncher/AutoLauncher.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
ENABLE_HARDENED_RUNTIME = YES;
Expand All @@ -614,7 +616,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = AutoLauncher/AutoLauncher.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
ENABLE_HARDENED_RUNTIME = YES;
Expand Down
19 changes: 17 additions & 2 deletions MeetingBar/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
}
}

/**
* implementation is necessary to show notifications even when the app has focus!
*/
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler(.alert)
}
completionHandler([.alert, .badge, .sound]) }

internal func userNotificationCenter(_: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
switch response.actionIdentifier {
Expand Down Expand Up @@ -330,6 +332,19 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
openMeetingURL(nil, CreateMeetingLinks.outlook_office365)
case .outlook_live:
openMeetingURL(nil, CreateMeetingLinks.outlook_live)
case .url:
var url: String = Defaults[.createMeetingServiceUrl]
let checkedUrl = NSURL(string: url)

if !url.isEmpty && checkedUrl != nil {
openMeetingURL(nil, URL(string: url)!)
} else {
if !url.isEmpty {
url += " "
}

sendNotification("Cannot create new meeeting", "Custom url \(url)is missing or invalid. Please enter a value in the app preferences.")
}
}
}

Expand Down
1 change: 1 addition & 0 deletions MeetingBar/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ enum CreateMeetingServices: String, Codable, CaseIterable {
case gcalendar = "Google Calendar"
case outlook_live = "Outlook Live"
case outlook_office365 = "Outlook Office365"
case url = "Custom url"
}

enum Links {
Expand Down
4 changes: 4 additions & 0 deletions MeetingBar/Extensions/DefaultsKeys.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ extension Defaults.Keys {

// Integrations
static let createMeetingService = Key<CreateMeetingServices>("createMeetingService", default: .zoom)

// custom url to create meetings
static let createMeetingServiceUrl = Key<String>("createMeetingServiceUrl", default: "")

static let useChromeForMeetLinks = Key<ChromeExecutable>("useChromeForMeetLinks", default: .defaultBrowser)
static let useChromeForHangoutsLinks = Key<ChromeExecutable>("useChromeForHangoutsLinks", default: .defaultBrowser)
static let useAppForZoomLinks = Key<Bool>("useAppForZoomLinks", default: false)
Expand Down
59 changes: 55 additions & 4 deletions MeetingBar/Notifications.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//
import EventKit
import UserNotifications

import AppKit
import Defaults

func requestNotificationAuthorization() {
Expand Down Expand Up @@ -52,7 +52,7 @@ func registerNotificationCategories() {
func sendNotification(title: String, text: String, subtitle: String = "") {
requestNotificationAuthorization() // By the apple best practices

NSLog("Send notification: \(title) - \(text)")
NSLog("Send notification: \(title) - \(text) - \(subtitle)")
let center = UNUserNotificationCenter.current()

let content = UNMutableNotificationContent()
Expand All @@ -62,8 +62,8 @@ func sendNotification(title: String, text: String, subtitle: String = "") {
content.subtitle = subtitle
}

let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.1, repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil)

center.add(request) { error in
if let error = error {
NSLog("%@", "request \(request) could not be added because of error \(error)")
Expand All @@ -72,6 +72,57 @@ func sendNotification(title: String, text: String, subtitle: String = "") {
}
}}

/**
* check whether the notifications for meetingbar are enabled and alert or banner style is enabled.
* in this case the method will return true, otherwise false.
*
*/
func notificationsEnabled() -> Bool {
let center = UNUserNotificationCenter.current()
let group = DispatchGroup()
group.enter()

var correctAlertStyle = false
var notificationsEnabled = false

center.getNotificationSettings { notificationSettings in
correctAlertStyle = notificationSettings.alertStyle == UNAlertStyle.alert || notificationSettings.alertStyle == UNAlertStyle.banner
notificationsEnabled = notificationSettings.authorizationStatus == UNAuthorizationStatus.authorized
group.leave()
}

group.wait()
return correctAlertStyle && notificationsEnabled
}

/**
* sends a notification to the user.
*/
func sendNotification(_ title: String, _ text: String) {
requestNotificationAuthorization() // By the apple best practices

if notificationsEnabled() {
sendNotification(title, text)
} else {
displayAlert(title: title, text: text)
}
}

/**
* adds an alert for the user- we will only use NSAlert if the user has switched off notifications
*/
func displayAlert(title: String, text: String) {
NSLog("Display alert: \(title) - \(text)")

let userAlert = NSAlert()
userAlert.messageText = title
userAlert.informativeText = text
userAlert.alertStyle = NSAlert.Style.informational
userAlert.addButton(withTitle: "OK")

userAlert.runModal()
}

func scheduleEventNotification(_ event: EKEvent) {
requestNotificationAuthorization() // By the apple best practices

Expand Down
23 changes: 19 additions & 4 deletions MeetingBar/Views/Preferences/ServicesTab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ struct ServicesTab: View {
@Default(.useChromeForHangoutsLinks) var useChromeForHangoutsLinks
@Default(.useAppForZoomLinks) var useAppForZoomLinks
@Default(.useAppForTeamsLinks) var useAppForTeamsLinks
@Default(.createMeetingServiceUrl) var createMeetingServiceUrl
@Default(.createMeetingService) var createMeetingService

var body: some View {
VStack {
Expand All @@ -41,10 +43,22 @@ struct ServicesTab: View {
}
}.foregroundColor(.gray).font(.system(size: 12)).padding(.horizontal, 10)
Divider()
HStack {
Text("Create meetings in").frame(width: 150, alignment: .leading)
CreateMeetingServicePicker()
}.padding(.horizontal, 10)
VStack {
HStack {
Text("Create meetings via").frame(width: 150, alignment: .leading)
CreateMeetingServicePicker()
}.padding(.horizontal, 10)

if createMeetingService == CreateMeetingServices.url {
HStack {
Text("Custom url").frame(width: 150, alignment: .leading)
TextField("Please enter a valid url (with the url scheme, e.g. https://)", text: $createMeetingServiceUrl).textFieldStyle(RoundedBorderTextFieldStyle())
}.padding(.horizontal, 10)
HStack {
Text("Tip: Google Meet supports choosing account via parameter, e.g. https://meet.google.com/new?authuser=1").foregroundColor(.gray).font(.system(size: 12))
}
}
}
Spacer()
}.padding()
}
Expand All @@ -62,6 +76,7 @@ struct CreateMeetingServicePicker: View {
Text(CreateMeetingServices.gcalendar.rawValue).tag(CreateMeetingServices.gcalendar)
Text(CreateMeetingServices.outlook_live.rawValue).tag(CreateMeetingServices.outlook_live)
Text(CreateMeetingServices.outlook_office365.rawValue).tag(CreateMeetingServices.outlook_office365)
Text(CreateMeetingServices.url.rawValue).tag(CreateMeetingServices.url)
}.labelsHidden()
}
}

0 comments on commit c7f81b3

Please sign in to comment.