Archive Project
This commit is contained in:
256
Notifications for YouTube/NYTAppDelegate.m
Normal file → Executable file
256
Notifications for YouTube/NYTAppDelegate.m
Normal file → Executable file
@@ -8,11 +8,263 @@
|
||||
|
||||
#import "NYTAppDelegate.h"
|
||||
|
||||
@implementation NYTAppDelegate
|
||||
// Core Imports
|
||||
#import "NYTAuthentication.h"
|
||||
#import "NYTUpdateManager.h"
|
||||
|
||||
// Other Imports
|
||||
#import "NumberValueTransformer.h"
|
||||
#import "NYTRulesWindowController.h"
|
||||
|
||||
@interface NYTAppDelegate ()
|
||||
|
||||
// Outlets etc.
|
||||
@property (weak) IBOutlet NSButton *loginButton;
|
||||
@property (readwrite, strong) NSStatusItem *statusItem;
|
||||
|
||||
// Login
|
||||
@property (readwrite) BOOL loggingIn;
|
||||
|
||||
@end
|
||||
|
||||
// Notifications used for KVO
|
||||
static void* const NYTLoginChangedNotification = @"NYTLoginChangedNotification";
|
||||
static void* const NYTUpdateManagerPropertyDidChangeNotification = @"NYTUpdateManagerPropertyDidChangeNotification";
|
||||
|
||||
@implementation NYTAppDelegate {
|
||||
NYTRulesWindowController *_rulesController;
|
||||
}
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
[super initialize];
|
||||
// Register our value transformers
|
||||
[NSValueTransformer setValueTransformer:[NumberValueTransformer new] forName:@"NumberValueTransformer"];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
// Make sure this object gets removed from any observed object
|
||||
NYTUpdateManager *manager = [NYTUpdateManager sharedManager];
|
||||
[manager removeObserver:self forKeyPath:@"autoRefreshEnabled"];
|
||||
[manager removeObserver:self forKeyPath:@"autoRefreshInterval"];
|
||||
[manager removeObserver:self forKeyPath:@"coalescesNotifications"];
|
||||
[manager removeObserver:self forKeyPath:@"maximumVideoAge"];
|
||||
[[NYTAuthentication sharedAuthentication] removeObserver:self forKeyPath:@"isLoggedIn"];
|
||||
}
|
||||
|
||||
#pragma mark - Application Delegate
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
// Insert code here to initialize your application
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NYTUpdateManager *manager = [NYTUpdateManager sharedManager];
|
||||
NYTAuthentication *auth = [NYTAuthentication sharedAuthentication];
|
||||
|
||||
// Configure the User Defaults
|
||||
NSDictionary *userDefaults = @{@"autoRefreshEnabled": @YES, @"autoRefreshInterval": @600, @"coalescesNotifications": @YES, @"maximumVideoAge": @3600};
|
||||
[defaults registerDefaults:userDefaults];
|
||||
|
||||
// Configure Notification Centers
|
||||
[NSUserNotificationCenter defaultUserNotificationCenter].delegate = self;
|
||||
// Notification Startup
|
||||
NSUserNotification *startNotification = aNotification.userInfo[NSApplicationLaunchUserNotificationKey];
|
||||
if (startNotification) {
|
||||
[self userNotificationCenter:[NSUserNotificationCenter defaultUserNotificationCenter] didActivateNotification:startNotification];
|
||||
}
|
||||
|
||||
// Configure the status item
|
||||
self.statusItemVisible = YES;
|
||||
|
||||
// Configure the login (and log in). Do so before configuring notifications or auto refresh because this can take a while
|
||||
[auth addObserver:self forKeyPath:@"isLoggedIn" options:0 context:NYTLoginChangedNotification];
|
||||
self.loggingIn = YES;
|
||||
[auth tryLoginFromKeychainWithCompletionHandler:^{
|
||||
self.loggingIn = NO;
|
||||
// If there is no login in the keychain show the preferences
|
||||
if (!auth.isLoggedIn) {
|
||||
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
|
||||
[self.window makeKeyAndOrderFront:self];
|
||||
}
|
||||
}];
|
||||
|
||||
// Configure the update manager
|
||||
manager.maximumVideoAge = [defaults integerForKey:@"maximumVideoAge"];
|
||||
manager.coalescesNotifications = [defaults boolForKey:@"coalescesNotifications"];
|
||||
manager.autoRefreshInterval = [defaults integerForKey:@"autoRefreshInterval"];
|
||||
[manager addObserver:self forKeyPath:@"maximumVideoAge" options:NSKeyValueObservingOptionNew context:NYTUpdateManagerPropertyDidChangeNotification];
|
||||
[manager addObserver:self forKeyPath:@"coalescesNotifications" options:NSKeyValueObservingOptionNew context:NYTUpdateManagerPropertyDidChangeNotification];
|
||||
[manager addObserver:self forKeyPath:@"autoRefreshInterval" options:NSKeyValueObservingOptionNew context:NYTUpdateManagerPropertyDidChangeNotification];
|
||||
|
||||
// Configure (Auto) Refresh
|
||||
manager.autoRefreshEnabled = [defaults boolForKey:@"autoRefreshEnabled"];
|
||||
[manager addObserver:self forKeyPath:@"autoRefreshEnabled" options:NSKeyValueObservingOptionNew context:NYTUpdateManagerPropertyDidChangeNotification];
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
|
||||
{
|
||||
// Open the preferences on reopen (if no other window is visible)
|
||||
if (!flag) {
|
||||
[self.window makeKeyAndOrderFront:nil];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)notification
|
||||
{
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
|
||||
#pragma mark - User Notification Center Delegate
|
||||
|
||||
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
|
||||
{
|
||||
// Show the URL
|
||||
NSString *videoURL = notification.userInfo[NYTUserNotificationURLKey];
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:videoURL]];
|
||||
// Remove the notification
|
||||
[center removeDeliveredNotification:notification];
|
||||
}
|
||||
|
||||
- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark *** Handling the Status Item ***
|
||||
|
||||
- (void)setStatusItemVisible:(BOOL)visible
|
||||
{
|
||||
if (visible) {
|
||||
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
|
||||
//NSMutableAttributedString *title = [[NSMutableAttributedString alloc] initWithString:@"(4)"];
|
||||
//[title addAttribute:NSStrokeWidthAttributeName value:@-5.0 range:NSMakeRange/*(3, 4)*/(1, 1)];
|
||||
//self.statusItem.attributedTitle = title;
|
||||
self.statusItem.image = [NSImage imageNamed:@"play-icon-bw"];
|
||||
self.statusItem.alternateImage = [NSImage imageNamed:@"play-icon-s"];
|
||||
self.statusItem.menu = self.statusMenu;
|
||||
self.statusItem.highlightMode = YES;
|
||||
} else {
|
||||
[[NSStatusBar systemStatusBar] removeStatusItem:self.statusItem];
|
||||
self.statusItem = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isStatusItemVisible
|
||||
{
|
||||
return self.statusItem != nil;
|
||||
}
|
||||
|
||||
#pragma mark *** Handling Login ***
|
||||
|
||||
- (IBAction)login:(id)sender {
|
||||
if ([NYTAuthentication sharedAuthentication].isLoggedIn) {
|
||||
// Logout: Present a sheet giving the following options: Logout, Cancel, Switch user
|
||||
NSString *title = NSLocalizedString(@"Do you want to log out or switch to another user?", nil);
|
||||
NSString *switchUser = NSLocalizedString(@"Switch User…", nil);
|
||||
NSString *logout = NSLocalizedString(@"Logout", nil);
|
||||
NSString *cancel = NSLocalizedString(@"Cancel", nil);
|
||||
NSString *msg = NSLocalizedString(@"If you logout the login stored in your keychain will be removed. You would have to log in agin the next time you want to use Notifications for YouTube.", nil);
|
||||
NSBeginAlertSheet(title, switchUser, logout, cancel, self.window, self, NULL, @selector(sheetDidDismiss:returnCode:contextInfo:), NULL, @"%@", msg);
|
||||
} else {
|
||||
[self doLogin];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)sheetDidDismiss:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
|
||||
{
|
||||
if (returnCode == NSAlertDefaultReturn) {
|
||||
// Switch User
|
||||
[self doLogin];
|
||||
} else if (returnCode == NSAlertAlternateReturn) {
|
||||
// Logout: Redirect to Update Manager
|
||||
[[NYTAuthentication sharedAuthentication] discardLogin];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)doLogin
|
||||
{
|
||||
// Login: Redirect to Update Manager
|
||||
self.loggingIn = YES;
|
||||
[[NYTAuthentication sharedAuthentication] beginLoginSheetForWindow:self.window completionHandler:^(NSError *error) {
|
||||
if (error) {
|
||||
// Show the error as sheet if possible
|
||||
if (self.window.isVisible) {
|
||||
[NSApp presentError:error modalForWindow:self.window delegate:nil didPresentSelector:NULL contextInfo:NULL];
|
||||
} else {
|
||||
[NSApp presentError:error];
|
||||
}
|
||||
}
|
||||
self.loggingIn = NO;
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark *** Handling Refreshing ***
|
||||
|
||||
- (IBAction)performRefresh:(id)sender {
|
||||
// Refresh with notifications
|
||||
[[NYTUpdateManager sharedManager] refreshFeedsWithErrorHandler:^(NSError *error) {
|
||||
// Show the error if the refresh was triggered manually
|
||||
// Possibly show it in a modal sheet otherwise a modal window
|
||||
if (error) {
|
||||
if ([sender respondsToSelector:@selector(window)] && [sender window].isVisible) {
|
||||
NSAlert *alert = [NSAlert alertWithError:error];
|
||||
[alert beginSheetModalForWindow:[sender window] modalDelegate:nil didEndSelector:NULL contextInfo:NULL];
|
||||
} else {
|
||||
[NSApp presentError:error];
|
||||
}
|
||||
}
|
||||
} notify:YES];
|
||||
}
|
||||
|
||||
#pragma mark *** Configure Notifications ***
|
||||
|
||||
- (IBAction)editRules:(id)sender {
|
||||
_rulesController = [[NYTRulesWindowController alloc] init];
|
||||
[NSApp beginSheet:_rulesController.window modalForWindow:self.window modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:NULL];
|
||||
}
|
||||
|
||||
- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
|
||||
{
|
||||
// For efficiency reasons
|
||||
_rulesController = nil;
|
||||
}
|
||||
|
||||
#pragma mark *** Other Actions ***
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
||||
{
|
||||
if (context == NYTUpdateManagerPropertyDidChangeNotification) {
|
||||
id value = change[NSKeyValueChangeNewKey];
|
||||
[[NSUserDefaults standardUserDefaults] setObject:value forKey:keyPath];
|
||||
}else if (context == NYTLoginChangedNotification) {
|
||||
// Manage the title of the login/logout button based on wether login information is present (using KVO)
|
||||
if ([NYTAuthentication sharedAuthentication].isLoggedIn) {
|
||||
self.loginButton.title = NSLocalizedString(@"Logout…", nil);
|
||||
} else {
|
||||
self.loginButton.title = NSLocalizedString(@"Login…", nil);
|
||||
}
|
||||
} else {
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)showPreferenceWindow:(id)sender
|
||||
{
|
||||
// Activate the app first
|
||||
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
|
||||
[self.window makeKeyAndOrderFront:sender];
|
||||
[self.window makeMainWindow];
|
||||
}
|
||||
|
||||
- (IBAction)showAboutPanel:(id)sender {
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
[NSApp orderFrontStandardAboutPanel:sender];
|
||||
}
|
||||
|
||||
- (IBAction)browseYouTube:(id)sender {
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.youtube.com/"]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user