Browse Source

Swiftformatting.

pull/92/head
Abhishek Banthia 5 years ago
parent
commit
05505fc235
  1. 1
      .swiftformat
  2. 25
      Clocker/AppDelegate.swift
  3. 8
      Clocker/Clocker.xcodeproj/project.pbxproj
  4. 1
      Clocker/Clocker/LocationController.swift
  5. 3
      Clocker/ClockerUITests/NetworkDisconnectionTests.swift
  6. 9
      Clocker/ClockerUITests/OnboardingTests.swift
  7. 3
      Clocker/ClockerUITests/PanelTests.swift
  8. 5
      Clocker/ClockerUITests/PreferencesTest.swift
  9. 3
      Clocker/ClockerUITests/ReviewTests.swift
  10. 3
      Clocker/ClockerUITests/ShortcutTests.swift
  11. 9
      Clocker/ClockerUnitTests/ClockerUnitTests.swift
  12. 4
      Clocker/ClockerUnitTests/RateTests.swift
  13. 16
      Clocker/Dependencies/Date Additions/Constants.swift
  14. 1
      Clocker/Dependencies/Date Additions/Date+Bundle.swift
  15. 23
      Clocker/Dependencies/Date Additions/Date+Comparators.swift
  16. 22
      Clocker/Dependencies/Date Additions/Date+Components.swift
  17. 1
      Clocker/Dependencies/Date Additions/Date+Format.swift
  18. 1
      Clocker/Dependencies/Date Additions/Date+Inits.swift
  19. 12
      Clocker/Dependencies/Date Additions/Date+Manipulations.swift
  20. 126
      Clocker/Dependencies/Date Additions/Date+TimeAgo.swift
  21. 1
      Clocker/Dependencies/Date Additions/Integer+DateTools.swift
  22. 86
      Clocker/Dependencies/Date Additions/TimeChunk.swift
  23. 175
      Clocker/Dependencies/Date Additions/TimePeriod.swift
  24. 21
      Clocker/Dependencies/Date Additions/TimePeriodChain.swift
  25. 42
      Clocker/Dependencies/Date Additions/TimePeriodCollection.swift
  26. 25
      Clocker/Dependencies/Date Additions/TimePeriodGroup.swift
  27. 34
      Clocker/Dependencies/Solar.swift
  28. 15
      Clocker/Events and Reminders/CalendarHandler.swift
  29. 2
      Clocker/Events and Reminders/EventCenter.swift
  30. 3
      Clocker/Events and Reminders/RemindersHandler.swift
  31. 12
      Clocker/Menu Bar/MenubarHandler.swift
  32. 8
      Clocker/Menu Bar/StatusContainerView.swift
  33. 5
      Clocker/Menu Bar/StatusItemHandler.swift
  34. 15
      Clocker/Menu Bar/StatusItemView.swift
  35. 6
      Clocker/Onboarding/OnboardingParentViewController.swift
  36. 3
      Clocker/Onboarding/OnboardingPermissionsViewController.swift
  37. 30
      Clocker/Onboarding/OnboardingSearchController.swift
  38. 9
      Clocker/Overall App/AppDefaults.swift
  39. 6
      Clocker/Overall App/AppKit + Additions.swift
  40. 2
      Clocker/Overall App/DateFormatterManager.swift
  41. 2
      Clocker/Overall App/Reach.swift
  42. 5
      Clocker/Overall App/Themer.swift
  43. 4
      Clocker/Overall App/Timer.swift
  44. 1
      Clocker/Overall App/UserDefaults + KVOExtensions.swift
  45. 7
      Clocker/Panel/Data Layer/TimezoneData.swift
  46. 5
      Clocker/Panel/Data Layer/TimezoneDataOperations.swift
  47. 2
      Clocker/Panel/FloatingWindowController.swift
  48. 8
      Clocker/Panel/Notes Popover/NotesPopover.swift
  49. 4
      Clocker/Panel/Notes Popover/TextViewWithPlaceholder.swift
  50. 11
      Clocker/Panel/PanelController.swift
  51. 38
      Clocker/Panel/ParentPanelController.swift
  52. 2
      Clocker/Panel/Rate Controller/RateController.swift
  53. 4
      Clocker/Panel/Rate Controller/ReviewView.swift
  54. 2
      Clocker/Panel/UI/PanelTableView.swift
  55. 2
      Clocker/Panel/UI/TimezoneCellView.swift
  56. 4
      Clocker/Panel/UI/TimezoneDataSource.swift
  57. 11
      Clocker/Preferences/About/AboutViewController.swift
  58. 2
      Clocker/Preferences/App Feedback/AppFeedbackWindowController.swift
  59. 57
      Clocker/Preferences/Appearance/AppearanceViewController.swift
  60. 54
      Clocker/Preferences/Calendar/CalendarViewController.swift
  61. 48
      Clocker/Preferences/General/PreferencesViewController.swift
  62. 20
      Clocker/Preferences/OneWindowController.swift
  63. 3
      Clocker/Preferences/Permissions/PermissionsViewController.swift

1
.swiftformat

@ -0,0 +1 @@
--disable

25
Clocker/AppDelegate.swift

