@ -479,7 +479,10 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate
UserDefaults . standard . set ( filteredMenubars , forKey : CLMenubarFavorites )
if let appDelegate = NSApplication . shared . delegate as ? AppDelegate , let menubarFavourites = DataStore . shared ( ) . retrieve ( key : CLMenubarFavorites ) as ? [ Data ] , menubarFavourites . isEmpty , DataStore . shared ( ) . shouldDisplay ( . showMeetingInMenubar ) = = false {
if let appDelegate = NSApplication . shared . delegate as ? AppDelegate ,
let menubarFavourites = DataStore . shared ( ) . retrieve ( key : CLMenubarFavorites ) as ? [ Data ] ,
menubarFavourites . isEmpty ,
DataStore . shared ( ) . shouldDisplay ( . showMeetingInMenubar ) = = false {
appDelegate . invalidateMenubarTimer ( true )
}
@ -532,10 +535,15 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate
// T i m e t o d i s p l a y t h e a l e r t .
NSApplication . shared . activate ( ignoringOtherApps : true )
let infoText = " " "
Multiple timezones occupy space and if macOS determines Clocker is occupying too much space , it ' ll hide Clocker entirely !
Enable Menubar Compact Mode to fit in more timezones in less space .
" " "
let alert = NSAlert ( )
alert . showsSuppressionButton = true
alert . messageText = " More than one location added to the menubar 😅 "
alert . informativeText = " Multiple timezones occupy space and if macOS determines Clocker is occupying too much space, it'll hide Clocker entirely! Enable Menubar Compact Mode to fit in more timezones in less space. "
alert . informativeText = infoText
alert . addButton ( withTitle : " Enable Compact Mode " )
alert . addButton ( withTitle : " Cancel " )
@ -626,13 +634,21 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate
}
if tableColumn . identifier . rawValue = = " formattedAddress " {
return arePlacesSortedInAscendingOrder ? object1 . formattedAddress ! > object2 . formattedAddress ! : object1 . formattedAddress ! < object2 . formattedAddress !
return arePlacesSortedInAscendingOrder ?
object1 . formattedAddress ! > object2 . formattedAddress ! :
object1 . formattedAddress ! < object2 . formattedAddress !
} else {
return arePlacesSortedInAscendingOrder ? object1 . customLabel ! > object2 . customLabel ! : object1 . customLabel ! < object2 . customLabel !
return arePlacesSortedInAscendingOrder ?
object1 . customLabel ! > object2 . customLabel ! :
object1 . customLabel ! < object2 . customLabel !
}
}
arePlacesSortedInAscendingOrder ? timezoneTableView . setIndicatorImage ( NSImage ( named : NSImage . Name ( " NSDescendingSortIndicator " ) ) ! , in : tableColumn ) : timezoneTableView . setIndicatorImage ( NSImage ( named : NSImage . Name ( " NSAscendingSortIndicator " ) ) ! , in : tableColumn )
let indicatorImage = arePlacesSortedInAscendingOrder ?
NSImage ( named : NSImage . Name ( " NSDescendingSortIndicator " ) ) ! :
NSImage ( named : NSImage . Name ( " NSAscendingSortIndicator " ) ) !
timezoneTableView . setIndicatorImage ( indicatorImage , in : tableColumn )
arePlacesSortedInAscendingOrder . toggle ( )
@ -645,7 +661,7 @@ extension PreferencesViewController: NSTableViewDataSource, NSTableViewDelegate
extension PreferencesViewController {
@objc private func search ( ) {
var searchString = searchField . stringValue
let searchString = searchField . stringValue
if searchString . isEmpty {
dataTask ? . cancel ( )
@ -657,8 +673,6 @@ extension PreferencesViewController {
dataTask ? . cancel ( )
}
let userPreferredLanguage = Locale . preferredLanguages . first ? ? " en-US "
OperationQueue . main . addOperation {
if self . availableTimezoneTableView . isHidden {
self . availableTimezoneTableView . isHidden = false
@ -675,26 +689,14 @@ extension PreferencesViewController {
self . placeholderLabel . placeholderString = " Searching for \( searchString ) "
let words = searchString . components ( separatedBy : CharacterSet . whitespacesAndNewlines )
searchString = words . joined ( separator : CLEmptyString )
let urlString = " https://maps.googleapis.com/maps/api/geocode/json?address= \( searchString ) &key= \( CLGeocodingKey ) &language= \( userPreferredLanguage ) "
self . dataTask = NetworkManager . task ( with : urlString ,
self . dataTask = NetworkManager . task ( with : self . generateSearchURL ( ) ,
completionHandler : { [ weak self ] response , error in
guard let ` self ` = self else { return }
OperationQueue . main . addOperation {
if let errorPresent = error {
if errorPresent . localizedDescription = = PreferencesConstants . offlineErrorMessage {
self . placeholderLabel . placeholderString = PreferencesConstants . noInternetConnectivityError
} else {
self . placeholderLabel . placeholderString = PreferencesConstants . tryAgainMessage
}
self . isActivityInProgress = false
self . presentError ( errorPresent . localizedDescription )
return
}
@ -711,11 +713,41 @@ extension PreferencesViewController {
return
}
for result in searchResults ! . results {
let location = result . geometry . location
self . appendResultsToFilteredArray ( searchResults ! . results )
self . prepareUIForPresentingResults ( )
}
} )
}
}
private func generateSearchURL ( ) -> String {
let userPreferredLanguage = Locale . preferredLanguages . first ? ? " en-US "
var searchString = searchField . stringValue
let words = searchString . components ( separatedBy : CharacterSet . whitespacesAndNewlines )
searchString = words . joined ( separator : CLEmptyString )
let url = " https://maps.googleapis.com/maps/api/geocode/json?address= \( searchString ) &key= \( CLGeocodingKey ) &language= \( userPreferredLanguage ) "
return url
}
private func presentError ( _ errorMessage : String ) {
if errorMessage = = PreferencesConstants . offlineErrorMessage {
self . placeholderLabel . placeholderString = PreferencesConstants . noInternetConnectivityError
} else {
self . placeholderLabel . placeholderString = PreferencesConstants . tryAgainMessage
}
self . isActivityInProgress = false
}
private func appendResultsToFilteredArray ( _ results : [ SearchResult . Result ] ) {
results . forEach {
let location = $0 . geometry . location
let latitude = location . lat
let longitude = location . lng
let formattedAddress = result . formattedAddress
let formattedAddress = $0 . formattedAddress
let totalPackage = [
" latitude " : latitude ,
@ -723,23 +755,19 @@ extension PreferencesViewController {
CLTimezoneName : formattedAddress ,
CLCustomLabel : formattedAddress ,
CLTimezoneID : CLEmptyString ,
CLPlaceIdentifier : result . placeId
CLPlaceIdentifier : $0 . placeId
] as [ String : Any ]
self . filteredArray . append ( TimezoneData ( with : totalPackage ) )
}
}
private func prepareUIForPresentingResults ( ) {
self . placeholderLabel . placeholderString = CLEmptyString
self . isActivityInProgress = false
self . availableTimezoneTableView . reloadData ( )
}
} )
}
}
// E x t r a c t i n g t h i s o u t f o r t e s t s
private func decode ( from data : Data ) -> SearchResult ? {
let jsonDecoder = JSONDecoder ( )
@ -802,6 +830,25 @@ extension PreferencesViewController {
if error = = nil , let json = response , let timezone = self . decodeTimezone ( from : json ) {
if self . availableTimezoneTableView . selectedRow >= 0 && self . availableTimezoneTableView . selectedRow < self . filteredArray . count {
self . installTimezone ( timezone )
}
self . updateViewState ( )
} else {
OperationQueue . main . addOperation {
if error ? . localizedDescription = = " The Internet connection appears to be offline. " {
self . placeholderLabel . placeholderString = PreferencesConstants . noInternetConnectivityError
} else {
self . placeholderLabel . placeholderString = PreferencesConstants . tryAgainMessage
}
self . isActivityInProgress = false
}
}
}
}
}
private func installTimezone ( _ timezone : Timezone ) {
guard let dataObject = self . filteredArray [ self . availableTimezoneTableView . selectedRow ] as ? TimezoneData else {
assertionFailure ( " Data was unexpectedly nil " )
return
@ -830,22 +877,6 @@ extension PreferencesViewController {
Logger . log ( object : [ " PlaceName " : filteredAddress , " Timezone " : timezone . timeZoneId ] , for : " Filtered Address " )
}
self . updateViewState ( )
} else {
OperationQueue . main . addOperation {
if error ? . localizedDescription = = " The Internet connection appears to be offline. " {
self . placeholderLabel . placeholderString = PreferencesConstants . noInternetConnectivityError
} else {
self . placeholderLabel . placeholderString = PreferencesConstants . tryAgainMessage
}
self . isActivityInProgress = false
}
}
}
}
}
private func resetStateAndShowDisconnectedMessage ( ) {
OperationQueue . main . addOperation {
self . showMessage ( )
@ -969,6 +1000,11 @@ extension PreferencesViewController {
}
} else {
cleanupAfterInstallingTimezone ( )
}
}
private func cleanupAfterInstallingTimezone ( ) {
let data = TimezoneData ( )
data . setLabel ( CLEmptyString )
@ -1018,7 +1054,6 @@ extension PreferencesViewController {
isActivityInProgress = false
}
}
private func metadata ( for selection : String ) -> ( String , String ) {
if selection = = " Anywhere on Earth " {