diff --git a/Clocker/AppDelegate.swift b/Clocker/AppDelegate.swift index 778248f..6f265da 100644 --- a/Clocker/AppDelegate.swift +++ b/Clocker/AppDelegate.swift @@ -43,7 +43,7 @@ open class AppDelegate: NSObject, NSApplicationDelegate { // Required for migrating our model type to CoreModelKit NSKeyedUnarchiver.setClass(CoreModelKit.TimezoneData.classForKeyedUnarchiver(), forClassName: "Clocker.TimezoneData") - AppDefaults.initialize() + AppDefaults.initialize(with: DataStore.shared(), defaults: UserDefaults.standard) // Check if we can show the onboarding flow! showOnboardingFlowIfEligible() @@ -73,9 +73,9 @@ open class AppDelegate: NSObject, NSApplicationDelegate { } @objc private func openPreferencesWindow() { - let displayMode = UserDefaults.standard.integer(forKey: CLShowAppInForeground) + let displayMode = DataStore.shared().shouldDisplay(.showAppInForeground) - if displayMode == 1 { + if displayMode { let floatingWindow = FloatingWindowController.shared() floatingWindow.openPreferences(NSButton()) } else { @@ -88,16 +88,22 @@ open class AppDelegate: NSObject, NSApplicationDelegate { NSApp.setActivationPolicy(.accessory) } - private lazy var controller: OnboardingController? = { - let onboardingStoryboard = NSStoryboard(name: NSStoryboard.Name("Onboarding"), bundle: nil) - return onboardingStoryboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("onboardingFlow")) as? OnboardingController - }() + private var controller: OnboardingController? private func showOnboardingFlowIfEligible() { - let shouldLaunchOnboarding = (DataStore.shared().retrieve(key: CLShowOnboardingFlow) == nil && DataStore.shared().timezones().isEmpty) - || ProcessInfo.processInfo.arguments.contains(CLOnboaringTestsLaunchArgument) - - shouldLaunchOnboarding ? controller?.launch() : continueUsually() + let isTestInProgress = ProcessInfo.processInfo.arguments.contains(CLOnboaringTestsLaunchArgument) + let shouldLaunchOnboarding = + (DataStore.shared().retrieve(key: CLShowOnboardingFlow) == nil + && DataStore.shared().timezones().isEmpty) + || isTestInProgress + + if shouldLaunchOnboarding { + let onboardingStoryboard = NSStoryboard(name: NSStoryboard.Name("Onboarding"), bundle: nil) + controller = onboardingStoryboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("onboardingFlow")) as? OnboardingController + controller?.launch() + } else { + continueUsually() + } } func continueUsually() { diff --git a/Clocker/ClockerUnitTests/ClockerUnitTests.swift b/Clocker/ClockerUnitTests/ClockerUnitTests.swift index f433f0a..efc3a60 100644 --- a/Clocker/ClockerUnitTests/ClockerUnitTests.swift +++ b/Clocker/ClockerUnitTests/ClockerUnitTests.swift @@ -53,23 +53,23 @@ class ClockerUnitTests: XCTestCase { "longitude": "-95.9345034"] private var operations: TimezoneDataOperations { - return TimezoneDataOperations(with: TimezoneData(with: mumbai)) + return TimezoneDataOperations(with: TimezoneData(with: mumbai), store: DataStore.shared()) } private var californiaOperations: TimezoneDataOperations { - return TimezoneDataOperations(with: TimezoneData(with: california)) + return TimezoneDataOperations(with: TimezoneData(with: california), store: DataStore.shared()) } private var floridaOperations: TimezoneDataOperations { - return TimezoneDataOperations(with: TimezoneData(with: florida)) + return TimezoneDataOperations(with: TimezoneData(with: florida), store: DataStore.shared()) } private var aucklandOperations: TimezoneDataOperations { - return TimezoneDataOperations(with: TimezoneData(with: auckland)) + return TimezoneDataOperations(with: TimezoneData(with: auckland), store: DataStore.shared()) } private var omahaOperations: TimezoneDataOperations { - return TimezoneDataOperations(with: TimezoneData(with: omaha)) + return TimezoneDataOperations(with: TimezoneData(with: omaha), store: DataStore.shared()) } func testOverridingSecondsComponent_shouldHideSeconds() { @@ -81,7 +81,7 @@ class ClockerUnitTests: XCTestCase { TimezoneData(with: california)] timezoneObjects.forEach { - let operationsObject = TimezoneDataOperations(with: $0) + let operationsObject = TimezoneDataOperations(with: $0, store: DataStore.shared()) let currentTime = operationsObject.time(with: 0) XCTAssert(currentTime.count == 8) // 8 includes 2 colons @@ -97,7 +97,7 @@ class ClockerUnitTests: XCTestCase { let currentFavourites = DataStore.shared().timezones() let oldCount = currentFavourites.count - let operationsObject = TimezoneDataOperations(with: timezoneData) + let operationsObject = TimezoneDataOperations(with: timezoneData, store: DataStore.shared()) operationsObject.saveObject() let newDefaults = DataStore.shared().timezones() @@ -151,7 +151,7 @@ class ClockerUnitTests: XCTestCase { // California is absent. Add it! if filteredCount.count == 0 { let timezoneData = TimezoneData(with: california) - let operationsObject = TimezoneDataOperations(with: timezoneData) + let operationsObject = TimezoneDataOperations(with: timezoneData, store: DataStore.shared()) operationsObject.saveObject() } @@ -179,7 +179,7 @@ class ClockerUnitTests: XCTestCase { func testSunriseSunset() { let dataObject = TimezoneData(with: mumbai) - let operations = TimezoneDataOperations(with: dataObject) + let operations = TimezoneDataOperations(with: dataObject, store: DataStore.shared()) XCTAssertNotNil(operations.formattedSunriseTime(with: 0)) XCTAssertNotNil(dataObject.sunriseTime) @@ -187,7 +187,7 @@ class ClockerUnitTests: XCTestCase { let timezoneObject = TimezoneData(with: onlyTimezone) timezoneObject.selectionType = .timezone - let timezoneOperations = TimezoneDataOperations(with: timezoneObject) + let timezoneOperations = TimezoneDataOperations(with: timezoneObject, store: DataStore.shared()) XCTAssertTrue(timezoneOperations.formattedSunriseTime(with: 0) == "") XCTAssertNil(timezoneObject.sunriseTime) @@ -196,7 +196,7 @@ class ClockerUnitTests: XCTestCase { func testDateWithSliderValue() { let dataObject = TimezoneData(with: mumbai) - let operations = TimezoneDataOperations(with: dataObject) + let operations = TimezoneDataOperations(with: dataObject, store: DataStore.shared()) XCTAssertNotNil(operations.date(with: 0, displayType: .menu)) } @@ -359,7 +359,7 @@ class ClockerUnitTests: XCTestCase { func testWithAllLocales() { let dataObject1 = TimezoneData(with: mumbai) - let operations = TimezoneDataOperations(with: dataObject1) + let operations = TimezoneDataOperations(with: dataObject1, store: DataStore.shared()) for locale in Locale.availableIdentifiers { let currentLocale = Locale(identifier: locale) @@ -430,4 +430,14 @@ class ClockerUnitTests: XCTestCase { XCTAssertEqual(subject.subviews.count, 2) // Two textfields XCTAssertEqual(subject.subviews.first?.layer?.animationKeys(), ["notimezone.emoji"]) } + + func testDefaultsWiping() { + let defaultsDict: [String: Any] = ["test1": "testString", "test2": 24] + let domainName = "com.test.clocker" + let defaults = UserDefaults(suiteName: domainName) + defaults?.setPersistentDomain(defaultsDict, forName: domainName) + defaults?.wipe(for: domainName) + XCTAssertNil(defaults?.object(forKey: "test1")) + XCTAssertNil(defaults?.object(forKey: "test2")) + } } diff --git a/Clocker/Events and Reminders/EventCenter.swift b/Clocker/Events and Reminders/EventCenter.swift index 5d6e5ee..9c3b8d2 100644 --- a/Clocker/Events and Reminders/EventCenter.swift +++ b/Clocker/Events and Reminders/EventCenter.swift @@ -42,7 +42,7 @@ class EventCenter: NSObject { } private func refetchAll() { - Logger.info("\nRefetching events from the store") + Logger.info("Refetching events from the store") eventsForDate = [:] filteredEvents = [:] diff --git a/Clocker/Onboarding/OnboardingParentViewController.swift b/Clocker/Onboarding/OnboardingParentViewController.swift index 1772011..80d7c68 100644 --- a/Clocker/Onboarding/OnboardingParentViewController.swift +++ b/Clocker/Onboarding/OnboardingParentViewController.swift @@ -189,7 +189,7 @@ class OnboardingParentViewController: NSViewController { currentTimezone.isSystemTimezone = true currentTimezone.placeID = "Home" - let operations = TimezoneDataOperations(with: currentTimezone) + let operations = TimezoneDataOperations(with: currentTimezone, store: DataStore.shared()) operations.saveObject(at: 0) } diff --git a/Clocker/Onboarding/OnboardingSearchController.swift b/Clocker/Onboarding/OnboardingSearchController.swift index d87dbac..cfded45 100644 --- a/Clocker/Onboarding/OnboardingSearchController.swift +++ b/Clocker/Onboarding/OnboardingSearchController.swift @@ -21,7 +21,7 @@ class OnboardingSearchController: NSViewController { @IBOutlet private var accessoryLabel: NSTextField! @IBOutlet var undoButton: NSButton! - private var searchResultsDataSource: SearchDataSource! + private var searchResultsDataSource: SearchDataSource? private var dataTask: URLSessionDataTask? = .none private var themeDidChangeNotification: NSObjectProtocol? @@ -81,17 +81,19 @@ class OnboardingSearchController: NSViewController { @objc func doubleClickAction(_ tableView: NSTableView) { [accessoryLabel].forEach { $0?.isHidden = false } - if tableView.selectedRow >= 0, tableView.selectedRow < searchResultsDataSource.resultsCount() { - let selectedType = searchResultsDataSource.placeForRow(resultsTableView.selectedRow) + if tableView.selectedRow >= 0, tableView.selectedRow < (searchResultsDataSource?.resultsCount() ?? 0) { + let selectedType = searchResultsDataSource?.placeForRow(resultsTableView.selectedRow) switch selectedType { case .city: - if let filteredGoogleResult = searchResultsDataSource.retrieveFilteredResultFromGoogleAPI(resultsTableView.selectedRow) { + if let filteredGoogleResult = searchResultsDataSource?.retrieveFilteredResultFromGoogleAPI(resultsTableView.selectedRow) { addTimezoneToDefaults(filteredGoogleResult) } return case .timezone: cleanupAfterInstallingTimezone() return + case .none: + return } } } @@ -100,28 +102,28 @@ class OnboardingSearchController: NSViewController { let data = TimezoneData() data.setLabel(CLEmptyString) - let currentSelection = searchResultsDataSource.retrieveSelectedTimezone(resultsTableView.selectedRow) - - let metaInfo = metadata(for: currentSelection) - data.timezoneID = metaInfo.0.name - data.formattedAddress = metaInfo.1.formattedName - data.selectionType = .timezone - data.isSystemTimezone = metaInfo.0.name == NSTimeZone.system.identifier + if let currentSelection = searchResultsDataSource?.retrieveSelectedTimezone(resultsTableView.selectedRow) { + let metaInfo = metadata(for: currentSelection) + data.timezoneID = metaInfo.0.name + data.formattedAddress = metaInfo.1.formattedName + data.selectionType = .timezone + data.isSystemTimezone = metaInfo.0.name == NSTimeZone.system.identifier - let operationObject = TimezoneDataOperations(with: data) - operationObject.saveObject() + let operationObject = TimezoneDataOperations(with: data, store: DataStore.shared()) + operationObject.saveObject() - searchResultsDataSource.cleanupFilterArray() - searchResultsDataSource.timezoneFilteredArray = [] - searchResultsDataSource.calculateChangesets() - searchBar.stringValue = CLEmptyString + searchResultsDataSource?.cleanupFilterArray() + searchResultsDataSource?.timezoneFilteredArray = [] + searchResultsDataSource?.calculateChangesets() + searchBar.stringValue = CLEmptyString - accessoryLabel.stringValue = "Added \(metaInfo.1.formattedName)." - undoButton.isHidden = false - setupLabelHidingTimer() + accessoryLabel.stringValue = "Added \(metaInfo.1.formattedName)." + undoButton.isHidden = false + setupLabelHidingTimer() - resultsTableView.reloadData() - resultsTableView.isHidden = true + resultsTableView.reloadData() + resultsTableView.isHidden = true + } } private func metadata(for selection: TimezoneMetadata) -> (NSTimeZone, TimezoneMetadata) { @@ -194,7 +196,7 @@ class OnboardingSearchController: NSViewController { private func fetchTimezone(for latitude: Double, and longitude: Double, _ dataObject: TimezoneData) { if NetworkManager.isConnected() == false || ProcessInfo.processInfo.arguments.contains("mockTimezoneDown") { setInfoLabel(PreferencesConstants.noInternetConnectivityError) - searchResultsDataSource.cleanupFilterArray() + searchResultsDataSource?.cleanupFilterArray() resultsTableView.reloadData() return } @@ -215,7 +217,7 @@ class OnboardingSearchController: NSViewController { } if error == nil, let json = response, let response = json.decodeTimezone() { - if self.resultsTableView.selectedRow >= 0, self.resultsTableView.selectedRow < self.searchResultsDataSource.resultsCount() { + if self.resultsTableView.selectedRow >= 0, self.resultsTableView.selectedRow < (self.searchResultsDataSource?.resultsCount()) ?? 0 { var filteredAddress = "Error" if let address = dataObject.formattedAddress { @@ -312,7 +314,7 @@ class OnboardingSearchController: NSViewController { @objc func actualSearch() { func setupForError() { - searchResultsDataSource.calculateChangesets() + searchResultsDataSource?.calculateChangesets() resultsTableView.isHidden = true } @@ -345,12 +347,12 @@ class OnboardingSearchController: NSViewController { return } - self.searchResultsDataSource.cleanupFilterArray() - self.searchResultsDataSource.timezoneFilteredArray = [] + self.searchResultsDataSource?.cleanupFilterArray() + self.searchResultsDataSource?.timezoneFilteredArray = [] if let errorPresent = error { self.findLocalSearchResultsForTimezones() - if self.searchResultsDataSource.timezoneFilteredArray.count == 0 { + if self.searchResultsDataSource?.timezoneFilteredArray.count == 0 { self.presentErrorMessage(errorPresent.localizedDescription) setupForError() return @@ -391,12 +393,12 @@ class OnboardingSearchController: NSViewController { private func findLocalSearchResultsForTimezones() { let lowercasedSearchString = searchBar.stringValue.lowercased() - searchResultsDataSource.searchTimezones(lowercasedSearchString) + searchResultsDataSource?.searchTimezones(lowercasedSearchString) } private func prepareUIForPresentingResults() { setInfoLabel(CLEmptyString) - if searchResultsDataSource.calculateChangesets() { + if let dataSource = searchResultsDataSource, dataSource.calculateChangesets() { resultsTableView.isHidden = false resultsTableView.reloadData() } @@ -421,13 +423,13 @@ class OnboardingSearchController: NSViewController { return TimezoneData(with: totalPackage) } - searchResultsDataSource.setFilteredArrayValue(finalTimezones) + searchResultsDataSource?.setFilteredArrayValue(finalTimezones) } private func resetSearchView() { - searchResultsDataSource.cleanupFilterArray() - searchResultsDataSource.timezoneFilteredArray = [] - searchResultsDataSource.calculateChangesets() + searchResultsDataSource?.cleanupFilterArray() + searchResultsDataSource?.timezoneFilteredArray = [] + searchResultsDataSource?.calculateChangesets() resultsTableView.reloadData() searchBar.stringValue = CLEmptyString searchBar.placeholderString = "Press Enter to Search" @@ -441,15 +443,15 @@ class OnboardingSearchController: NSViewController { extension OnboardingSearchController: NSTableViewDataSource { func numberOfRows(in _: NSTableView) -> Int { - return searchResultsDataSource != nil ? searchResultsDataSource.resultsCount() : 0 + return searchResultsDataSource?.resultsCount() ?? 0 } func tableView(_ tableView: NSTableView, viewFor _: NSTableColumn?, row: Int) -> NSView? { if let result = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "resultCellView"), owner: self) as? ResultTableViewCell, row >= 0, - row < searchResultsDataSource.resultsCount() + row < (searchResultsDataSource?.resultsCount() ?? 0) { - let currentSelection = searchResultsDataSource.retrieveResult(row) + let currentSelection = searchResultsDataSource?.retrieveResult(row) if let timezone = currentSelection as? TimezoneMetadata { result.result.stringValue = " \(timezone.formattedName)" } else if let location = currentSelection as? TimezoneData { @@ -466,7 +468,7 @@ extension OnboardingSearchController: NSTableViewDataSource { extension OnboardingSearchController: NSTableViewDelegate { func tableView(_: NSTableView, heightOfRow row: Int) -> CGFloat { - if row == 0, searchResultsDataSource.resultsCount() == 0 { + if row == 0, searchResultsDataSource?.resultsCount() == 0 { return 30 } @@ -474,7 +476,7 @@ extension OnboardingSearchController: NSTableViewDelegate { } func tableView(_: NSTableView, shouldSelectRow row: Int) -> Bool { - return searchResultsDataSource.resultsCount() == 0 ? row != 0 : true + return searchResultsDataSource?.resultsCount() == 0 ? row != 0 : true } func tableView(_: NSTableView, rowViewForRow _: Int) -> NSTableRowView? { diff --git a/Clocker/Overall App/AppDefaults.swift b/Clocker/Overall App/AppDefaults.swift index a81c6e5..e99ba51 100644 --- a/Clocker/Overall App/AppDefaults.swift +++ b/Clocker/Overall App/AppDefaults.swift @@ -4,46 +4,19 @@ import Cocoa import CoreLoggerKit class AppDefaults { - class func initialize() { - initializeDefaults() + class func initialize(with store: DataStore, defaults: UserDefaults) { + initializeDefaults(with: store, defaults: defaults) } - private class func deleteOldUserDefaults() { - let userDefaults = UserDefaults.standard - - // Now delete the old preferences - if let bundleID = Bundle.main.bundleIdentifier, userDefaults.object(forKey: "PreferencesHaveBeenWiped") == nil { - userDefaults.removePersistentDomain(forName: bundleID) - userDefaults.set(true, forKey: "PreferencesHaveBeenWiped") - } - } - - private class func initializeDefaults() { - let userDefaults = UserDefaults.standard - let dataStore = DataStore.shared() - - let timezones = dataStore.timezones() - let selectedCalendars = userDefaults.object(forKey: CLSelectedCalendars) - - // Now delete the old preferences - userDefaults.wipeIfNeccesary() + private class func initializeDefaults(with store: DataStore, defaults: UserDefaults) { + let timezones = store.timezones() + let selectedCalendars = defaults.object(forKey: CLSelectedCalendars) // Register the usual suspects - userDefaults.register(defaults: defaultsDictionary()) - - dataStore.setTimezones(timezones) - userDefaults.set(selectedCalendars, forKey: CLSelectedCalendars) - - // Set the theme default as Light! - setDefaultTheme() - } - - private class func setDefaultTheme() { - let defaults = UserDefaults.standard + defaults.register(defaults: defaultsDictionary()) - if defaults.object(forKey: CLThemeKey) == nil { - Themer.shared().set(theme: 0) - } + store.setTimezones(timezones) + defaults.set(selectedCalendars, forKey: CLSelectedCalendars) } private class func defaultsDictionary() -> [String: Any] { @@ -69,25 +42,9 @@ class AppDefaults { } } -extension String { - func localized() -> String { - return NSLocalizedString(self, comment: "Title for \(self)") - } -} - extension UserDefaults { // Use this with caution. Exposing this for debugging purposes only. - func wipe() { - if let bundleID = Bundle.main.bundleIdentifier { - removePersistentDomain(forName: bundleID) - } - } - - func wipeIfNeccesary() { - if let bundleID = Bundle.main.bundleIdentifier, object(forKey: "PreferencesHaveBeenWiped") == nil { - Logger.info("Wiping all user defaults") - removePersistentDomain(forName: bundleID) - set(true, forKey: "PreferencesHaveBeenWiped") - } + func wipe(for bundleID: String) { + removePersistentDomain(forName: bundleID) } } diff --git a/Clocker/Overall App/ConfigExport.swift b/Clocker/Overall App/ConfigExport.swift index 482ec5f..f96e5bc 100644 --- a/Clocker/Overall App/ConfigExport.swift +++ b/Clocker/Overall App/ConfigExport.swift @@ -1,6 +1,7 @@ // Copyright © 2015 Abhishek Banthia import CoreModelKit +import CoreLoggerKit import Foundation struct ConfigExport { @@ -34,7 +35,7 @@ struct ConfigExport { var clockerPrefs: [String: Any] = [:] for (key, value) in dictionaryRep { if selectedKeys.contains(key) { - print("Key is \(key) and value is \(value)") + Logger.info("Config Export: Key is \(key) and value is \(value)") clockerPrefs[key] = value } } @@ -73,7 +74,7 @@ struct ConfigExport { let json = try JSONSerialization.data(withJSONObject: clockerPrefs, options: .prettyPrinted) print(json) } catch { - print("Failure Observed \(error.localizedDescription)") + Logger.info("Failure Observed \(error.localizedDescription)") } } } diff --git a/Clocker/Overall App/DataStore.swift b/Clocker/Overall App/DataStore.swift index 2cdb2eb..8ed0f6a 100644 --- a/Clocker/Overall App/DataStore.swift +++ b/Clocker/Overall App/DataStore.swift @@ -41,8 +41,6 @@ class DataStore: NSObject { init(with defaults: UserDefaults) { super.init() userDefaults = defaults - shouldDisplayDayInMenubar = shouldDisplay(.dayInMenubar) - shouldDisplayDateInMenubar = shouldDisplay(.dateInMenubar) setupSyncNotification() } @@ -66,7 +64,7 @@ class DataStore: NSObject { @objc func ubiquitousKeyValueStoreChanged(_ notification: Notification) { let userInfo = notification.userInfo ?? [:] let ubiquitousStore = notification.object as? NSUbiquitousKeyValueStore - print("--- User Info is \(userInfo)") + Logger.info("Ubiquitous Store Changed: User Info is \(userInfo)") let currentTimezones = userDefaults.object(forKey: CLDefaultPreferenceKey) as? [Data] let cloudTimezones = ubiquitousStore?.object(forKey: CLDefaultPreferenceKey) as? [Data] let cloudLastUpdateDate = (ubiquitousStore?.object(forKey: CLUbiquitousStoreLastUpdateKey) as? Date) ?? Date() @@ -113,20 +111,14 @@ class DataStore: NSObject { } } - func updateDayPreference() { - shouldDisplayDayInMenubar = shouldDisplay(.dayInMenubar) - } - - func updateDateInPreference() { - shouldDisplayDateInMenubar = shouldDisplay(.dateInMenubar) + // MARK: Date (May 8th) in Compact Menubar + func shouldShowDateInMenubar() -> Bool { + return shouldDisplay(.dateInMenubar) } - + + // MARK: Day (Sun, Mon etc.) in Compact Menubar func shouldShowDayInMenubar() -> Bool { - return shouldDisplayDayInMenubar - } - - func shouldShowDateInMenubar() -> Bool { - return shouldDisplayDateInMenubar + return shouldDisplay(.dayInMenubar) } func retrieve(key: String) -> Any? { @@ -189,11 +181,11 @@ class DataStore: NSObject { } return value.isEqual(to: NSNumber(value: 1)) case .dateInMenubar: - return shouldDisplayHelper(CLShowDateInMenu) + return shouldDisplayNonObjectHelper(CLShowDateInMenu) case .placeInMenubar: return shouldDisplayHelper(CLShowPlaceInMenu) case .dayInMenubar: - return shouldDisplayHelper(CLShowDayInMenu) + return shouldDisplayNonObjectHelper(CLShowDayInMenu) case .appDisplayOptions: return shouldDisplayHelper(CLAppDisplayOptions) case .menubarCompactMode: @@ -215,6 +207,12 @@ class DataStore: NSObject { } return value.isEqual(to: NSNumber(value: 0)) } + + // MARK: Some values are stored as plain integers; objectForKey: will return nil, so using integerForKey: + private func shouldDisplayNonObjectHelper(_ key: String) -> Bool { + let value = userDefaults.integer(forKey: key) + return value == 0 + } } extension DataStore { diff --git a/Clocker/Overall App/String + Additions.swift b/Clocker/Overall App/String + Additions.swift index 9095ba6..c28c0c3 100644 --- a/Clocker/Overall App/String + Additions.swift +++ b/Clocker/Overall App/String + Additions.swift @@ -14,4 +14,8 @@ extension String { return filteredAddress } + + func localized() -> String { + return NSLocalizedString(self, comment: "Title for \(self)") + } } diff --git a/Clocker/Panel/Data Layer/TimezoneDataOperations.swift b/Clocker/Panel/Data Layer/TimezoneDataOperations.swift index 0db1170..e6a6dda 100644 --- a/Clocker/Panel/Data Layer/TimezoneDataOperations.swift +++ b/Clocker/Panel/Data Layer/TimezoneDataOperations.swift @@ -6,14 +6,17 @@ import CoreLoggerKit import CoreModelKit class TimezoneDataOperations: NSObject { - private var dataObject: TimezoneData! + private let dataObject: TimezoneData + private let store: DataStore private lazy var nsCalendar = Calendar.autoupdatingCurrent private static var gregorianCalendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian) private static var swiftyCalendar = Calendar(identifier: .gregorian) private static let currentLocale = Locale.current.identifier - init(with timezone: TimezoneData) { + init(with timezone: TimezoneData, store: DataStore) { dataObject = timezone + self.store = store + super.init() } } @@ -28,7 +31,7 @@ extension TimezoneDataOperations { return CLEmptyString } - if dataObject.timezoneFormat(DataStore.shared().timezoneFormat()) == DateFormat.epochTime { + if dataObject.timezoneFormat(store.timezoneFormat()) == DateFormat.epochTime { let timezone = TimeZone(identifier: dataObject.timezone()) let offset = timezone?.secondsFromGMT(for: newDate) ?? 0 let value = Int(Date().timeIntervalSince1970 + Double(offset)) @@ -36,7 +39,7 @@ extension TimezoneDataOperations { } let dateFormatter = DateFormatterManager.dateFormatterWithFormat(with: .none, - format: dataObject.timezoneFormat(DataStore.shared().timezoneFormat()), + format: dataObject.timezoneFormat(store.timezoneFormat()), timezoneIdentifier: dataObject.timezone(), locale: Locale.autoupdatingCurrent) @@ -80,15 +83,15 @@ extension TimezoneDataOperations { func compactMenuTitle() -> String { var subtitle = CLEmptyString - let shouldDayBeShown = DataStore.shared().shouldShowDayInMenubar() - let shouldLabelBeShownAlongWithTime = !DataStore.shared().shouldDisplay(.placeInMenubar) + let shouldDayBeShown = store.shouldShowDayInMenubar() + let shouldLabelBeShownAlongWithTime = !store.shouldDisplay(.placeInMenubar) if shouldDayBeShown, shouldLabelBeShownAlongWithTime { let substring = date(with: 0, displayType: .menu) subtitle.append(substring) } - let shouldDateBeShown = DataStore.shared().shouldShowDateInMenubar() + let shouldDateBeShown = store.shouldShowDateInMenubar() if shouldDateBeShown, shouldLabelBeShownAlongWithTime { let date = Date().formatter(with: "MMM d", timeZone: dataObject.timezone()) subtitle.isEmpty ? subtitle.append("\(date)") : subtitle.append(" \(date)") @@ -100,15 +103,15 @@ extension TimezoneDataOperations { func compactMenuSubtitle() -> String { var subtitle = CLEmptyString - let shouldDayBeShown = DataStore.shared().shouldShowDayInMenubar() - let shouldLabelsNotBeShownAlongWithTime = DataStore.shared().shouldDisplay(.placeInMenubar) + let shouldDayBeShown = store.shouldShowDayInMenubar() + let shouldLabelsNotBeShownAlongWithTime = store.shouldDisplay(.placeInMenubar) if shouldDayBeShown, shouldLabelsNotBeShownAlongWithTime { let substring = date(with: 0, displayType: .menu) subtitle.append(substring) } - let shouldDateBeShown = DataStore.shared().shouldShowDateInMenubar() + let shouldDateBeShown = store.shouldShowDateInMenubar() if shouldDateBeShown, shouldLabelsNotBeShownAlongWithTime { let date = Date().formatter(with: "MMM d", timeZone: dataObject.timezone()) subtitle.isEmpty ? subtitle.append("\(date)") : subtitle.append(" \(date)") @@ -122,7 +125,7 @@ extension TimezoneDataOperations { func menuTitle() -> String { var menuTitle = CLEmptyString - let dataStore = DataStore.shared() + let dataStore = store let shouldCityBeShown = dataStore.shouldDisplay(.placeInMenubar) let shouldDayBeShown = dataStore.shouldShowDayInMenubar() @@ -199,7 +202,7 @@ extension TimezoneDataOperations { } func date(with sliderValue: Int, displayType: TimezoneData.DateDisplayType) -> String { - guard let relativeDayPreference = DataStore.shared().retrieve(key: CLRelativeDateKey) as? NSNumber else { + guard let relativeDayPreference = store.retrieve(key: CLRelativeDateKey) as? NSNumber else { assertionFailure("Data was unexpectedly nil") return CLEmptyString } @@ -332,7 +335,7 @@ extension TimezoneDataOperations { let minuteDifference = calculateTimeDifference(with: local as NSDate, timezoneDate: timezoneDate as NSDate) - minuteDifference == 0 ? replaceAgo.append("behind") : replaceAgo.append("\(minuteDifference) mins behind") + minuteDifference == 0 ? replaceAgo.append("behind") : replaceAgo.append("\(minuteDifference)m behind") return replaceAgo.lowercased() } @@ -388,7 +391,7 @@ extension TimezoneDataOperations { let dateFormatter = DateFormatter() dateFormatter.locale = Locale(identifier: "en_US") dateFormatter.timeZone = TimeZone(identifier: dataObject.timezone()) - dateFormatter.dateFormat = dataObject.timezoneFormat(DataStore.shared().timezoneFormat()) + dateFormatter.dateFormat = dataObject.timezoneFormat(store.timezoneFormat()) return dateFormatter.string(from: correct) } @@ -417,10 +420,10 @@ extension TimezoneDataOperations { } func saveObject(at index: Int = -1) { - var defaults = DataStore.shared().timezones() + var defaults = store.timezones() let encodedObject = NSKeyedArchiver.archivedData(withRootObject: dataObject as Any) index == -1 ? defaults.append(encodedObject) : defaults.insert(encodedObject, at: index) - DataStore.shared().setTimezones(defaults) + store.setTimezones(defaults) } } diff --git a/Clocker/Panel/PanelController.swift b/Clocker/Panel/PanelController.swift index 355e0a4..0b11f08 100644 --- a/Clocker/Panel/PanelController.swift +++ b/Clocker/Panel/PanelController.swift @@ -268,7 +268,7 @@ class PanelController: ParentPanelController { if count >= 1 || DataStore.shared().shouldDisplay(.showMeetingInMenubar) { if let delegate = NSApplication.shared.delegate as? AppDelegate { - Logger.info("\nWe will be invalidating the menubar timer as we want the parent timer to take care of both panel and menubar ") + Logger.info("We will be invalidating the menubar timer as we want the parent timer to take care of both panel and menubar ") delegate.invalidateMenubarTimer(false) } diff --git a/Clocker/Panel/ParentPanelController.swift b/Clocker/Panel/ParentPanelController.swift index 05b8324..8745d30 100644 --- a/Clocker/Panel/ParentPanelController.swift +++ b/Clocker/Panel/ParentPanelController.swift @@ -89,7 +89,7 @@ class ParentPanelController: NSWindowController { // Upcoming Events @IBOutlet var upcomingEventCollectionView: NSCollectionView! @IBOutlet var upcomingEventContainerView: NSView! - public var upcomingEventsDataSource: UpcomingEventsDataSource! + public var upcomingEventsDataSource: UpcomingEventsDataSource? var defaultPreferences: [Data] { return DataStore.shared().timezones() @@ -426,7 +426,7 @@ class ParentPanelController: NSWindowController { if let note = object?.note, note.isEmpty == false { newHeight += 20 } else if let obj = object, - TimezoneDataOperations(with: obj).nextDaylightSavingsTransitionIfAvailable(with: futureSliderValue) != nil + TimezoneDataOperations(with: obj, store: DataStore.shared()).nextDaylightSavingsTransitionIfAvailable(with: futureSliderValue) != nil { newHeight += 20 } @@ -436,7 +436,7 @@ class ParentPanelController: NSWindowController { // Set it to 90 expicity in case the row height is calculated be higher. newHeight = 88.0 - if let note = object?.note, note.isEmpty, let obj = object, TimezoneDataOperations(with: obj).nextDaylightSavingsTransitionIfAvailable(with: futureSliderValue) == nil { + if let note = object?.note, note.isEmpty, let obj = object, TimezoneDataOperations(with: obj, store: DataStore.shared()).nextDaylightSavingsTransitionIfAvailable(with: futureSliderValue) == nil { newHeight -= 20.0 } } @@ -509,12 +509,13 @@ class ParentPanelController: NSWindowController { updatePanelColor() - let defaults = DataStore.shared().timezones() + let store = DataStore.shared() + let defaults = store.timezones() let convertedTimezones = defaults.map { data -> TimezoneData in TimezoneData.customObject(from: data)! } - datasource = TimezoneDataSource(items: convertedTimezones) + datasource = TimezoneDataSource(items: convertedTimezones, store: store) mainTableView.dataSource = datasource mainTableView.delegate = datasource mainTableView.panelDelegate = datasource @@ -585,6 +586,9 @@ class ParentPanelController: NSWindowController { } private lazy var menubarTitleHandler = MenubarTitleProvider(with: DataStore.shared(), eventStore: EventCenter.sharedCenter()) + + static private let attributes: [NSAttributedString.Key : Any] = [NSAttributedString.Key.font: NSFont.monospacedDigitSystemFont(ofSize: 13.0, weight: NSFont.Weight.regular), + NSAttributedString.Key.baselineOffset : 0.1] @objc func updateTime() { let store = DataStore.shared() @@ -596,7 +600,8 @@ class ParentPanelController: NSWindowController { if store.shouldDisplay(.menubarCompactMode) { status.updateCompactMenubar() } else { - status.statusItem.title = menubarTitleHandler.titleForMenubar() + status.statusItem.button?.attributedTitle = NSAttributedString(string: menubarTitleHandler.titleForMenubar() ?? "", + attributes: ParentPanelController.attributes) } } } @@ -623,7 +628,7 @@ class ParentPanelController: NSWindowController { if modernContainerView != nil, modernSlider.isHidden == false, modernContainerView.currentlyInFocus { return } - let dataOperation = TimezoneDataOperations(with: model) + let dataOperation = TimezoneDataOperations(with: model, store: DataStore.shared()) cellView.time.stringValue = dataOperation.time(with: futureSliderValue) cellView.sunriseSetTime.stringValue = dataOperation.formattedSunriseTime(with: futureSliderValue) cellView.sunriseSetTime.lineBreakMode = .byClipping @@ -635,7 +640,7 @@ class ParentPanelController: NSWindowController { } if let note = model.note, !note.isEmpty { cellView.noteLabel.stringValue = note - } else if let value = TimezoneDataOperations(with: model).nextDaylightSavingsTransitionIfAvailable(with: futureSliderValue) { + } else if let value = TimezoneDataOperations(with: model, store: DataStore.shared()).nextDaylightSavingsTransitionIfAvailable(with: futureSliderValue) { cellView.noteLabel.stringValue = value } else { cellView.noteLabel.stringValue = CLEmptyString @@ -829,7 +834,7 @@ class ParentPanelController: NSWindowController { if self.upcomingEventCollectionView != nil, let upcomingEvents = eventCenter.upcomingEventsForDay(events) { - self.upcomingEventsDataSource.updateEventsDataSource(upcomingEvents) + self.upcomingEventsDataSource?.updateEventsDataSource(upcomingEvents) self.upcomingEventCollectionView.reloadData() return } @@ -840,7 +845,7 @@ class ParentPanelController: NSWindowController { } } else { if upcomingEventCollectionView != nil { - upcomingEventsDataSource.updateEventsDataSource([]) + upcomingEventsDataSource?.updateEventsDataSource([]) upcomingEventCollectionView.reloadData() return } @@ -1124,7 +1129,7 @@ extension ParentPanelController: NSSharingServicePickerDelegate { return clipboardCopy } - let timezoneOperations = TimezoneDataOperations(with: earliestTimezone) + let timezoneOperations = TimezoneDataOperations(with: earliestTimezone, store: DataStore.shared()) var sectionTitle = timezoneOperations.todaysDate(with: 0) // TODO: Take slider value into consideration clipboardCopy.append("\(sectionTitle)\n") @@ -1132,7 +1137,7 @@ extension ParentPanelController: NSSharingServicePickerDelegate { if $0 < sortedByTime.count, let dataModel = TimezoneData.customObject(from: sortedByTime[$0]) { - let dataOperations = TimezoneDataOperations(with: dataModel) + let dataOperations = TimezoneDataOperations(with: dataModel, store: DataStore.shared()) let date = dataOperations.todaysDate(with: 0) let time = dataOperations.time(with: 0) if date != sectionTitle { diff --git a/Clocker/Panel/Rate Controller/UpcomingEventView.swift b/Clocker/Panel/Rate Controller/UpcomingEventView.swift index 7bd1026..152c9c6 100644 --- a/Clocker/Panel/Rate Controller/UpcomingEventView.swift +++ b/Clocker/Panel/Rate Controller/UpcomingEventView.swift @@ -1,6 +1,7 @@ // Copyright © 2015 Abhishek Banthia import Cocoa +import CoreLoggerKit class ModernSliderContainerView: NSView { private var trackingArea: NSTrackingArea? @@ -67,7 +68,7 @@ class DraggableClipView: NSClipView { clickPoint = nil gestureInProgress = false default: - print("Default case is happening \(event.type)") + Logger.info("Default mouse event occurred for \(event.type)") } } } diff --git a/Clocker/Panel/UI/TimezoneDataSource.swift b/Clocker/Panel/UI/TimezoneDataSource.swift index be15e45..1d74463 100644 --- a/Clocker/Panel/UI/TimezoneDataSource.swift +++ b/Clocker/Panel/UI/TimezoneDataSource.swift @@ -6,10 +6,13 @@ import CoreModelKit class TimezoneDataSource: NSObject { var timezones: [TimezoneData] = [] var sliderValue: Int = 0 + var dataStore: DataStore - init(items: [TimezoneData]) { + init(items: [TimezoneData], store: DataStore) { sliderValue = 0 timezones = Array(items) + dataStore = store + super.init() } } @@ -51,7 +54,7 @@ extension TimezoneDataSource: NSTableViewDataSource, NSTableViewDelegate { } let currentModel = timezones[row] - let operation = TimezoneDataOperations(with: currentModel) + let operation = TimezoneDataOperations(with: currentModel, store: dataStore) cellView.sunriseSetTime.stringValue = operation.formattedSunriseTime(with: sliderValue) cellView.sunriseImage.image = currentModel.isSunriseOrSunset ? Themer.shared().sunriseImage() : Themer.shared().sunsetImage() @@ -85,12 +88,12 @@ extension TimezoneDataSource: NSTableViewDataSource, NSTableViewDelegate { return 100 } - if let userFontSize = DataStore.shared().retrieve(key: CLUserFontSizePreference) as? NSNumber, + if let userFontSize = dataStore.retrieve(key: CLUserFontSizePreference) as? NSNumber, timezones.count > row, - let relativeDisplay = DataStore.shared().retrieve(key: CLRelativeDateKey) as? NSNumber + let relativeDisplay = dataStore.retrieve(key: CLRelativeDateKey) as? NSNumber { let model = timezones[row] - let shouldShowSunrise = DataStore.shared().shouldDisplay(.sunrise) + let shouldShowSunrise = dataStore.shouldDisplay(.sunrise) var rowHeight: Int = userFontSize == 4 ? 60 : 65 @@ -104,7 +107,7 @@ extension TimezoneDataSource: NSTableViewDataSource, NSTableViewDelegate { if let note = model.note, !note.isEmpty { rowHeight += userFontSize.intValue + 15 - } else if TimezoneDataOperations(with: model).nextDaylightSavingsTransitionIfAvailable(with: sliderValue) != nil { + } else if TimezoneDataOperations(with: model, store: dataStore).nextDaylightSavingsTransitionIfAvailable(with: sliderValue) != nil { rowHeight += userFontSize.intValue + 15 } @@ -140,7 +143,7 @@ extension TimezoneDataSource: NSTableViewDataSource, NSTableViewDelegate { tableView.removeRows(at: indexSet, withAnimation: NSTableView.AnimationOptions()) - if DataStore.shared().shouldDisplay(ViewType.showAppInForeground) { + if self.dataStore.shouldDisplay(ViewType.showAppInForeground) { windowController.deleteTimezone(at: row) } else { guard let panelController = PanelController.panel() else { return } @@ -173,12 +176,14 @@ extension TimezoneDataSource: NSTableViewDataSource, NSTableViewDelegate { let response = alert.runModal() if response.rawValue == 1000 { - OperationQueue.main.addOperation { + OperationQueue.main.addOperation { [weak self] in + guard let sSelf = self else { return } + let indexSet = IndexSet(integer: row) tableView.removeRows(at: indexSet, withAnimation: NSTableView.AnimationOptions.slideUp) - if DataStore.shared().shouldDisplay(ViewType.showAppInForeground) { + if sSelf.dataStore.shouldDisplay(ViewType.showAppInForeground) { let windowController = FloatingWindowController.shared() windowController.deleteTimezone(at: row) } else { diff --git a/Clocker/Preferences/App Feedback/AppFeedbackWindowController.swift b/Clocker/Preferences/App Feedback/AppFeedbackWindowController.swift index a351edc..05ef776 100644 --- a/Clocker/Preferences/App Feedback/AppFeedbackWindowController.swift +++ b/Clocker/Preferences/App Feedback/AppFeedbackWindowController.swift @@ -18,7 +18,6 @@ extension NSNib.Name { } enum AppFeedbackConstants { - static let CLAppFeedbackNibIdentifier = "AppFeedbackWindow" static let CLAppFeedbackNoResponseString = "Not Provided" static let CLAppFeedbackNameProperty = "name" static let CLAppFeedbackEmailProperty = "email" @@ -256,7 +255,7 @@ class AppFeedbackWindowController: NSWindowController { isActivityInProgress = false let alert = NSAlert() - alert.messageText = "Thank you for helping make Clocker even better!" + alert.messageText = AppFeedbackConstants.CLFeedbackAlertTitle alert.informativeText = AppFeedbackConstants.CLFeedbackAlertInformativeText alert.addButton(withTitle: AppFeedbackConstants.CLFeedbackAlertButtonTitle) alert.beginSheetModal(for: feedbackWindow) { _ in diff --git a/Clocker/Preferences/Appearance/AppearanceViewController.swift b/Clocker/Preferences/Appearance/AppearanceViewController.swift index 679fb54..002c6be 100644 --- a/Clocker/Preferences/Appearance/AppearanceViewController.swift +++ b/Clocker/Preferences/Appearance/AppearanceViewController.swift @@ -316,12 +316,10 @@ class AppearanceViewController: ParentViewController { } @IBAction func displayDayInMenubarAction(_: Any) { - DataStore.shared().updateDayPreference() updateStatusItem() } @IBAction func displayDateInMenubarAction(_: Any) { - DataStore.shared().updateDateInPreference() updateStatusItem() } @@ -381,7 +379,7 @@ extension AppearanceViewController: NSTableViewDataSource, NSTableViewDelegate { } let currentModel = previewTimezones[row] - let operation = TimezoneDataOperations(with: currentModel) + let operation = TimezoneDataOperations(with: currentModel, store: DataStore.shared()) cellView.sunriseSetTime.stringValue = operation.formattedSunriseTime(with: 0) cellView.sunriseImage.image = currentModel.isSunriseOrSunset ? Themer.shared().sunriseImage() : Themer.shared().sunsetImage() diff --git a/Clocker/Preferences/General/PreferencesDataSource.swift b/Clocker/Preferences/General/PreferencesDataSource.swift index 63d464d..aafef6c 100644 --- a/Clocker/Preferences/General/PreferencesDataSource.swift +++ b/Clocker/Preferences/General/PreferencesDataSource.swift @@ -22,11 +22,13 @@ protocol PreferenceSelectionUpdates: AnyObject { class PreferencesDataSource: NSObject { private weak var updateDelegate: PreferenceSelectionUpdates? + private let store: DataStore var selectedTimezones: [Data] { - return DataStore.shared().timezones() + return store.timezones() } - init(callbackDelegate delegate: PreferenceSelectionUpdates) { + init(with store: DataStore, callbackDelegate delegate: PreferenceSelectionUpdates) { + self.store = store updateDelegate = delegate super.init() } @@ -75,7 +77,7 @@ extension PreferencesDataSource: NSTableViewDelegate { newOrder.insert(currentObject, at: destination) - DataStore.shared().setTimezones(newOrder) + store.setTimezones(newOrder) tableView.reloadData() @@ -185,7 +187,7 @@ extension PreferencesDataSource: NSTableViewDataSource { let encodedObject = NSKeyedArchiver.archivedData(withRootObject: timezone) var newDefaults = selectedTimezones newDefaults[index] = encodedObject - DataStore.shared().setTimezones(newDefaults) + store.setTimezones(newDefaults) } private func updateMenubarTitles() { diff --git a/Clocker/Preferences/General/PreferencesViewController.swift b/Clocker/Preferences/General/PreferencesViewController.swift index 4226215..6c8c6ad 100644 --- a/Clocker/Preferences/General/PreferencesViewController.swift +++ b/Clocker/Preferences/General/PreferencesViewController.swift @@ -116,7 +116,7 @@ class PreferencesViewController: ParentViewController { searchField.placeholderString = "Enter city, state, country or timezone name" - selectionsDataSource = PreferencesDataSource(callbackDelegate: self) + selectionsDataSource = PreferencesDataSource(with: DataStore.shared(), callbackDelegate: self) timezoneTableView.dataSource = selectionsDataSource timezoneTableView.delegate = selectionsDataSource @@ -612,7 +612,7 @@ extension PreferencesViewController { // Mark if the timezone is same as local timezone let timezoneObject = TimezoneData(with: newTimeZone) - let operationsObject = TimezoneDataOperations(with: timezoneObject) + let operationsObject = TimezoneDataOperations(with: timezoneObject, store: DataStore.shared()) operationsObject.saveObject() Logger.log(object: ["PlaceName": filteredAddress, "Timezone": timezone.timeZoneId], for: "Filtered Address") @@ -746,7 +746,7 @@ extension PreferencesViewController { data.selectionType = .timezone data.isSystemTimezone = metaInfo.0.name == NSTimeZone.system.identifier - let operationObject = TimezoneDataOperations(with: data) + let operationObject = TimezoneDataOperations(with: data, store: DataStore.shared()) operationObject.saveObject() searchResultsDataSource.cleanupFilterArray() diff --git a/Clocker/Preferences/Menu Bar/MenubarTitleProvider.swift b/Clocker/Preferences/Menu Bar/MenubarTitleProvider.swift index d4305e3..1a36310 100644 --- a/Clocker/Preferences/Menu Bar/MenubarTitleProvider.swift +++ b/Clocker/Preferences/Menu Bar/MenubarTitleProvider.swift @@ -34,7 +34,7 @@ class MenubarTitleProvider: NSObject { if menubarTitles.isEmpty == false { let titles = menubarTitles.map { data -> String? in let timezone = TimezoneData.customObject(from: data) - let operationsObject = TimezoneDataOperations(with: timezone!) + let operationsObject = TimezoneDataOperations(with: timezone!, store: store) return "\(operationsObject.menuTitle().trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines))" } diff --git a/Clocker/Preferences/Menu Bar/StatusContainerView.swift b/Clocker/Preferences/Menu Bar/StatusContainerView.swift index 6de08d5..a3105af 100644 --- a/Clocker/Preferences/Menu Bar/StatusContainerView.swift +++ b/Clocker/Preferences/Menu Bar/StatusContainerView.swift @@ -47,6 +47,12 @@ protocol StatusItemViewConforming { func statusItemViewIdentifier() -> String } +/// Observe for User Default changes for timezones in App Delegate and reconstruct the Status View if neccesary +/// We'll inject the menubar timezones into Status Container View which'll pass it to StatusItemView +/// The benefit of doing so is reducing time-spent calculating menubar timezones and deserialization through `TimezoneData.customObject` +/// Also inject, `shouldDisplaySecondsInMenubar` +/// + class StatusContainerView: NSView { private var previousX: Int = 0 private let store: DataStore @@ -96,7 +102,7 @@ class StatusContainerView: NSView { if let timezoneObject = TimezoneData.customObject(from: timezone) { let precalculatedWidth = Double(compactWidth(for: timezoneObject, with: store)) - let operationObject = TimezoneDataOperations(with: timezoneObject) + let operationObject = TimezoneDataOperations(with: timezoneObject, store: store) let calculatedSubtitleSize = compactModeTimeFont.size(for: operationObject.compactMenuSubtitle(), width: precalculatedWidth, attributes: timeBasedAttributes) @@ -158,7 +164,7 @@ class StatusContainerView: NSView { NSAttributedString.Key.paragraphStyle: defaultParagraphStyle, ] - let operation = TimezoneDataOperations(with: timezone) + let operation = TimezoneDataOperations(with: timezone, store: store) let bestSize = compactModeTimeFont.size(for: operation.compactMenuSubtitle(), width: Double(compactWidth(for: timezone, with: store)), attributes: timeBasedAttributes) diff --git a/Clocker/Preferences/Menu Bar/StatusItemHandler.swift b/Clocker/Preferences/Menu Bar/StatusItemHandler.swift index 7d6be19..f4b40ad 100644 --- a/Clocker/Preferences/Menu Bar/StatusItemHandler.swift +++ b/Clocker/Preferences/Menu Bar/StatusItemHandler.swift @@ -61,7 +61,7 @@ class StatusItemHandler: NSObject { setClockerIcon() } - Logger.info("\nStatus Bar Current State changed: \(currentState)\n") + Logger.info("Status Bar Current State changed: \(currentState)\n") } } @@ -365,9 +365,10 @@ class StatusItemHandler: NSObject { setClockerIcon() return } - - statusItem.button?.title = menubarText - statusItem.button?.font = NSFont.monospacedDigitSystemFont(ofSize: 14.0, weight: NSFont.Weight.regular) + + let attributes = [NSAttributedString.Key.font: NSFont.monospacedDigitSystemFont(ofSize: 13.0, weight: NSFont.Weight.regular), + NSAttributedString.Key.baselineOffset : 0.1] as [NSAttributedString.Key : Any] + statusItem.button?.attributedTitle = NSAttributedString(string: menubarText, attributes: attributes) statusItem.button?.image = nil statusItem.button?.imagePosition = .imageLeft } diff --git a/Clocker/Preferences/Menu Bar/StatusItemView.swift b/Clocker/Preferences/Menu Bar/StatusItemView.swift index a2b871b..ea61d36 100644 --- a/Clocker/Preferences/Menu Bar/StatusItemView.swift +++ b/Clocker/Preferences/Menu Bar/StatusItemView.swift @@ -40,7 +40,7 @@ class StatusItemView: NSView { private let locationView = NSTextField(labelWithString: "Hello") private let timeView = NSTextField(labelWithString: "Mon 19:14 PM") private var operationsObject: TimezoneDataOperations { - return TimezoneDataOperations(with: dataObject) + return TimezoneDataOperations(with: dataObject, store: DataStore.shared()) } private var timeAttributes: [NSAttributedString.Key: AnyObject] { diff --git a/Clocker/Preferences/Preferences.storyboard b/Clocker/Preferences/Preferences.storyboard index 8bffd78..9648eed 100644 --- a/Clocker/Preferences/Preferences.storyboard +++ b/Clocker/Preferences/Preferences.storyboard @@ -283,7 +283,7 @@ - When selected, your upcoming meeting title will appear in the menubar 30 mins before it starts. All Day Events won't be shown in the menubar! + When selected, your upcoming meeting title will appear in the menubar 30m before it starts. All Day Events won't be shown in the menubar! @@ -411,7 +411,7 @@ - + @@ -434,7 +434,7 @@ - + - + - + - + @@ -1666,14 +1666,14 @@ DQ - + - +