Skip to content

Commit

Permalink
Merge pull request #8 from IBM/version-2.1.0-updates
Browse files Browse the repository at this point in the history
Version 2.1.0 from internal developments
  • Loading branch information
Johny committed Mar 25, 2021
2 parents 19cd4f8 + c4a8889 commit 6adb996
Show file tree
Hide file tree
Showing 19 changed files with 286 additions and 126 deletions.
8 changes: 4 additions & 4 deletions Notification Agent.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 24;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = "Notification Agent/Info.plist";
Expand All @@ -793,7 +793,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.14;
MARKETING_VERSION = 2.0.0;
MARKETING_VERSION = 2.1.0;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.ibm.cio.be.mac-notification-agent";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -810,7 +810,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 24;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = "Notification Agent/Info.plist";
Expand All @@ -819,7 +819,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.14;
MARKETING_VERSION = 2.0.0;
MARKETING_VERSION = 2.1.0;
ONLY_ACTIVE_ARCH = NO;
PRODUCT_BUNDLE_IDENTIFIER = "com.ibm.cio.be.mac-notification-agent";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
5 changes: 4 additions & 1 deletion Notification Agent/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}

func application(_ application: NSApplication, open urls: [URL]) {
guard UserDefaults.standard.bool(forKey: "deeplinkSecurity") else { return }
self.deepLinkEngine.agentTriggeredByDeepLink = true
guard UserDefaults.standard.bool(forKey: "deeplinkSecurity") else {
logger.log(.error, "You need to enable deep link security to use deep link")
return
}
configureApp {
for url in urls {
self.logger.log("Mac@IBM Notification Agent was triggered by a URL", [url.absoluteString])
Expand Down
4 changes: 2 additions & 2 deletions Notification Agent/Controllers/EFCLController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ final class EFCLController {
"--config",
"-reset",
"sudo"]
static let standaloneBooleanArguments = ["always_on_top"]
static let standaloneBooleanArguments = ["always_on_top", "silent"]
// MARK: - Variables

let logger = Logger.shared
Expand Down Expand Up @@ -192,7 +192,7 @@ final class EFCLController {
/// - Parameter arguments: the app's launch arguments.
private func checkSpecialArguments(_ arguments: [String]) {
guard !arguments.contains("--help") else {
HelpBuilder.printHelpPage()
HelpBuilder.printHelp(arguments)
applicationExit(withReason: .untrackedSuccess)
return
}
Expand Down
215 changes: 166 additions & 49 deletions Notification Agent/Controllers/HelpBuilder.swift

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Notification Agent/Controllers/NotificationDispatch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ final class NotificationDispatch {
window.styleMask.remove(.closable)
window.center()
window.makeKeyAndOrderFront(self)
guard object.silent == false else { return }
NSSound(named: .init("Funk"))?.play()
}
case .onboarding:
Expand Down
24 changes: 22 additions & 2 deletions Notification Agent/Extensions/Decodable-Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,30 @@
import Foundation

extension Decodable {
/// Initializing object decoding JSON format string.
/// - Parameter json: the JSON format string.
/// - Throws: deconding or data errors.
init(from json: String) throws {
guard let jsonData = json.data(using: .utf8) else {
throw NAError.dataFormat(type: .invalidDecodingFromJSON)
throw NAError.dataFormat(type: .invalidJSONPayload)
}
do {
self = try JSONDecoder().decode(Self.self, from: jsonData)
} catch let error {
throw NAError.dataFormat(type: .invalidJSONDecoding(errorDescription: error.localizedDescription))
}
}
/// Intializing obeject from decoding JSON file.
/// - Parameter url: JSON file url.
/// - Throws: deconding or url errors.
init(from url: URL) throws {
guard let jsonData = try? Data(contentsOf: url, options: .mappedIfSafe) else {
throw NAError.dataFormat(type: .invalidJSONFilepath)
}
do {
self = try JSONDecoder().decode(Self.self, from: jsonData)
} catch let error {
throw NAError.dataFormat(type: .invalidJSONDecoding(errorDescription: error.localizedDescription))
}
self = try JSONDecoder().decode(Self.self, from: jsonData)
}
}
12 changes: 9 additions & 3 deletions Notification Agent/Model/Common/NAError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ extension NAError.Enums {
case noInfoToShow
case noButtonDefined
case noHelpButtonAllowedInNotification
case invalidDecodingFromJSON
case invalidJSONPayload
case invalidJSONFilepath
case invalidJSONDecoding(errorDescription: String)
}
}

Expand All @@ -61,8 +63,12 @@ extension NAError.Enums.ModelError: LocalizedError {
return "No button defined"
case .noHelpButtonAllowedInNotification:
return "It's not allowed to define an help button in a \"banner\" UI type style."
case .invalidDecodingFromJSON:
return "Invalid JSON."
case .invalidJSONPayload:
return "Invalid JSON payload."
case .invalidJSONFilepath:
return "Invalid JSON file path."
case .invalidJSONDecoding(let errorDescription):
return "Invalid JSON format: \(errorDescription)"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public final class NotificationAccessoryElement: NSObject, Codable, NSSecureCodi
case image
case video
case input
case securedInput
case securedinput
}

// MARK: - Variables
Expand Down
29 changes: 27 additions & 2 deletions Notification Agent/Model/UIObjects/NotificationObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ public final class NotificationObject: NSObject, Codable, NSSecureCoding {
var helpButton: NotificationButton?
/// The timeout for the notification. After this amount of seconds past a default action is triggered.
var timeout: String?
/// A boolean value that set if the popup window if always on top of the window hierarchy.
/// A boolean value that set if the pop-up window if always on top of the window hierarchy.
var alwaysOnTop: Bool?
/// A boolean value that set if the pop-up must not trigger any sound when appear.
var silent: Bool?
/// The payload data needed for the "onboarding" UI type.
var payload: OnboardingData?

Expand All @@ -74,7 +76,7 @@ public final class NotificationObject: NSObject, Codable, NSSecureCoding {
self.subtitle = dict["subtitle"] as? String
self.iconPath = dict["icon_path"] as? String
if let onboardingRawData = dict["payload"] as? String {
self.payload = try OnboardingData(from: onboardingRawData)
self.payload = try Self.loadOnboardingPayload(onboardingRawData)
}

if let accessoryviewTyperawValue = dict["accessory_view_type"] as? String,
Expand Down Expand Up @@ -117,6 +119,11 @@ public final class NotificationObject: NSObject, Codable, NSSecureCoding {
} else {
self.alwaysOnTop = false
}
if let silentRaw = dict["silent"] as? String {
self.silent = silentRaw.lowercased() == "true"
} else {
self.silent = false
}

super.init()
switch type {
Expand All @@ -130,6 +137,16 @@ public final class NotificationObject: NSObject, Codable, NSSecureCoding {
}
}
}

static func loadOnboardingPayload(_ payload: String) throws -> OnboardingData? {
if payload.isValidURL, let url = URL(string: payload) {
return try OnboardingData(from: url)
} else if FileManager.default.fileExists(atPath: payload) {
return try OnboardingData(from: URL(fileURLWithPath: payload))
} else {
return try OnboardingData(from: payload)
}
}

// MARK: - Codable protocol conformity - START

Expand All @@ -147,6 +164,7 @@ public final class NotificationObject: NSObject, Codable, NSSecureCoding {
case helpButton
case timeout
case alwaysOnTop
case silent
}

required public init(from decoder: Decoder) throws {
Expand All @@ -166,6 +184,7 @@ public final class NotificationObject: NSObject, Codable, NSSecureCoding {
self.helpButton = try container.decodeIfPresent(NotificationButton.self, forKey: .helpButton)
self.timeout = try container.decodeIfPresent(String.self, forKey: .timeout)
self.alwaysOnTop = try container.decodeIfPresent(Bool.self, forKey: .alwaysOnTop)
self.silent = try container.decodeIfPresent(Bool.self, forKey: .silent)
}

public func encode(to encoder: Encoder) throws {
Expand All @@ -183,6 +202,7 @@ public final class NotificationObject: NSObject, Codable, NSSecureCoding {
try container.encodeIfPresent(self.helpButton, forKey: .helpButton)
try container.encodeIfPresent(self.timeout, forKey: .timeout)
try container.encodeIfPresent(self.alwaysOnTop, forKey: .alwaysOnTop)
try container.encodeIfPresent(self.silent, forKey: .silent)
}

// MARK: Codable protocol conformity - END
Expand Down Expand Up @@ -224,6 +244,10 @@ public final class NotificationObject: NSObject, Codable, NSSecureCoding {
let number = NSNumber(booleanLiteral: alwaysOnTop)
coder.encode(number, forKey: NOCodingKeys.alwaysOnTop.rawValue)
}
if let silent = self.silent {
let number = NSNumber(booleanLiteral: silent)
coder.encode(number, forKey: NOCodingKeys.silent.rawValue)
}
}

public required init?(coder: NSCoder) {
Expand All @@ -240,6 +264,7 @@ public final class NotificationObject: NSObject, Codable, NSSecureCoding {
self.helpButton = coder.decodeObject(of: NotificationButton.self, forKey: NOCodingKeys.helpButton.rawValue)
self.timeout = coder.decodeObject(of: NSString.self, forKey: NOCodingKeys.timeout.rawValue) as String?
self.alwaysOnTop = coder.decodeObject(of: NSNumber.self, forKey: NOCodingKeys.alwaysOnTop.rawValue) as? Bool
self.silent = coder.decodeObject(of: NSNumber.self, forKey: NOCodingKeys.silent.rawValue) as? Bool
}

// MARK: - NSSecureCoding protocol conformity - END
Expand Down

This file was deleted.

This file was deleted.

Binary file not shown.
3 changes: 0 additions & 3 deletions Notification Agent/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
// MARK: - Main popup window
"default_popup_bar_title" = "Mac@IBM Notifications";

// MARK: - Accessory views
"accessory_view_timer_label" = "Please make a selection in %@";

// MARK: - Buttons
"default_main_button_label" = "OK";
"cancel_label" = "Cancel";
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@ final class MarkdownTextView: NSView {
scrollView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true

self.setText(text)
if drawsBackground {
textViewBackgroundColor = .white
textColor = .black
} else {
textViewBackgroundColor = nil
textColor = .labelColor
}
self.setText(text)
}

required init?(coder: NSCoder) {
Expand All @@ -123,12 +123,17 @@ final class MarkdownTextView: NSView {
/// - Parameter text: the text that needs to be displayed.
func setText(_ text: String) {
let markdownText = SwiftyMarkdown(string: text)
markdownText.setFontColorForAllStyles(with: textView.drawsBackground ? .black : .labelColor)
markdownText.h1.fontSize = 20
markdownText.h1.fontStyle = .bold
markdownText.h2.fontSize = 18
markdownText.h2.fontStyle = .bold
markdownText.h3.fontSize = 16
markdownText.h3.fontStyle = .bold

markdownText.code.color = .gray
markdownText.code.fontName = "CourierNewPSMT"

let attributedString = markdownText.attributedString()
self.textView.textStorage?.setAttributedString(attributedString)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,20 +125,17 @@ extension ProgressBarAccessoryView: InteractiveEFCLControllerDelegate {
func didReceivedNewStateforProgressBar(_ newState: ProgressState) {
DispatchQueue.main.async {
self.viewState = newState
self.progressBar.isIndeterminate = self.viewState.isIndeterminate
if self.viewState.isIndeterminate {
self.progressBar.startAnimation(nil)
}
NSAnimationContext.runAnimationGroup { (context) in
context.duration = 0.2
self.topMessageLabel.animator().stringValue = self.viewState.topMessage
self.bottomMessageLabel.animator().stringValue = self.viewState.bottomMessage
if self.progressBar.isIndeterminate != self.viewState.isIndeterminate {
self.delegate?.didChangeEstimation(self.viewState.isIndeterminate)
if self.viewState.isIndeterminate {
self.progressBar.startAnimation(nil)
} else {
self.progressBar.stopAnimation(nil)
}
if !self.viewState.isIndeterminate {
self.progressBar.animator().doubleValue = self.viewState.percent
}
self.progressBar.animator().isIndeterminate = self.viewState.isIndeterminate
self.progressBar.animator().doubleValue = self.viewState.percent
if self.viewState.percent >= 100 {
self.delegate?.didFinishLoading(self)
}
Expand All @@ -148,9 +145,13 @@ extension ProgressBarAccessoryView: InteractiveEFCLControllerDelegate {

/// Interactive updates ended.
func didFinishedInteractiveUpdates() {
defer {
self.delegate?.didFinishLoading(self)
}
DispatchQueue.main.async {
self.progressBar.isIndeterminate = false
self.progressBar.doubleValue = 100
self.progressBar.stopAnimation(nil)
self.delegate?.didFinishLoading(self)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,23 @@ public final class TimerAccessoryView: NSView {
weak var delegate: TimerAccessoryViewDelegate?
var timerLabel: NSTextField!
var timer: Timer?
var label: String
var countDown: Int {
didSet {
DispatchQueue.main.async {
self.timerLabel.stringValue = String(format: "accessory_view_timer_label".localized,
self.timerLabel.stringValue = String(format: self.label,
self.countDown.timeFormattedString)
}
}
}

// MARK: - Initializers

init(withTimeInSeconds time: Int) {
self.timerLabel = NSTextField(labelWithString: String(format: "accessory_view_timer_label".localized,
init(withTimeInSeconds time: Int, label: String) {
self.timerLabel = NSTextField(labelWithString: String(format: label,
time.timeFormattedString))
self.countDown = time
self.label = label
super.init(frame: .zero)
self.startTimer()
self.buildView()
Expand Down
Loading

0 comments on commit 6adb996

Please sign in to comment.