@ -3,9 +3,8 @@
import Cocoa
open class AppDelegate: NSObject, NSApplicationDelegate {
lazy private var floatingWindow: FloatingWindowController = FloatingWindowController.shared()
lazy private var panelController: PanelController = PanelController.shared()
private lazy var floatingWindow: FloatingWindowController = FloatingWindowController.shared()
private lazy var panelController: PanelController = PanelController.shared()
private var statusBarHandler: StatusItemHandler!
private var panelObserver: NSKeyValueObservation?
@ -13,10 +12,8 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
panelObserver?.invalidate()
}
open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change _: [NSKeyValueChangeKey: Any]?, context _: UnsafeMutableRawPointer?) {
if let path = keyPath, path == "values.globalPing" {
let hotKeyCenter = PTHotKeyCenter.shared()
// Unregister old hot key
@ -36,16 +33,14 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
hotKeyCenter?.register(newHotKey)
}
}
public func applicationWillFinishLaunching(_ notification: Notification) {
public func applicationWillFinishLaunching(_: Notification) {
iVersion.sharedInstance().useAllAvailableLanguages = true
iVersion.sharedInstance().verboseLogging = false
}
public func applicationDidFinishLaunching(_ notification: Notification) {
public func applicationDidFinishLaunching(_: Notification) {
// Initializing the event store takes really long
EventCenter.sharedCenter()
@ -64,7 +59,7 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
#endif
}
public func applicationDockMenu(_ sender: NSApplication) -> NSMenu? {
public func applicationDockMenu(_: NSApplication) -> NSMenu? {
let menu = NSMenu(title: "Quick Access")
Logger.log(object: ["Dock Menu Triggered": "YES"], for: "Dock Menu Triggered")
@ -99,7 +94,7 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
private func showOnboardingFlow() {
let shouldLaunchOnboarding = (DataStore.shared().retrieve(key: CLShowOnboardingFlow) == nil && DataStore.shared().timezones().isEmpty)
|| (ProcessInfo.processInfo.arguments.contains(CLOnboaringTestsLaunchArgument))
|| ProcessInfo.processInfo.arguments.contains(CLOnboaringTestsLaunchArgument)
shouldLaunchOnboarding ? controller?.launch() : continueUsually()
}
@ -127,7 +122,7 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
assignShortcut()
panelObserver = panelController.observe(\.hasActivePanel, options: [.new]) { (obj, _) in
panelObserver = panelController.observe(\.hasActivePanel, options: [.new]) { obj, _ in
self.statusBarHandler.setHasActiveIcon(obj.hasActivePanelGetter())
}
@ -224,7 +219,6 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
}
private func checkIfRunFromApplicationsFolder() {
if let shortCircuit = UserDefaults.standard.object(forKey: "AllowOutsideApplicationsFolder") as? Bool, shortCircuit == true {
return
}
@ -255,8 +249,7 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
NSApp.terminate(nil)
}
@IBAction open func togglePanel(_ sender: Any) {
@IBAction open func togglePanel(_: Any) {
let displayMode = UserDefaults.standard.integer(forKey: CLShowAppInForeground)
if displayMode == 1 {

8
Clocker/Clocker.xcodeproj/project.pbxproj

@ -896,7 +896,7 @@
9A4379201BEC220200F4E27F /* ShellScript */,
9A20A0711C4E808500FB45AB /* Login Item Helper */,
9A5E75EC204CC39700119939 /* Embed Frameworks */,
C2A632A020EAC5EE00EB6BEA /* Move .app to Applications */,
C2A632A020EAC5EE00EB6BEA /* SwiftFormat */,
);
buildRules = (
);
@ -1070,19 +1070,19 @@
shellScript = "";
showEnvVarsInLog = 0;
};
C2A632A020EAC5EE00EB6BEA /* Move .app to Applications */ = {
C2A632A020EAC5EE00EB6BEA /* SwiftFormat */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Move .app to Applications";
name = SwiftFormat;
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# sh /Users/abhishek_banthia/Documents/GitLab/Check/Clocker-Private/Clocker/Move.sh\n";
shellScript = "if which swiftformat >/dev/null; then\n swiftformat . --swiftversion 5\nelse\n echo \"warning: SwiftFormat not installed, download from https://github.com/nicklockwood/SwiftFormat\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */

1
Clocker/Clocker/LocationController.swift

@ -87,7 +87,6 @@ class LocationController: NSObject {
extension LocationController: CLLocationManagerDelegate {
func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard !locations.isEmpty, let coordinates = locations.first?.coordinate else { return }
let reverseGeoCoder = CLGeocoder()

3
Clocker/ClockerUITests/NetworkDisconnectionTests.swift

@ -3,7 +3,6 @@
import XCTest
class NetworkDisconnectionTests: XCTestCase {
var app: XCUIApplication!
override func setUp() {
@ -41,7 +40,6 @@ class NetworkDisconnectionTests: XCTestCase {
}
func testFetchingATimezone() {
app.launchArguments.append("mockTimezoneDown")
precondition()
app.buttons["FloatingPreferences"].click()
@ -70,5 +68,4 @@ class NetworkDisconnectionTests: XCTestCase {
XCTAssertTrue(app.sheets.staticTexts["ErrorPlaceholder"].exists)
app.sheets.buttons["Close"].click()
}
}

9
Clocker/ClockerUITests/OnboardingTests.swift

@ -5,7 +5,6 @@ import XCTest
let CLOnboaringTestsLaunchArgument = "isTestingTheOnboardingFlow"
class OnboardingTests: XCTestCase {
var app: XCUIApplication!
override func setUp() {
@ -19,7 +18,6 @@ class OnboardingTests: XCTestCase {
// 1. The flow (forward button and back button take the user to the correct screen)
// 2. Static texts and button title's are appropriate
func testForwardButton() {
welcomeControllerTests()
// Let's go to the Permissions View
@ -42,7 +40,6 @@ class OnboardingTests: XCTestCase {
}
func backButtonTests() {
moveBackward()
searchControllerTests()
@ -59,7 +56,6 @@ class OnboardingTests: XCTestCase {
}
func alternateStartupFlowTests() {
// Let's go to the Permissions View
moveForward()
permissionsControllerTests()
@ -114,7 +110,6 @@ class OnboardingTests: XCTestCase {
}
private func permissionsControllerTests() {
let onboardingWindow = app.windows["OnboardingWindow"]
XCTAssertTrue(onboardingWindow.staticTexts["Permissions"].exists, "Header label's static text was unexpectedly wrong.")
@ -126,7 +121,6 @@ class OnboardingTests: XCTestCase {
}
private func startupControllerTests() {
let onboardingWindow = app.windows["OnboardingWindow"]
XCTAssertTrue(onboardingWindow.buttons["Forward"].title == "Open Clocker At Login", "Forward button title's was unexpectedly wrong")
@ -137,7 +131,6 @@ class OnboardingTests: XCTestCase {
}
private func searchControllerTests() {
let onboardingWindow = app.windows["OnboardingWindow"]
XCTAssertFalse(onboardingWindow.buttons["Alternate"].exists, "Alternate button was unexpectedly present.")
@ -148,7 +141,6 @@ class OnboardingTests: XCTestCase {
}
private func finalOnboardingControllerTests() {
let onboardingWindow = app.windows["OnboardingWindow"]
// Let's test the buttons
@ -158,5 +150,4 @@ class OnboardingTests: XCTestCase {
XCTAssertFalse(onboardingWindow.buttons["Alternate"].exists, "Alternate button was unexpectedly present.")
XCTAssertTrue(onboardingWindow.buttons["Forward"].title == "Launch Clocker", "Forward button's title was unexpectedly wrong.")
}
}

3
Clocker/ClockerUITests/PanelTests.swift

@ -37,7 +37,6 @@ class PanelTests: XCTestCase {
}
func testChangingLabelFromPopover() {
app.tapMenubarIcon()
let cell = app.tables["mainTableView"].cells.firstMatch
@ -109,7 +108,6 @@ class PanelTests: XCTestCase {
}
func testRightMouseDownToShowPopover() {
app.tapMenubarIcon()
let cell = app.tables["mainTableView"].cells.firstMatch
@ -117,5 +115,4 @@ class PanelTests: XCTestCase {
XCTAssert(app.popovers.count > 0)
}
}

5
Clocker/ClockerUITests/PreferencesTest.swift

@ -3,7 +3,6 @@
import XCTest
class PreferencesTest: XCTestCase {
var app: XCUIApplication!
override func setUp() {
@ -56,7 +55,6 @@ class PreferencesTest: XCTestCase {
}
func testEditingLabel() {
let placeToAdd = "Auckland"
app.tapMenubarIcon()
@ -83,7 +81,6 @@ class PreferencesTest: XCTestCase {
app.tables["mainTableView"].typeKey(",", modifierFlags: .command)
deleteAPlace(place: placeToAdd, for: app)
}
func testSortingByTimezoneDifference() {
@ -347,7 +344,6 @@ class PreferencesTest: XCTestCase {
let rowQueryCount = clockerWindow.tables["TimezoneTableView"].tableRows.count
if rowQueryCount > 0 {
let currentElement = clockerWindow.tables["TimezoneTableView"].tableRows.firstMatch
currentElement.click()
@ -355,7 +351,6 @@ class PreferencesTest: XCTestCase {
clockerWindow.typeKey(XCUIKeyboardKey.delete,
modifierFlags: XCUIElement.KeyModifierFlags())
}
}
}
}

3
Clocker/ClockerUITests/ReviewTests.swift

@ -3,7 +3,6 @@
import XCTest
class ReviewTests: XCTestCase {
var app: XCUIApplication!
override func setUp() {
@ -19,7 +18,6 @@ class ReviewTests: XCTestCase {
}
func testIfReviewIsNegativeAndUserWantsToProvideFeedback() {
guard app.buttons["Not Really"].exists else { return }
XCTAssertTrue(app.staticTexts["ReviewLabel"].exists)
app.buttons["Not Really"].click()
@ -55,5 +53,4 @@ class ReviewTests: XCTestCase {
app.buttons["Yes"].click()
XCTAssertFalse(app.staticTexts["ReviewLabel"].exists)
}
}

3
Clocker/ClockerUITests/ShortcutTests.swift

@ -3,7 +3,6 @@
import XCTest
class ShortcutTests: XCTestCase {
var app: XCUIApplication!
let randomIndex = Int(arc4random_uniform(26))
@ -22,7 +21,6 @@ class ShortcutTests: XCTestCase {
}
func testShortcuts() {
app.tables["mainTableView"].typeKey(",", modifierFlags: .command)
XCTAssertFalse(app.tables["mainTableView"].exists)
@ -56,5 +54,4 @@ class ShortcutTests: XCTestCase {
let alphabet: [String] = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
return alphabet[randomIndex]
}
}

9
Clocker/ClockerUnitTests/ClockerUnitTests.swift

@ -1,10 +1,9 @@
// Copyright © 2015 Abhishek Banthia
import XCTest
@testable import Clocker
import XCTest
class ClockerUnitTests: XCTestCase {
private let california = ["customLabel": "Test",
"formattedAddress": "San Francisco",
"place_id": "TestIdentifier",
@ -72,7 +71,6 @@ class ClockerUnitTests: XCTestCase {
}
func testAddingATimezoneToDefaults() {
let timezoneData = TimezoneData(with: california)
let defaults = UserDefaults.standard
@ -134,7 +132,6 @@ class ClockerUnitTests: XCTestCase {
}
func testDateWithSliderValue() {
let dataObject = TimezoneData(with: mumbai)
let operations = TimezoneDataOperations(with: dataObject)
@ -174,7 +171,6 @@ class ClockerUnitTests: XCTestCase {
}
func testFormattedLabel() {
let dataObject = TimezoneData(with: mumbai)
XCTAssertTrue(dataObject.formattedTimezoneLabel() == "Ghar", "Incorrect custom label returned by model.")
@ -200,7 +196,6 @@ class ClockerUnitTests: XCTestCase {
}
func testWithAllLocales() {
let dataObject1 = TimezoneData(with: mumbai)
let operations = TimezoneDataOperations(with: dataObject1)
@ -212,7 +207,6 @@ class ClockerUnitTests: XCTestCase {
}
func testTimeWithAllLocales() {
let dataObject = TimezoneData(with: mumbai)
let cal = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)
@ -235,5 +229,4 @@ class ClockerUnitTests: XCTestCase {
XCTAssertNotNil(convertedDate)
}
}
}

4
Clocker/ClockerUnitTests/RateTests.swift

@ -1,10 +1,9 @@
// Copyright © 2015 Abhishek Banthia
import XCTest
@testable import Clocker
import XCTest
class RateTests: XCTestCase {
let rateController = RateController.applicationDidLaunch(UserDefaults())
override func setUp() {
@ -15,5 +14,4 @@ class RateTests: XCTestCase {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
}

16
Clocker/Dependencies/Date Additions/Constants.swift

@ -12,17 +12,17 @@ import Foundation
* Time conversions used across DateTools
*/
public class Constants {
public static let SecondsInYear: TimeInterval = 31536000
public static let SecondsInLeapYear: TimeInterval = 31622400
public static let SecondsInMonth28: TimeInterval = 2419200
public static let SecondsInMonth29: TimeInterval = 2505600
public static let SecondsInMonth30: TimeInterval = 2592000
public static let SecondsInMonth31: TimeInterval = 2678400
public static let SecondsInWeek: TimeInterval = 604800
public static let SecondsInYear: TimeInterval = 31_536_000
public static let SecondsInLeapYear: TimeInterval = 31_622_400
public static let SecondsInMonth28: TimeInterval = 2_419_200
public static let SecondsInMonth29: TimeInterval = 2_505_600
public static let SecondsInMonth30: TimeInterval = 2_592_000
public static let SecondsInMonth31: TimeInterval = 2_678_400
public static let SecondsInWeek: TimeInterval = 604_800
public static let SecondsInDay: TimeInterval = 86400
public static let SecondsInHour: TimeInterval = 3600
public static let SecondsInMinute: TimeInterval = 60
public static let MillisecondsInDay: TimeInterval = 86400000
public static let MillisecondsInDay: TimeInterval = 86_400_000
public static let AllCalendarUnitFlags: Set<Calendar.Component> = [.year, .quarter, .month, .weekOfYear, .weekOfMonth, .day, .hour, .minute, .second, .era, .weekday, .weekdayOrdinal, .weekOfYear]
}

1
Clocker/Dependencies/Date Additions/Date+Bundle.swift

@ -9,7 +9,6 @@
import Foundation
public extension Bundle {
class func dateToolsBundle() -> Bundle {
let assetPath = Bundle(for: Constants.self).resourcePath!
return Bundle(path: NSString(string: assetPath).appendingPathComponent("DateTools.bundle"))!

23
Clocker/Dependencies/Date Additions/Date+Comparators.swift

@ -15,7 +15,6 @@ import Foundation
* for a given unit of time.
*/
public extension Date {
// MARK: - Comparisons
/**
@ -57,7 +56,7 @@ public extension Date {
* - returns: Bool representing comparison result
*/
func equals(_ date: Date) -> Bool {
return self.compare(date) == .orderedSame
return compare(date) == .orderedSame
}
/**
@ -69,7 +68,7 @@ public extension Date {
* - returns: Bool representing comparison result
*/
func isLater(than date: Date) -> Bool {
return self.compare(date) == .orderedDescending
return compare(date) == .orderedDescending
}
/**
@ -81,7 +80,7 @@ public extension Date {
* - returns: Bool representing comparison result
*/
func isLaterThanOrEqual(to date: Date) -> Bool {
return self.compare(date) == .orderedDescending || self.compare(date) == .orderedSame
return compare(date) == .orderedDescending || compare(date) == .orderedSame
}
/**
@ -93,7 +92,7 @@ public extension Date {
* - returns: Bool representing comparison result
*/
func isEarlier(than date: Date) -> Bool {
return self.compare(date) == .orderedAscending
return compare(date) == .orderedAscending
}
/**
@ -105,7 +104,7 @@ public extension Date {
* - returns: Bool representing comparison result
*/
func isEarlierThanOrEqual(to date: Date) -> Bool {
return self.compare(date) == .orderedAscending || self.compare(date) == .orderedSame
return compare(date) == .orderedAscending || compare(date) == .orderedSame
}
/**
@ -213,7 +212,7 @@ public extension Date {
* - returns: The hours between receiver and provided date
*/
func hours(from date: Date) -> Int {
return Int(self.timeIntervalSince(date)/Constants.SecondsInHour)
return Int(timeIntervalSince(date) / Constants.SecondsInHour)
}
/**
@ -227,7 +226,7 @@ public extension Date {
* - returns: The minutes between receiver and provided date
*/
func minutes(from date: Date) -> Int {
return Int(self.timeIntervalSince(date)/Constants.SecondsInMinute)
return Int(timeIntervalSince(date) / Constants.SecondsInMinute)
}
/**
@ -259,7 +258,7 @@ public extension Date {
*/
func years(from date: Date, calendar: Calendar?) -> Int {
var calendarCopy = calendar
if (calendar == nil) {
if calendar == nil {
calendarCopy = Calendar.autoupdatingCurrent
}
@ -283,7 +282,7 @@ public extension Date {
*/
func months(from date: Date, calendar: Calendar?) -> Int {
var calendarCopy = calendar
if (calendar == nil) {
if calendar == nil {
calendarCopy = Calendar.autoupdatingCurrent
}
@ -307,7 +306,7 @@ public extension Date {
*/
func weeks(from date: Date, calendar: Calendar?) -> Int {
var calendarCopy = calendar
if (calendar == nil) {
if calendar == nil {
calendarCopy = Calendar.autoupdatingCurrent
}
@ -331,7 +330,7 @@ public extension Date {
*/
func days(from date: Date, calendar: Calendar?) -> Int {
var calendarCopy = calendar
if (calendar == nil) {
if calendar == nil {
calendarCopy = Calendar.autoupdatingCurrent
}

22
Clocker/Dependencies/Date Additions/Date+Components.swift

@ -14,7 +14,6 @@ import Foundation
* several computed Bools.
*/
public extension Date {
/**
* Convenient accessor of the date's `Calendar` components.
*
@ -60,11 +59,10 @@ public extension Date {
var unitRange: Range<Int>?
if larger.hashValue < smaller.hashValue {
for x in larger.hashValue ..< smaller.hashValue {
var stepLarger: Calendar.Component
var stepSmaller: Calendar.Component
switch(x) {
switch x {
case 0:
stepLarger = Calendar.Component.era
stepSmaller = Calendar.Component.year
@ -79,10 +77,10 @@ public extension Date {
}
case 2:
if larger.hashValue < 2 {
if self.isInLeapYear {
unitRange = Range.init(uncheckedBounds: (lower: 0, upper: 366))
if isInLeapYear {
unitRange = Range(uncheckedBounds: (lower: 0, upper: 366))
} else {
unitRange = Range.init(uncheckedBounds: (lower: 0, upper: 365))
unitRange = Range(uncheckedBounds: (lower: 0, upper: 365))
}
} else {
stepLarger = Calendar.Component.month
@ -229,42 +227,42 @@ public extension Date {
* Convenience setter for the date's `year` component
*/
mutating func year(_ year: Int) {
self = Date.init(year: year, month: self.month, day: self.day, hour: self.hour, minute: self.minute, second: self.second)
self = Date(year: year, month: month, day: day, hour: hour, minute: minute, second: second)
}
/**
* Convenience setter for the date's `month` component
*/
mutating func month(_ month: Int) {
self = Date.init(year: self.year, month: month, day: self.day, hour: self.hour, minute: self.minute, second: self.second)
self = Date(year: year, month: month, day: day, hour: hour, minute: minute, second: second)
}
/**
* Convenience setter for the date's `day` component
*/
mutating func day(_ day: Int) {
self = Date.init(year: self.year, month: self.month, day: day, hour: self.hour, minute: self.minute, second: self.second)
self = Date(year: year, month: month, day: day, hour: hour, minute: minute, second: second)
}
/**
* Convenience setter for the date's `hour` component
*/
mutating func hour(_ hour: Int) {
self = Date.init(year: self.year, month: self.month, day: self.day, hour: hour, minute: self.minute, second: self.second)
self = Date(year: year, month: month, day: day, hour: hour, minute: minute, second: second)
}
/**
* Convenience setter for the date's `minute` component
*/
mutating func minute(_ minute: Int) {
self = Date.init(year: self.year, month: self.month, day: self.day, hour: self.hour, minute: minute, second: self.second)
self = Date(year: year, month: month, day: day, hour: hour, minute: minute, second: second)
}
/**
* Convenience setter for the date's `second` component
*/
mutating func second(_ second: Int) {
self = Date.init(year: self.year, month: self.month, day: self.day, hour: self.hour, minute: self.minute, second: second)
self = Date(year: year, month: month, day: day, hour: hour, minute: minute, second: second)
}
// MARK: - Bools

1
Clocker/Dependencies/Date Additions/Date+Format.swift

@ -12,7 +12,6 @@ import Foundation
* Extends the Date class by adding convenience methods for formatting dates.
*/
public extension Date {
// MARK: - Formatted Date - Style
/**

1
Clocker/Dependencies/Date Additions/Date+Inits.swift

@ -14,7 +14,6 @@ import Foundation
*/
public extension Date {
// MARK: - Initializers
/**

12
Clocker/Dependencies/Date Additions/Date+Manipulations.swift

@ -12,7 +12,6 @@ import Foundation
* Extends the Date class by adding manipulation methods for transforming dates
*/
public extension Date {
// MARK: - StartOf
/**
@ -26,7 +25,7 @@ public extension Date {
func start(of component: Component) -> Date {
var newDate = self
if component == .second {
newDate.second(self.second)
newDate.second(second)
} else if component == .minute {
newDate.second(0)
} else if component == .hour {
@ -99,10 +98,10 @@ public extension Date {
if month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 {
// 31 day month
return 31
} else if month == 2 && date.isInLeapYear {
} else if month == 2, date.isInLeapYear {
// February with leap year
return 29
} else if month == 2 && !date.isInLeapYear {
} else if month == 2, !date.isInLeapYear {
// February without leap year
return 28
} else {
@ -175,14 +174,13 @@ public extension Date {
* Operator overload for adding a `TimeInterval` to a date.
*/
static func + (leftAddend: Date, rightAddend: Int) -> Date {
return leftAddend.addingTimeInterval((TimeInterval(rightAddend)))
return leftAddend.addingTimeInterval(TimeInterval(rightAddend))
}
/**
* Operator overload for subtracting a `TimeInterval` from a date.
*/
static func - (minuend: Date, subtrahend: Int) -> Date {
return minuend.addingTimeInterval(-(TimeInterval(subtrahend)))
return minuend.addingTimeInterval(-TimeInterval(subtrahend))
}
}

126
Clocker/Dependencies/Date Additions/Date+TimeAgo.swift

@ -13,7 +13,6 @@ import Foundation
* time in String format.
*/
public extension Date {
// MARK: - Time Ago
/**
@ -47,7 +46,7 @@ public extension Date {
* - returns String - Formatted return string
*/
var timeAgoSinceNow: String {
return self.timeAgo(since:Date())
return timeAgo(since: Date())
}
/**
@ -57,82 +56,76 @@ public extension Date {
* - returns String - Formatted return string
*/
var shortTimeAgoSinceNow: String {
return self.shortTimeAgo(since:Date())
return shortTimeAgo(since: Date())
}
func timeAgo(since date: Date, numericDates: Bool = false, numericTimes: Bool = false) -> String {
let calendar = NSCalendar.current
let unitFlags = Set<Calendar.Component>([.second, .minute, .hour, .day, .weekOfYear, .month, .year])
let earliest = self.earlierDate(date)
let earliest = earlierDate(date)
let latest = (earliest == self) ? date : self // Should be triple equals, but not extended to Date at this time
let components = calendar.dateComponents(unitFlags, from: earliest, to: latest)
let yesterday = date.subtract(1.days)
let isYesterday = yesterday.day == self.day
let isYesterday = yesterday.day == day
// Not Yet Implemented/Optional
// The following strings are present in the translation files but lack logic as of 2014.04.05
// @"Today", @"This week", @"This month", @"This year"
// and @"This morning", @"This afternoon"
if (components.year! >= 2) {
return self.logicalLocalizedStringFromFormat(format: "%%d %@years ago", value: components.year!)
} else if (components.year! >= 1) {
if (numericDates) {
if components.year! >= 2 {
return logicalLocalizedStringFromFormat(format: "%%d %@years ago", value: components.year!)
} else if components.year! >= 1 {
if numericDates {
return DateToolsLocalizedStrings("1 year ago")
}
return DateToolsLocalizedStrings("Last year")
} else if (components.month! >= 2) {
return self.logicalLocalizedStringFromFormat(format: "%%d %@months ago", value: components.month!)
} else if (components.month! >= 1) {
if (numericDates) {
} else if components.month! >= 2 {
return logicalLocalizedStringFromFormat(format: "%%d %@months ago", value: components.month!)
} else if components.month! >= 1 {
if numericDates {
return DateToolsLocalizedStrings("1 month ago")
}
return DateToolsLocalizedStrings("Last month")
} else if (components.weekOfYear! >= 2) {
return self.logicalLocalizedStringFromFormat(format: "%%d %@weeks ago", value: components.weekOfYear!)
} else if (components.weekOfYear! >= 1) {
if (numericDates) {
} else if components.weekOfYear! >= 2 {
return logicalLocalizedStringFromFormat(format: "%%d %@weeks ago", value: components.weekOfYear!)
} else if components.weekOfYear! >= 1 {
if numericDates {
return DateToolsLocalizedStrings("1 week ago")
}
return DateToolsLocalizedStrings("Last week")
} else if (components.day! >= 2) {
return self.logicalLocalizedStringFromFormat(format: "%%d %@days ago", value: components.day!)
} else if (isYesterday) {
if (numericDates) {
} else if components.day! >= 2 {
return logicalLocalizedStringFromFormat(format: "%%d %@days ago", value: components.day!)
} else if isYesterday {
if numericDates {
return DateToolsLocalizedStrings("1 day ago")
}
return DateToolsLocalizedStrings("Yesterday")
} else if (components.hour! >= 2) {
return self.logicalLocalizedStringFromFormat(format: "%%d %@hours ago", value: components.hour!)
} else if (components.hour! >= 1) {
if (numericTimes) {
} else if components.hour! >= 2 {
return logicalLocalizedStringFromFormat(format: "%%d %@hours ago", value: components.hour!)
} else if components.hour! >= 1 {
if numericTimes {
return DateToolsLocalizedStrings("1 hour ago")
}
return DateToolsLocalizedStrings("An hour ago")
} else if (components.minute! >= 2) {
return self.logicalLocalizedStringFromFormat(format: "%%d %@minutes ago", value: components.minute!)
} else if (components.minute! >= 1) {
if (numericTimes) {
} else if components.minute! >= 2 {
return logicalLocalizedStringFromFormat(format: "%%d %@minutes ago", value: components.minute!)
} else if components.minute! >= 1 {
if numericTimes {
return DateToolsLocalizedStrings("1 minute ago")
}
return DateToolsLocalizedStrings("A minute ago")
} else if (components.second! >= 3) {
return self.logicalLocalizedStringFromFormat(format: "%%d %@seconds ago", value: components.second!)
} else if components.second! >= 3 {
return logicalLocalizedStringFromFormat(format: "%%d %@seconds ago", value: components.second!)
} else {
if (numericTimes) {
if numericTimes {
return DateToolsLocalizedStrings("1 second ago")
}
@ -143,55 +136,55 @@ public extension Date {
func shortTimeAgo(since date: Date) -> String {
let calendar = NSCalendar.current
let unitFlags = Set<Calendar.Component>([.second, .minute, .hour, .day, .weekOfYear, .month, .year])
let earliest = self.earlierDate(date)
let earliest = earlierDate(date)
let latest = (earliest == self) ? date : self // Should pbe triple equals, but not extended to Date at this time
let components = calendar.dateComponents(unitFlags, from: earliest, to: latest)
let yesterday = date.subtract(1.days)
let isYesterday = yesterday.day == self.day
if (components.year! >= 1) {
return self.logicalLocalizedStringFromFormat(format: "%%d%@y", value: components.year!)
} else if (components.month! >= 1) {
return self.logicalLocalizedStringFromFormat(format: "%%d%@M", value: components.month!)
} else if (components.weekOfYear! >= 1) {
return self.logicalLocalizedStringFromFormat(format: "%%d%@w", value: components.weekOfYear!)
} else if (components.day! >= 2) {
return self.logicalLocalizedStringFromFormat(format: "%%d%@d", value: components.day!)
} else if (isYesterday) {
return self.logicalLocalizedStringFromFormat(format: "%%d%@d", value: 1)
} else if (components.hour! >= 1) {
return self.logicalLocalizedStringFromFormat(format: "%%d%@h", value: components.hour!)
} else if (components.minute! >= 1) {
return self.logicalLocalizedStringFromFormat(format: "%%d%@m", value: components.minute!)
} else if (components.second! >= 3) {
return self.logicalLocalizedStringFromFormat(format: "%%d%@s", value: components.second!)
let isYesterday = yesterday.day == day
if components.year! >= 1 {
return logicalLocalizedStringFromFormat(format: "%%d%@y", value: components.year!)
} else if components.month! >= 1 {
return logicalLocalizedStringFromFormat(format: "%%d%@M", value: components.month!)
} else if components.weekOfYear! >= 1 {
return logicalLocalizedStringFromFormat(format: "%%d%@w", value: components.weekOfYear!)
} else if components.day! >= 2 {
return logicalLocalizedStringFromFormat(format: "%%d%@d", value: components.day!)
} else if isYesterday {
return logicalLocalizedStringFromFormat(format: "%%d%@d", value: 1)
} else if components.hour! >= 1 {
return logicalLocalizedStringFromFormat(format: "%%d%@h", value: components.hour!)
} else if components.minute! >= 1 {
return logicalLocalizedStringFromFormat(format: "%%d%@m", value: components.minute!)
} else if components.second! >= 3 {
return logicalLocalizedStringFromFormat(format: "%%d%@s", value: components.second!)
} else {
return self.logicalLocalizedStringFromFormat(format: "%%d%@s", value: components.second!)
return logicalLocalizedStringFromFormat(format: "%%d%@s", value: components.second!)
// return DateToolsLocalizedStrings(@"Now"); //string not yet translated 2014.04.05
}
}
private func logicalLocalizedStringFromFormat(format: String, value: Int) -> String {
let localeFormat = String.init(format: format, getLocaleFormatUnderscoresWithValue(Double(value)))
return String.init(format: DateToolsLocalizedStrings(localeFormat), value)
let localeFormat = String(format: format, getLocaleFormatUnderscoresWithValue(Double(value)))
return String(format: DateToolsLocalizedStrings(localeFormat), value)
}
private func getLocaleFormatUnderscoresWithValue(_ value: Double) -> String {
let localCode = Bundle.main.preferredLocalizations[0]
if (localCode == "ru" || localCode == "uk") {
if localCode == "ru" || localCode == "uk" {
let XY = Int(floor(value).truncatingRemainder(dividingBy: 100))
let Y = Int(floor(value).truncatingRemainder(dividingBy: 10))
if(Y == 0 || Y > 4 || (XY > 10 && XY < 15)) {
if Y == 0 || Y > 4 || (XY > 10 && XY < 15) {
return ""
}
if(Y > 1 && Y < 5 && (XY < 10 || XY > 20)) {
if Y > 1, Y < 5, XY < 10 || XY > 20 {
return "_"
}
if(Y == 1 && XY != 11) {
if Y == 1, XY != 11 {
return "__"
}
}
@ -224,7 +217,7 @@ public extension Date {
* - returns: The date that is earlier
*/
func earlierDate(_ date: Date) -> Date {
return (self.timeIntervalSince1970 <= date.timeIntervalSince1970) ? self : date
return (timeIntervalSince1970 <= date.timeIntervalSince1970) ? self : date
}
/**
@ -235,7 +228,6 @@ public extension Date {
* - returns: The date that is later
*/
func laterDate(_ date: Date) -> Date {
return (self.timeIntervalSince1970 >= date.timeIntervalSince1970) ? self : date
return (timeIntervalSince1970 >= date.timeIntervalSince1970) ? self : date
}
}

1
Clocker/Dependencies/Date Additions/Integer+DateTools.swift

@ -9,7 +9,6 @@
import Foundation
public extension Int {
// MARK: TimePeriod
/**

86
Clocker/Dependencies/Date Additions/TimeChunk.swift

@ -20,7 +20,6 @@ import Foundation
* For more information about the utility of TimeChunks in relation to Dates, see the `Date+Manipulations` class.
*/
public struct TimeChunk {
// MARK: - Variables
public var seconds = 0
@ -67,57 +66,57 @@ public struct TimeChunk {
* well defined unit of time without the context of a calendar. !
*/
public func to(_ unit: TimeUnits) -> Int {
if self.months != 0 {
if months != 0 {
print("Months are not supported for conversion due to their uncertain number of days.")
return 0
}
if (unit == .seconds) {
var total = self.seconds
total += self.minutes * 60
total += self.hours * 60 * 60
total += self.days * 24 * 60 * 60
total += self.weeks * 7 * 24 * 60 * 60
total += self.years * 365 * 24 * 60 * 60
if unit == .seconds {
var total = seconds
total += minutes * 60
total += hours * 60 * 60
total += days * 24 * 60 * 60
total += weeks * 7 * 24 * 60 * 60
total += years * 365 * 24 * 60 * 60
return total
} else if (unit == .minutes) {
var total = self.minutes
total += self.seconds / 60
total += self.hours * 60
total += self.days * 24 * 60
total += self.weeks * 7 * 24 * 60
total += self.years * 365 * 24 * 60
} else if unit == .minutes {
var total = minutes
total += seconds / 60
total += hours * 60
total += days * 24 * 60
total += weeks * 7 * 24 * 60
total += years * 365 * 24 * 60
return total
} else if (unit == .hours) {
var total = self.hours
let secondsToMinutes = self.seconds / 60
total += (self.minutes + secondsToMinutes) / 60
total += self.days * 24
total += self.weeks * 7 * 24
total += self.years * 365 * 24
} else if unit == .hours {
var total = hours
let secondsToMinutes = seconds / 60
total += (minutes + secondsToMinutes) / 60
total += days * 24
total += weeks * 7 * 24
total += years * 365 * 24
return total
} else if (unit == .days) {
var total = self.days
let secondsToMinutes = self.seconds / 60
let minutesToHours = (self.minutes + secondsToMinutes) / 60
total += (self.hours + minutesToHours) / 24
total += self.weeks * 7
total += self.years * 365
} else if unit == .days {
var total = days
let secondsToMinutes = seconds / 60
let minutesToHours = (minutes + secondsToMinutes) / 60
total += (hours + minutesToHours) / 24
total += weeks * 7
total += years * 365
return total
} else if (unit == .weeks) {
var total = self.weeks
let secondsToMinutes = self.seconds / 60
let minutesToHours = (self.minutes + secondsToMinutes) / 60
let hoursToDays = (self.hours + minutesToHours) / 24
total += (self.days + hoursToDays) / 7
total += self.years * 52
} else if unit == .weeks {
var total = weeks
let secondsToMinutes = seconds / 60
let minutesToHours = (minutes + secondsToMinutes) / 60
let hoursToDays = (hours + minutesToHours) / 24
total += (days + hoursToDays) / 7
total += years * 52
return total
} else if (unit == .years) {
var total = self.years
let secondsToMinutes = self.seconds / 60
let minutesToHours = (self.minutes + secondsToMinutes) / 60
let hoursToDays = (self.hours + minutesToHours) / 24
} else if unit == .years {
var total = years
let secondsToMinutes = seconds / 60
let minutesToHours = (minutes + secondsToMinutes) / 60
let hoursToDays = (hours + minutesToHours) / 24
let weeksToDays = weeks * 7
total += (self.days + hoursToDays + weeksToDays) / 365
total += (days + hoursToDays + weeksToDays) / 365
return total
}
return 0
@ -274,5 +273,4 @@ public struct TimeChunk {
invertedChunk.years = -chunk.years
return invertedChunk
}
}

175
Clocker/Dependencies/Date Additions/TimePeriod.swift

@ -16,7 +16,6 @@ import Foundation
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-periods) for more information.
*/
public protocol TimePeriodProtocol {
// MARK: - Variables
/**
@ -31,14 +30,13 @@ public protocol TimePeriodProtocol {
}
public extension TimePeriodProtocol {
// MARK: - Information
/**
* True if the `TimePeriod`'s duration is zero
*/
var isMoment: Bool {
return self.beginning == self.end
return beginning == end
}
/**
@ -46,8 +44,8 @@ public extension TimePeriodProtocol {
* Returns the max int if beginning or end are nil.
*/
var years: Int {
if self.beginning != nil && self.end != nil {
return self.beginning!.yearsEarlier(than: self.end!)
if beginning != nil, end != nil {
return beginning!.yearsEarlier(than: end!)
}
return Int.max
}
@ -57,8 +55,8 @@ public extension TimePeriodProtocol {
* Returns the max int if beginning or end are nil.
*/
var weeks: Int {
if self.beginning != nil && self.end != nil {
return self.beginning!.weeksEarlier(than: self.end!)
if beginning != nil, end != nil {
return beginning!.weeksEarlier(than: end!)
}
return Int.max
}
@ -68,8 +66,8 @@ public extension TimePeriodProtocol {
* Returns the max int if beginning or end are nil.
*/
var days: Int {
if self.beginning != nil && self.end != nil {
return self.beginning!.daysEarlier(than: self.end!)
if beginning != nil, end != nil {
return beginning!.daysEarlier(than: end!)
}
return Int.max
}
@ -79,8 +77,8 @@ public extension TimePeriodProtocol {
* Returns the max int if beginning or end are nil.
*/
var hours: Int {
if self.beginning != nil && self.end != nil {
return self.beginning!.hoursEarlier(than: self.end!)
if beginning != nil, end != nil {
return beginning!.hoursEarlier(than: end!)
}
return Int.max
}
@ -90,8 +88,8 @@ public extension TimePeriodProtocol {
* Returns the max int if beginning or end are nil.
*/
var minutes: Int {
if self.beginning != nil && self.end != nil {
return self.beginning!.minutesEarlier(than: self.end!)
if beginning != nil, end != nil {
return beginning!.minutesEarlier(than: end!)
}
return Int.max
}
@ -101,8 +99,8 @@ public extension TimePeriodProtocol {
* Returns the max int if beginning or end are nil.
*/
var seconds: Int {
if self.beginning != nil && self.end != nil {
return self.beginning!.secondsEarlier(than: self.end!)
if beginning != nil, end != nil {
return beginning!.secondsEarlier(than: end!)
}
return Int.max
}
@ -112,7 +110,7 @@ public extension TimePeriodProtocol {
* Returns a time chunk with all zeroes if beginning or end are nil.
*/
var chunk: TimeChunk {
if beginning != nil && end != nil {
if beginning != nil, end != nil {
return beginning!.chunkBetween(date: end!)
}
return TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 0)
@ -123,8 +121,8 @@ public extension TimePeriodProtocol {
* `TimePeriod` as a `TimeInterval`.
*/
var duration: TimeInterval {
if self.beginning != nil && self.end != nil {
return abs(self.beginning!.timeIntervalSince(self.end!))
if beginning != nil, end != nil {
return abs(beginning!.timeIntervalSince(end!))
}
return TimeInterval(Double.greatestFiniteMagnitude)
@ -145,36 +143,35 @@ public extension TimePeriodProtocol {
*/
func relation(to period: TimePeriodProtocol) -> Relation {
// Make sure that all start and end points exist for comparison
if (self.beginning != nil && self.end != nil && period.beginning != nil && period.end != nil) {
if beginning != nil, end != nil, period.beginning != nil, period.end != nil {
// Make sure time periods are of positive durations
if (self.beginning!.isEarlier(than: self.end!) && period.beginning!.isEarlier(than: period.end!)) {
if beginning!.isEarlier(than: end!), period.beginning!.isEarlier(than: period.end!) {
// Make comparisons
if (period.end!.isEarlier(than: self.beginning!)) {
if period.end!.isEarlier(than: beginning!) {
return .after
} else if (period.end!.equals(self.beginning!)) {
} else if period.end!.equals(beginning!) {
return .startTouching
} else if (period.beginning!.isEarlier(than: self.beginning!) && period.end!.isEarlier(than: self.end!)) {
} else if period.beginning!.isEarlier(than: beginning!), period.end!.isEarlier(than: end!) {
return .startInside
} else if (period.beginning!.equals(self.beginning!) && period.end!.isLater(than: self.end!)) {
} else if period.beginning!.equals(beginning!), period.end!.isLater(than: end!) {
return .insideStartTouching
} else if (period.beginning!.equals(self.beginning!) && period.end!.isEarlier(than: self.end!)) {
} else if period.beginning!.equals(beginning!), period.end!.isEarlier(than: end!) {
return .enclosingStartTouching
} else if (period.beginning!.isLater(than: self.beginning!) && period.end!.isEarlier(than: self.end!)) {
} else if period.beginning!.isLater(than: beginning!), period.end!.isEarlier(than: end!) {
return .enclosing
} else if (period.beginning!.isLater(than: self.beginning!) && period.end!.equals(self.end!)) {
} else if period.beginning!.isLater(than: beginning!), period.end!.equals(end!) {
return .enclosingEndTouching
} else if (period.beginning!.equals(self.beginning!) && period.end!.equals(self.end!)) {
} else if period.beginning!.equals(beginning!), period.end!.equals(end!) {
return .exactMatch
} else if (period.beginning!.isEarlier(than: self.beginning!) && period.end!.isLater(than: self.end!)) {
} else if period.beginning!.isEarlier(than: beginning!), period.end!.isLater(than: end!) {
return .inside
} else if (period.beginning!.isEarlier(than: self.beginning!) && period.end!.equals(self.end!)) {
} else if period.beginning!.isEarlier(than: beginning!), period.end!.equals(end!) {
return .insideEndTouching
} else if (period.beginning!.isEarlier(than: self.end!) && period.end!.isLater(than: self.end!)) {
} else if period.beginning!.isEarlier(than: end!), period.end!.isLater(than: end!) {
return .endInside
} else if (period.beginning!.equals(self.end!) && period.end!.isLater(than: self.end!)) {
} else if period.beginning!.equals(end!), period.end!.isLater(than: end!) {
return .endTouching
} else if (period.beginning!.isLater(than: self.end!)) {
} else if period.beginning!.isLater(than: end!) {
return .before
}
}
@ -192,7 +189,7 @@ public extension TimePeriodProtocol {
* - returns: True if the periods are the same
*/
func equals(_ period: TimePeriodProtocol) -> Bool {
return self.beginning == period.beginning && self.end == period.end
return beginning == period.beginning && end == period.end
}
/**
@ -204,7 +201,7 @@ public extension TimePeriodProtocol {
* - returns: True if self is inside of the given `TimePeriod`
*/
func isInside(of period: TimePeriodProtocol) -> Bool {
return period.beginning!.isEarlierThanOrEqual(to: self.beginning!) && period.end!.isLaterThanOrEqual(to: self.end!)
return period.beginning!.isEarlierThanOrEqual(to: beginning!) && period.end!.isLaterThanOrEqual(to: end!)
}
/**
@ -216,10 +213,10 @@ public extension TimePeriodProtocol {
* - returns: True if the given `TimePeriod` is inside of self
*/
func contains(_ date: Date, interval: Interval) -> Bool {
if (interval == .open) {
return self.beginning!.isEarlier(than: date) && self.end!.isLater(than: date)
} else if (interval == .closed) {
return (self.beginning!.isEarlierThanOrEqual(to: date) && self.end!.isLaterThanOrEqual(to: date))
if interval == .open {
return beginning!.isEarlier(than: date) && end!.isLater(than: date)
} else if interval == .closed {
return (beginning!.isEarlierThanOrEqual(to: date) && end!.isLaterThanOrEqual(to: date))
}
return false
@ -234,7 +231,7 @@ public extension TimePeriodProtocol {
* - returns: True if the given `TimePeriod` is inside of self
*/
func contains(_ period: TimePeriodProtocol) -> Bool {
return self.beginning!.isEarlierThanOrEqual(to: period.beginning!) && self.end!.isLaterThanOrEqual(to: period.end!)
return beginning!.isEarlierThanOrEqual(to: period.beginning!) && end!.isLaterThanOrEqual(to: period.end!)
}
/**
@ -246,15 +243,15 @@ public extension TimePeriodProtocol {
*/
func overlaps(with period: TimePeriodProtocol) -> Bool {
// Outside -> Inside
if (period.beginning!.isEarlier(than: self.beginning!) && period.end!.isLater(than: self.beginning!)) {
if period.beginning!.isEarlier(than: beginning!), period.end!.isLater(than: beginning!) {
return true
}
// Enclosing
else if (period.beginning!.isLaterThanOrEqual(to: self.beginning!) && period.end!.isEarlierThanOrEqual(to: self.end!)) {
else if period.beginning!.isLaterThanOrEqual(to: beginning!), period.end!.isEarlierThanOrEqual(to: end!) {
return true
}
// Inside -> Out
else if(period.beginning!.isEarlier(than: self.end!) && period.end!.isLater(than: self.end!)) {
else if period.beginning!.isEarlier(than: end!), period.end!.isLater(than: end!) {
return true
}
return false
@ -268,7 +265,7 @@ public extension TimePeriodProtocol {
* - returns: True if there is a period of time or moment that is shared by both `TimePeriod`s
*/
func intersects(with period: TimePeriodProtocol) -> Bool {
return self.relation(to: period) != .after && self.relation(to: period) != .before
return relation(to: period) != .after && relation(to: period) != .before
}
/**
@ -279,7 +276,7 @@ public extension TimePeriodProtocol {
* - returns: True if there is a period of time between self and the given `TimePeriod` not contained by either period
*/
func hasGap(between period: TimePeriodProtocol) -> Bool {
return self.isBefore(period: period) || self.isAfter(period: period)
return isBefore(period: period) || isAfter(period: period)
}
/**
@ -290,10 +287,10 @@ public extension TimePeriodProtocol {
* - returns: The gap between the periods. Zero if there is no gap.
*/
func gap(between period: TimePeriodProtocol) -> TimeInterval {
if (self.end!.isEarlier(than: period.beginning!)) {
return abs(self.end!.timeIntervalSince(period.beginning!))
} else if (period.end!.isEarlier(than: self.beginning!)) {
return abs(period.end!.timeIntervalSince(self.beginning!))
if end!.isEarlier(than: period.beginning!) {
return abs(end!.timeIntervalSince(period.beginning!))
} else if period.end!.isEarlier(than: beginning!) {
return abs(period.end!.timeIntervalSince(beginning!))
}
return 0
}
@ -307,8 +304,8 @@ public extension TimePeriodProtocol {
* - returns: The gap between the periods, zero if there is no gap
*/
func gap(between period: TimePeriodProtocol) -> TimeChunk? {
if self.end != nil && period.beginning != nil {
return (self.end?.chunkBetween(date: period.beginning!))!
if end != nil, period.beginning != nil {
return (end?.chunkBetween(date: period.beginning!))!
}
return nil
}
@ -321,7 +318,7 @@ public extension TimePeriodProtocol {
* - returns: True if self is after the given `TimePeriod`
*/
func isAfter(period: TimePeriodProtocol) -> Bool {
return self.relation(to: period) == .after
return relation(to: period) == .after
}
/**
@ -332,7 +329,7 @@ public extension TimePeriodProtocol {
* - returns: True if self is after the given `TimePeriod`
*/
func isBefore(period: TimePeriodProtocol) -> Bool {
return self.relation(to: period) == .before
return relation(to: period) == .before
}
// MARK: - Shifts
@ -345,8 +342,8 @@ public extension TimePeriodProtocol {
* - parameter timeInterval: The time interval to shift the period by
*/
mutating func shift(by timeInterval: TimeInterval) {
self.beginning?.addTimeInterval(timeInterval)
self.end?.addTimeInterval(timeInterval)
beginning?.addTimeInterval(timeInterval)
end?.addTimeInterval(timeInterval)
}
/**
@ -355,8 +352,8 @@ public extension TimePeriodProtocol {
* - parameter chunk: The time chunk to shift the period by
*/
mutating func shift(by chunk: TimeChunk) {
self.beginning = self.beginning?.add(chunk)
self.end = self.end?.add(chunk)
beginning = beginning?.add(chunk)
end = end?.add(chunk)
}
// MARK: - Lengthen / Shorten
@ -372,12 +369,12 @@ public extension TimePeriodProtocol {
mutating func lengthen(by timeInterval: TimeInterval, at anchor: Anchor) {
switch anchor {
case .beginning:
self.end = self.end?.addingTimeInterval(timeInterval)
end = end?.addingTimeInterval(timeInterval)
case .center:
self.beginning = self.beginning?.addingTimeInterval(-timeInterval/2.0)
self.end = self.end?.addingTimeInterval(timeInterval/2.0)
beginning = beginning?.addingTimeInterval(-timeInterval / 2.0)
end = end?.addingTimeInterval(timeInterval / 2.0)
case .end:
self.beginning = self.beginning?.addingTimeInterval(-timeInterval)
beginning = beginning?.addingTimeInterval(-timeInterval)
}
}
@ -390,12 +387,12 @@ public extension TimePeriodProtocol {
mutating func lengthen(by chunk: TimeChunk, at anchor: Anchor) {
switch anchor {
case .beginning:
self.end = self.end?.add(chunk)
end = end?.add(chunk)
case .center:
// Do not lengthen by TimeChunk at center
print("Mutation via chunk from center anchor is not supported.")
case .end:
self.beginning = self.beginning?.subtract(chunk)
beginning = beginning?.subtract(chunk)
}
}
@ -408,12 +405,12 @@ public extension TimePeriodProtocol {
mutating func shorten(by timeInterval: TimeInterval, at anchor: Anchor) {
switch anchor {
case .beginning:
self.end = self.end?.addingTimeInterval(-timeInterval)
end = end?.addingTimeInterval(-timeInterval)
case .center:
self.beginning = self.beginning?.addingTimeInterval(timeInterval/2.0)
self.end = self.end?.addingTimeInterval(-timeInterval/2.0)
beginning = beginning?.addingTimeInterval(timeInterval / 2.0)
end = end?.addingTimeInterval(-timeInterval / 2.0)
case .end:
self.beginning = self.beginning?.addingTimeInterval(timeInterval)
beginning = beginning?.addingTimeInterval(timeInterval)
}
}
@ -426,12 +423,12 @@ public extension TimePeriodProtocol {
mutating func shorten(by chunk: TimeChunk, at anchor: Anchor) {
switch anchor {
case .beginning:
self.end = self.end?.subtract(chunk)
end = end?.subtract(chunk)
case .center:
// Do not shorten by TimeChunk at center
print("Mutation via chunk from center anchor is not supported.")
case .end:
self.beginning = self.beginning?.add(chunk)
beginning = beginning?.add(chunk)
}
}
}
@ -444,8 +441,8 @@ public extension TimePeriodProtocol {
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-periods) for more information.
*/
open class TimePeriod: TimePeriodProtocol {
// MARK: - Variables
/**
* The start date for a TimePeriod representing the starting boundary of the time period
*/
@ -458,9 +455,7 @@ open class TimePeriod: TimePeriodProtocol {
// MARK: - Initializers
init() {
}
init() {}
init(beginning: Date?, end: Date?) {
self.beginning = beginning
@ -469,27 +464,27 @@ open class TimePeriod: TimePeriodProtocol {
init(beginning: Date, duration: TimeInterval) {
self.beginning = beginning
self.end = beginning + duration
end = beginning + duration
}
init(end: Date, duration: TimeInterval) {
self.end = end
self.beginning = end.addingTimeInterval(-duration)
beginning = end.addingTimeInterval(-duration)
}
init(beginning: Date, chunk: TimeChunk) {
self.beginning = beginning
self.end = beginning + chunk
end = beginning + chunk
}
init(end: Date, chunk: TimeChunk) {
self.end = end
self.beginning = end - chunk
beginning = end - chunk
}
init(chunk: TimeChunk) {
self.beginning = Date()
self.end = self.beginning?.add(chunk)
beginning = Date()
end = beginning?.add(chunk)
}
// MARK: - Shifted
@ -503,8 +498,8 @@ open class TimePeriod: TimePeriodProtocol {
*/
func shifted(by timeInterval: TimeInterval) -> TimePeriod {
let timePeriod = TimePeriod()
timePeriod.beginning = self.beginning?.addingTimeInterval(timeInterval)
timePeriod.end = self.end?.addingTimeInterval(timeInterval)
timePeriod.beginning = beginning?.addingTimeInterval(timeInterval)
timePeriod.end = end?.addingTimeInterval(timeInterval)
return timePeriod
}
@ -517,8 +512,8 @@ open class TimePeriod: TimePeriodProtocol {
*/
func shifted(by chunk: TimeChunk) -> TimePeriod {
let timePeriod = TimePeriod()
timePeriod.beginning = self.beginning?.add(chunk)
timePeriod.end = self.end?.add(chunk)
timePeriod.beginning = beginning?.add(chunk)
timePeriod.end = end?.add(chunk)
return timePeriod
}
@ -538,14 +533,14 @@ open class TimePeriod: TimePeriodProtocol {
let timePeriod = TimePeriod()
switch anchor {
case .beginning:
timePeriod.beginning = self.beginning
timePeriod.end = self.end?.addingTimeInterval(timeInterval)
timePeriod.beginning = beginning
timePeriod.end = end?.addingTimeInterval(timeInterval)
case .center:
timePeriod.beginning = self.beginning?.addingTimeInterval(-timeInterval)
timePeriod.end = self.end?.addingTimeInterval(timeInterval)
timePeriod.beginning = beginning?.addingTimeInterval(-timeInterval)
timePeriod.end = end?.addingTimeInterval(timeInterval)
case .end:
timePeriod.beginning = self.beginning?.addingTimeInterval(-timeInterval)
timePeriod.end = self.end
timePeriod.beginning = beginning?.addingTimeInterval(-timeInterval)
timePeriod.end = end
}
return timePeriod

21
Clocker/Dependencies/Date Additions/TimePeriodChain.swift

@ -18,7 +18,6 @@ import Foundation
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-period-chains) for more information.
*/
open class TimePeriodChain: TimePeriodGroup {
// MARK: - Chain Existence Manipulation
/**
@ -28,10 +27,10 @@ open class TimePeriodChain: TimePeriodGroup {
* - parameter period: TimePeriodProtocol to add to the collection
*/
public func append(_ period: TimePeriodProtocol) {
let beginning = (self.periods.isEmpty == false) ? self.periods.last!.end! : period.beginning
let beginning = (periods.isEmpty == false) ? periods.last!.end! : period.beginning
let newPeriod = TimePeriod(beginning: beginning!, duration: period.duration)
self.periods.append(newPeriod)
periods.append(newPeriod)
// Update updateExtremes
if periods.count == 1 {
@ -50,10 +49,10 @@ open class TimePeriodChain: TimePeriodGroup {
*/
public func append<G: TimePeriodGroup>(contentsOf group: G) {
for period in group.periods {
let beginning = (self.periods.isEmpty == false) ? self.periods.last!.end! : period.beginning
let beginning = (periods.isEmpty == false) ? periods.last!.end! : period.beginning
let newPeriod = TimePeriod(beginning: beginning!, duration: period.duration)
self.periods.append(newPeriod)
periods.append(newPeriod)
// Update updateExtremes
if periods.count == 1 {
@ -73,10 +72,10 @@ open class TimePeriodChain: TimePeriodGroup {
*/
public func insert(_ period: TimePeriodProtocol, at index: Int) {
// Check for special zero case which takes the beginning date
if index == 0 && period.beginning != nil && period.end != nil {
if index == 0, period.beginning != nil, period.end != nil {
// Insert new period
periods.insert(period, at: index)
} else if period.beginning != nil && period.end != nil {
} else if period.beginning != nil, period.end != nil {
// Insert new period
periods.insert(period, at: index)
} else {
@ -86,7 +85,7 @@ open class TimePeriodChain: TimePeriodGroup {
// Shift all periods after inserted period
for i in 0 ..< periods.count {
if i > index && i > 0 {
if i > index, i > 0 {
let currentPeriod = TimePeriod(beginning: period.beginning, end: period.end)
periods[i].beginning = periods[i - 1].end
periods[i].end = periods[i].beginning!.addingTimeInterval(currentPeriod.duration)
@ -119,7 +118,7 @@ open class TimePeriodChain: TimePeriodGroup {
* Remove all periods from period array.
*/
public func removeAll() {
self.periods.removeAll()
periods.removeAll()
updateExtremes()
}
@ -131,7 +130,7 @@ open class TimePeriodChain: TimePeriodGroup {
* - parameter duration: The time interval to shift the period by
*/
public func shift(by duration: TimeInterval) {
for var period in self.periods {
for var period in periods {
period.shift(by: duration)
}
@ -156,7 +155,7 @@ open class TimePeriodChain: TimePeriodGroup {
*
*/
public func pop() -> TimePeriodProtocol? {
let period = self.periods.popLast()
let period = periods.popLast()
updateExtremes()
return period

42
Clocker/Dependencies/Date Additions/TimePeriodCollection.swift

@ -17,7 +17,6 @@ import Foundation
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-period-collections) for more information.
*/
open class TimePeriodCollection: TimePeriodGroup {
// MARK: - Collection Manipulation
/**
@ -93,12 +92,12 @@ open class TimePeriodCollection: TimePeriodGroup {
* Sort periods array in place by beginning
*/
public func sortByBeginning() {
self.sort { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in
if period1.beginning == nil && period2.beginning == nil {
sort { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in
if period1.beginning == nil, period2.beginning == nil {
return false
} else if (period1.beginning == nil) {
} else if period1.beginning == nil {
return true
} else if (period2.beginning == nil) {
} else if period2.beginning == nil {
return false
} else {
return period2.beginning! < period1.beginning!
@ -110,7 +109,7 @@ open class TimePeriodCollection: TimePeriodGroup {
* Sort periods array in place
*/
public func sort(by areInIncreasingOrder: (TimePeriodProtocol, TimePeriodProtocol) -> Bool) {
self.periods.sort(by: areInIncreasingOrder)
periods.sort(by: areInIncreasingOrder)
}
// New collection
@ -120,12 +119,12 @@ open class TimePeriodCollection: TimePeriodGroup {
* - returns: Collection with sorted periods
*/
public func sortedByBeginning() -> TimePeriodCollection {
let array = self.periods.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in
if period1.beginning == nil && period2.beginning == nil {
let array = periods.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in
if period1.beginning == nil, period2.beginning == nil {
return false
} else if (period1.beginning == nil) {
} else if period1.beginning == nil {
return true
} else if (period2.beginning == nil) {
} else if period2.beginning == nil {
return false
} else {
return period2.beginning! < period1.beginning!
@ -143,7 +142,7 @@ open class TimePeriodCollection: TimePeriodGroup {
*/
public func sorted(by areInIncreasingOrder: (TimePeriodProtocol, TimePeriodProtocol) -> Bool) -> TimePeriodCollection {
let collection = TimePeriodCollection()
collection.append(self.periods.sorted(by: areInIncreasingOrder))
collection.append(periods.sorted(by: areInIncreasingOrder))
return collection
}
@ -161,9 +160,9 @@ open class TimePeriodCollection: TimePeriodGroup {
public func allInside(in period: TimePeriodProtocol) -> TimePeriodCollection {
let collection = TimePeriodCollection()
// Filter by period
collection.periods = self.periods.filter({ (timePeriod: TimePeriodProtocol) -> Bool in
return timePeriod.isInside(of: period)
})
collection.periods = periods.filter { (timePeriod: TimePeriodProtocol) -> Bool in
timePeriod.isInside(of: period)
}
return collection
}
@ -178,9 +177,9 @@ open class TimePeriodCollection: TimePeriodGroup {
public func periodsIntersected(by date: Date) -> TimePeriodCollection {
let collection = TimePeriodCollection()
// Filter by period
collection.periods = self.periods.filter({ (timePeriod: TimePeriodProtocol) -> Bool in
return timePeriod.contains(date, interval: .closed)
})
collection.periods = periods.filter { (timePeriod: TimePeriodProtocol) -> Bool in
timePeriod.contains(date, interval: .closed)
}
return collection
}
@ -195,9 +194,9 @@ open class TimePeriodCollection: TimePeriodGroup {
public func periodsIntersected(by period: TimePeriodProtocol) -> TimePeriodCollection {
let collection = TimePeriodCollection()
// Filter by periop
collection.periods = self.periods.filter({ (timePeriod: TimePeriodProtocol) -> Bool in
return timePeriod.intersects(with: period)
})
collection.periods = periods.filter { (timePeriod: TimePeriodProtocol) -> Bool in
timePeriod.intersects(with: period)
}
return collection
}
@ -227,14 +226,13 @@ open class TimePeriodCollection: TimePeriodGroup {
internal func updateExtremes(period: TimePeriodProtocol) {
// Check incoming period against previous beginning and end date
if self.count == 1 {
if count == 1 {
_beginning = period.beginning
_end = period.end
} else {
_beginning = nilOrEarlier(date1: _beginning, date2: period.beginning)
_end = nilOrLater(date1: _end, date2: period.end)
}
}
internal func updateExtremes() {

25
Clocker/Dependencies/Date Additions/TimePeriodGroup.swift

@ -16,7 +16,6 @@ import Foundation
* [Visit our github page](https://github.com/MatthewYork/DateTools#time-period-groups) for more information.
*/
open class TimePeriodGroup: Sequence {
// MARK: - Variables
/**
@ -57,7 +56,7 @@ open class TimePeriodGroup: Sequence {
* periods array. Nil if any beginning or end date in any contained period is nil.
*/
public var duration: TimeInterval? {
if beginning != nil && end != nil {
if beginning != nil, end != nil {
return end!.timeIntervalSince(beginning!)
}
return nil
@ -65,9 +64,7 @@ open class TimePeriodGroup: Sequence {
// MARK: - Initializers
public init() {
}
public init() {}
// MARK: - Comparisons
@ -79,12 +76,12 @@ open class TimePeriodGroup: Sequence {
* - returns: True if the periods arrays are the same
*/
public func equals(_ group: TimePeriodGroup) -> Bool {
return containSameElements(array1: self.periods, group.periods)
return containSameElements(array1: periods, group.periods)
}
// MARK: - Sequence Protocol
public func makeIterator() -> IndexingIterator<Array<TimePeriodProtocol>> {
public func makeIterator() -> IndexingIterator<[TimePeriodProtocol]> {
return periods.makeIterator()
}
@ -105,10 +102,8 @@ open class TimePeriodGroup: Sequence {
}
subscript(index: Int) -> TimePeriodProtocol {
get {
return periods[index]
}
}
internal func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, TimePeriodProtocol) throws -> Result) rethrows -> Result {
return try periods.reduce(initialResult, nextPartialResult)
@ -120,22 +115,22 @@ open class TimePeriodGroup: Sequence {
}
var compArray1: [TimePeriodProtocol] = array1.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in
if period1.beginning == nil && period2.beginning == nil {
if period1.beginning == nil, period2.beginning == nil {
return false
} else if (period1.beginning == nil) {
} else if period1.beginning == nil {
return true
} else if (period2.beginning == nil) {
} else if period2.beginning == nil {
return false
} else {
return period2.beginning! < period1.beginning!
}
}
var compArray2: [TimePeriodProtocol] = array2.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in
if period1.beginning == nil && period2.beginning == nil {
if period1.beginning == nil, period2.beginning == nil {
return false
} else if (period1.beginning == nil) {
} else if period1.beginning == nil {
return true
} else if (period2.beginning == nil) {
} else if period2.beginning == nil {
return false
} else {
return period2.beginning! < period1.beginning!

34
Clocker/Dependencies/Solar.swift

@ -4,21 +4,20 @@ import Cocoa
import CoreLocation
public struct Solar {
/// The coordinate that is used for the calculation
public let coordinate: CLLocationCoordinate2D
/// The date to generate sunrise / sunset times for
public fileprivate(set) var date: Date
public private(set) var date: Date
public fileprivate(set) var sunrise: Date?
public fileprivate(set) var sunset: Date?
public fileprivate(set) var civilSunrise: Date?
public fileprivate(set) var civilSunset: Date?
public fileprivate(set) var nauticalSunrise: Date?
public fileprivate(set) var nauticalSunset: Date?
public fileprivate(set) var astronomicalSunrise: Date?
public fileprivate(set) var astronomicalSunset: Date?
public private(set) var sunrise: Date?
public private(set) var sunset: Date?
public private(set) var civilSunrise: Date?
public private(set) var civilSunset: Date?
public private(set) var nauticalSunrise: Date?
public private(set) var nauticalSunset: Date?
public private(set) var astronomicalSunrise: Date?
public private(set) var astronomicalSunset: Date?
// MARK: Init
@ -52,20 +51,20 @@ public struct Solar {
// MARK: - Private functions
fileprivate enum SunriseSunset {
private enum SunriseSunset {
case sunrise
case sunset
}
/// Used for generating several of the possible sunrise / sunset times
fileprivate enum Zenith: Double {
private enum Zenith: Double {
case official = 90.83
case civil = 96
case nautical = 102
case astronimical = 108
}
fileprivate func calculate(_ sunriseSunset: SunriseSunset, for date: Date, and zenith: Zenith) -> Date? {
private func calculate(_ sunriseSunset: SunriseSunset, for date: Date, and zenith: Zenith) -> Date? {
guard let utcTimezone = TimeZone(identifier: "UTC") else { return nil }
// Get the day of the year
@ -147,7 +146,7 @@ public struct Solar {
if shouldBeYesterday {
setDate = Date(timeInterval: -(60 * 60 * 24), since: date)
} else if shouldBeTomorrow {
setDate = Date(timeInterval: (60 * 60 * 24), since: date)
setDate = Date(timeInterval: 60 * 60 * 24, since: date)
} else {
setDate = date
}
@ -162,7 +161,7 @@ public struct Solar {
}
/// Normalises a value between 0 and `maximum`, by adding or subtracting `maximum`
fileprivate func normalise(_ value: Double, withMaximum maximum: Double) -> Double {
private func normalise(_ value: Double, withMaximum maximum: Double) -> Double {
var value = value
if value < 0 {
@ -175,11 +174,9 @@ public struct Solar {
return value
}
}
extension Solar {
/// Whether the location specified by the `latitude` and `longitude` is in daytime on `date`
/// - Complexity: O(1)
public var isDaytime: Bool {
@ -192,7 +189,7 @@ extension Solar {
let beginningOfDay = sunrise.timeIntervalSince1970
let endOfDay = sunset.timeIntervalSince1970
let currentTime = self.date.timeIntervalSince1970
let currentTime = date.timeIntervalSince1970
let isSunriseOrLater = currentTime >= beginningOfDay
let isBeforeSunset = currentTime < endOfDay
@ -205,7 +202,6 @@ extension Solar {
public var isNighttime: Bool {
return !isDaytime
}
}
// MARK: - Helper extensions

15
Clocker/Events and Reminders/CalendarHandler.swift

@ -94,17 +94,17 @@ extension EventCenter {
let relevantEvents = filteredEvents[autoupdatingCalendar.startOfDay(for: Date())] ?? []
let filteredEvent = relevantEvents.filter({
let filteredEvent = relevantEvents.filter {
$0.event.isAllDay == false && $0.event.startDate.timeIntervalSinceNow > 0
}).first
}.first
if let firstEvent = filteredEvent {
return firstEvent.event
}
let filteredAllDayEvent = relevantEvents.filter({
let filteredAllDayEvent = relevantEvents.filter {
$0.isAllDay
}).first
}.first
return filteredAllDayEvent?.event
}
@ -113,7 +113,7 @@ extension EventCenter {
store.requestAccess(to: entity) { [weak self] granted, _ in
// On successful granting of calendar permission, we default to showing events from all calendars
if let `self` = self, entity == .event, granted {
if let self = self, entity == .event, granted {
self.saveDefaultIdentifiersList()
}
@ -149,7 +149,7 @@ extension EventCenter {
func saveDefaultIdentifiersList() {
OperationQueue.main.addOperation { [weak self] in
guard let `self` = self else { return }
guard let self = self else { return }
let allCalendars = self.retrieveAllCalendarIdentifiers()
if !allCalendars.isEmpty {
@ -162,7 +162,7 @@ extension EventCenter {
func retrieveAllCalendarIdentifiers() -> [String] {
return store.calendars(for: .event).map { (calendar) -> String in
return calendar.calendarIdentifier
calendar.calendarIdentifier
}
}
@ -211,7 +211,6 @@ extension EventCenter {
// We map eachDate to array of events happening on that day
for event in events where shouldSkipEvent(event) == false {
// Iterate through the days this event spans. We only care about
// days for this event that are between startDate and endDate
let eventStartDate = event.startDate as NSDate

2
Clocker/Events and Reminders/EventCenter.swift

@ -29,7 +29,7 @@ class EventCenter: NSObject {
object: nil)
}
@objc func eventStoreDidChange(_ sender: Any) {
@objc func eventStoreDidChange(_: Any) {
refetchAll()
}

3
Clocker/Events and Reminders/RemindersHandler.swift

@ -3,7 +3,6 @@
import EventKit
extension EventCenter {
// MARK: Private helper methods
private func retrieveCalendar() -> EKCalendar? {
@ -11,7 +10,7 @@ extension EventCenter {
let calendars = store.calendars(for: .reminder)
let calendarTitle = "Clocker Reminders"
let predicate = NSPredicate(format: "title matches %@", calendarTitle)
let filtered = calendars.filter({ predicate.evaluate(with: $0) })
let filtered = calendars.filter { predicate.evaluate(with: $0) }
if !filtered.isEmpty {
calendar = filtered.first

12
Clocker/Menu Bar/MenubarHandler.swift

@ -5,7 +5,6 @@ import EventKit
class MenubarHandler: NSObject {
@objc func titleForMenubar() -> String? {
if let nextEvent = checkForUpcomingEvents() {
return nextEvent
}
@ -20,11 +19,11 @@ class MenubarHandler: NSObject {
}
if menubarTitles.isEmpty == false {
let titles = menubarTitles.map({ (data) -> String? in
let titles = menubarTitles.map { (data) -> String? in
let timezone = TimezoneData.customObject(from: data)
let operationsObject = TimezoneDataOperations(with: timezone!)
return "\(operationsObject.menuTitle().trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines))"
})
}
let titlesStringified = titles.compactMap { $0 }
return titlesStringified.joined(separator: " ")
@ -34,9 +33,7 @@ class MenubarHandler: NSObject {
}
private func checkForUpcomingEvents() -> String? {
if DataStore.shared().shouldDisplay(.showMeetingInMenubar) {
let filteredDates = EventCenter.sharedCenter().eventsForDate
let autoupdatingCal = EventCenter.sharedCenter().autoupdatingCalendar
guard let events = filteredDates[autoupdatingCal.startOfDay(for: Date())] else {
@ -44,13 +41,10 @@ class MenubarHandler: NSObject {
}
for event in events {
if event.event.startDate.timeIntervalSinceNow > 0 && !event.isAllDay {
if event.event.startDate.timeIntervalSinceNow > 0, !event.isAllDay {
let timeForEventToStart = event.event.startDate.timeIntervalSinceNow / 60
if timeForEventToStart > 30 {
print("Our next event: \(event.event.title ?? "Error") starts in \(timeForEventToStart) mins")
continue

8
Clocker/Menu Bar/StatusContainerView.swift

@ -21,7 +21,6 @@ func bufferCalculatedWidth() -> Int {
}
func compactWidth(for timezone: TimezoneData) -> Int {
var totalWidth = 55
let timeFormat = timezone.timezoneFormat()
@ -47,7 +46,6 @@ func compactWidth(for timezone: TimezoneData) -> Int {
let bufferWidth: CGFloat = 9.5
class StatusContainerView: NSView {
private var previousX: Int = 0
override func awakeFromNib() {
@ -57,7 +55,6 @@ class StatusContainerView: NSView {
}
init(with timezones: [Data]) {
func addSubviews() {
timezones.forEach {
if let timezoneObject = TimezoneData.customObject(from: $0) {
@ -91,12 +88,11 @@ class StatusContainerView: NSView {
addSubviews()
}
required init?(coder decoder: NSCoder) {
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func addTimezone(_ timezone: TimezoneData) {
let calculatedWidth = bestWidth(for: timezone)
let frame = NSRect(x: previousX, y: 0, width: calculatedWidth, height: 30)
@ -118,7 +114,6 @@ class StatusContainerView: NSView {
}
func updateTime() {
if subviews.isEmpty {
assertionFailure("Subviews count should > 0")
}
@ -129,5 +124,4 @@ class StatusContainerView: NSView {
}
}
}
}

5
Clocker/Menu Bar/StatusItemHandler.swift

@ -9,7 +9,6 @@ private enum MenubarState {
}
class StatusItemHandler: NSObject {
var hasActiveIcon: Bool = false
var menubarTimer: Timer?
@ -219,7 +218,7 @@ class StatusItemHandler: NSObject {
let shouldDisplaySeconds = shouldDisplaySecondsInMenubar()
let menubarFavourites = DataStore.shared().retrieve(key: CLMenubarFavorites)
if !units.contains(.second) && shouldDisplaySeconds {
if !units.contains(.second), shouldDisplaySeconds {
units.insert(.second)
}
@ -281,7 +280,7 @@ class StatusItemHandler: NSObject {
let menubarFavourites = (DataStore.shared().retrieve(key: CLMenubarFavorites) as? [Data]) ?? []
if menubarFavourites.isEmpty && DataStore.shared().shouldDisplay(.showMeetingInMenubar) == false {
if menubarFavourites.isEmpty, DataStore.shared().shouldDisplay(.showMeetingInMenubar) == false {
print("Invalidating menubar timer!")
invalidation()

15
Clocker/Menu Bar/StatusItemView.swift

@ -14,26 +14,26 @@ var compactModeTimeFont: NSFont {
}
var timeAttributes: [NSAttributedString.Key: AnyObject] {
let textColor = UserDefaults.standard.string(forKey: "AppleInterfaceStyle") == "Dark" ? NSColor.white : NSColor.black
let attributes = [
NSAttributedString.Key.font: compactModeTimeFont,
NSAttributedString.Key.foregroundColor: textColor,
NSAttributedString.Key.backgroundColor: NSColor.clear,
NSAttributedString.Key.paragraphStyle: defaultParagraphStyle
NSAttributedString.Key.paragraphStyle: defaultParagraphStyle,
]
return attributes
}
class StatusItemView: NSView {
// MARK: Private variables
private let locationView: NSTextField = NSTextField(labelWithString: "Hello")
private let timeView: NSTextField = NSTextField(labelWithString: "Mon 19:14 PM")
private var operationsObject: TimezoneDataOperations {
return TimezoneDataOperations(with: dataObject)
}
private var textFontAttributes: [NSAttributedString.Key: Any] {
let textColor = UserDefaults.standard.string(forKey: "AppleInterfaceStyle") == "Dark" ? NSColor.white : NSColor.black
@ -41,12 +41,13 @@ class StatusItemView: NSView {
NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 10),
NSAttributedString.Key.foregroundColor: textColor,
NSAttributedString.Key.backgroundColor: NSColor.clear,
NSAttributedString.Key.paragraphStyle: defaultParagraphStyle
NSAttributedString.Key.paragraphStyle: defaultParagraphStyle,
]
return textFontAttributes
}
// MARK: Public
var dataObject: TimezoneData! {
didSet {
initialSetup()
@ -69,14 +70,14 @@ class StatusItemView: NSView {
locationView.leadingAnchor.constraint(equalTo: leadingAnchor),
locationView.trailingAnchor.constraint(equalTo: trailingAnchor),
locationView.topAnchor.constraint(equalTo: topAnchor, constant: 7),
locationView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.35)
locationView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.35),
])
NSLayoutConstraint.activate([
timeView.leadingAnchor.constraint(equalTo: leadingAnchor),
timeView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 0),
timeView.topAnchor.constraint(equalTo: locationView.bottomAnchor),
timeView.bottomAnchor.constraint(equalTo: bottomAnchor)
timeView.bottomAnchor.constraint(equalTo: bottomAnchor),
])
}
@ -89,7 +90,7 @@ class StatusItemView: NSView {
timeView.attributedStringValue = NSAttributedString(string: operationsObject.compactMenuHeader(), attributes: timeAttributes)
}
required init?(coder decoder: NSCoder) {
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

6
Clocker/Onboarding/OnboardingParentViewController.swift

@ -58,7 +58,6 @@ class OnboardingParentViewController: NSViewController {
}
private func setupUI() {
setIdentifiersForTests()
positiveButton.title = "Get Started"
@ -178,11 +177,10 @@ class OnboardingParentViewController: NSViewController {
self.positiveButton.tag = OnboardingType.final.rawValue
self.positiveButton.title = "Launch Clocker"
}
}
private func performFinalStepsBeforeFinishing() {
self.positiveButton.tag = OnboardingType.complete.rawValue
positiveButton.tag = OnboardingType.complete.rawValue
// Install the menubar option!
let appDelegate = NSApplication.shared.delegate as? AppDelegate
@ -279,7 +277,6 @@ class OnboardingParentViewController: NSViewController {
}
private func shouldStartAtLogin(_ shouldStart: Bool) {
// If tests are going on, we don't want to enable/disable launch at login!
if ProcessInfo.processInfo.arguments.contains(CLOnboaringTestsLaunchArgument) {
return
@ -307,7 +304,6 @@ class OnboardingParentViewController: NSViewController {
}
private func currentController() -> [String: String] {
switch positiveButton.tag {
case 0:
return ["Onboarding Process Interrupted": "Welcome View"]

3
Clocker/Onboarding/OnboardingPermissionsViewController.swift

@ -91,7 +91,7 @@ class OnboardingPermissionsViewController: NSViewController {
eventCenter.requestAccess(to: .event, completionHandler: { [weak self] granted in
OperationQueue.main.addOperation {
guard let `self` = self else { return }
guard let self = self else { return }
self.calendarActivityIndicator.stopAnimation(nil)
@ -130,7 +130,6 @@ class OnboardingPermissionsViewController: NSViewController {
if granted {
OperationQueue.main.addOperation {
self.view.window?.orderBack(nil)
NSApp.activate(ignoringOtherApps: true)

30
Clocker/Onboarding/OnboardingSearchController.swift

@ -14,7 +14,7 @@ class OnboardingSearchController: NSViewController {
@IBOutlet private var searchBar: ClockerSearchField!
@IBOutlet private var resultsTableView: NSTableView!
@IBOutlet private var accessoryLabel: NSTextField!
@IBOutlet weak var undoButton: NSButton!
@IBOutlet var undoButton: NSButton!
private var results: [TimezoneData] = []
private var dataTask: URLSessionDataTask? = .none
@ -57,7 +57,7 @@ class OnboardingSearchController: NSViewController {
@objc func doubleClickAction(_: NSTableView?) {
[accessoryLabel].forEach { $0?.isHidden = false }
if resultsTableView.selectedRow >= 0 && resultsTableView.selectedRow < results.count {
if resultsTableView.selectedRow >= 0, resultsTableView.selectedRow < results.count {
let selectedTimezone = results[resultsTableView.selectedRow]
addTimezoneToDefaults(selectedTimezone)
@ -65,7 +65,6 @@ class OnboardingSearchController: NSViewController {
}
private func addTimezoneToDefaults(_ timezone: TimezoneData) {
func setupLabelHidingTimer() {
Timer.scheduledTimer(withTimeInterval: 5,
repeats: false) { _ in
@ -104,7 +103,6 @@ class OnboardingSearchController: NSViewController {
/// Returns true if there's an error.
private func handleEdgeCase(for response: Data?) -> Bool {
func setErrorPlaceholders() {
setInfoLabel("No timezone found! Try entering an exact name.")
searchBar.placeholderString = placeholders.randomElement()
@ -150,7 +148,7 @@ class OnboardingSearchController: NSViewController {
NetworkManager.task(with: urlString) { [weak self] response, error in
guard let `self` = self else { return }
guard let self = self else { return }
OperationQueue.main.addOperation {
if self.handleEdgeCase(for: response) == true {
@ -158,7 +156,7 @@ class OnboardingSearchController: NSViewController {
}
if error == nil, let json = response, let response = self.decodeTimezone(from: json) {
if self.resultsTableView.selectedRow >= 0 && self.resultsTableView.selectedRow < self.results.count {
if self.resultsTableView.selectedRow >= 0, self.resultsTableView.selectedRow < self.results.count {
var filteredAddress = "Error"
if let address = dataObject.formattedAddress {
@ -172,7 +170,7 @@ class OnboardingSearchController: NSViewController {
"latitude": latitude,
"longitude": longitude,
"nextUpdate": CLEmptyString,
CLCustomLabel: filteredAddress
CLCustomLabel: filteredAddress,
] as [String: Any]
DataStore.shared().addTimezone(TimezoneData(with: newTimeZone))
@ -222,7 +220,6 @@ class OnboardingSearchController: NSViewController {
}
@IBAction func search(_ sender: NSSearchField) {
resultsTableView.deselectAll(nil)
let searchString = sender.stringValue
@ -249,9 +246,8 @@ class OnboardingSearchController: NSViewController {
}
@objc func actualSearch() {
func setupForError() {
self.resultsTableView.isHidden = true
resultsTableView.isHidden = true
}
let userPreferredLanguage = Locale.preferredLanguages.first ?? "en-US"
@ -267,10 +263,9 @@ class OnboardingSearchController: NSViewController {
dataTask = NetworkManager.task(with: urlString,
completionHandler: { [weak self] response, error in
guard let `self` = self else { return }
guard let self = self else { return }
OperationQueue.main.addOperation {
print("Search string was: \(searchString)")
let currentSearchBarValue = self.searchBar.stringValue
@ -314,9 +309,9 @@ class OnboardingSearchController: NSViewController {
private func presentErrorMessage(_ errorMessage: String) {
if errorMessage == PreferencesConstants.offlineErrorMessage {
self.setInfoLabel(PreferencesConstants.noInternetConnectivityError)
setInfoLabel(PreferencesConstants.noInternetConnectivityError)
} else {
self.setInfoLabel(PreferencesConstants.tryAgainMessage)
setInfoLabel(PreferencesConstants.tryAgainMessage)
}
}
@ -333,7 +328,7 @@ class OnboardingSearchController: NSViewController {
CLTimezoneName: formattedAddress,
CLCustomLabel: formattedAddress,
CLTimezoneID: CLEmptyString,
CLPlaceIdentifier: $0.placeId
CLPlaceIdentifier: $0.placeId,
] as [String: Any]
self.results.append(TimezoneData(with: totalPackage))
@ -359,11 +354,10 @@ class OnboardingSearchController: NSViewController {
searchBar.placeholderString = placeholders.randomElement()
}
@IBAction func undoAction(_ sender: Any) {
@IBAction func undoAction(_: Any) {
DataStore.shared().removeLastTimezone()
setInfoLabel("Removed.")
}
}
extension OnboardingSearchController: NSTableViewDataSource {
@ -385,7 +379,7 @@ extension OnboardingSearchController: NSTableViewDataSource {
extension OnboardingSearchController: NSTableViewDelegate {
func tableView(_: NSTableView, heightOfRow row: Int) -> CGFloat {
if row == 0 && results.isEmpty {
if row == 0, results.isEmpty {
return 30
}

9
Clocker/Overall App/AppDefaults.swift

@ -3,7 +3,6 @@
import Cocoa
class AppDefaults {
class func initialize() {
initializeDefaults()
}
@ -19,7 +18,6 @@ class AppDefaults {
}
private class func initializeDefaults() {
let userDefaults = UserDefaults.standard
let menubarFavourites = userDefaults.object(forKey: CLMenubarFavorites)
@ -43,7 +41,6 @@ class AppDefaults {
// If we already have timezones to display in menubar, do nothing.
// Else, we switch the menubar mode default to compact mode for new users
if userDefaults.bool(forKey: CLDefaultMenubarMode) == false {
if let menubarFavourites = userDefaults.object(forKey: CLDefaultPreferenceKey) as? [Data], menubarFavourites.isEmpty == false {
userDefaults.set(1, forKey: CLMenubarCompactMode)
} else {
@ -54,11 +51,9 @@ class AppDefaults {
}
if userDefaults.bool(forKey: CLSwitchToCompactModeAlert) == false {
userDefaults.set(true, forKey: CLSwitchToCompactModeAlert)
if let menubarFavourites = DataStore.shared().retrieve(key: CLMenubarFavorites) as? [Data], menubarFavourites.count > 1 {
// If the user is already using the compact mode, abort.
if DataStore.shared().shouldDisplay(.menubarCompactMode) {
return
@ -78,7 +73,6 @@ class AppDefaults {
// Set default to System theme for Mojave
if #available(macOS 10.14, *) {
if defaults.bool(forKey: CLDefaultThemeOnMojave) == false {
if isDarkModeOn() {
Themer.shared().set(theme: 2)
@ -139,16 +133,13 @@ class AppDefaults {
CLAppDislayOptions: 0,
CLMenubarCompactMode: 1]
}
}
extension UserDefaults {
func wipeIfNeccesary() {
if let bundleID = Bundle.main.bundleIdentifier, object(forKey: "PreferencesHaveBeenWiped") == nil {
removePersistentDomain(forName: bundleID)
set(true, forKey: "PreferencesHaveBeenWiped")
}
}
}

6
Clocker/Overall App/AppKit + Additions.swift

@ -1,7 +1,6 @@
// Copyright © 2015 Abhishek Banthia
extension NSTextField {
func applyDefaultStyle() {
backgroundColor = NSColor.clear
isEditable = false
@ -19,24 +18,21 @@ extension NSTextField {
cell?.wraps = false
cell?.isScrollable = true
}
}
extension NSFont {
func size(_ string: String, _ width: Double, attributes: [NSAttributedString.Key: AnyObject]) -> CGSize {
let size = CGSize(width: width,
height: Double.greatestFiniteMagnitude)
var otherAttributes: [NSAttributedString.Key: AnyObject] = [NSAttributedString.Key.font: self]
attributes.forEach { (arg) in let (key, value) = arg; otherAttributes[key] = value }
attributes.forEach { arg in let (key, value) = arg; otherAttributes[key] = value }
return NSString(string: string).boundingRect(with: size,
options: NSString.DrawingOptions.usesLineFragmentOrigin,
attributes: attributes).size
}
}
class ClockerSearchField: NSSearchField {

2
Clocker/Overall App/DateFormatterManager.swift

@ -46,7 +46,7 @@ class DateFormatterManager: NSObject {
return specializedFormatter
}
@objc class func localizedFormatter(with format: String, for timezoneIdentifier: String, locale: Locale = Locale.autoupdatingCurrent) -> DateFormatter {
@objc class func localizedFormatter(with format: String, for timezoneIdentifier: String, locale _: Locale = Locale.autoupdatingCurrent) -> DateFormatter {
dateFormatter.dateStyle = .none
dateFormatter.timeStyle = .none
dateFormatter.locale = Locale.autoupdatingCurrent

2
Clocker/Overall App/Reach.swift

@ -76,7 +76,7 @@ extension ReachabilityStatus {
let connectionRequired = flags.contains(.connectionRequired)
let isReachable = flags.contains(.reachable)
if !connectionRequired && isReachable {
if !connectionRequired, isReachable {
self = .online(.wiFi)
} else {
self = .offline

5
Clocker/Overall App/Themer.swift

@ -76,7 +76,6 @@ extension Themer {
}
setAppAppearance()
}
@objc func respondToInterfaceStyle() {
@ -315,7 +314,6 @@ extension Themer {
}
func currentLocationImage() -> NSImage {
if #available(macOS 10.14, *) {
switch themeIndex {
case .light:
@ -365,7 +363,6 @@ extension Themer {
}
func privacyTabImage() -> NSImage {
if #available(macOS 10.14, *) {
switch themeIndex {
case .light:
@ -381,7 +378,6 @@ extension Themer {
}
func appearanceTabImage() -> NSImage {
if #available(macOS 10.14, *) {
switch themeIndex {
case .light:
@ -397,7 +393,6 @@ extension Themer {
}
func calendarTabImage() -> NSImage {
if #available(macOS 10.14, *) {
switch themeIndex {
case .light:

4
Clocker/Overall App/Timer.swift

@ -126,7 +126,7 @@ open class Repeater: Equatable {
/// Current state of the timer
public private(set) var state: State = .paused {
didSet {
self.onStateChanged?(self, state)
onStateChanged?(self, state)
}
}
@ -334,7 +334,7 @@ open class Repeater: Equatable {
/// Pause a running timer. If timer is paused it does nothing.
@discardableResult
public func pause() -> Bool {
guard state != .paused && state != .finished else {
guard state != .paused, state != .finished else {
return false
}

1
Clocker/Overall App/UserDefaults + KVOExtensions.swift

@ -3,7 +3,6 @@
import Cocoa
extension UserDefaults {
@objc dynamic var displayFutureSlider: Int {
return integer(forKey: CLDisplayFutureSliderKey)
}

7
Clocker/Panel/Data Layer/TimezoneData.swift

@ -12,7 +12,6 @@ struct DateFormat {
// Non-class type cannot conform to NSCoding!
class TimezoneData: NSObject, NSCoding {
enum SelectionType: Int {
case city
case timezone
@ -202,7 +201,7 @@ class TimezoneData: NSObject, NSCoding {
let feedbackInfo = [
AppFeedbackConstants.CLOperatingSystemVersion: osVersion,
AppFeedbackConstants.CLClockerVersion: versionInfo
AppFeedbackConstants.CLClockerVersion: versionInfo,
]
Logger.log(object: feedbackInfo, for: "CLTimezoneData is still being used!")
@ -256,7 +255,7 @@ class TimezoneData: NSObject, NSCoding {
// Do the serialization
let serializedModels = newModels.map { (place) -> Data in
return NSKeyedArchiver.archivedData(withRootObject: place)
NSKeyedArchiver.archivedData(withRootObject: place)
}
return serializedModels
@ -361,7 +360,7 @@ class TimezoneData: NSObject, NSCoding {
let errorDictionary = [
"Formatted Address": name,
"Place Identifier": placeIdentifier,
"TimezoneID": timezoneIdentifier
"TimezoneID": timezoneIdentifier,
]
Logger.log(object: errorDictionary, for: "Error fetching timezone() in TimezoneData")

5
Clocker/Panel/Data Layer/TimezoneDataOperations.swift

@ -33,7 +33,6 @@ extension TimezoneDataOperations {
}
func compactMenuHeader() -> String {
var subtitle = CLEmptyString
let shouldDayBeShown = DataStore.shared().shouldShowDateInMenubar()
@ -136,10 +135,8 @@ extension TimezoneDataOperations {
}
if displayType == CLDateDisplayType.panelDisplay {
// Yesterday, tomorrow, etc
if relativeDayPreference.intValue == 0 {
let localFormatter = DateFormatterManager.localizedSimpleFormatter("EEEE")
let local = localFormatter.date(from: localeDate(with: "EEEE"))
@ -207,7 +204,7 @@ extension TimezoneDataOperations {
let unableToConvertDateParameters = [
"New Date": newDate,
"Timezone": dataObject.timezone(),
"Locale": dateFormatter.locale.identifier
"Locale": dateFormatter.locale.identifier,
] as [String: Any]
Logger.log(object: unableToConvertDateParameters, for: "Date conversion failure - New Date is nil")
return CLEmptyString

2
Clocker/Panel/FloatingWindowController.swift

@ -55,7 +55,7 @@ class FloatingWindowController: ParentPanelController {
target.image = Themer.shared().extraOptionsHighlightedImage()
if popover.isShown && row == previousPopoverRow {
if popover.isShown, row == previousPopoverRow {
popover.close()
target.image = Themer.shared().extraOptionsImage()
previousPopoverRow = -1

8
Clocker/Panel/Notes Popover/NotesPopover.swift

@ -3,7 +3,6 @@
import Cocoa
class NotesPopover: NSViewController {
private enum OverrideType {
case timezoneFormat
case seconds
@ -37,7 +36,7 @@ class NotesPopover: NSViewController {
@IBOutlet var timeFormatControl: NSSegmentedControl!
@IBOutlet weak var secondsFormatControl: NSSegmentedControl!
@IBOutlet var secondsFormatControl: NSSegmentedControl!
@IBOutlet var notesTextView: TextViewWithPlaceholder!
@ -62,7 +61,7 @@ class NotesPopover: NSViewController {
"1 hour before",
"2 hour before",
"1 day before",
"2 days before"
"2 days before",
]
alertPopupButton.removeAllItems()
@ -200,7 +199,7 @@ class NotesPopover: NSViewController {
let attributesDictionary = [
NSAttributedString.Key.font: font,
NSAttributedString.Key.foregroundColor: Themer.shared().mainTextColor(),
NSAttributedString.Key.paragraphStyle: style
NSAttributedString.Key.paragraphStyle: style,
]
button.attributedTitle = NSAttributedString(string: title,
@ -448,7 +447,6 @@ class NotesPopover: NSViewController {
handler.setupStatusItem()
}
}
}
@objc extension NotesPopover {

4
Clocker/Panel/Notes Popover/TextViewWithPlaceholder.swift

@ -18,7 +18,7 @@ class TextViewWithPlaceholder: NSTextView {
if let placeHolderFont = NSFont(name: "Avenir", size: 14) {
let textDict = [
NSAttributedString.Key.foregroundColor: NSColor.gray,
NSAttributedString.Key.font: placeHolderFont
NSAttributedString.Key.font: placeHolderFont,
]
return NSAttributedString(string: " Add your notes here.", attributes: textDict)
}
@ -32,7 +32,7 @@ class TextViewWithPlaceholder: NSTextView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
if string == CLEmptyString && self != window?.firstResponder {
if string == CLEmptyString, self != window?.firstResponder {
placeholder.draw(at: NSPoint(x: 0, y: 0))
}
}

11
Clocker/Panel/PanelController.swift

@ -3,7 +3,6 @@
import Cocoa
class PanelController: ParentPanelController {
@objc dynamic var hasActivePanel: Bool = false
static var sharedWindow = PanelController(windowNibName: .panel)
@ -76,7 +75,7 @@ class PanelController: ParentPanelController {
setTimezoneDatasourceSlider(sliderValue: 0)
reviewView.isHidden = !(RateController.canPrompt())
reviewView.isHidden = !RateController.canPrompt()
reviewView.layer?.backgroundColor = NSColor.clear.cgColor
@ -100,7 +99,6 @@ class PanelController: ParentPanelController {
// New way to set the panel's frame.
// This takes into account the screen's dimensions.
private func setPanelFrame() {
guard let appDelegate = NSApplication.shared.delegate as? AppDelegate else {
return
}
@ -176,14 +174,13 @@ class PanelController: ParentPanelController {
"Show Upcoming Event View": showUpcomingEventView == "YES" ? "Yes" : "No",
"Country": country,
"Calendar Access Provided": EventCenter.sharedCenter().calendarAccessGranted() ? "Yes" : "No",
"Number of Timezones": preferences.count
"Number of Timezones": preferences.count,
]
Logger.log(object: panelEvent, for: "openedPanel")
}
private func startWindowTimer() {
stopMenubarTimerIfNeccesary()
if let timer = parentTimer, timer.state == .paused {
@ -195,7 +192,6 @@ class PanelController: ParentPanelController {
}
private func startTimer() {
print("Start timer called")
parentTimer = Repeater(interval: .seconds(1), mode: .infinite) { _ in
@ -204,7 +200,6 @@ class PanelController: ParentPanelController {
}
}
parentTimer!.start()
}
private func stopMenubarTimerIfNeccesary() {
@ -278,7 +273,7 @@ class PanelController: ParentPanelController {
target.image = Themer.shared().extraOptionsHighlightedImage()
if popover.isShown && row == previousPopoverRow {
if popover.isShown, row == previousPopoverRow {
popover.close()
target.image = Themer.shared().extraOptionsImage()
previousPopoverRow = -1

38
Clocker/Panel/ParentPanelController.swift

@ -12,7 +12,6 @@ struct PanelConstants {
}
class ParentPanelController: NSWindowController {
private var futureSliderObserver: NSKeyValueObservation?
private var userFontSizeSelectionObserver: NSKeyValueObservation?
private var futureSliderRangeObserver: NSKeyValueObservation?
@ -98,13 +97,13 @@ class ParentPanelController: NSWindowController {
}
private func setupObservers() {
futureSliderObserver = UserDefaults.standard.observe(\.displayFutureSlider, options: [.new]) { (_, change) in
futureSliderObserver = UserDefaults.standard.observe(\.displayFutureSlider, options: [.new]) { _, change in
if let changedValue = change.newValue {
self.futureSliderView.isHidden = changedValue == 1
}
}
userFontSizeSelectionObserver = UserDefaults.standard.observe(\.userFontSize, options: [.new]) { (_, change) in
userFontSizeSelectionObserver = UserDefaults.standard.observe(\.userFontSize, options: [.new]) { _, change in
if let newFontSize = change.newValue {
Logger.log(object: ["FontSize": newFontSize], for: "User Font Size Preference")
self.mainTableView.reloadData()
@ -112,7 +111,7 @@ class ParentPanelController: NSWindowController {
}
}
futureSliderRangeObserver = UserDefaults.standard.observe(\.sliderDayRange, options: [.new]) { (_, change) in
futureSliderRangeObserver = UserDefaults.standard.observe(\.sliderDayRange, options: [.new]) { _, change in
if change.newValue != nil {
self.adjustFutureSliderBasedOnPreferences()
}
@ -153,7 +152,7 @@ class ParentPanelController: NSWindowController {
themeChanged()
futureSliderView.isHidden = !(DataStore.shared().shouldDisplay(.futureSlider))
futureSliderView.isHidden = !DataStore.shared().shouldDisplay(.futureSlider)
sharingButton.sendAction(on: .leftMouseDown)
@ -168,14 +167,13 @@ class ParentPanelController: NSWindowController {
}
private func showDebugVersionViewIfNeccesary() {
if debugVersionView != nil {
debugVersionView.wantsLayer = true
debugVersionView.layer?.backgroundColor = NSColor.systemRed.cgColor
}
#if RELEASE
if debugVersionView != nil && stackView.arrangedSubviews.contains(debugVersionView) {
if debugVersionView != nil, stackView.arrangedSubviews.contains(debugVersionView) {
stackView.removeView(debugVersionView)
}
#endif
@ -277,7 +275,7 @@ class ParentPanelController: NSWindowController {
let styleAttributes = [
NSAttributedString.Key.paragraphStyle: paragraphStyle,
NSAttributedString.Key.font: NSFont(name: "Avenir-Light", size: 13) ?? NSFont.systemFont(ofSize: 13)
NSAttributedString.Key.font: NSFont(name: "Avenir-Light", size: 13) ?? NSFont.systemFont(ofSize: 13),
]
let leftButtonAttributedTitle = NSAttributedString(string: leftButton.title, attributes: styleAttributes)
@ -830,7 +828,7 @@ class ParentPanelController: NSWindowController {
let styleAttributes = [
NSAttributedString.Key.paragraphStyle: paragraphStyle,
NSAttributedString.Key.font: NSFont(name: "Avenir-Light", size: 13)!
NSAttributedString.Key.font: NSFont(name: "Avenir-Light", size: 13)!,
]
leftButton.attributedTitle = NSAttributedString(string: "Not Really", attributes: styleAttributes)
rightButton.attributedTitle = NSAttributedString(string: "Yes!", attributes: styleAttributes)
@ -841,7 +839,7 @@ class ParentPanelController: NSWindowController {
return
}
NSAnimationContext.runAnimationGroup({ (context) in
NSAnimationContext.runAnimationGroup({ context in
context.duration = 1
context.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
leftButton.animator().alphaValue = 0.0
@ -849,7 +847,7 @@ class ParentPanelController: NSWindowController {
}, completionHandler: {
field.stringValue = title
NSAnimationContext.runAnimationGroup({ (context) in
NSAnimationContext.runAnimationGroup({ context in
context.duration = 1
context.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn)
self.runAnimationCompletionBlock(leftTitle, rightTitle)
@ -858,27 +856,27 @@ class ParentPanelController: NSWindowController {
}
private func runAnimationCompletionBlock(_ leftButtonTitle: String, _ rightButtonTitle: String) {
self.leftButton.animator().alphaValue = 1.0
self.rightButton.animator().alphaValue = 1.0
leftButton.animator().alphaValue = 1.0
rightButton.animator().alphaValue = 1.0
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let styleAttributes = [
NSAttributedString.Key.paragraphStyle: paragraphStyle,
NSAttributedString.Key.font: NSFont(name: "Avenir-Light", size: 13)!
NSAttributedString.Key.font: NSFont(name: "Avenir-Light", size: 13)!,
]
if self.leftButton.attributedTitle.string == "Not Really" {
self.leftButton.animator().attributedTitle = NSAttributedString(string: PanelConstants.noThanksTitle, attributes: styleAttributes)
if leftButton.attributedTitle.string == "Not Really" {
leftButton.animator().attributedTitle = NSAttributedString(string: PanelConstants.noThanksTitle, attributes: styleAttributes)
}
if self.rightButton.attributedTitle.string == PanelConstants.yesWithExclamation {
self.rightButton.animator().attributedTitle = NSAttributedString(string: "Yes, sure", attributes: styleAttributes)
if rightButton.attributedTitle.string == PanelConstants.yesWithExclamation {
rightButton.animator().attributedTitle = NSAttributedString(string: "Yes, sure", attributes: styleAttributes)
}
self.leftButton.animator().attributedTitle = NSAttributedString(string: leftButtonTitle, attributes: styleAttributes)
self.rightButton.animator().attributedTitle = NSAttributedString(string: rightButtonTitle, attributes: styleAttributes)
leftButton.animator().attributedTitle = NSAttributedString(string: leftButtonTitle, attributes: styleAttributes)
rightButton.animator().attributedTitle = NSAttributedString(string: rightButtonTitle, attributes: styleAttributes)
}
// MARK: Date Picker + Slider

2
Clocker/Panel/Rate Controller/RateController.swift

@ -3,7 +3,6 @@
import Cocoa
final class RateController {
private static var storage = UserDefaults.standard
private static let version: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String ?? "N/A"
private static var debugging = false
@ -66,5 +65,4 @@ final class RateController {
NSWorkspace.shared.open(ratingsURL)
prompted()
}
}

4
Clocker/Panel/Rate Controller/ReviewView.swift

@ -7,7 +7,7 @@ class ReviewView: NSView {
override func mouseEntered(with event: NSEvent) {
super.mouseEntered(with: event)
let dismissalButton = subviews.filter({ $0.tag == 55 }).first
let dismissalButton = subviews.filter { $0.tag == 55 }.first
if let firstMatch = dismissalButton, firstMatch.isHidden {
firstMatch.isHidden = false
}
@ -15,7 +15,7 @@ class ReviewView: NSView {
override func mouseExited(with event: NSEvent) {
super.mouseExited(with: event)
let dismissalButton = subviews.filter({ $0.tag == 55 }).first
let dismissalButton = subviews.filter { $0.tag == 55 }.first
if let firstMatch = dismissalButton, !firstMatch.isHidden {
firstMatch.isHidden = true
}

2
Clocker/Panel/UI/PanelTableView.swift

@ -31,7 +31,7 @@ class PanelTableView: NSTableView {
let options: NSTrackingArea.Options = [
.mouseMoved,
.mouseEnteredAndExited,
.activeAlways
.activeAlways,
]
let clipRect = enclosingScrollView?.contentView.bounds ?? .zero

2
Clocker/Panel/UI/TimezoneCellView.swift

@ -116,7 +116,7 @@ class TimezoneCellView: NSTableCellView {
var searchView = superview
while searchView != nil && searchView is PanelTableView == false {
while searchView != nil, searchView is PanelTableView == false {
searchView = searchView?.superview
}

4
Clocker/Panel/UI/TimezoneDataSource.swift

@ -60,7 +60,7 @@ extension TimezoneDataSource: NSTableViewDataSource, NSTableViewDelegate {
cellView.time.stringValue = operation.time(with: sliderValue)
cellView.noteLabel.stringValue = currentModel.note ?? CLEmptyString
cellView.noteLabel.toolTip = currentModel.note ?? CLEmptyString
cellView.currentLocationIndicator.isHidden = !(currentModel.isSystemTimezone)
cellView.currentLocationIndicator.isHidden = !currentModel.isSystemTimezone
cellView.time.setAccessibilityIdentifier("ActualTime")
cellView.layout(with: currentModel)
@ -177,7 +177,7 @@ extension TimezoneCellView {
sunriseImage.isHidden = !shouldDisplay
// If it's a timezone and not a place, we can't determine the sunrise/sunset time; hide the sunrise image
if model.selectionType == .timezone && (model.latitude == nil && model.longitude == nil) {
if model.selectionType == .timezone, model.latitude == nil, model.longitude == nil {
sunriseImage.isHidden = true
}

11
Clocker/Preferences/About/AboutViewController.swift

@ -33,7 +33,7 @@ class AboutViewController: ParentViewController {
setup()
themeDidChangeNotification = NotificationCenter.default.addObserver(forName: .themeDidChangeNotification, object: nil, queue: OperationQueue.main) { (_) in
themeDidChangeNotification = NotificationCenter.default.addObserver(forName: .themeDidChangeNotification, object: nil, queue: OperationQueue.main) { _ in
self.setup()
}
}
@ -48,14 +48,12 @@ class AboutViewController: ParentViewController {
let rangesInOrder = [NSRange(location: 3, length: 8),
NSRange(location: 7, length: privateFeedback.attributedTitle.length - 7),
NSRange(location: 27, length: 33),
NSRange(location: 32, length: 30)
]
NSRange(location: 32, length: 30)]
let buttonsInOrder = [quickCommentAction,
privateFeedback,
supportClocker,
openSourceButton
]
openSourceButton]
let localizedKeys = ["1. @n0shake on Twitter for quick comments",
"2. For Private Feedback",
@ -126,7 +124,6 @@ class AboutViewController: ParentViewController {
let custom: [String: Any] = ["Country": countryCode]
Logger.log(object: custom, for: "Report Issue Opened")
}
}
@IBAction func openGitHub(_: Any) {
@ -139,7 +136,7 @@ class AboutViewController: ParentViewController {
Logger.log(object: custom, for: "Opened GitHub")
}
@IBOutlet weak var feedbackLabel: NSTextField!
@IBOutlet var feedbackLabel: NSTextField!
private func setup() {
feedbackLabel.stringValue = "Feedback is always welcome:"

2
Clocker/Preferences/App Feedback/AppFeedbackWindowController.swift

@ -155,7 +155,7 @@ class AppFeedbackWindowController: NSWindowController {
AppFeedbackConstants.CLAppFeedbackEmailProperty: email,
AppFeedbackConstants.CLAppFeedbackFeedbackProperty: appFeedbackProperty,
AppFeedbackConstants.CLOperatingSystemVersion: osVersion,
AppFeedbackConstants.CLClockerVersion: versionInfo
AppFeedbackConstants.CLClockerVersion: versionInfo,
]
return feedbackInfo

57
Clocker/Preferences/Appearance/AppearanceViewController.swift

@ -8,10 +8,10 @@ class AppearanceViewController: ParentViewController {
@IBOutlet var informationLabel: NSTextField!
@IBOutlet var sliderDayRangePopup: NSPopUpButton!
@IBOutlet var visualEffectView: NSVisualEffectView!
@IBOutlet weak var menubarMode: NSSegmentedControl!
@IBOutlet weak var includeDayInMenubarControl: NSSegmentedControl!
@IBOutlet weak var includeDateInMenubarControl: NSSegmentedControl!
@IBOutlet weak var includePlaceNameControl: NSSegmentedControl!
@IBOutlet var menubarMode: NSSegmentedControl!
@IBOutlet var includeDayInMenubarControl: NSSegmentedControl!
@IBOutlet var includeDateInMenubarControl: NSSegmentedControl!
@IBOutlet var includePlaceNameControl: NSSegmentedControl!
private var themeDidChangeNotification: NSObjectProtocol?
@ -31,12 +31,12 @@ class AppearanceViewController: ParentViewController {
"4 days",
"5 days",
"6 days",
"7 days"
"7 days",
])
setup()
themeDidChangeNotification = NotificationCenter.default.addObserver(forName: .themeDidChangeNotification, object: nil, queue: OperationQueue.main) { (_) in
themeDidChangeNotification = NotificationCenter.default.addObserver(forName: .themeDidChangeNotification, object: nil, queue: OperationQueue.main) { _ in
self.setup()
self.animateBackgroundColorChange()
self.view.needsDisplay = true // Let's make the color change permanent.
@ -54,7 +54,7 @@ class AppearanceViewController: ParentViewController {
colorAnimation.duration = 0.25
colorAnimation.fromValue = previousBackgroundColor.cgColor
colorAnimation.toValue = Themer.shared().mainBackgroundColor().cgColor
self.view.layer?.add(colorAnimation, forKey: "backgroundColor")
view.layer?.add(colorAnimation, forKey: "backgroundColor")
}
override func viewWillAppear() {
@ -80,21 +80,21 @@ class AppearanceViewController: ParentViewController {
updateMenubarControls(!shouldDisplayCompact)
}
@IBOutlet weak var headerLabel: NSTextField!
@IBOutlet weak var timeFormatLabel: NSTextField!
@IBOutlet weak var panelTheme: NSTextField!
@IBOutlet weak var dayDisplayOptionsLabel: NSTextField!
@IBOutlet weak var showSliderLabel: NSTextField!
@IBOutlet weak var showSunriseLabel: NSTextField!
@IBOutlet weak var showSecondsLabel: NSTextField!
@IBOutlet weak var largerTextLabel: NSTextField!
@IBOutlet weak var futureSliderRangeLabel: NSTextField!
@IBOutlet weak var includeDateLabel: NSTextField!
@IBOutlet weak var includeDayLabel: NSTextField!
@IBOutlet weak var includePlaceLabel: NSTextField!
@IBOutlet weak var menubarDisplayOptionsLabel: NSTextField!
@IBOutlet weak var appDisplayLabel: NSTextField!
@IBOutlet weak var menubarModeLabel: NSTextField!
@IBOutlet var headerLabel: NSTextField!
@IBOutlet var timeFormatLabel: NSTextField!
@IBOutlet var panelTheme: NSTextField!
@IBOutlet var dayDisplayOptionsLabel: NSTextField!
@IBOutlet var showSliderLabel: NSTextField!
@IBOutlet var showSunriseLabel: NSTextField!
@IBOutlet var showSecondsLabel: NSTextField!
@IBOutlet var largerTextLabel: NSTextField!
@IBOutlet var futureSliderRangeLabel: NSTextField!
@IBOutlet var includeDateLabel: NSTextField!
@IBOutlet var includeDayLabel: NSTextField!
@IBOutlet var includePlaceLabel: NSTextField!
@IBOutlet var menubarDisplayOptionsLabel: NSTextField!
@IBOutlet var appDisplayLabel: NSTextField!
@IBOutlet var menubarModeLabel: NSTextField!
private func setup() {
headerLabel.stringValue = "Main Panel Options"
@ -136,7 +136,6 @@ class AppearanceViewController: ParentViewController {
private var previousBackgroundColor: NSColor = NSColor.white
@IBAction func themeChanged(_ sender: NSSegmentedControl) {
previousBackgroundColor = Themer.shared().mainBackgroundColor()
Themer.shared().set(theme: sender.selectedSegment)
@ -208,7 +207,6 @@ class AppearanceViewController: ParentViewController {
}
@IBAction func changeAppDisplayOptions(_ sender: NSSegmentedControl) {
if sender.selectedSegment == 0 {
Logger.log(object: ["Selection": "Menubar"], for: "Dock Mode")
NSApp.setActivationPolicy(.accessory)
@ -220,7 +218,7 @@ class AppearanceViewController: ParentViewController {
private func refresh(panel: Bool, floating: Bool) {
OperationQueue.main.addOperation {
if panel && DataStore.shared().shouldDisplay(ViewType.showAppInForeground) == false {
if panel, DataStore.shared().shouldDisplay(ViewType.showAppInForeground) == false {
guard let panelController = PanelController.panel() else { return }
let futureSliderBounds = panelController.futureSlider.bounds
@ -232,7 +230,7 @@ class AppearanceViewController: ParentViewController {
panelController.setupMenubarTimer()
}
if floating && DataStore.shared().shouldDisplay(ViewType.showAppInForeground) {
if floating, DataStore.shared().shouldDisplay(ViewType.showAppInForeground) {
if DataStore.shared().shouldDisplay(ViewType.showAppInForeground) {
let floatingWindow = FloatingWindowController.shared()
floatingWindow.updateTableContent()
@ -246,16 +244,16 @@ class AppearanceViewController: ParentViewController {
}
}
@IBAction func displayDayInMenubarAction(_ sender: Any) {
@IBAction func displayDayInMenubarAction(_: Any) {
DataStore.shared().updateDayPreference()
updateStatusItem()
}
@IBAction func displayDateInMenubarAction(_ sender: Any) {
@IBAction func displayDateInMenubarAction(_: Any) {
updateStatusItem()
}
@IBAction func displayPlaceInMenubarAction(_ sender: Any) {
@IBAction func displayPlaceInMenubarAction(_: Any) {
updateStatusItem()
}
@ -285,7 +283,6 @@ class AppearanceViewController: ParentViewController {
} else {
Logger.log(object: ["Context": "In Appearance View"], for: "Switched to Standard Mode")
}
}
// We don't support showing day or date in the menubar for compact mode yet.

54
Clocker/Preferences/Calendar/CalendarViewController.swift

@ -4,7 +4,6 @@ import Cocoa
import EventKit
class ClockerTextBackgroundView: NSView {
private var themeDidChangeNotification: NSObjectProtocol?
override func awakeFromNib() {
@ -13,7 +12,7 @@ class ClockerTextBackgroundView: NSView {
layer?.masksToBounds = false
layer?.backgroundColor = Themer.shared().textBackgroundColor().cgColor
themeDidChangeNotification = NotificationCenter.default.addObserver(forName: .themeDidChangeNotification, object: nil, queue: OperationQueue.main) { (_) in
themeDidChangeNotification = NotificationCenter.default.addObserver(forName: .themeDidChangeNotification, object: nil, queue: OperationQueue.main) { _ in
self.layer?.backgroundColor = Themer.shared().textBackgroundColor().cgColor
}
}
@ -31,18 +30,17 @@ class ClockerTextBackgroundView: NSView {
}
class CalendarViewController: ParentViewController {
@IBOutlet var showSegmentedControl: NSSegmentedControl!
@IBOutlet var allDaysSegmentedControl: NSSegmentedControl!
@IBOutlet var truncateTextField: NSTextField!
@IBOutlet var noAccessView: NSVisualEffectView!
@IBOutlet var informationField: NSTextField!
@IBOutlet var grantAccessButton: NSButton!
@IBOutlet weak var calendarsTableView: NSTableView!
@IBOutlet var calendarsTableView: NSTableView!
@IBOutlet weak var showNextMeetingInMenubarControl: NSSegmentedControl!
@IBOutlet weak var backgroundView: NSView!
@IBOutlet weak var nextMeetingBackgroundView: NSView!
@IBOutlet var showNextMeetingInMenubarControl: NSSegmentedControl!
@IBOutlet var backgroundView: NSView!
@IBOutlet var nextMeetingBackgroundView: NSView!
private var themeDidChangeNotification: NSObjectProtocol?
private lazy var calendars: [Any] = EventCenter.sharedCenter().fetchSourcesAndCalendars()
@ -57,7 +55,7 @@ class CalendarViewController: ParentViewController {
name: .calendarAccessGranted,
object: nil)
themeDidChangeNotification = NotificationCenter.default.addObserver(forName: .themeDidChangeNotification, object: nil, queue: OperationQueue.main) { (_) in
themeDidChangeNotification = NotificationCenter.default.addObserver(forName: .themeDidChangeNotification, object: nil, queue: OperationQueue.main) { _ in
self.setup()
}
@ -91,7 +89,7 @@ class CalendarViewController: ParentViewController {
}
// If the menubar mode is compact, we can't show meetings in the menubar. So disable toggling that option.
showNextMeetingInMenubarControl.isEnabled = !(DataStore.shared().shouldDisplay(.menubarCompactMode))
showNextMeetingInMenubarControl.isEnabled = !DataStore.shared().shouldDisplay(.menubarCompactMode)
}
private func verifyCalendarAccess() {
@ -121,7 +119,7 @@ class CalendarViewController: ParentViewController {
let attributesDictionary: [NSAttributedString.Key: Any] = [
NSAttributedString.Key.paragraphStyle: style,
NSAttributedString.Key.font: boldFont,
NSAttributedString.Key.foregroundColor: Themer.shared().mainTextColor()
NSAttributedString.Key.foregroundColor: Themer.shared().mainTextColor(),
]
let attributedString = NSAttributedString(string: title,
attributes: attributesDictionary)
@ -146,7 +144,6 @@ class CalendarViewController: ParentViewController {
}
@IBAction func showNextMeetingAction(_ sender: NSSegmentedControl) {
// We need to start the menubar timer if it hasn't been started already
guard let delegate = NSApplication.shared.delegate as? AppDelegate else {
assertionFailure()
@ -156,7 +153,6 @@ class CalendarViewController: ParentViewController {
let statusItemHandler = delegate.statusItemForPanel()
if sender.selectedSegment == 0 {
if let isValid = statusItemHandler.menubarTimer?.isValid, isValid == true {
print("Timer is already in progress")
updateStatusItem()
@ -164,10 +160,8 @@ class CalendarViewController: ParentViewController {
}
} else {
statusItemHandler.invalidateTimer(showIcon: true, isSyncing: false)
}
}
@IBAction func showUpcomingEventView(_ sender: NSSegmentedControl) {
@ -203,15 +197,15 @@ class CalendarViewController: ParentViewController {
statusItem.performTimerWork()
}
@IBOutlet weak var headerLabel: NSTextField!
@IBOutlet weak var upcomingEventView: NSTextField!
@IBOutlet weak var allDayMeetingsLabel: NSTextField!
@IBOutlet weak var showNextMeetingLabel: NSTextField!
@IBOutlet weak var nextMeetingAccessoryLabel: NSTextField!
@IBOutlet weak var truncateTextLabel: NSTextField!
@IBOutlet weak var showEventsFromLabel: NSTextField!
@IBOutlet weak var charactersField: NSTextField!
@IBOutlet weak var truncateAccessoryLabel: NSTextField!
@IBOutlet var headerLabel: NSTextField!
@IBOutlet var upcomingEventView: NSTextField!
@IBOutlet var allDayMeetingsLabel: NSTextField!
@IBOutlet var showNextMeetingLabel: NSTextField!
@IBOutlet var nextMeetingAccessoryLabel: NSTextField!
@IBOutlet var truncateTextLabel: NSTextField!
@IBOutlet var showEventsFromLabel: NSTextField!
@IBOutlet var charactersField: NSTextField!
@IBOutlet var truncateAccessoryLabel: NSTextField!
private func setup() {
// Grant access button's text color is taken care above.
@ -231,21 +225,18 @@ class CalendarViewController: ParentViewController {
}
extension CalendarViewController: NSTableViewDataSource {
func numberOfRows(in tableView: NSTableView) -> Int {
func numberOfRows(in _: NSTableView) -> Int {
let hasCalendarAccess = EventCenter.sharedCenter().calendarAccessGranted()
return hasCalendarAccess ? calendars.count : 0
}
}
extension CalendarViewController: NSTableViewDelegate {
func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
func tableView(_: NSTableView, shouldSelectRow _: Int) -> Bool {
return false
}
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
func tableView(_: NSTableView, heightOfRow row: Int) -> CGFloat {
guard let currentSource = calendars[row] as? String, !currentSource.isEmpty else {
return 30.0
}
@ -253,8 +244,7 @@ extension CalendarViewController: NSTableViewDelegate {
return 24.0
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
func tableView(_ tableView: NSTableView, viewFor _: NSTableColumn?, row: Int) -> NSView? {
if let currentSource = calendars[row] as? String,
let message = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "sourceCellView"), owner: self) as? SourceTableViewCell {
message.sourceName.stringValue = currentSource
@ -273,7 +263,6 @@ extension CalendarViewController: NSTableViewDelegate {
}
return nil
}
@objc func calendarSelected(_ checkbox: NSButton) {
@ -290,7 +279,6 @@ extension CalendarViewController: NSTableViewDelegate {
}
private func updateSelectedCalendars(_ selection: [Any]) {
var selectedCalendars: [String] = []
for obj in selection {

48
Clocker/Preferences/General/PreferencesViewController.swift

@ -70,7 +70,7 @@ class PreferencesViewController: ParentViewController {
@IBOutlet private var headerView: NSView!
@IBOutlet private var tableview: NSView!
@IBOutlet private var additionalSortOptions: NSView!
@IBOutlet weak var startAtLoginLabel: NSTextField!
@IBOutlet var startAtLoginLabel: NSTextField!
@IBOutlet var startupCheckbox: NSButton!
@IBOutlet var headerLabel: NSTextField!
@ -198,7 +198,7 @@ class PreferencesViewController: ParentViewController {
}
let archivedObjects = menubarTimes.map { (timezone) -> Data in
return NSKeyedArchiver.archivedData(withRootObject: timezone)
NSKeyedArchiver.archivedData(withRootObject: timezone)
}
UserDefaults.standard.set(archivedObjects, forKey: CLMenubarFavorites)
@ -244,7 +244,7 @@ class PreferencesViewController: ParentViewController {
[timezoneNameSortButton, labelSortButton, timezoneSortButton].forEach {
$0?.attributedTitle = NSAttributedString(string: $0?.title ?? CLEmptyString, attributes: [
NSAttributedString.Key.foregroundColor: Themer.shared().mainTextColor(),
NSAttributedString.Key.font: NSFont(name: "Avenir-Light", size: 13)!
NSAttributedString.Key.font: NSFont(name: "Avenir-Light", size: 13)!,
])
}
@ -362,7 +362,7 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate
return nil
}
private func handleTimezoneNameIdentifier(for row: Int, _ selectedDataSource: TimezoneData?) -> Any? {
private func handleTimezoneNameIdentifier(for _: Int, _ selectedDataSource: TimezoneData?) -> Any? {
guard let model = selectedDataSource else {
return nil
}
@ -382,7 +382,7 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate
return dataSource?.formattedAddress
}
} else {
if searchField.stringValue.isEmpty == false && row < timezoneFilteredArray.count {
if searchField.stringValue.isEmpty == false, row < timezoneFilteredArray.count {
return timezoneFilteredArray[row]
}
return timezoneArray[row]
@ -391,7 +391,7 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate
}
private func handleAbbreviationColumn(for row: Int) -> Any? {
if searchField.stringValue.isEmpty == false && (row < timezoneFilteredArray.count) {
if searchField.stringValue.isEmpty == false, row < timezoneFilteredArray.count {
let currentSelection = timezoneFilteredArray[row]
if currentSelection == "UTC" {
return "UTC"
@ -497,7 +497,7 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate
if selectedTimeZones.count > row {
Logger.log(object: [
"Old Label": dataObject.customLabel ?? "Error",
"New Label": formattedValue
"New Label": formattedValue,
],
for: "Custom Label Changed")
@ -510,25 +510,24 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate
Logger.log(object: [
"MethodName": "SetObjectValue",
"Selected Timezone Count": selectedTimeZones.count,
"Current Row": row
"Current Row": row,
],
for: "Error in selected row count")
}
}
private func showAlertIfMoreThanOneTimezoneHasBeenAddedToTheMenubar() {
let isUITestRunning = ProcessInfo.processInfo.arguments.contains(CLUITestingLaunchArgument)
// If we have seen displayed the message before, abort!
let haveWeSeenThisMessageBefore = UserDefaults.standard.bool(forKey: CLLongStatusBarWarningMessage)
if haveWeSeenThisMessageBefore && !isUITestRunning {
if haveWeSeenThisMessageBefore, !isUITestRunning {
return
}
// If the user is already using the compact mode, abort.
if DataStore.shared().shouldDisplay(.menubarCompactMode) && !isUITestRunning {
if DataStore.shared().shouldDisplay(.menubarCompactMode), !isUITestRunning {
return
}
@ -692,7 +691,7 @@ extension PreferencesViewController {
self.dataTask = NetworkManager.task(with: self.generateSearchURL(),
completionHandler: { [weak self] response, error in
guard let `self` = self else { return }
guard let self = self else { return }
OperationQueue.main.addOperation {
if let errorPresent = error {
@ -734,12 +733,12 @@ extension PreferencesViewController {
private func presentError(_ errorMessage: String) {
if errorMessage == PreferencesConstants.offlineErrorMessage {
self.placeholderLabel.placeholderString = PreferencesConstants.noInternetConnectivityError
placeholderLabel.placeholderString = PreferencesConstants.noInternetConnectivityError
} else {
self.placeholderLabel.placeholderString = PreferencesConstants.tryAgainMessage
placeholderLabel.placeholderString = PreferencesConstants.tryAgainMessage
}
self.isActivityInProgress = false
isActivityInProgress = false
}
private func appendResultsToFilteredArray(_ results: [SearchResult.Result]) {
@ -755,7 +754,7 @@ extension PreferencesViewController {
CLTimezoneName: formattedAddress,
CLCustomLabel: formattedAddress,
CLTimezoneID: CLEmptyString,
CLPlaceIdentifier: $0.placeId
CLPlaceIdentifier: $0.placeId,
] as [String: Any]
self.filteredArray.append(TimezoneData(with: totalPackage))
@ -763,9 +762,9 @@ extension PreferencesViewController {
}
private func prepareUIForPresentingResults() {
self.placeholderLabel.placeholderString = CLEmptyString
self.isActivityInProgress = false
self.availableTimezoneTableView.reloadData()
placeholderLabel.placeholderString = CLEmptyString
isActivityInProgress = false
availableTimezoneTableView.reloadData()
}
// Extracting this out for tests
@ -821,7 +820,7 @@ extension PreferencesViewController {
NetworkManager.task(with: urlString) { [weak self] response, error in
guard let `self` = self else { return }
guard let self = self else { return }
OperationQueue.main.addOperation {
if self.handleEdgeCase(for: response) == true {
@ -829,7 +828,7 @@ extension PreferencesViewController {
}
if error == nil, let json = response, let timezone = self.decodeTimezone(from: json) {
if self.availableTimezoneTableView.selectedRow >= 0 && self.availableTimezoneTableView.selectedRow < self.filteredArray.count {
if self.availableTimezoneTableView.selectedRow >= 0, self.availableTimezoneTableView.selectedRow < self.filteredArray.count {
self.installTimezone(timezone)
}
self.updateViewState()
@ -867,7 +866,7 @@ extension PreferencesViewController {
"latitude": dataObject.latitude!,
"longitude": dataObject.longitude!,
"nextUpdate": CLEmptyString,
CLCustomLabel: filteredAddress
CLCustomLabel: filteredAddress,
] as [String: Any]
let timezoneObject = TimezoneData(with: newTimeZone)
@ -1118,7 +1117,7 @@ extension PreferencesViewController {
var newDefaults = selectedTimeZones
let objectsToRemove = timezoneTableView.selectedRowIndexes.map { (index) -> Data in
return selectedTimeZones[index]
selectedTimeZones[index]
}
newDefaults = newDefaults.filter { !objectsToRemove.contains($0) }
@ -1331,8 +1330,7 @@ extension PreferencesViewController {
}
}
extension PreferencesViewController: SRRecorderControlDelegate {
}
extension PreferencesViewController: SRRecorderControlDelegate {}
// Helpers
extension PreferencesViewController {

20
Clocker/Preferences/OneWindowController.swift

@ -3,15 +3,14 @@
import Cocoa
class CenteredTabViewController: NSTabViewController {
override func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
super.toolbarDefaultItemIdentifiers(toolbar)
var toolbarItems: [NSToolbarItem.Identifier] = [NSToolbarItem.Identifier.flexibleSpace]
tabViewItems.forEach { (item) in
tabViewItems.forEach { item in
if let identifier = item.identifier as? String {
toolbarItems.append(NSToolbarItem.Identifier.init(identifier))
toolbarItems.append(NSToolbarItem.Identifier(identifier))
}
}
@ -19,11 +18,9 @@ class CenteredTabViewController: NSTabViewController {
return toolbarItems
}
}
class OneWindowController: NSWindowController {
private static var sharedWindow: OneWindowController!
private var themeDidChangeNotification: NSObjectProtocol?
@ -31,13 +28,13 @@ class OneWindowController: NSWindowController {
super.windowDidLoad()
setup()
themeDidChangeNotification = NotificationCenter.default.addObserver(forName: .themeDidChangeNotification, object: nil, queue: OperationQueue.main) { (_) in
themeDidChangeNotification = NotificationCenter.default.addObserver(forName: .themeDidChangeNotification, object: nil, queue: OperationQueue.main) { _ in
NSAnimationContext.runAnimationGroup({ (context) in
NSAnimationContext.runAnimationGroup { context in
context.duration = 1
context.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
self.window?.animator().backgroundColor = Themer.shared().mainBackgroundColor()
})
}
self.setupToolbarImages()
}
@ -61,7 +58,7 @@ class OneWindowController: NSWindowController {
class func shared() -> OneWindowController {
if sharedWindow == nil {
let prefStoryboard = NSStoryboard.init(name: "Preferences", bundle: nil)
let prefStoryboard = NSStoryboard(name: "Preferences", bundle: nil)
sharedWindow = prefStoryboard.instantiateInitialController() as? OneWindowController
}
return sharedWindow
@ -72,7 +69,7 @@ class OneWindowController: NSWindowController {
return
}
if !(window.isMainWindow) || !(window.isVisible) {
if !window.isMainWindow || !window.isVisible {
showWindow(nil)
}
@ -93,12 +90,11 @@ class OneWindowController: NSWindowController {
"Calendar": themer.calendarTabImage(),
"Permissions": themer.privacyTabImage()]
tabViewController.tabViewItems.forEach { (tabViewItem) in
tabViewController.tabViewItems.forEach { tabViewItem in
let identity = (tabViewItem.identifier as? String) ?? ""
if identifierTOImageMapping[identity] != nil {
tabViewItem.image = identifierTOImageMapping[identity]
}
}
}
}

3
Clocker/Preferences/Permissions/PermissionsViewController.swift

@ -3,7 +3,6 @@
import Cocoa
class PermissionsViewController: ParentViewController {
@IBOutlet var calendarContainerView: NSView!
@IBOutlet var remindersContainerView: NSView!
@ -129,7 +128,6 @@ class PermissionsViewController: ParentViewController {
if granted {
OperationQueue.main.addOperation {
self.view.window?.orderBack(nil)
NSApp.activate(ignoringOtherApps: true)
@ -163,7 +161,6 @@ class PermissionsViewController: ParentViewController {
if granted {
OperationQueue.main.addOperation {
self.view.window?.orderBack(nil)
NSApp.activate(ignoringOtherApps: true)

Loading…
Cancel
Save