Browse Source

Formatting + Dropping Hotkey Demo App.

pull/101/head
Abhishek Banthia 4 years ago
parent
commit
3b453deea7
  1. 14
      Clocker/AppDelegate.swift
  2. 38
      Clocker/Clocker.xcodeproj/project.pbxproj
  3. 4
      Clocker/Clocker.xcodeproj/xcuserdata/abhishekbanthia.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
  4. 2
      Clocker/ClockerUITests/AboutUsTests.swift
  5. 46
      Clocker/ClockerUITests/CopyToClipboardTests.swift
  6. 2
      Clocker/ClockerUITests/FloatingWindowTests.swift
  7. 8
      Clocker/ClockerUITests/PreferencesTest.swift
  8. 9
      Clocker/ClockerUnitTests/ClockerUnitTests.swift
  9. 18
      Clocker/CoreModelKit/Sources/CoreModelKit/TimezoneData.swift
  10. 6
      Clocker/Dependencies/Date Additions/TimePeriodChain.swift
  11. 6
      Clocker/Dependencies/Solar.swift
  12. 12
      Clocker/Events and Reminders/CalendarHandler.swift
  13. 5
      Clocker/Events and Reminders/EventCenter.swift
  14. 3
      Clocker/Events and Reminders/RemindersHandler.swift
  15. 2
      Clocker/Menu Bar/MenubarHandler.swift
  16. 9
      Clocker/Menu Bar/StatusContainerView.swift
  17. 4
      Clocker/Menu Bar/StatusItemHandler.swift
  18. 5
      Clocker/Menu Bar/StatusItemView.swift
  19. 8
      Clocker/Onboarding/FinalOnboardingViewController.swift
  20. 9
      Clocker/Onboarding/OnboardingSearchController.swift
  21. 6
      Clocker/Overall App/DateFormatterManager.swift

14
Clocker/AppDelegate.swift

