#import "AppDelegate.h" #import "DirectoryWatcher.h" #import "Uploader.h" @interface AppDelegate ()<DirectoryWatcherDelegate, UploaderDelegate, NSUserNotificationCenterDelegate> @property DirectoryWatcher * watcher; @property Uploader * uploader; @property NSStatusItem * menubarItem; @end @implementation AppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { // Insert code here to initialize your application self.watcher = [[DirectoryWatcher alloc] initWithPath:[self downloadsDirectory]]; self.watcher.delegate = self; [self.watcher startWatching]; self.uploader = [[Uploader alloc] init]; self.uploader.delegate = self; [NSUserNotificationCenter defaultUserNotificationCenter].delegate = self; [self createMenuBarIcon]; [self configureVolumeMountNotifications]; [self showActiveMicroBits]; } - (void)applicationWillTerminate:(NSNotification *)aNotification { // Insert code here to tear down your application [self.watcher stopWatching]; } - (void)dealloc { [[NSWorkspace sharedWorkspace].notificationCenter removeObserver:self]; } #pragma mark - Directory - (void)watcher:(DirectoryWatcher *)watcher observedNewFileAtPath:(NSString *)path { NSString * fullPath = [watcher.path stringByAppendingPathComponent:path]; if ([self.uploader shouldUploadFileAtPath:fullPath]) { [self.uploader uploadFile:fullPath]; } } - (NSString*)downloadsDirectory { NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDownloadsDirectory, NSUserDomainMask, YES); return paths.firstObject; } #pragma mark - Uploader delegate - (void)uploader:(Uploader *)uploader transferredFile:(NSString *)file toMicroBit:(NSString *)microbit { [self showNotification:@"micro:bit upload" withDescription:[NSString stringWithFormat:@"%@ uploaded to %@", file.lastPathComponent, microbit]]; } - (void)uploader:(Uploader *)uploader failedToTransferFile:(NSString *)file toMicroBit:(NSString *)microbit { [self showNotification:@"micro:bit upload failed" withDescription:[NSString stringWithFormat:@"Couldn't transfer %@ to %@", file.lastPathComponent, microbit]]; } - (void)showNotification:(NSString*)title withDescription:(NSString*)description { NSUserNotification * notification = [NSUserNotification new]; notification.title = title; notification.informativeText = description; notification.soundName = NSUserNotificationDefaultSoundName; [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; } #pragma mark - NSUserNotificationCenterDelegate - (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification { return YES; } #pragma mark - Volume mount/unmount notification - (void)configureVolumeMountNotifications { [[NSWorkspace sharedWorkspace].notificationCenter addObserver:self selector:@selector(volumeMountNotification:) name:NSWorkspaceDidRenameVolumeNotification object:nil]; [[NSWorkspace sharedWorkspace].notificationCenter addObserver:self selector:@selector(volumeMountNotification:) name:NSWorkspaceDidMountNotification object:nil]; [[NSWorkspace sharedWorkspace].notificationCenter addObserver:self selector:@selector(volumeMountNotification:) name:NSWorkspaceDidUnmountNotification object:nil]; } - (void)volumeMountNotification:(NSNotification*)sender { //Delay upadting the menu to give the chance for the disk to fully mount or unmount dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self showActiveMicroBits]; }); } #pragma mark - Menu bar app - (void)createMenuBarIcon { self.menubarItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength]; self.menubarItem.button.image = [NSImage imageNamed:@"menubar"]; } - (void)showActiveMicroBits { NSMenu * menu = [NSMenu new]; NSString * countString; NSUInteger count = self.uploader.microBitPaths.count; if (count == 0) { countString = @"No connect micro:bits"; } else if (count == 1) { countString = @"1 connected micro:bit"; } else { countString = [NSString stringWithFormat:@"%lu connected micro:bits", count]; } NSMenuItem * microBitCount = [[NSMenuItem alloc] initWithTitle:countString action:nil keyEquivalent:@""]; microBitCount.enabled = NO; [menu addItem:microBitCount]; NSMenuItem * websiteItem = [[NSMenuItem alloc] initWithTitle:@"Editor" action:@selector(launchEditor:) keyEquivalent:@"e"]; [menu addItem:websiteItem]; NSMenuItem * quitItem = [[NSMenuItem alloc] initWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"]; [menu addItem:quitItem]; self.menubarItem.menu = menu; } - (void)launchEditor:(id)sender { [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://makecode.microbit.org/"]]; } @end