Browse Source

One step closer to unified search.

pull/92/head
Abhishek 6 years ago
parent
commit
e095ad0d7a
  1. 4
      Clocker/AppDelegate.swift
  2. 24
      Clocker/ClockerUITests/AboutUsTests.swift
  3. 27
      Clocker/ClockerUITests/PreferencesTest.swift
  4. 3
      Clocker/Panel/Data Layer/TimezoneData.swift
  5. 1
      Clocker/Preferences/General/PreferencesDataSource.swift
  6. 266
      Clocker/Preferences/General/PreferencesViewController.swift

4
Clocker/AppDelegate.swift

@ -47,7 +47,7 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
AppDefaults.initialize() AppDefaults.initialize()
// Check if we can show the onboarding flow! // Check if we can show the onboarding flow!
showOnboardingFlow() showOnboardingFlowIfEligible()
// Ratings Controller initialization // Ratings Controller initialization
RateController.applicationDidLaunch(UserDefaults.standard) RateController.applicationDidLaunch(UserDefaults.standard)
@ -92,7 +92,7 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
return onboardingStoryboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("onboardingFlow")) as? OnboardingController return onboardingStoryboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("onboardingFlow")) as? OnboardingController
}() }()
private func showOnboardingFlow() { private func showOnboardingFlowIfEligible() {
let shouldLaunchOnboarding = (DataStore.shared().retrieve(key: CLShowOnboardingFlow) == nil && DataStore.shared().timezones().isEmpty) let shouldLaunchOnboarding = (DataStore.shared().retrieve(key: CLShowOnboardingFlow) == nil && DataStore.shared().timezones().isEmpty)
|| ProcessInfo.processInfo.arguments.contains(CLOnboaringTestsLaunchArgument) || ProcessInfo.processInfo.arguments.contains(CLOnboaringTestsLaunchArgument)

24
Clocker/ClockerUITests/AboutUsTests.swift

@ -109,7 +109,7 @@ extension XCTestCase {
func addAPlace(place: String, to app: XCUIApplication, shouldSleep: Bool = true) { func addAPlace(place: String, to app: XCUIApplication, shouldSleep: Bool = true) {
// Let's first check if the place is already present in the list // Let's first check if the place is already present in the list
let matchPredicate = NSPredicate(format: "value == %@", place) let matchPredicate = NSPredicate(format: "value contains %@", place)
let matchingFields = app.windows["Clocker"].tables["TimezoneTableView"].textFields.matching(matchPredicate) let matchingFields = app.windows["Clocker"].tables["TimezoneTableView"].textFields.matching(matchPredicate)
if matchingFields.count > 0 { if matchingFields.count > 0 {
return return
@ -121,18 +121,25 @@ extension XCTestCase {
let searchField = app.searchFields["AvailableSearchField"] let searchField = app.searchFields["AvailableSearchField"]
searchField.reset(text: place) searchField.reset(text: place)
let firstResult = app.tables["AvailableTimezoneTableView"].tableRows.firstMatch let results = app.tables["AvailableTimezoneTableView"].cells.staticTexts.matching(matchPredicate)
let waiter = XCTWaiter() let waiter = XCTWaiter()
let isHittable = NSPredicate(format: "exists == true", "") let isHittable = NSPredicate(format: "exists == true", "")
let addExpectation = expectation(for: isHittable, let addExpectation = expectation(for: isHittable,
evaluatedWith: firstResult, evaluatedWith: results.firstMatch) { () -> Bool in
handler: nil) print("Handler called")
return true
}
waiter.wait(for: [addExpectation], timeout: 5) waiter.wait(for: [addExpectation], timeout: 5)
app.tables["AvailableTimezoneTableView"].click()
if results.count > 0 {
results.firstMatch.click()
}
app.buttons["AddAvailableTimezone"].click() app.buttons["AddAvailableTimezone"].click()
if shouldSleep { if shouldSleep {
sleep(2) sleep(2)
} }
@ -154,7 +161,8 @@ extension XCTestCase {
} }
func deleteAPlace(place: String, for app: XCUIApplication, shouldSleep: Bool = true) { func deleteAPlace(place: String, for app: XCUIApplication, shouldSleep: Bool = true) {
let row = app.windows["Clocker"].textFields[place].firstMatch let matchPredicate = NSPredicate(format: "value == %@", place)
let row = app.tables["TimezoneTableView"].textFields.matching(matchPredicate).firstMatch
row.click() row.click()
row.typeKey(XCUIKeyboardKey.delete, modifierFlags: XCUIElement.KeyModifierFlags()) row.typeKey(XCUIKeyboardKey.delete, modifierFlags: XCUIElement.KeyModifierFlags())
if shouldSleep { if shouldSleep {

27
Clocker/ClockerUITests/PreferencesTest.swift

@ -43,12 +43,10 @@ class PreferencesTest: XCTestCase {
app.windows["Clocker"].checkBoxes["AddTimezone"].click() app.windows["Clocker"].checkBoxes["AddTimezone"].click()
} }
app.sheets.radioGroups.radioButtons["Search by Timezone(s)"].click()
addAPlace(place: "UTC", to: app) addAPlace(place: "UTC", to: app)
let matchPredicate = NSPredicate(format: "value == %@", "UTC") let matchPredicate = NSPredicate(format: "value == %@", "UTC")
let matchingFields = app.windows["Clocker"].textFields.matching(matchPredicate) let matchingFields = app.tables["TimezoneTableView"].textFields.matching(matchPredicate)
XCTAssertTrue(matchingFields.count > 0, "Matching Fields count was zero") XCTAssertTrue(matchingFields.count > 0, "Matching Fields count was zero")
deleteAPlace(place: "UTC", for: app) deleteAPlace(place: "UTC", for: app)
@ -225,7 +223,7 @@ class PreferencesTest: XCTestCase {
let searchField = app.searchFields["AvailableSearchField"] let searchField = app.searchFields["AvailableSearchField"]
searchField.reset(text: "StuJjlqh7AcJFnBuOdgNa2dQ4WrIajP9Mo8R83FV7fIZ3B8zE2n") searchField.reset(text: "StuJjlqh7AcJFnBuOdgNa2dQ4WrIajP9Mo8R83FV7fIZ3B8zE2n")
sleep(1) sleep(2)
let maxCharacterCountPredicate = NSPredicate(format: "value like %@", "Only 50 characters allowed!") let maxCharacterCountPredicate = NSPredicate(format: "value like %@", "Only 50 characters allowed!")
let currentSheets = app.sheets.firstMatch.staticTexts let currentSheets = app.sheets.firstMatch.staticTexts
@ -253,27 +251,6 @@ class PreferencesTest: XCTestCase {
deleteAPlace(place: "Cambodia", for: app, shouldSleep: false) deleteAPlace(place: "Cambodia", for: app, shouldSleep: false)
} }
func testPlaceholderStrings() {
app.tapMenubarIcon()
app.tables["mainTableView"].typeKey(",", modifierFlags: .command)
if app.sheets.count == 0 {
app.windows["Clocker"].checkBoxes["AddTimezone"].click()
}
app.sheets.radioGroups.radioButtons["Search by Timezone(s)"].click()
let expectedPlaceholder = "Enter a timezone name"
let currentPlaceholder = app.sheets.searchFields["AvailableSearchField"]
XCTAssertTrue(currentPlaceholder.exists, "Search Field doesn't exist")
XCTAssertEqual(currentPlaceholder.placeholderValue!, expectedPlaceholder)
let newPlaceholderValue = "Enter a city, state or country name"
app.sheets.radioGroups.radioButtons["Search By City"].click()
let newPlaceholder = app.sheets.searchFields["AvailableSearchField"]
XCTAssertTrue(newPlaceholder.exists, "Search Field doesn't exist")
XCTAssertEqual(newPlaceholder.placeholderValue!, newPlaceholderValue)
}
func testNoTimezone() { func testNoTimezone() {
app.tapMenubarIcon() app.tapMenubarIcon()
app.buttons["Preferences"].click() app.buttons["Preferences"].click()

3
Clocker/Panel/Data Layer/TimezoneData.swift

@ -218,8 +218,6 @@ class TimezoneData: NSObject, NSCoding {
// Now point it to new models // Now point it to new models
DataStore.shared().setTimezones(newModels) DataStore.shared().setTimezones(newModels)
print("Successfully converted: \(newModels.count) timezones")
} }
} }
@ -246,6 +244,7 @@ class TimezoneData: NSObject, NSCoding {
let old = NSKeyedUnarchiver.unarchiveObject(with: timezone) let old = NSKeyedUnarchiver.unarchiveObject(with: timezone)
if let oldModel = old as? CLTimezoneData { if let oldModel = old as? CLTimezoneData {
// Convert it to new model and add it // Convert it to new model and add it
print("We're still using old Objective-C models");
let newTimezone = TimezoneData(with: oldModel) let newTimezone = TimezoneData(with: oldModel)
newModels.append(newTimezone) newModels.append(newTimezone)
} else if let newModel = old as? TimezoneData { } else if let newModel = old as? TimezoneData {

1
Clocker/Preferences/General/PreferencesDataSource.swift

@ -3,7 +3,6 @@
import Cocoa import Cocoa
protocol PreferenceSelectionUpdates: AnyObject { protocol PreferenceSelectionUpdates: AnyObject {
func didAddTimezone(_ timezone: TimezoneData)
func markAsFavorite(_ dataObject: TimezoneData) func markAsFavorite(_ dataObject: TimezoneData)
func unfavourite(_ dataObject: TimezoneData) func unfavourite(_ dataObject: TimezoneData)
func refreshTimezoneTable() func refreshTimezoneTable()

266
Clocker/Preferences/General/PreferencesViewController.swift

@ -14,6 +14,18 @@ struct PreferencesConstants {
static let offlineErrorMessage = "The Internet connection appears to be offline." static let offlineErrorMessage = "The Internet connection appears to be offline."
} }
enum RowType {
case timezoneHeader
case cityHeader
case city
case timezone
}
struct TimezoneMetadata {
let timezone: Timezone
let tages: Set<String> = Set()
}
class PreferencesViewController: ParentViewController { class PreferencesViewController: ParentViewController {
private var isActivityInProgress = false { private var isActivityInProgress = false {
didSet { didSet {
@ -33,7 +45,6 @@ class PreferencesViewController: ParentViewController {
private var filteredArray: [Any] = [] private var filteredArray: [Any] = []
private var timezoneArray: [String] = [] private var timezoneArray: [String] = []
private var timezoneFilteredArray: [String] = [] private var timezoneFilteredArray: [String] = []
private var columnName = "Place(s)"
private var dataTask: URLSessionDataTask? = .none private var dataTask: URLSessionDataTask? = .none
private lazy var notimezoneView: NoTimezoneView? = { private lazy var notimezoneView: NoTimezoneView? = {
@ -75,8 +86,8 @@ class PreferencesViewController: ParentViewController {
@IBOutlet var sortToggle: NSButton! @IBOutlet var sortToggle: NSButton!
private var themeDidChangeNotification: NSObjectProtocol? private var themeDidChangeNotification: NSObjectProtocol?
private var selectionsDataSource: PreferencesDataSource! private var selectionsDataSource: PreferencesDataSource!
private var finalArray: [RowType] = []
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
@ -90,8 +101,6 @@ class PreferencesViewController: ParentViewController {
setup() setup()
availableTimezoneTableView.reloadData()
setupShortcutObserver() setupShortcutObserver()
darkModeChanges() darkModeChanges()
@ -106,9 +115,37 @@ class PreferencesViewController: ParentViewController {
selectionsDataSource = PreferencesDataSource(callbackDelegate: self) selectionsDataSource = PreferencesDataSource(callbackDelegate: self)
timezoneTableView.dataSource = selectionsDataSource timezoneTableView.dataSource = selectionsDataSource
timezoneTableView.delegate = selectionsDataSource timezoneTableView.delegate = selectionsDataSource
reloadSearchResults()
}
private func calculateArray() {
finalArray = []
func addTimezonesIfNeeded(_ data: [String]) {
if !data.isEmpty {
finalArray.append(.timezoneHeader)
}
data.forEach { (_) in
finalArray.append(.timezone)
}
}
if searchField.stringValue.isEmpty {
addTimezonesIfNeeded(timezoneArray)
} else {
if !filteredArray.isEmpty {
finalArray.append(.cityHeader)
}
filteredArray.forEach { (_) in
finalArray.append(.city)
}
addTimezonesIfNeeded(timezoneFilteredArray)
}
} }
deinit { deinit {
// We still need to remove observers set using NotificationCenter block: APIs
if let themeDidChangeNotif = themeDidChangeNotification { if let themeDidChangeNotif = themeDidChangeNotification {
NotificationCenter.default.removeObserver(themeDidChangeNotif) NotificationCenter.default.removeObserver(themeDidChangeNotif)
} }
@ -223,12 +260,6 @@ class PreferencesViewController: ParentViewController {
[placeholderLabel, additionalSortOptions].forEach { $0.isHidden = true } [placeholderLabel, additionalSortOptions].forEach { $0.isHidden = true }
if timezoneArray.isEmpty {
timezoneArray.append("UTC")
timezoneArray.append("Anywhere on Earth")
timezoneArray.append(contentsOf: NSTimeZone.knownTimeZoneNames)
}
messageLabel.stringValue = CLEmptyString messageLabel.stringValue = CLEmptyString
timezoneTableView.registerForDraggedTypes([.dragSession]) timezoneTableView.registerForDraggedTypes([.dragSession])
@ -325,60 +356,72 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate
func numberOfRows(in _: NSTableView) -> Int { func numberOfRows(in _: NSTableView) -> Int {
return numberOfSearchResults() return numberOfSearchResults()
} }
func tableView(_ tableView: NSTableView, viewFor _: NSTableColumn?, row _: Int) -> NSView? { func tableView(_ tableView: NSTableView, isGroupRow row: Int) -> Bool {
if let message = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "resultCell"), owner: self) as? SearchResultTableViewCell { let currentRowType = finalArray[row]
message.sourceName.stringValue = "Nicaragua" return
return message currentRowType == .timezoneHeader ||
} currentRowType == .cityHeader
}
return nil
func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
print("Should Select Row")
let currentRowType = finalArray[row]
return !(currentRowType == .timezoneHeader || currentRowType == .cityHeader)
}
func tableView(_ tableView: NSTableView, selectionIndexesForProposedSelection proposedSelectionIndexes: IndexSet) -> IndexSet {
// print("Selection Indexes for Proposed Selection: \(proposedSelectionIndexes.first!)")
return proposedSelectionIndexes
} }
func tableView(_: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? { func tableView(_ tableView: NSTableView, viewFor _: NSTableColumn?, row: Int) -> NSView? {
var dataSource: TimezoneData? let currentRowType = finalArray[row]
if filteredArray.count > row, let currentFilteredObject = filteredArray[row] as? TimezoneData { switch currentRowType {
dataSource = currentFilteredObject case .timezoneHeader, .cityHeader:
return headerCell(tableView, currentRowType)
case .timezone:
return timezoneCell(tableView, currentRowType, row)
case .city:
return cityCell(tableView, currentRowType, row)
} }
}
if tableColumn?.identifier.rawValue == PreferencesConstants.availableTimezoneIdentifier { private func timezoneCell(_ tableView: NSTableView, _ rowType: RowType, _ row: Int) -> NSView? {
if filteredArray.isEmpty { if let message = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "resultCell"), owner: self) as? SearchResultTableViewCell {
return timezoneArray[row] let datasource = searchField.stringValue.isEmpty ? timezoneArray : timezoneFilteredArray
guard !datasource.isEmpty else {
return nil
} }
let index = searchField.stringValue.isEmpty ? row - 1 : row
return dataSource != nil ? message.sourceName.stringValue = datasource[index % datasource.count]
handleAvailableTimezoneColumn(for: row, dataSource) : return message
filteredArray[row] as? String
}
if tableColumn?.identifier.rawValue == "abbreviation" {
return handleAbbreviationColumn(for: row)
} }
return nil return nil
} }
private func handleAvailableTimezoneColumn(for row: Int, _ dataSource: TimezoneData?) -> Any? { private func cityCell(_ tableView: NSTableView, _ rowType: RowType, _ row: Int) -> NSView? {
if row < filteredArray.count { if let cityCell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "resultCell"), owner: self) as? SearchResultTableViewCell {
return dataSource?.formattedAddress
guard let timezoneData = filteredArray[row % filteredArray.count] as? TimezoneData else {
assertionFailure()
return nil
}
cityCell.sourceName.stringValue = timezoneData.formattedAddress ?? "Error"
return cityCell
} }
return nil return nil
} }
private func handleAbbreviationColumn(for row: Int) -> Any? { private func headerCell(_ tableView: NSTableView, _ headerType: RowType) -> NSView? {
if timezoneArray.count > row { if let message = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "headerCell"), owner: self) as? HeaderTableViewCell {
// Special return for manually inserted 'UTC' message.headerField.stringValue = headerType == .timezoneHeader ? "Timezones" : "Places"
if timezoneArray[row] == "UTC" { return message
return "UTC"
}
if timezoneArray[row] == "Anywhere on Earth" {
return "AoE"
}
return NSTimeZone(name: timezoneArray[row])?.abbreviation ?? "Error"
} }
return nil return nil
} }
@ -534,6 +577,8 @@ extension PreferencesViewController {
if searchResults?.status == "ZERO_RESULTS" { if searchResults?.status == "ZERO_RESULTS" {
self.placeholderLabel.placeholderString = "No results! 😔 Try entering the exact name." self.placeholderLabel.placeholderString = "No results! 😔 Try entering the exact name."
self.findLocalSearchResultsForTimezones()
self.reloadSearchResults()
self.isActivityInProgress = false self.isActivityInProgress = false
return return
} }
@ -551,7 +596,6 @@ extension PreferencesViewController {
timezoneFilteredArray = [] timezoneFilteredArray = []
let lowercasedSearchString = searchField.stringValue.lowercased() let lowercasedSearchString = searchField.stringValue.lowercased()
timezoneFilteredArray = timezoneArray.filter { $0.lowercased().contains(lowercasedSearchString) } timezoneFilteredArray = timezoneArray.filter { $0.lowercased().contains(lowercasedSearchString) }
filteredArray.append(contentsOf: timezoneFilteredArray)
} }
private func generateSearchURL() -> String { private func generateSearchURL() -> String {
@ -598,6 +642,12 @@ extension PreferencesViewController {
private func prepareUIForPresentingResults() { private func prepareUIForPresentingResults() {
placeholderLabel.placeholderString = CLEmptyString placeholderLabel.placeholderString = CLEmptyString
isActivityInProgress = false isActivityInProgress = false
reloadSearchResults()
}
private func reloadSearchResults() {
print("Reloading Search Results")
calculateArray()
availableTimezoneTableView.reloadData() availableTimezoneTableView.reloadData()
} }
@ -647,7 +697,7 @@ extension PreferencesViewController {
searchField.placeholderString = "Fetching data might take some time!" searchField.placeholderString = "Fetching data might take some time!"
placeholderLabel.placeholderString = "Retrieving timezone data" placeholderLabel.placeholderString = "Retrieving timezone data"
availableTimezoneTableView.isHidden = true availableTimezoneTableView.isHidden = true
let tuple = "\(latitude),\(longitude)" let tuple = "\(latitude),\(longitude)"
let timeStamp = Date().timeIntervalSince1970 let timeStamp = Date().timeIntervalSince1970
let urlString = "https://maps.googleapis.com/maps/api/timezone/json?location=\(tuple)&timestamp=\(timeStamp)&key=\(CLGeocodingKey)" let urlString = "https://maps.googleapis.com/maps/api/timezone/json?location=\(tuple)&timestamp=\(timeStamp)&key=\(CLGeocodingKey)"
@ -658,11 +708,12 @@ extension PreferencesViewController {
OperationQueue.main.addOperation { OperationQueue.main.addOperation {
if self.handleEdgeCase(for: response) == true { if self.handleEdgeCase(for: response) == true {
self.reloadSearchResults()
return return
} }
if error == nil, let json = response, let timezone = self.decodeTimezone(from: json) { if error == nil, let json = response, let timezone = self.decodeTimezone(from: json) {
if self.availableTimezoneTableView.selectedRow >= 0, self.availableTimezoneTableView.selectedRow < self.filteredArray.count { if self.availableTimezoneTableView.selectedRow >= 0 {
self.installTimezone(timezone) self.installTimezone(timezone)
} }
self.updateViewState() self.updateViewState()
@ -682,7 +733,7 @@ extension PreferencesViewController {
} }
private func installTimezone(_ timezone: Timezone) { private func installTimezone(_ timezone: Timezone) {
guard let dataObject = self.filteredArray[self.availableTimezoneTableView.selectedRow] as? TimezoneData else { guard let dataObject = self.filteredArray[self.availableTimezoneTableView.selectedRow % filteredArray.count] as? TimezoneData else {
assertionFailure("Data was unexpectedly nil") assertionFailure("Data was unexpectedly nil")
return return
} }
@ -720,7 +771,7 @@ extension PreferencesViewController {
placeholderLabel.placeholderString = PreferencesConstants.noInternetConnectivityError placeholderLabel.placeholderString = PreferencesConstants.noInternetConnectivityError
isActivityInProgress = false isActivityInProgress = false
filteredArray = [] filteredArray = []
availableTimezoneTableView.reloadData() reloadSearchResults()
} }
/// Returns true if there's an error. /// Returns true if there's an error.
@ -745,7 +796,7 @@ extension PreferencesViewController {
private func updateViewState() { private func updateViewState() {
filteredArray = [] filteredArray = []
availableTimezoneTableView.reloadData() reloadSearchResults()
refreshTimezoneTableView() refreshTimezoneTableView()
refreshMainTable() refreshMainTable()
timezonePanel.close() timezonePanel.close()
@ -797,25 +848,56 @@ extension PreferencesViewController {
isActivityInProgress = false isActivityInProgress = false
return return
} }
if let dataObject = filteredArray[availableTimezoneTableView.selectedRow] as? String, dataObject != nil { if searchField.stringValue.isEmpty {
addTimezoneIfSearchStringIsEmpty()
} else {
addTimezoneIfSearchStringIsNotEmpty()
}
}
private func addTimezoneIfSearchStringIsEmpty() {
let currentRowType = finalArray[availableTimezoneTableView.selectedRow]
switch currentRowType {
case .timezoneHeader, .cityHeader:
isActivityInProgress = false
return
case .timezone:
cleanupAfterInstallingTimezone() cleanupAfterInstallingTimezone()
default:
return return
} }
}
guard let dataObject = filteredArray[availableTimezoneTableView.selectedRow] as? TimezoneData else {
private func addTimezoneIfSearchStringIsNotEmpty() {
let currentRowType = finalArray[availableTimezoneTableView.selectedRow]
switch currentRowType {
case .timezoneHeader, .cityHeader:
isActivityInProgress = false
return
case .timezone:
cleanupAfterInstallingTimezone()
case .city:
cleanupAfterInstallingCity()
}
}
private func cleanupAfterInstallingCity() {
guard let dataObject = filteredArray[availableTimezoneTableView.selectedRow % filteredArray.count] as? TimezoneData else {
assertionFailure("Data was unexpectedly nil") assertionFailure("Data was unexpectedly nil")
return return
} }
if messageLabel.stringValue.isEmpty { if messageLabel.stringValue.isEmpty {
searchField.stringValue = CLEmptyString searchField.stringValue = CLEmptyString
guard let latitude = dataObject.latitude, let longitude = dataObject.longitude else { guard let latitude = dataObject.latitude, let longitude = dataObject.longitude else {
assertionFailure("Data was unexpectedly nil") assertionFailure("Data was unexpectedly nil")
return return
} }
getTimezone(for: latitude, and: longitude) getTimezone(for: latitude, and: longitude)
} }
} }
@ -825,23 +907,14 @@ extension PreferencesViewController {
data.setLabel(CLEmptyString) data.setLabel(CLEmptyString)
if searchField.stringValue.isEmpty == false { if searchField.stringValue.isEmpty == false {
if filteredArray.count <= availableTimezoneTableView.selectedRow { let currentSelection = timezoneFilteredArray[availableTimezoneTableView.selectedRow % timezoneFilteredArray.count]
return
} let metaInfo = metadata(for: currentSelection)
let currentSelection = filteredArray[availableTimezoneTableView.selectedRow]
guard let selection = currentSelection as? String else {
assertionFailure()
return
}
let metaInfo = metadata(for: selection)
data.timezoneID = metaInfo.0 data.timezoneID = metaInfo.0
data.formattedAddress = metaInfo.1 data.formattedAddress = metaInfo.1
} else { } else {
let currentSelection = timezoneArray[availableTimezoneTableView.selectedRow] let currentSelection = timezoneArray[availableTimezoneTableView.selectedRow - 1]
let metaInfo = metadata(for: currentSelection) let metaInfo = metadata(for: currentSelection)
data.timezoneID = metaInfo.0 data.timezoneID = metaInfo.0
@ -856,7 +929,7 @@ extension PreferencesViewController {
filteredArray = [] filteredArray = []
timezoneFilteredArray = [] timezoneFilteredArray = []
availableTimezoneTableView.reloadData() reloadSearchResults()
refreshTimezoneTableView() refreshTimezoneTableView()
@ -887,21 +960,15 @@ extension PreferencesViewController {
@IBAction func closePanel(_: NSButton) { @IBAction func closePanel(_: NSButton) {
filteredArray = [] filteredArray = []
timezoneFilteredArray = []
columnName = "Place(s)"
availableTimezoneTableView.reloadData()
searchField.stringValue = CLEmptyString searchField.stringValue = CLEmptyString
placeholderLabel.placeholderString = CLEmptyString placeholderLabel.placeholderString = CLEmptyString
searchField.placeholderString = "Enter a city, state or country name" searchField.placeholderString = "Enter a city, state or country name"
reloadSearchResults()
timezonePanel.close() timezonePanel.close()
isActivityInProgress = false isActivityInProgress = false
addTimezoneButton.state = .off addTimezoneButton.state = .off
// The table might be hidden because of an early exit especially // The table might be hidden because of an early exit especially
@ -994,7 +1061,6 @@ extension PreferencesViewController {
@IBAction func filterTimezoneArray(_: Any?) { @IBAction func filterTimezoneArray(_: Any?) {
let lowercasedSearchString = searchField.stringValue.lowercased() let lowercasedSearchString = searchField.stringValue.lowercased()
timezoneFilteredArray = timezoneArray.filter { $0.lowercased().contains(lowercasedSearchString) } timezoneFilteredArray = timezoneArray.filter { $0.lowercased().contains(lowercasedSearchString) }
availableTimezoneTableView.reloadData()
} }
@IBAction func filterArray(_: Any?) { @IBAction func filterArray(_: Any?) {
@ -1005,6 +1071,7 @@ extension PreferencesViewController {
if searchField.stringValue.count > 50 { if searchField.stringValue.count > 50 {
isActivityInProgress = false isActivityInProgress = false
messageLabel.stringValue = PreferencesConstants.maxCharactersAllowed messageLabel.stringValue = PreferencesConstants.maxCharactersAllowed
reloadSearchResults()
Timer.scheduledTimer(withTimeInterval: 5, Timer.scheduledTimer(withTimeInterval: 5,
repeats: false) { _ in repeats: false) { _ in
OperationQueue.main.addOperation { OperationQueue.main.addOperation {
@ -1021,8 +1088,8 @@ extension PreferencesViewController {
} else { } else {
resetSearchView() resetSearchView()
} }
availableTimezoneTableView.reloadData() reloadSearchResults()
} }
} }
@ -1079,7 +1146,9 @@ extension PreferencesViewController {
return isLabelOptionSelected ? object1.customLabel! > object2.customLabel! : object1.customLabel! < object2.customLabel! return isLabelOptionSelected ? object1.customLabel! > object2.customLabel! : object1.customLabel! < object2.customLabel!
} }
sender.image = isLabelOptionSelected ? NSImage(named: NSImage.Name("NSDescendingSortIndicator"))! : NSImage(named: NSImage.Name("NSAscendingSortIndicator"))! sender.image = isLabelOptionSelected ?
NSImage(named: NSImage.Name("NSDescendingSortIndicator"))! :
NSImage(named: NSImage.Name("NSAscendingSortIndicator"))!
isLabelOptionSelected.toggle() isLabelOptionSelected.toggle()
@ -1111,9 +1180,7 @@ extension PreferencesViewController {
private func updateAfterSorting() { private func updateAfterSorting() {
let newDefaults = selectedTimeZones let newDefaults = selectedTimeZones
DataStore.shared().setTimezones(newDefaults) DataStore.shared().setTimezones(newDefaults)
refreshTimezoneTableView() refreshTimezoneTableView()
refreshMainTable() refreshMainTable()
} }
@ -1124,11 +1191,7 @@ extension PreferencesViewController: SRRecorderControlDelegate {}
// Helpers // Helpers
extension PreferencesViewController { extension PreferencesViewController {
private func numberOfSearchResults() -> Int { private func numberOfSearchResults() -> Int {
if searchField.stringValue.isEmpty == false { return finalArray.count
return filteredArray.count
}
return timezoneArray.count
} }
private func insert(timezone: TimezoneData, at index: Int) { private func insert(timezone: TimezoneData, at index: Int) {
@ -1143,8 +1206,11 @@ class SearchResultTableViewCell: NSTableCellView {
@IBOutlet var sourceName: NSTextField! @IBOutlet var sourceName: NSTextField!
} }
class HeaderTableViewCell: NSTableCellView {
@IBOutlet var headerField: NSTextField!
}
extension PreferencesViewController: PreferenceSelectionUpdates { extension PreferencesViewController: PreferenceSelectionUpdates {
func didAddTimezone(_: TimezoneData) {}
func markAsFavorite(_ dataObject: TimezoneData) { func markAsFavorite(_ dataObject: TimezoneData) {
_markAsFavorite(dataObject) _markAsFavorite(dataObject)
} }

Loading…
Cancel
Save