@ -7,8 +7,8 @@ import FirebaseCore
import FirebaseCrashlytics import FirebaseCrashlytics
open class AppDelegate: NSObject, NSApplicationDelegate { open class AppDelegate: NSObject, NSApplicationDelegate {
private lazy var floatingWindow: FloatingWindowController = FloatingWindowController.shared() private lazy var floatingWindow = FloatingWindowController.shared()
private lazy var panelController: PanelController = PanelController.shared() private lazy var panelController = PanelController.shared()
private var statusBarHandler: StatusItemHandler! private var statusBarHandler: StatusItemHandler!
private var panelObserver: NSKeyValueObservation? private var panelObserver: NSKeyValueObservation?
@ -16,7 +16,7 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
panelObserver?.invalidate() panelObserver?.invalidate()
} }
open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change _: [NSKeyValueChangeKey: Any]?, context _: UnsafeMutableRawPointer?) { override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change _: [NSKeyValueChangeKey: Any]?, context _: UnsafeMutableRawPointer?) {
if let path = keyPath, path == PreferencesConstants.hotKeyPathIdentifier { if let path = keyPath, path == PreferencesConstants.hotKeyPathIdentifier {
let hotKeyCenter = PTHotKeyCenter.shared() let hotKeyCenter = PTHotKeyCenter.shared()
@ -30,10 +30,10 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
} }
// Register new key // Register new key
let newHotKey: PTHotKey = PTHotKey(identifier: keyPath, let newHotKey = PTHotKey(identifier: keyPath,
keyCombo: newShortcut, keyCombo: newShortcut,
target: self, target: self,
action: #selector(ping(_:))) action: #selector(ping(_:)))
hotKeyCenter?.register(newHotKey) hotKeyCenter?.register(newHotKey)
} }

38
Clocker/Clocker.xcodeproj/project.pbxproj

@ -22,7 +22,6 @@
3531F7F126936DE900DF0111 /* upload-symbols in Resources */ = {isa = PBXBuildFile; fileRef = 3531F7EC26936DE900DF0111 /* upload-symbols */; }; 3531F7F126936DE900DF0111 /* upload-symbols in Resources */ = {isa = PBXBuildFile; fileRef = 3531F7EC26936DE900DF0111 /* upload-symbols */; };
3531F7F226936DE900DF0111 /* upload-symbols in Resources */ = {isa = PBXBuildFile; fileRef = 3531F7EC26936DE900DF0111 /* upload-symbols */; }; 3531F7F226936DE900DF0111 /* upload-symbols in Resources */ = {isa = PBXBuildFile; fileRef = 3531F7EC26936DE900DF0111 /* upload-symbols */; };
3531F7F52693882300DF0111 /* Keys.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3531F7F42693882300DF0111 /* Keys.plist */; }; 3531F7F52693882300DF0111 /* Keys.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3531F7F42693882300DF0111 /* Keys.plist */; };
3531F7F62693882300DF0111 /* Keys.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3531F7F42693882300DF0111 /* Keys.plist */; };
3531F7F72693882300DF0111 /* Keys.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3531F7F42693882300DF0111 /* Keys.plist */; }; 3531F7F72693882300DF0111 /* Keys.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3531F7F42693882300DF0111 /* Keys.plist */; };
3531F80626938D7700DF0111 /* GoogleUtilities.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FC26938D7600DF0111 /* GoogleUtilities.framework */; }; 3531F80626938D7700DF0111 /* GoogleUtilities.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FC26938D7600DF0111 /* GoogleUtilities.framework */; };
3531F80726938D7700DF0111 /* GoogleUtilities.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FC26938D7600DF0111 /* GoogleUtilities.framework */; }; 3531F80726938D7700DF0111 /* GoogleUtilities.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3531F7FC26938D7600DF0111 /* GoogleUtilities.framework */; };
@ -216,13 +215,6 @@
remoteGlobalIDString = E273122E1349EC9000A84433; remoteGlobalIDString = E273122E1349EC9000A84433;
remoteInfo = PTHotKey.framework; remoteInfo = PTHotKey.framework;
}; };
9A86E2BF1CE04F1600547EE7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 9A86E2B51CE04F1600547EE7 /* ShortcutRecorder.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 0D6B2468180304DE00CE1142;
remoteInfo = Demo;
};
C20839CC21515C1F00C86589 /* PBXContainerItemProxy */ = { C20839CC21515C1F00C86589 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = DD4F7BFB13C30F9F00825C6E /* Project object */; containerPortal = DD4F7BFB13C30F9F00825C6E /* Project object */;
@ -769,7 +761,6 @@
children = ( children = (
9A86E2BC1CE04F1600547EE7 /* ShortcutRecorder.framework */, 9A86E2BC1CE04F1600547EE7 /* ShortcutRecorder.framework */,
9A86E2BE1CE04F1600547EE7 /* PTHotKey.framework */, 9A86E2BE1CE04F1600547EE7 /* PTHotKey.framework */,
9A86E2C01CE04F1600547EE7 /* Demo.app */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
@ -842,6 +833,14 @@
path = Frameworks; path = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
9AEF66812693A6270036142F /* Recovered References */ = {
isa = PBXGroup;
children = (
3531F7F42693882300DF0111 /* Keys.plist */,
);
name = "Recovered References";
sourceTree = "<group>";
};
C2021B89219F30960036C247 /* Onboarding */ = { C2021B89219F30960036C247 /* Onboarding */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -916,6 +915,7 @@
3531F7EC26936DE900DF0111 /* upload-symbols */, 3531F7EC26936DE900DF0111 /* upload-symbols */,
3531F7C026936C6E00DF0111 /* GoogleService-Info.plist */, 3531F7C026936C6E00DF0111 /* GoogleService-Info.plist */,
DD4F7C0513C30F9F00825C6E /* Products */, DD4F7C0513C30F9F00825C6E /* Products */,
9AEF66812693A6270036142F /* Recovered References */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -1032,7 +1032,6 @@
DD4F7C0213C30F9F00825C6E /* Resources */, DD4F7C0213C30F9F00825C6E /* Resources */,
9A20A0711C4E808500FB45AB /* Login Item Helper */, 9A20A0711C4E808500FB45AB /* Login Item Helper */,
9A5E75EC204CC39700119939 /* Embed Frameworks */, 9A5E75EC204CC39700119939 /* Embed Frameworks */,
C2A632A020EAC5EE00EB6BEA /* SwiftFormat */,
3531F7F326936F5000DF0111 /* ShellScript */, 3531F7F326936F5000DF0111 /* ShellScript */,
); );
buildRules = ( buildRules = (
@ -1156,13 +1155,6 @@
remoteRef = 9A86E2BD1CE04F1600547EE7 /* PBXContainerItemProxy */; remoteRef = 9A86E2BD1CE04F1600547EE7 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR; sourceTree = BUILT_PRODUCTS_DIR;
}; };
9A86E2C01CE04F1600547EE7 /* Demo.app */ = {
isa = PBXReferenceProxy;
fileType = wrapper.application;
path = Demo.app;
remoteRef = 9A86E2BF1CE04F1600547EE7 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */ /* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
@ -1559,7 +1551,7 @@
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 94; CURRENT_PROJECT_VERSION = 95;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@ -1592,7 +1584,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 10.13; MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 21.07.01; MARKETING_VERSION = 21.07.02;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "-ObjC"; OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = com.abhishek.Clocker; PRODUCT_BUNDLE_IDENTIFIER = com.abhishek.Clocker;
@ -2128,7 +2120,7 @@
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 94; CURRENT_PROJECT_VERSION = 95;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
@ -2162,7 +2154,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 10.13; MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 21.07.01; MARKETING_VERSION = 21.07.02;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "-ObjC"; OTHER_LDFLAGS = "-ObjC";
"OTHER_SWIFT_FLAGS[arch=*]" = "-D DEBUG"; "OTHER_SWIFT_FLAGS[arch=*]" = "-D DEBUG";
@ -2210,7 +2202,7 @@
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 94; CURRENT_PROJECT_VERSION = 95;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@ -2243,7 +2235,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 10.13; MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 21.07.01; MARKETING_VERSION = 21.07.02;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "-ObjC"; OTHER_LDFLAGS = "-ObjC";
"OTHER_SWIFT_FLAGS[arch=*]" = "-D RELEASE"; "OTHER_SWIFT_FLAGS[arch=*]" = "-D RELEASE";

4
Clocker/Clocker.xcodeproj/xcuserdata/abhishekbanthia.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@ -27,8 +27,8 @@
endingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807"
startingLineNumber = "47" startingLineNumber = "47"
endingLineNumber = "47" endingLineNumber = "47"
landmarkName = "geocodingKey" landmarkName = "unknown"
landmarkType = "24"> landmarkType = "0">
</BreakpointContent> </BreakpointContent>
</BreakpointProxy> </BreakpointProxy>
</Breakpoints> </Breakpoints>

2
Clocker/ClockerUITests/AboutUsTests.swift

@ -33,7 +33,7 @@ class AboutUsTests: XCTestCase {
tapAboutTab() tapAboutTab()
let appDisplayName = "CFBundleDisplayName".localizedString() let appDisplayName = "CFBundleDisplayName".localizedString()
let expectedVersion = "\(appDisplayName) 21.07.01 (93)" let expectedVersion = "\(appDisplayName) 21.07.02 (95)"
guard let presentVersion = app.windows["Clocker"].staticTexts["ClockerVersion"].value as? String else { guard let presentVersion = app.windows["Clocker"].staticTexts["ClockerVersion"].value as? String else {
XCTFail("Present version not present") XCTFail("Present version not present")

46
Clocker/ClockerUITests/CopyToClipboardTests.swift

@ -4,16 +4,16 @@ import XCTest
class CopyToClipboardTests: XCTestCase { class CopyToClipboardTests: XCTestCase {
var app: XCUIApplication! var app: XCUIApplication!
override func setUp() { override func setUp() {
continueAfterFailure = false continueAfterFailure = false
app = XCUIApplication() app = XCUIApplication()
app.launch() app.launch()
if app.tables["FloatingTableView"].exists == false { // if app.tables["FloatingTableView"].exists == false {
app.tapMenubarIcon() // app.tapMenubarIcon()
app.buttons["Pin"].click() // app.buttons["Pin"].click()
} // }
} }
override func tearDownWithError() throws { override func tearDownWithError() throws {
@ -23,20 +23,20 @@ class CopyToClipboardTests: XCTestCase {
func testFullCopy() throws { func testFullCopy() throws {
let cellCount = app.tables["FloatingTableView"].cells.count let cellCount = app.tables["FloatingTableView"].cells.count
var clipboardValue = String() var clipboardValue = String()
for cellIndex in 0..<cellCount { for cellIndex in 0 ..< cellCount {
let cell = app.tables["FloatingTableView"].cells.element(boundBy: cellIndex) let cell = app.tables["FloatingTableView"].cells.element(boundBy: cellIndex)
let customLabel = cell.staticTexts["CustomNameLabelForCell"].value ?? "Nil Custom Label" let customLabel = cell.staticTexts["CustomNameLabelForCell"].value ?? "Nil Custom Label"
let time = cell.staticTexts["ActualTime"].value ?? "Nil Value" let time = cell.staticTexts["ActualTime"].value ?? "Nil Value"
clipboardValue.append(contentsOf: "\(customLabel) - \(time)\n") clipboardValue.append(contentsOf: "\(customLabel) - \(time)\n")
} }
app.buttons["Share"].click() app.buttons["Share"].click()
app/*@START_MENU_TOKEN@*/.menuItems["Copy All Times"]/*[[".dialogs[\"Clocker Panel\"]",".buttons[\"Share\"]",".menus.menuItems[\"Copy All Times\"]",".menuItems[\"Copy All Times\"]"],[[[-1,3],[-1,2],[-1,1,2],[-1,0,1]],[[-1,3],[-1,2],[-1,1,2]],[[-1,3],[-1,2]]],[0]]@END_MENU_TOKEN@*/.click() app/*@START_MENU_TOKEN@*/ .menuItems["Copy All Times"]/*[[".dialogs[\"Clocker Panel\"]",".buttons[\"Share\"]",".menus.menuItems[\"Copy All Times\"]",".menuItems[\"Copy All Times\"]"],[[[-1,3],[-1,2],[-1,1,2],[-1,0,1]],[[-1,3],[-1,2],[-1,1,2]],[[-1,3],[-1,2]]],[0]]@END_MENU_TOKEN@*/ .click()
let clipboard = NSPasteboard.general.string(forType: .string) let clipboard = NSPasteboard.general.string(forType: .string)
XCTAssert(clipboardValue == clipboard) XCTAssert(clipboardValue == clipboard)
} }
func testIndividualTimezoneCopy() { func testIndividualTimezoneCopy() {
let cell = app.tables["FloatingTableView"].cells.firstMatch let cell = app.tables["FloatingTableView"].cells.firstMatch
let customLabel = cell.staticTexts["CustomNameLabelForCell"].value ?? "Nil Custom Label" let customLabel = cell.staticTexts["CustomNameLabelForCell"].value ?? "Nil Custom Label"
@ -45,9 +45,35 @@ class CopyToClipboardTests: XCTestCase {
// Tap to copy! // Tap to copy!
cell.tap() cell.tap()
let clipboard = NSPasteboard.general.string(forType: .string) ?? "Empty Pasteboard" let clipboard = NSPasteboard.general.string(forType: .string) ?? "Empty Pasteboard"
XCTAssert(expectedValue == clipboard, "Clipboard value (\(clipboard)) doesn't match expected result") XCTAssert(expectedValue == clipboard, "Clipboard value (\(clipboard)) doesn't match expected result")
} }
func testModernSlider() {
if app.buttons["FloatingPin"].exists {
app.buttons["FloatingPin"].click()
}
app.tapMenubarIcon()
let modernSliderExists = app.collectionViews["ModernSlider"].exists
app.buttons["Preferences"].click()
let appearanceTab = app.toolbars.buttons.element(boundBy: 1)
appearanceTab.click()
let miscTab = app.tabs.element(boundBy: 1)
miscTab.click()
if modernSliderExists {
app.radioGroups["FutureSlider"].radioButtons["Legacy"].click()
} else {
app.radioGroups["FutureSlider"].radioButtons["Modern"].click()
}
app.tapMenubarIcon()
let newFloatingSliderExists = app.collectionViews["ModernSlider"].exists
XCTAssertNotEqual(newFloatingSliderExists, modernSliderExists)
}
} }

