You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

926 lines
35 KiB

//
// CLPreferencesViewController.m
// Clocker
//
// Created by Abhishek Banthia on 12/12/15.
//
//
#import "CLPreferencesViewController.h"
#import "Panel.h"
#import "PanelController.h"
#import "ApplicationDelegate.h"
#import <QuartzCore/QuartzCore.h>
#import "CommonStrings.h"
#import "CLTimezoneData.h"
#import "CLAPI.h"
#import "EDSunriseSet.h"
#import <ServiceManagement/ServiceManagement.h>
NSString *const CLSearchPredicateKey = @"SELF CONTAINS[cd]%@";
NSString *const CLPreferencesViewNibIdentifier = @"PreferencesWindow";
NSString *const CLPreferencesTimezoneNameIdentifier = @"formattedAddress";
NSString *const CLPreferencesAbbreviationIdentifier = @"abbreviation";
NSString *const CLPreferencesCustomLabelIdentifier = @"label";
NSString *const CLPreferencesAvailableTimezoneIdentifier = @"availableTimezones";
NSString *const CLNoTimezoneSelectedErrorMessage = @"Please select a timezone!";
NSString *const CLMaxTimezonesErrorMessage = @"Maximum 10 timezones allowed!";
NSString *const CLTimezoneAlreadySelectedError = @"Timezone has already been selected!";
NSString *const CLParseTimezoneSelectionClassIdentifier = @"CLTimezoneSelection";
NSString *const CLParseTimezoneNameProperty = @"areaName";
NSString *const CLMaxCharactersReachedError = @"Only 50 characters allowed!";
NSString *const CLNoInternetConnectivityError = @"You're offline, maybe?";
NSString *const CLLocationSearchURL = @"https://maps.googleapis.com/maps/api/geocode/json?address=%@&key=AIzaSyCyf2knCi6KiKuDJLYDBD3Odq5dt4c-_KI&language=%@";
NSString *const CLTimezoneSearchURL = @"https://maps.googleapis.com/maps/api/timezone/json?location=%@&timestamp=%f&key=AIzaSyCyf2knCi6KiKuDJLYDBD3Odq5dt4c-_KI";
NSString *const CLTryAgainMessage = @"Try again, maybe?";
@interface CLPreferencesViewController ()
@property (weak) IBOutlet NSTextField *placeholderLabel;
@property (assign) BOOL activityInProgress;
@property (strong, nonatomic) NSMutableArray *selectedTimeZones;
@property (strong, nonatomic) NSMutableArray *filteredArray;
@property (atomic, assign) BOOL launchOnLogin;
@property (nonatomic, strong) NSMutableArray *timeZoneArray;
@property (nonatomic, strong) NSMutableArray *timeZoneFilteredArray;
@property (nonatomic, copy) NSString *columnName;
@property (atomic, copy) NSArray *themes;
@property (nonatomic, strong) NSURLSessionDataTask *dataTask;
@property (weak) IBOutlet SRRecorderControl *recorderControl;
@property (weak) IBOutlet NSTableView *timezoneTableView;
@property (strong) IBOutlet Panel *timezonePanel;
@property (weak) IBOutlet NSTableView *availableTimezoneTableView;
@property (weak) IBOutlet NSSearchField *searchField;
@property (weak) IBOutlet NSTextField *messageLabel;
@property (weak) IBOutlet NSSegmentedControl *searchCriteria;
@property (weak) IBOutlet NSTableColumn *abbreviation;
@end
@implementation CLPreferencesViewController
- (void)viewDidLoad {
[super viewDidLoad];
CALayer *viewLayer = [CALayer layer];
[viewLayer setBackgroundColor:CGColorCreateGenericRGB(255.0, 255.0, 255.0, 0.8)]; //RGB plus Alpha Channel
[self.view setWantsLayer:YES];
[self.view setLayer:viewLayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(refereshTimezoneTableView) name:CLCustomLabelChangedNotification object:nil];
self.placeholderLabel.hidden = YES;
[self refereshTimezoneTableView];
if (!self.filteredArray)
{
self.timeZoneArray = [[NSMutableArray alloc] initWithArray:[NSTimeZone knownTimeZoneNames]];
self.timeZoneFilteredArray = [NSMutableArray new];
self.filteredArray = [NSMutableArray new];
}
self.messageLabel.stringValue = CLEmptyString;
[self.availableTimezoneTableView reloadData];
//Register for drag and drop
[self.timezoneTableView registerForDraggedTypes: [NSArray arrayWithObject: CLDragSessionKey]];
self.columnName = @"Place(s)";
// Do view setup here.
NSUserDefaultsController *defaults = [NSUserDefaultsController sharedUserDefaultsController];
self.recorderControl.delegate = self;
[self.recorderControl bind:NSValueBinding
toObject:defaults
withKeyPath:@"values.globalPing"
options:nil];
[defaults addObserver:self forKeyPath:@"values.globalPing" options:NSKeyValueObservingOptionInitial context:NULL];
}
/*
- (void)initializeHotkeySequence
{
PTHotKeyCenter *hotKeyCenter = [PTHotKeyCenter sharedCenter];
PTHotKey *oldHotKey = [hotKeyCenter hotKeyWithIdentifier:aKeyPath];
[hotKeyCenter unregisterHotKey:oldHotKey];
PTHotKey *newHotKey = [PTHotKey hotKeyWithIdentifier:aKeyPath
keyCombo:newShortcut
target:self
action:@selector(ping:)];
[hotKeyCenter registerHotKey:newHotKey];
}*/
-(void)observeValueForKeyPath:(NSString *)aKeyPath ofObject:(id)anObject change:(NSDictionary<NSString *,id> *)aChange context:(void *)aContext
{
if ([aKeyPath isEqualToString:@"values.globalPing"])
{
PTHotKeyCenter *hotKeyCenter = [PTHotKeyCenter sharedCenter];
PTHotKey *oldHotKey = [hotKeyCenter hotKeyWithIdentifier:aKeyPath];
[hotKeyCenter unregisterHotKey:oldHotKey];
NSDictionary *newShortcut = [anObject valueForKeyPath:aKeyPath];
if (newShortcut && (NSNull *)newShortcut != [NSNull null])
{
PTHotKey *newHotKey = [PTHotKey hotKeyWithIdentifier:aKeyPath
keyCombo:newShortcut
target:self
action:@selector(ping:)];
[hotKeyCenter registerHotKey:newHotKey];
}
}
else
[super observeValueForKeyPath:aKeyPath ofObject:anObject change:aChange context:aContext];
}
-(IBAction)ping:(id)sender
{
ApplicationDelegate *delegate = (ApplicationDelegate *)[[NSApplication sharedApplication] delegate];
[delegate togglePanel:nil];
}
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:CLCustomLabelChangedNotification object:nil];
}
-(BOOL)acceptsFirstResponder
{
return YES;
}
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
if (tableView == self.timezoneTableView)
{
return self.selectedTimeZones.count;
}
else
{
NSInteger searchCriteria = [self.searchCriteria selectedSegment];
if (searchCriteria == 0) {
return self.filteredArray.count;
}
else
{
if (self.searchField.stringValue.length > 0) {
return self.timeZoneFilteredArray.count;
}
return self.timeZoneArray.count;
}
}
return 0;
}
- (nullable id)tableView:(NSTableView *)tableView objectValueForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row
{
CLTimezoneData *dataSource, *selectedDataSource;
if (self.filteredArray.count > row)
{
dataSource = self.filteredArray[row];
}
if (self.selectedTimeZones.count > row) {
selectedDataSource = [CLTimezoneData getCustomObject:self.selectedTimeZones[row]];
}
if ([[tableColumn identifier] isEqualToString:CLPreferencesTimezoneNameIdentifier])
{
if ([selectedDataSource.formattedAddress length] > 0) {
return selectedDataSource.formattedAddress;
}
return selectedDataSource.timezoneID;
}
else if([[tableColumn identifier] isEqualToString:CLPreferencesAvailableTimezoneIdentifier])
{
NSInteger searchCriteria = [self.searchCriteria selectedSegment];
if (searchCriteria == 0)
{
if (row < self.filteredArray.count)
{
return dataSource.formattedAddress;
}
}
else
{
if (self.searchField.stringValue.length > 0)
{
if (row < self.timeZoneFilteredArray.count) {
return self.timeZoneFilteredArray[row];
}
}
return self.timeZoneArray[row];
}
return nil;
}
else if([[tableColumn identifier] isEqualToString:CLPreferencesCustomLabelIdentifier])
{
return selectedDataSource.customLabel;
}
else if ([tableColumn.identifier isEqualToString:@"favouriteTimezone"])
{
return selectedDataSource.isFavourite;
}
else if ([tableColumn.identifier isEqualToString:@"abbreviation"])
{
if (self.searchField.stringValue.length > 0)
{
if (row < self.timeZoneFilteredArray.count)
{
return [NSTimeZone timeZoneWithName:self.timeZoneFilteredArray[row]].abbreviation;
}
}
if (self.timeZoneArray.count > row)
{
return [NSTimeZone timeZoneWithName:self.timeZoneArray[row]].abbreviation;
}
}
return nil;
}
-(void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
if ([object isKindOfClass:[NSString class]])
{
NSString *originalValue = (NSString *)object;
NSString *customLabelValue = [originalValue stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceCharacterSet]];
CLTimezoneData *dataObject = [CLTimezoneData getCustomObject:self.selectedTimeZones[row]];
dataObject.customLabel = customLabelValue.length > 0 ? customLabelValue : CLEmptyString;
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:dataObject];
[self.selectedTimeZones replaceObjectAtIndex:row withObject:encodedObject];
[[NSUserDefaults standardUserDefaults] setObject:self.selectedTimeZones forKey:CLDefaultPreferenceKey];
if ([dataObject.isFavourite isEqualToNumber:@1])
{
[[NSUserDefaults standardUserDefaults] setObject:encodedObject
forKey:@"favouriteTimezone"];
}
[self refreshMainTableview];
}
else
{
NSMutableArray *newArray = [NSMutableArray new];
NSNumber *isFavouriteValue = (NSNumber *)object;
[self.selectedTimeZones enumerateObjectsUsingBlock:^(NSData * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop)
{
CLTimezoneData *timezone = [CLTimezoneData getCustomObject:obj];
timezone.isFavourite = [NSNumber numberWithInt:0];
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:timezone];
[newArray addObject:encodedObject];
}];
CLTimezoneData *dataObject = [CLTimezoneData getCustomObject:newArray[row]];
dataObject.isFavourite = isFavouriteValue;
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:dataObject];
[newArray replaceObjectAtIndex:row withObject:encodedObject];
[[NSUserDefaults standardUserDefaults] setObject:newArray forKey:CLDefaultPreferenceKey];
ApplicationDelegate *appDelegate = (ApplicationDelegate*)[NSApplication sharedApplication].delegate;
if (dataObject.isFavourite.integerValue == 1)
{
[[NSUserDefaults standardUserDefaults] setObject:encodedObject
forKey:@"favouriteTimezone"];
[appDelegate.menubarController shouldIconBeUpdated:YES];
}
else
{
[[NSUserDefaults standardUserDefaults] setObject:nil
forKey:@"favouriteTimezone"];
[appDelegate.menubarController shouldIconBeUpdated:NO];
}
[self refereshTimezoneTableView];
[self refreshMainTableview];
}
}
- (IBAction)addTimeZone:(id)sender
{
self.abbreviation.hidden = YES;
self.filteredArray = [NSMutableArray new];
self.searchCriteria.selectedSegment = 0;
[self.view.window beginSheet:self.timezonePanel
completionHandler:nil];
}
- (IBAction)addToFavorites:(id)sender
{
self.activityInProgress = YES;
if (self.availableTimezoneTableView.selectedRow == -1)
{
self.messageLabel.stringValue = CLNoTimezoneSelectedErrorMessage;
[NSTimer scheduledTimerWithTimeInterval:5 target:self
selector:@selector(clearLabel)
userInfo:nil
repeats:NO];
self.activityInProgress = NO;
return;
}
if (self.selectedTimeZones.count >= 10)
{
self.messageLabel.stringValue = CLMaxTimezonesErrorMessage;
[NSTimer scheduledTimerWithTimeInterval:5 target:self
selector:@selector(clearLabel)
userInfo:nil
repeats:NO];
self.activityInProgress = NO;
return;
}
if (self.searchCriteria.selectedSegment == 0)
{
CLTimezoneData *dataObject = self.filteredArray[self.availableTimezoneTableView.selectedRow];
[self.selectedTimeZones enumerateObjectsUsingBlock:^(NSData * _Nonnull encodedData, NSUInteger idx, BOOL * _Nonnull stop) {
CLTimezoneData *timezoneObject = [CLTimezoneData getCustomObject:encodedData];
NSString *name = timezoneObject.place_id;
NSString *selectedPlaceID = dataObject.place_id;
if (self.searchField.stringValue.length > 0) {
if ([name isKindOfClass:[NSString class]] &&
[name isEqualToString:selectedPlaceID])
{
self.messageLabel.stringValue = CLTimezoneAlreadySelectedError;
[NSTimer scheduledTimerWithTimeInterval:5
target:self
selector:@selector(clearLabel) userInfo:nil
repeats:NO];
self.activityInProgress = NO;
return;
}
}
}];
self.searchField.stringValue = CLEmptyString;
[self getTimeZoneForLatitude:dataObject.latitude
andLongitude:dataObject.longitude];
}
else
{
CLTimezoneData *data = [CLTimezoneData new];
data.isFavourite = [NSNumber numberWithInt:NSOffState];
data.customLabel = CLEmptyString;
if (self.searchField.stringValue.length > 0)
{
data.timezoneID = self.timeZoneFilteredArray[self.availableTimezoneTableView.selectedRow];
data.formattedAddress = self.timeZoneFilteredArray[self.availableTimezoneTableView.selectedRow];
}
else
{
data.timezoneID = self.timeZoneArray[self.availableTimezoneTableView.selectedRow];
data.formattedAddress = self.timeZoneArray[self.availableTimezoneTableView.selectedRow];
}
NSArray *defaultPreference = [[NSUserDefaults standardUserDefaults] objectForKey:CLDefaultPreferenceKey];
if (defaultPreference == nil)
{
defaultPreference = [NSMutableArray new];
}
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:data];
NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:defaultPreference];
[newArray addObject:encodedObject];
[[NSUserDefaults standardUserDefaults] setObject:newArray forKey:CLDefaultPreferenceKey];
self.timeZoneFilteredArray = [NSMutableArray array];
self.timeZoneArray = [NSMutableArray new];
[self.availableTimezoneTableView reloadData];
[self refereshTimezoneTableView];
[self refreshMainTableview];
[self.timezonePanel close];
self.placeholderLabel.placeholderString = CLEmptyString;
self.searchField.stringValue = CLEmptyString;
self.searchField.placeholderString = @"Enter a city, state or country name";
self.availableTimezoneTableView.hidden = NO;
self.activityInProgress = NO;
}
}
- (IBAction)closePanel:(id)sender
{
self.filteredArray = [NSMutableArray array];
self.timeZoneArray = [NSMutableArray new];
self.searchCriteria.selectedSegment = 0;
self.columnName = @"Place(s)";
self.placeholderLabel.placeholderString = CLEmptyString;
[self.availableTimezoneTableView reloadData];
self.searchField.stringValue = CLEmptyString;
self.searchField.placeholderString = @"Enter a city, state or country name";
[self.timezonePanel close];
self.activityInProgress = NO;
}
- (void)clearLabel
{
self.messageLabel.stringValue = CLEmptyString;
}
- (IBAction)removeFromFavourites:(id)sender
{
NSMutableArray *itemsToRemove = [NSMutableArray array];
if (self.timezoneTableView.selectedRow == -1)
{
return;
}
[self.timezoneTableView.selectedRowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
CLTimezoneData *dataObject = [CLTimezoneData getCustomObject:self.selectedTimeZones[idx]];
if (dataObject.isFavourite.integerValue == 1)
{
//Remove favourite from standard defaults
[[NSUserDefaults standardUserDefaults] setObject:nil
forKey:@"favouriteTimezone"];
}
[itemsToRemove addObject:self.selectedTimeZones[idx]];
}];
[self.selectedTimeZones removeObjectsInArray:itemsToRemove];
NSMutableArray *newDefaults = [[NSMutableArray alloc] initWithArray:self.selectedTimeZones];
[[NSUserDefaults standardUserDefaults] setObject:newDefaults forKey:CLDefaultPreferenceKey];
[self.timezoneTableView reloadData];
[self refreshMainTableview];
}
- (IBAction)filterTimezoneArray:(id)sender
{
if (self.searchField.stringValue.length > 0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:CLSearchPredicateKey, self.searchField.stringValue];
self.timeZoneFilteredArray = [NSMutableArray arrayWithArray:[self.timeZoneArray filteredArrayUsingPredicate:predicate]];
[self.availableTimezoneTableView reloadData];
}
}
- (IBAction)filterArray:(id)sender
{
if (self.searchCriteria.selectedSegment == 1)
{
[self filterTimezoneArray:sender];
return;
}
[self clearLabel];
self.filteredArray = [NSMutableArray array];
if (self.searchField.stringValue.length > 50)
{
self.activityInProgress = NO;
self.messageLabel.stringValue = CLMaxCharactersReachedError;
[NSTimer scheduledTimerWithTimeInterval:10
target:self
selector:@selector(clearLabel)
userInfo:nil
repeats:NO];
return;
}
if (self.searchField.stringValue.length > 0)
{
[self callGoogleAPiWithSearchString:self.searchField.stringValue];
}
else
{
if (self.dataTask.state == NSURLSessionTaskStateRunning) {
[self.dataTask cancel];
}
self.activityInProgress = NO;
self.placeholderLabel.placeholderString = CLEmptyString;
}
[self.availableTimezoneTableView reloadData];
}
- (void)refereshTimezoneTableView
{
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray *defaultTimeZones = [[NSUserDefaults standardUserDefaults]
objectForKey:CLDefaultPreferenceKey];
self.selectedTimeZones = [[NSMutableArray alloc] initWithArray:defaultTimeZones];
[self.timezoneTableView reloadData];
});
}
- (void)refreshMainTableview
{
dispatch_async(dispatch_get_main_queue(), ^{
ApplicationDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
PanelController *panelController = appDelegate.panelController;
[panelController updateDefaultPreferences];
[panelController.mainTableview reloadData];
//Get the current display mode
NSNumber *displayMode = [[NSUserDefaults standardUserDefaults] objectForKey:CLShowAppInForeground];
if (displayMode.integerValue == 1)
{
//Get the Floating window instance
for (NSWindow *window in [NSApplication sharedApplication].windows)
{
if ([window.windowController isKindOfClass:[CLFloatingWindowController class]])
{
CLFloatingWindowController *currentInstance = (CLFloatingWindowController *)window.windowController;
[currentInstance updateDefaultPreferences];
[currentInstance.mainTableview reloadData];
}
}
}
});
}
#pragma mark Reordering
- (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard
{
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes];
[pboard declareTypes:[NSArray arrayWithObject:CLDragSessionKey] owner:self];
[pboard setData:data forType:CLDragSessionKey];
return YES;
}
-(BOOL)tableView:(NSTableView *)tableView acceptDrop:(id<NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation
{
if (row == self.selectedTimeZones.count)
{
row--;
}
NSPasteboard *pBoard = [info draggingPasteboard];
NSData *data = [pBoard dataForType:CLDragSessionKey];
NSIndexSet *rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:data];
[self.selectedTimeZones exchangeObjectAtIndex:rowIndexes.firstIndex withObjectAtIndex:row];
[[NSUserDefaults standardUserDefaults] setObject:self.selectedTimeZones forKey:CLDefaultPreferenceKey];
[self.timezoneTableView reloadData];
[self refreshMainTableview];
[self.timezoneTableView deselectRow:self.timezoneTableView.selectedRow];
return YES;
}
-(NSDragOperation)tableView:(NSTableView *)tableView
validateDrop:(id<NSDraggingInfo>)info
proposedRow:(NSInteger)row
proposedDropOperation:(NSTableViewDropOperation)dropOperation
{
return NSDragOperationEvery;
}
- (void)callGoogleAPiWithSearchString:(NSString *)searchString
{
if (self.dataTask.state == NSURLSessionTaskStateRunning)
{
[self.dataTask cancel];
}
NSString *preferredLanguage = [NSLocale preferredLanguages][0];
dispatch_async(dispatch_get_main_queue(), ^{
if (self.availableTimezoneTableView.isHidden)
{
self.availableTimezoneTableView.hidden = NO;
}
self.placeholderLabel.hidden = NO;
if (![CLAPI isUserConnectedToInternet]) {
self.placeholderLabel.stringValue = CLNoInternetConnectivityError;
return;
}
});
self.activityInProgress = YES;
self.placeholderLabel.placeholderString = [NSString stringWithFormat:@"Searching for '%@'", searchString];
NSArray* words = [searchString componentsSeparatedByCharactersInSet :[NSCharacterSet whitespaceAndNewlineCharacterSet]];
searchString = [words componentsJoinedByString:CLEmptyString];
NSString *urlString = [NSString stringWithFormat:CLLocationSearchURL, searchString, preferredLanguage];
[CLAPI dataTaskWithServicePath:urlString
bySender:self
withCompletionBlock:^(NSError *error, NSDictionary *json) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error)
{
self.placeholderLabel.placeholderString = [error.localizedDescription isEqualToString:@"The Internet connection appears to be offline."] ?
CLNoInternetConnectivityError : CLTryAgainMessage;
self.activityInProgress = NO;
return;
}
self.placeholderLabel.placeholderString = CLEmptyString;
if ([json[@"status"] isEqualToString:@"ZERO_RESULTS"]) {
self.placeholderLabel.placeholderString = @"No results! 😔 Try entering the exact name.";
self.activityInProgress = NO;
return;
}
[json[@"results"] enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull dictionary, NSUInteger idx, BOOL * _Nonnull stop) {
NSDictionary *latLang = [[dictionary objectForKey:@"geometry"] objectForKey:@"location"];
NSString *latitude = latLang[@"lat"];
NSString *longitude = latLang[@"lng"];
NSString *formattedAddress = [dictionary objectForKey:@"formatted_address"];
NSDictionary *totalPackage = @{@"latitude":latitude,
@"longitude" : longitude,
CLTimezoneName:formattedAddress,
CLCustomLabel: CLEmptyString,
CLTimezoneID : CLEmptyString,
CLPlaceIdentifier : dictionary[CLPlaceIdentifier]};
CLTimezoneData *newObject = [[CLTimezoneData alloc] initWithDictionary:totalPackage];
[self.filteredArray addObject:newObject];
}];
self.activityInProgress = NO;
[self.availableTimezoneTableView reloadData];
});
}];
}
- (void)getTimeZoneForLatitude:(NSString *)latitude andLongitude:(NSString *)longitude
{
if (self.placeholderLabel.isHidden)
{
self.placeholderLabel.hidden = NO;
}
if (![CLAPI isUserConnectedToInternet]) {
dispatch_async(dispatch_get_main_queue(), ^{
self.placeholderLabel.placeholderString = CLNoInternetConnectivityError;
self.activityInProgress = NO;
self.filteredArray = [NSMutableArray array];
[self.availableTimezoneTableView reloadData];
});
return;
}
self.searchField.placeholderString = @"Fetching data might take some time!";
self.placeholderLabel.placeholderString = @"Retrieving timezone data";
self.availableTimezoneTableView.hidden = YES;
NSString *tuple = [NSString stringWithFormat:@"%@,%@", latitude, longitude];
NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970];
NSString *urlString = [NSString stringWithFormat:CLTimezoneSearchURL, tuple, timestamp];
[CLAPI dataTaskWithServicePath:urlString
bySender:self
withCompletionBlock:^(NSError *error, NSDictionary *json) {
if (!error)
{
dispatch_async(dispatch_get_main_queue(), ^{
if (json.count == 0) {
self.activityInProgress = NO;
self.placeholderLabel.placeholderString = @"No results found! ! 😔 Try Again?";
return;
}
if ([json[@"status"] isEqualToString:@"ZERO_RESULTS"]) {
self.placeholderLabel.placeholderString = @"No results! 😔 Try entering the exact name.";
self.activityInProgress = NO;
return;
}
/*Fix for http://crashes.to/s/5b1432e77c9
Additional precautions taken to make sure selected row's value is in the filtered array!
*/
if (self.availableTimezoneTableView.selectedRow >=0 && self.availableTimezoneTableView.selectedRow < self.filteredArray.count)
{
CLTimezoneData *dataObject = self.filteredArray[self.availableTimezoneTableView.selectedRow];
/*Strip till the first comma we encounter*/
NSString *filteredAddress = dataObject.formattedAddress;
NSRange range = [filteredAddress rangeOfString:@","];
if (range.location != NSNotFound)
{
filteredAddress = [dataObject.formattedAddress substringWithRange:NSMakeRange(0, range.location)];
}
NSMutableDictionary *newTimezone = [NSMutableDictionary dictionary];
[newTimezone setObject:json[@"timeZoneId"] forKey:CLTimezoneID];
[newTimezone setObject:filteredAddress forKey:CLTimezoneName];
[newTimezone setObject:dataObject.place_id forKey:CLPlaceIdentifier];
[newTimezone setObject:dataObject.latitude forKey:@"latitude"];
[newTimezone setObject:dataObject.longitude forKey:@"longitude"];
[newTimezone setObject:CLEmptyString forKey:@"nextUpdate"];
[newTimezone setObject:CLEmptyString forKey:CLCustomLabel];
CLTimezoneData *timezoneObject = [[CLTimezoneData alloc] initWithDictionary:newTimezone];
NSArray *defaultPreference = [[NSUserDefaults standardUserDefaults] objectForKey:CLDefaultPreferenceKey];
if (defaultPreference == nil)
{
defaultPreference = [NSMutableArray new];
}
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:timezoneObject];
NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:defaultPreference];
[newArray addObject:encodedObject];
[[NSUserDefaults standardUserDefaults] setObject:newArray forKey:CLDefaultPreferenceKey];
}
self.filteredArray = [NSMutableArray array];
[self.availableTimezoneTableView reloadData];
[self refereshTimezoneTableView];
[self refreshMainTableview];
[self.timezonePanel close];
self.placeholderLabel.placeholderString = CLEmptyString;
self.searchField.placeholderString = @"Enter a city, state or country name";
self.availableTimezoneTableView.hidden = NO;
self.activityInProgress = NO;
});
}
else
{
self.placeholderLabel.placeholderString = [error.localizedDescription isEqualToString:@"The Internet connection appears to be offline."] ?
CLNoInternetConnectivityError : CLTryAgainMessage;
self.activityInProgress = NO;
}
}];
}
- (IBAction)filterSearch:(id)sender
{
if (self.searchCriteria.selectedSegment == 1)
{
if (self.searchField.stringValue.length > 0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:CLSearchPredicateKey, self.searchField.stringValue];
self.timeZoneFilteredArray = [NSMutableArray arrayWithArray:[self.timeZoneArray filteredArrayUsingPredicate:predicate]];
[self.availableTimezoneTableView reloadData];
}
}
}
- (IBAction)searchOptions:(id)sender
{
self.placeholderLabel.placeholderString = CLEmptyString;
self.placeholderLabel.hidden = YES;
if (self.searchCriteria.selectedSegment == 0)
{
self.searchField.placeholderString = @"Enter a city, state or country name";
self.columnName = @"Place(s)";
self.abbreviation.hidden = YES;
}
else
{
self.searchField.placeholderString = @"Enter a timezone name";
self.columnName = @"Timezone(s)";
self.abbreviation.hidden = NO;
self.timeZoneArray = [NSMutableArray arrayWithArray:[NSTimeZone knownTimeZoneNames]];
}
self.searchField.stringValue = CLEmptyString;
[self.availableTimezoneTableView reloadData];
}
- (IBAction)loginPreferenceChanged:(NSButton *)sender
{
if(!(SMLoginItemSetEnabled((__bridge CFStringRef)@"com.abhishek.Clocker-Helper", (BOOL)[sender state])))
{
NSLog(@"Login item was not successful.");
}
}
@end