diff --git a/Clocker/ClockerUnitTests/ClockerUnitTests.swift b/Clocker/ClockerUnitTests/ClockerUnitTests.swift index 21cca39..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) 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 3b52c0a..cfded45 100644 --- a/Clocker/Onboarding/OnboardingSearchController.swift +++ b/Clocker/Onboarding/OnboardingSearchController.swift @@ -109,7 +109,7 @@ class OnboardingSearchController: NSViewController { 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/Panel/Data Layer/TimezoneDataOperations.swift b/Clocker/Panel/Data Layer/TimezoneDataOperations.swift index 5ec980f..8d436a8 100644 --- a/Clocker/Panel/Data Layer/TimezoneDataOperations.swift +++ b/Clocker/Panel/Data Layer/TimezoneDataOperations.swift @@ -7,13 +7,15 @@ import CoreModelKit class TimezoneDataOperations: NSObject { 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) { - dataObject = timezone + init(with timezone: TimezoneData, store: DataStore) { + self.dataObject = timezone + self.store = store super.init() } } @@ -29,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)) @@ -37,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) @@ -81,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)") @@ -101,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)") @@ -123,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() @@ -200,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 } @@ -389,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) } @@ -418,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/ParentPanelController.swift b/Clocker/Panel/ParentPanelController.swift index 9ce1654..4644e92 100644 --- a/Clocker/Panel/ParentPanelController.swift +++ b/Clocker/Panel/ParentPanelController.swift @@ -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 } } @@ -624,7 +624,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 @@ -636,7 +636,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 @@ -1125,7 +1125,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") @@ -1133,7 +1133,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/UI/TimezoneDataSource.swift b/Clocker/Panel/UI/TimezoneDataSource.swift index 8e1e12e..cc248ef 100644 --- a/Clocker/Panel/UI/TimezoneDataSource.swift +++ b/Clocker/Panel/UI/TimezoneDataSource.swift @@ -54,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() @@ -107,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 } @@ -176,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/Appearance/AppearanceViewController.swift b/Clocker/Preferences/Appearance/AppearanceViewController.swift index 679fb54..695175f 100644 --- a/Clocker/Preferences/Appearance/AppearanceViewController.swift +++ b/Clocker/Preferences/Appearance/AppearanceViewController.swift @@ -381,7 +381,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/PreferencesViewController.swift b/Clocker/Preferences/General/PreferencesViewController.swift index d413e72..6c8c6ad 100644 --- a/Clocker/Preferences/General/PreferencesViewController.swift +++ b/Clocker/Preferences/General/PreferencesViewController.swift @@ -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..e50ad6a 100644 --- a/Clocker/Preferences/Menu Bar/StatusContainerView.swift +++ b/Clocker/Preferences/Menu Bar/StatusContainerView.swift @@ -96,7 +96,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 +158,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/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] {