2
Clocker/ClockerUITests/FloatingWindowTests.swift

@ -24,7 +24,7 @@ class FloatingWindowTests: XCTestCase {
app.buttons["Pin"].click() app.buttons["Pin"].click()
} }
addUIInterruptionMonitor(withDescription: "Reminders Access") { (alert) -> Bool in addUIInterruptionMonitor(withDescription: "Reminders Access") { alert -> Bool in
let alertButton = alert.buttons["OK"] let alertButton = alert.buttons["OK"]
if alertButton.exists { if alertButton.exists {
alertButton.tap() alertButton.tap()

8
Clocker/ClockerUITests/PreferencesTest.swift

@ -31,7 +31,7 @@ class PreferencesTest: XCTestCase {
return return
} }
app.windows["Clocker"].tables["TimezoneTableView"].tableRows.firstMatch.click() app.windows["Clocker"].tables["TimezoneTableView"].tableRows.firstMatch.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0)).click()
XCTAssertTrue(app.checkBoxes["DeleteTimezone"].isEnabled) XCTAssertTrue(app.checkBoxes["DeleteTimezone"].isEnabled)
} }
@ -334,7 +334,7 @@ class PreferencesTest: XCTestCase {
if rowQueryCount > 0 { if rowQueryCount > 0 {
// Table Rows aren't hittable in Xcode 12.0 (10/7/20) and so we need to find a closer co-ordinate and perform click() // Table Rows aren't hittable in Xcode 12.0 (10/7/20) and so we need to find a closer co-ordinate and perform click()
let currentElement = clockerWindow.tables["TimezoneTableView"].tableRows.firstMatch let currentElement = clockerWindow.tables["TimezoneTableView"].tableRows.firstMatch.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0))
currentElement.click() currentElement.click()
for _ in 0 ..< rowQueryCount { for _ in 0 ..< rowQueryCount {
@ -416,7 +416,7 @@ extension XCTestCase {
return return
} }
let currentElement = app.windows["Clocker"].tableRows.firstMatch let currentElement = app.windows["Clocker"].tableRows.firstMatch.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0))
currentElement.click() currentElement.click()
while rowQueryCount > 0 { while rowQueryCount > 0 {
@ -442,7 +442,7 @@ extension XCTestCase {
} }
private func deleteAtRow(_ rowToDelete: XCUIElement, for _: XCUIApplication, shouldSleep: Bool) { private func deleteAtRow(_ rowToDelete: XCUIElement, for _: XCUIApplication, shouldSleep: Bool) {
rowToDelete.click() rowToDelete.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0)).click()
rowToDelete.typeKey(XCUIKeyboardKey.delete, modifierFlags: XCUIElement.KeyModifierFlags()) rowToDelete.typeKey(XCUIKeyboardKey.delete, modifierFlags: XCUIElement.KeyModifierFlags())
if shouldSleep { if shouldSleep {
sleep(2) sleep(2)

9
Clocker/ClockerUnitTests/ClockerUnitTests.swift

@ -120,16 +120,16 @@ class ClockerUnitTests: XCTestCase {
let timezone = TimezoneData.customObject(from: $0) let timezone = TimezoneData.customObject(from: $0)
return timezone?.placeID == "TestIdentifier" return timezone?.placeID == "TestIdentifier"
} }
// California is absent. Add it! // California is absent. Add it!
if filteredCount.count == 0 { if filteredCount.count == 0 {
let timezoneData = TimezoneData(with: california) let timezoneData = TimezoneData(with: california)
let operationsObject = TimezoneDataOperations(with: timezoneData) let operationsObject = TimezoneDataOperations(with: timezoneData)
operationsObject.saveObject() operationsObject.saveObject()
} }
let oldCount = (defaults.object(forKey: CLDefaultPreferenceKey) as? [Data])?.count ?? 0 let oldCount = (defaults.object(forKey: CLDefaultPreferenceKey) as? [Data])?.count ?? 0
currentFavourites = currentFavourites.filter { currentFavourites = currentFavourites.filter {
let timezone = TimezoneData.customObject(from: $0) let timezone = TimezoneData.customObject(from: $0)
return timezone?.placeID != "TestIdentifier" return timezone?.placeID != "TestIdentifier"
@ -288,7 +288,8 @@ class ClockerUnitTests: XCTestCase {
guard let newDate = cal?.date(byAdding: .minute, guard let newDate = cal?.date(byAdding: .minute,
value: 0, value: 0,
to: Date(), to: Date(),
options: .matchFirst) else { options: .matchFirst)
else {
XCTFail("Unable to add dates!") XCTFail("Unable to add dates!")
return return
} }

18
Clocker/CoreModelKit/Sources/CoreModelKit/TimezoneData.swift

@ -11,7 +11,7 @@ struct ModelConstants {
static let emptyString = "" static let emptyString = ""
} }
public struct DateFormat { public enum DateFormat {
public static let twelveHour = "h:mm a" public static let twelveHour = "h:mm a"
public static let twelveHourWithSeconds = "h:mm:ss a" public static let twelveHourWithSeconds = "h:mm:ss a"
public static let twentyFourHour = "HH:mm" public static let twentyFourHour = "HH:mm"
@ -82,7 +82,7 @@ public class TimezoneData: NSObject, NSCoding {
public var isSystemTimezone = false public var isSystemTimezone = false
public var overrideFormat: TimezoneOverride = .globalFormat public var overrideFormat: TimezoneOverride = .globalFormat
public override init() { override public init() {
selectionType = .timezone selectionType = .timezone
isFavourite = 0 isFavourite = 0
note = ModelConstants.emptyString note = ModelConstants.emptyString
@ -303,7 +303,7 @@ public class TimezoneData: NSObject, NSCoding {
public func timezoneFormat(_ currentFormat: NSNumber) -> String { public func timezoneFormat(_ currentFormat: NSNumber) -> String {
let chosenDefault = currentFormat let chosenDefault = currentFormat
let timeFormat = TimezoneData.values[chosenDefault] ?? DateFormat.twelveHour let timeFormat = TimezoneData.values[chosenDefault] ?? DateFormat.twelveHour
switch overrideFormat { switch overrideFormat {
case .globalFormat: case .globalFormat:
return timeFormat return timeFormat
@ -338,7 +338,7 @@ public class TimezoneData: NSObject, NSCoding {
return formatInString.contains("ss") return formatInString.contains("ss")
} }
public override var hash: Int { override public var hash: Int {
guard let placeIdentifier = placeID, let timezone = timezoneID else { guard let placeIdentifier = placeID, let timezone = timezoneID else {
return -1 return -1
} }
@ -350,14 +350,14 @@ public class TimezoneData: NSObject, NSCoding {
return lhs.placeID == rhs.placeID return lhs.placeID == rhs.placeID
} }
public override func isEqual(to object: Any?) -> Bool { override public func isEqual(to object: Any?) -> Bool {
if let other = object as? TimezoneData { if let other = object as? TimezoneData {
return placeID == other.placeID return placeID == other.placeID
} }
return false return false
} }
public override func isEqual(_ object: Any?) -> Bool { override public func isEqual(_ object: Any?) -> Bool {
guard let compared = object as? TimezoneData else { guard let compared = object as? TimezoneData else {
return false return false
} }
@ -367,12 +367,12 @@ public class TimezoneData: NSObject, NSCoding {
} }
} }
extension TimezoneData { public extension TimezoneData {
public override var description: String { override var description: String {
return objectDescription() return objectDescription()
} }
public override var debugDescription: String { override var debugDescription: String {
return objectDescription() return objectDescription()
} }

6
Clocker/Dependencies/Date Additions/TimePeriodChain.swift

@ -138,15 +138,15 @@ open class TimePeriodChain: TimePeriodGroup {
_end = _end?.addingTimeInterval(duration) _end = _end?.addingTimeInterval(duration)
} }
public override func map<T>(_ transform: (TimePeriodProtocol) throws -> T) rethrows -> [T] { override public func map<T>(_ transform: (TimePeriodProtocol) throws -> T) rethrows -> [T] {
return try periods.map(transform) return try periods.map(transform)
} }
public override func filter(_ isIncluded: (TimePeriodProtocol) throws -> Bool) rethrows -> [TimePeriodProtocol] { override public func filter(_ isIncluded: (TimePeriodProtocol) throws -> Bool) rethrows -> [TimePeriodProtocol] {
return try periods.filter(isIncluded) return try periods.filter(isIncluded)
} }
internal override func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, TimePeriodProtocol) throws -> Result) rethrows -> Result { override internal func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, TimePeriodProtocol) throws -> Result) rethrows -> Result {
return try periods.reduce(initialResult, nextPartialResult) return try periods.reduce(initialResult, nextPartialResult)
} }

6
Clocker/Dependencies/Solar.swift

@ -176,10 +176,10 @@ public struct Solar {
} }
} }
extension Solar { public extension Solar {
/// Whether the location specified by the `latitude` and `longitude` is in daytime on `date` /// Whether the location specified by the `latitude` and `longitude` is in daytime on `date`
/// - Complexity: O(1) /// - Complexity: O(1)
public var isDaytime: Bool { var isDaytime: Bool {
guard guard
let sunrise = sunrise, let sunrise = sunrise,
let sunset = sunset let sunset = sunset
@ -199,7 +199,7 @@ extension Solar {
/// Whether the location specified by the `latitude` and `longitude` is in nighttime on `date` /// Whether the location specified by the `latitude` and `longitude` is in nighttime on `date`
/// - Complexity: O(1) /// - Complexity: O(1)
public var isNighttime: Bool { var isNighttime: Bool {
return !isDaytime return !isDaytime
} }
} }

12
Clocker/Events and Reminders/CalendarHandler.swift

@ -21,7 +21,7 @@ extension EventCenter {
var sourcesAndCalendars: [Any] = [] var sourcesAndCalendars: [Any] = []
// Fetch array of user's calendars sorted first by source title and then by calendar title // Fetch array of user's calendars sorted first by source title and then by calendar title
let calendars = eventStore.calendars(for: .event).sorted { (cal1, cal2) -> Bool in let calendars = eventStore.calendars(for: .event).sorted { cal1, cal2 -> Bool in
if cal1.source.sourceIdentifier == cal2.source.sourceIdentifier { if cal1.source.sourceIdentifier == cal2.source.sourceIdentifier {
return cal1.title < cal2.title return cal1.title < cal2.title
@ -232,7 +232,7 @@ extension EventCenter {
} }
func retrieveAllCalendarIdentifiers() -> [String] { func retrieveAllCalendarIdentifiers() -> [String] {
return eventStore.calendars(for: .event).map { (calendar) -> String in return eventStore.calendars(for: .event).map { calendar -> String in
calendar.calendarIdentifier calendar.calendarIdentifier
} }
} }
@ -242,7 +242,8 @@ extension EventCenter {
dateComps.day = day dateComps.day = day
guard let convertedDate = calendar?.date(byAdding: dateComps, guard let convertedDate = calendar?.date(byAdding: dateComps,
to: Date(), to: Date(),
options: NSCalendar.Options.matchFirst) else { options: NSCalendar.Options.matchFirst)
else {
return Date() return Date()
} }
return convertedDate return convertedDate
@ -313,7 +314,7 @@ extension EventCenter {
// We now sort the array so that AllDay Events are first, then sort by startTime // We now sort the array so that AllDay Events are first, then sort by startTime
for date in eventsForDateMapper.keys { for date in eventsForDateMapper.keys {
let sortedEvents = eventsForDateMapper[date]?.sorted(by: { (event1, event2) -> Bool in let sortedEvents = eventsForDateMapper[date]?.sorted(by: { event1, event2 -> Bool in
if event1.isAllDay { return true } else if event2.isAllDay { return false } else { return event1.event.startDate < event2.event.startDate } if event1.isAllDay { return true } else if event2.isAllDay { return false } else { return event1.event.startDate < event2.event.startDate }
}) })
eventsForDateMapper[date] = sortedEvents eventsForDateMapper[date] = sortedEvents
@ -378,7 +379,8 @@ extension EventCenter {
|| actualLink.contains("indigo.collocall.de") || actualLink.contains("indigo.collocall.de")
|| actualLink.contains("public.senfcall.de") || actualLink.contains("public.senfcall.de")
|| actualLink.contains("youcanbook.me/zoom/") || actualLink.contains("youcanbook.me/zoom/")
|| actualLink.contains("workplace.com/groupcall") { || actualLink.contains("workplace.com/groupcall")
{
if let zoomLink = result.url { if let zoomLink = result.url {
return zoomLink return zoomLink
} }

5
Clocker/Events and Reminders/EventCenter.swift

@ -16,7 +16,7 @@ class EventCenter: NSObject {
var eventsForDate: [Date: [EventInfo]] = [:] var eventsForDate: [Date: [EventInfo]] = [:]
var filteredEvents: [Date: [EventInfo]] = [:] var filteredEvents: [Date: [EventInfo]] = [:]
private let fetchQueue = DispatchQueue(label: "com.abhishek.fetch") private let fetchQueue = DispatchQueue(label: "com.abhishek.fetch")
@discardableResult class func sharedCenter() -> EventCenter { @discardableResult class func sharedCenter() -> EventCenter {
@ -43,7 +43,7 @@ class EventCenter: NSObject {
private func refetchAll() { private func refetchAll() {
Logger.info("\nRefetching events from the store") Logger.info("\nRefetching events from the store")
eventsForDate = [:] eventsForDate = [:]
filteredEvents = [:] filteredEvents = [:]
autoreleasepool { autoreleasepool {
@ -53,6 +53,5 @@ class EventCenter: NSObject {
self.fetchEvents(-40, 80) self.fetchEvents(-40, 80)
} }
} }
} }
} }

3
Clocker/Events and Reminders/RemindersHandler.swift

@ -51,7 +51,8 @@ extension EventCenter {
timezone: String, timezone: String,
alertIndex: Int, alertIndex: Int,
reminderDate: Date, reminderDate: Date,
additionalNotes: String?) -> Bool { additionalNotes: String?) -> Bool
{
initializeStoreIfNeccesary() initializeStoreIfNeccesary()
if reminderAccessNotDetermined() || reminderAccessDenied() { if reminderAccessNotDetermined() || reminderAccessDenied() {

2
Clocker/Menu Bar/MenubarHandler.swift

@ -19,7 +19,7 @@ class MenubarHandler: NSObject {
} }
if menubarTitles.isEmpty == false { 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 timezone = TimezoneData.customObject(from: data)
let operationsObject = TimezoneDataOperations(with: timezone!) let operationsObject = TimezoneDataOperations(with: timezone!)
return "\(operationsObject.menuTitle().trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines))" return "\(operationsObject.menuTitle().trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines))"

9
Clocker/Menu Bar/StatusContainerView.swift

@ -31,10 +31,12 @@ func compactWidth(for timezone: TimezoneData) -> Int {
if timeFormat == DateFormat.twelveHour if timeFormat == DateFormat.twelveHour
|| timeFormat == DateFormat.twelveHourWithSeconds || timeFormat == DateFormat.twelveHourWithSeconds
|| timeFormat == DateFormat.twelveHourWithZero || timeFormat == DateFormat.twelveHourWithZero
|| timeFormat == DateFormat.twelveHourWithSeconds { || timeFormat == DateFormat.twelveHourWithSeconds
{
totalWidth += 20 totalWidth += 20
} else if timeFormat == DateFormat.twentyFourHour } else if timeFormat == DateFormat.twentyFourHour
|| timeFormat == DateFormat.twentyFourHourWithSeconds { || timeFormat == DateFormat.twentyFourHourWithSeconds
{
totalWidth += 0 totalWidth += 0
} }
@ -79,7 +81,7 @@ class StatusContainerView: NSView {
] ]
func containerWidth(for timezones: [Data]) -> CGFloat { func containerWidth(for timezones: [Data]) -> CGFloat {
let compressedWidth = timezones.reduce(0.0) { (result, timezone) -> CGFloat in let compressedWidth = timezones.reduce(0.0) { result, timezone -> CGFloat in
if let timezoneObject = TimezoneData.customObject(from: timezone) { if let timezoneObject = TimezoneData.customObject(from: timezone) {
let precalculatedWidth = Double(compactWidth(for: timezoneObject)) let precalculatedWidth = Double(compactWidth(for: timezoneObject))
@ -106,6 +108,7 @@ class StatusContainerView: NSView {
addSubviews() addSubviews()
} }
@available(*, unavailable)
required init?(coder _: NSCoder) { required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }

4
Clocker/Menu Bar/StatusItemHandler.swift

@ -141,7 +141,7 @@ class StatusItemHandler: NSObject {
private func retrieveSyncedMenubarTimezones() -> [Data] { private func retrieveSyncedMenubarTimezones() -> [Data] {
let defaultPreferences = DataStore.shared().retrieve(key: CLDefaultPreferenceKey) as? [Data] ?? [] let defaultPreferences = DataStore.shared().retrieve(key: CLDefaultPreferenceKey) as? [Data] ?? []
let menubarTimezones = defaultPreferences.filter { (data) -> Bool in let menubarTimezones = defaultPreferences.filter { data -> Bool in
if let timezoneObj = TimezoneData.customObject(from: data) { if let timezoneObj = TimezoneData.customObject(from: data) {
return timezoneObj.isFavourite == 1 return timezoneObj.isFavourite == 1
} }
@ -185,7 +185,7 @@ class StatusItemHandler: NSObject {
if let strongSelf = self { if let strongSelf = self {
strongSelf.performTimerWork() strongSelf.performTimerWork()
} }
}) })
// Tolerance, even a small amount, has a positive imapct on the power usage. As a rule, we set it to 10% of the interval // Tolerance, even a small amount, has a positive imapct on the power usage. As a rule, we set it to 10% of the interval
menubarTimer?.tolerance = shouldDisplaySeconds ? 0.5 : 20 menubarTimer?.tolerance = shouldDisplaySeconds ? 0.5 : 20

5
Clocker/Menu Bar/StatusItemView.swift

@ -36,8 +36,8 @@ extension NSView {
class StatusItemView: NSView { class StatusItemView: NSView {
// MARK: Private variables // MARK: Private variables
private let locationView: NSTextField = NSTextField(labelWithString: "Hello") private let locationView = NSTextField(labelWithString: "Hello")
private let timeView: NSTextField = NSTextField(labelWithString: "Mon 19:14 PM") private let timeView = NSTextField(labelWithString: "Mon 19:14 PM")
private var operationsObject: TimezoneDataOperations { private var operationsObject: TimezoneDataOperations {
return TimezoneDataOperations(with: dataObject) return TimezoneDataOperations(with: dataObject)
} }
@ -117,6 +117,7 @@ class StatusItemView: NSView {
timeView.attributedStringValue = NSAttributedString(string: operationsObject.compactMenuSubtitle(), attributes: timeAttributes) timeView.attributedStringValue = NSAttributedString(string: operationsObject.compactMenuSubtitle(), attributes: timeAttributes)
} }
@available(*, unavailable)
required init?(coder _: NSCoder) { required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }

8
Clocker/Onboarding/FinalOnboardingViewController.swift

@ -71,7 +71,7 @@ class FinalOnboardingViewController: NSViewController {
@IBAction func localizationAction(_: Any) { @IBAction func localizationAction(_: Any) {
guard let localizationURL = URL(string: AboutUsConstants.TwitterLink), guard let localizationURL = URL(string: AboutUsConstants.TwitterLink),
let languageCode = Locale.preferredLanguages.first else { return } let languageCode = Locale.preferredLanguages.first else { return }
NSWorkspace.shared.open(localizationURL) NSWorkspace.shared.open(localizationURL)
@ -103,7 +103,8 @@ class FinalOnboardingViewController: NSViewController {
} }
guard let shortVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String, guard let shortVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String,
let appVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String else { let appVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String
else {
return nil return nil
} }
let operatingSystem = ProcessInfo.processInfo.operatingSystemVersion let operatingSystem = ProcessInfo.processInfo.operatingSystemVersion
@ -134,7 +135,8 @@ class EmailTextFieldValidator {
range: range) range: range)
if allMatches.count == 1, if allMatches.count == 1,
allMatches.first?.url?.absoluteString.contains("mailto:") == true { allMatches.first?.url?.absoluteString.contains("mailto:") == true
{
return trimmedText return trimmedText
} }
return nil return nil

9
Clocker/Onboarding/OnboardingSearchController.swift

@ -27,8 +27,9 @@ class OnboardingSearchController: NSViewController {
private var geocodingKey: String = { private var geocodingKey: String = {
guard let path = Bundle.main.path(forResource: "Keys", ofType: "plist"), guard let path = Bundle.main.path(forResource: "Keys", ofType: "plist"),
let dictionary = NSDictionary(contentsOfFile: path), let dictionary = NSDictionary(contentsOfFile: path),
let apiKey = dictionary["GeocodingKey"] as? String else { let apiKey = dictionary["GeocodingKey"] as? String
else {
assertionFailure("Unable to find the API key") assertionFailure("Unable to find the API key")
return "" return ""
} }
@ -373,7 +374,7 @@ class OnboardingSearchController: NSViewController {
self.findLocalSearchResultsForTimezones() self.findLocalSearchResultsForTimezones()
self.prepareUIForPresentingResults() self.prepareUIForPresentingResults()
} }
}) })
} }
private func presentErrorMessage(_ errorMessage: String) { private func presentErrorMessage(_ errorMessage: String) {
@ -398,7 +399,7 @@ class OnboardingSearchController: NSViewController {
} }
private func appendResultsToFilteredArray(_ results: [SearchResult.Result]) { private func appendResultsToFilteredArray(_ results: [SearchResult.Result]) {
let finalTimezones: [TimezoneData] = results.map { (result) -> TimezoneData in let finalTimezones: [TimezoneData] = results.map { result -> TimezoneData in
let location = result.geometry.location let location = result.geometry.location
let latitude = location.lat let latitude = location.lat
let longitude = location.lng let longitude = location.lng

6
Clocker/Overall App/DateFormatterManager.swift

@ -5,9 +5,9 @@ import Cocoa
class DateFormatterManager: NSObject { class DateFormatterManager: NSObject {
public static let sharedInstance = DateFormatterManager() public static let sharedInstance = DateFormatterManager()
private static var dateFormatter: DateFormatter = DateFormatter() private static var dateFormatter = DateFormatter()
private static var calendarDateFormatter: DateFormatter = DateFormatter() private static var calendarDateFormatter = DateFormatter()
private static var simpleFormatter: DateFormatter = DateFormatter() private static var simpleFormatter = DateFormatter()
private static var specializedFormatter = DateFormatter() private static var specializedFormatter = DateFormatter()
private static var localizedForamtter = DateFormatter() private static var localizedForamtter = DateFormatter()
private static var localizedSimpleFormatter = DateFormatter() private static var localizedSimpleFormatter = DateFormatter()

Loading…
Cancel
Save