diff --git a/launchers/darwin/nib/ProcessScreen.xib b/launchers/darwin/nib/ProcessScreen.xib index d6a1da91c9..d16d71e5fa 100644 --- a/launchers/darwin/nib/ProcessScreen.xib +++ b/launchers/darwin/nib/ProcessScreen.xib @@ -22,12 +22,12 @@ - + - + @@ -36,7 +36,7 @@ - + @@ -49,6 +49,10 @@ + + + + @@ -56,6 +60,7 @@ + diff --git a/launchers/darwin/src/CustomUI.h b/launchers/darwin/src/CustomUI.h index a9d93d03c7..a5e27f5c1b 100644 --- a/launchers/darwin/src/CustomUI.h +++ b/launchers/darwin/src/CustomUI.h @@ -25,6 +25,6 @@ extern NSString* hifiBackgroundFilename; @end @interface Hyperlink : NSTextField { - + } @end diff --git a/launchers/darwin/src/CustomUI.m b/launchers/darwin/src/CustomUI.m index 156efe04d5..61f92fe51f 100644 --- a/launchers/darwin/src/CustomUI.m +++ b/launchers/darwin/src/CustomUI.m @@ -24,19 +24,19 @@ NSString* hifiBackgroundFilename = @"hifi_window"; [NSApp sendAction:(NSSelectorFromString(@"paste:")) to:nil from:self]; return TRUE; } - + if ([[event charactersIgnoringModifiers] isEqualToString:@"c"]) { [NSApp sendAction:(NSSelectorFromString(@"copy:")) to:nil from:self]; return TRUE; } - + if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) { [NSApp sendAction:(NSSelectorFromString(@"selectAll:")) to:nil from:self]; return TRUE; } } } - + return [super performKeyEquivalent:event]; } @@ -46,7 +46,7 @@ NSString* hifiBackgroundFilename = @"hifi_window"; NSTextView *fieldEditor = (NSTextView*)[self.window fieldEditor:YES forObject:self]; fieldEditor.insertionPointColor = insertionPointColor; - + } -(BOOL)becomeFirstResponder @@ -75,7 +75,7 @@ NSString* hifiBackgroundFilename = @"hifi_window"; NSTextView *fieldEditor = (NSTextView*)[self.window fieldEditor:YES forObject:self]; fieldEditor.insertionPointColor = insertionPointColor; - + } @@ -97,19 +97,19 @@ NSString* hifiBackgroundFilename = @"hifi_window"; [NSApp sendAction:(NSSelectorFromString(@"paste:")) to:nil from:self]; return TRUE; } - + if ([[event charactersIgnoringModifiers] isEqualToString:@"c"]) { [NSApp sendAction:(NSSelectorFromString(@"copy:")) to:nil from:self]; return TRUE; } - + if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) { [NSApp sendAction:(NSSelectorFromString(@"selectAll:")) to:nil from:self]; return TRUE; } } } - + return [super performKeyEquivalent:event]; } @end @@ -126,7 +126,7 @@ NSString* hifiBackgroundFilename = @"hifi_window"; - (void)awakeFromNib { [super awakeFromNib]; - + self.wantsLayer = YES; self.layer.backgroundColor = [NSColor blackColor].CGColor; self.layer.borderColor = [NSColor whiteColor].CGColor; @@ -134,16 +134,16 @@ NSString* hifiBackgroundFilename = @"hifi_window"; self.layer.masksToBounds = YES; _titleLayer = [[CATextLayer alloc] init]; - + CGSize buttonSize = self.frame.size; CGSize titleSize = [self.title sizeWithAttributes:@{NSFontAttributeName: self.font}]; CGFloat x = (buttonSize.width - titleSize.width) / 2.0; // Title's origin x CGFloat y = (buttonSize.height - titleSize.height) / 2.0; // Title's origin y - + self.titleLayer.frame = NSMakeRect(round(x), round(y), ceil(titleSize.width), ceil(titleSize.height)); self.titleLayer.string = self.title; self.titleLayer.foregroundColor = [NSColor whiteColor].CGColor; - + // TODO(huffman) Fix this to be dynamic based on screen? self.titleLayer.contentsScale = 2.0; @@ -151,7 +151,7 @@ NSString* hifiBackgroundFilename = @"hifi_window"; self.titleLayer.fontSize = self.font.pointSize; //self.titleLayer.allowsEdgeAntialiasing = YES; //self.titleLayer.allowsFontSubpixelQuantization = YES; - + [self.layer addSublayer:self.titleLayer]; } diff --git a/launchers/darwin/src/DownloadDomainContent.h b/launchers/darwin/src/DownloadDomainContent.h index c35c8b8f09..80d03fd1c8 100644 --- a/launchers/darwin/src/DownloadDomainContent.h +++ b/launchers/darwin/src/DownloadDomainContent.h @@ -2,7 +2,10 @@ @interface DownloadDomainContent : NSObject { } - +@property (nonatomic, assign) double progressPercentage; +@property (nonatomic, assign) double taskProgressPercentage; - (void) downloadDomainContent:(NSString*) domainContentUrl; +- (double) getProgressPercentage; + @end diff --git a/launchers/darwin/src/DownloadDomainContent.m b/launchers/darwin/src/DownloadDomainContent.m index 170ee1d43b..f95ae39fc8 100644 --- a/launchers/darwin/src/DownloadDomainContent.m +++ b/launchers/darwin/src/DownloadDomainContent.m @@ -3,8 +3,15 @@ @implementation DownloadDomainContent +- (double) getProgressPercentage +{ + return (self.progressPercentage * 0.70) + (self.taskProgressPercentage * 0.30); +} + - (void) downloadDomainContent:(NSString *)domainContentUrl { + self.progressPercentage = 0.0; + self.taskProgressPercentage = 0.0; NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:domainContentUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; @@ -17,7 +24,10 @@ -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { CGFloat prog = (float)totalBytesWritten/totalBytesExpectedToWrite; - NSLog(@"domain content downloaded %d%%", (int)(100.0*prog)); + NSLog(@"domain content downloaded %f", (100.0*prog)); + + self.progressPercentage = (int)(100.0 * prog); + [[Launcher sharedLauncher] updateProgressIndicator]; } @@ -27,6 +37,11 @@ -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { NSLog(@"Did finish downloading to url"); + NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval: 0.1 + target: self + selector: @selector(updatePercentage:) + userInfo:nil + repeats: YES]; NSError *error = nil; NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *destinationFileName = downloadTask.originalRequest.URL.lastPathComponent; @@ -47,6 +62,7 @@ if (error) { NSLog(@"DownlodDomainContent: failed to move file to destintation -> error: %@", error); + [timer invalidate]; [sharedLauncher displayErrorPage]; return; } @@ -55,18 +71,33 @@ BOOL extractionSuccessful = [sharedLauncher extractZipFileAtDestination:[[sharedLauncher getDownloadPathForContentAndScripts] stringByAppendingString:@"content"] :[[sharedLauncher getDownloadPathForContentAndScripts] stringByAppendingString:[sharedLauncher getDownloadContentFilename]]]; if (!extractionSuccessful) { + [timer invalidate]; [sharedLauncher displayErrorPage]; return; } NSLog(@"finished extracting content file"); + [timer invalidate]; + self.taskProgressPercentage = 100.0; + [sharedLauncher updateProgressIndicator]; [sharedLauncher domainContentDownloadFinished]; } --(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { NSLog(@"completed; error: %@", error); if (error) { [[Launcher sharedLauncher] displayErrorPage]; } } +- (void) updatePercentage:(NSTimer*) timer { + if (self.taskProgressPercentage < 100.0) { + self.taskProgressPercentage += 1.5; + + if (self.taskProgressPercentage > 100.0) { + self.taskProgressPercentage = 100.0; + } + } + [[Launcher sharedLauncher] updateProgressIndicator]; +} + @end diff --git a/launchers/darwin/src/DownloadInterface.h b/launchers/darwin/src/DownloadInterface.h index 08968f19f0..9d90688654 100644 --- a/launchers/darwin/src/DownloadInterface.h +++ b/launchers/darwin/src/DownloadInterface.h @@ -3,6 +3,10 @@ @interface DownloadInterface : NSObject { } @property (nonatomic, assign) NSString* finalFilePath; +@property (nonatomic, assign) double progressPercentage; +@property (nonatomic, assign) double taskProgressPercentage; - (void) downloadInterface:(NSString*) downloadUrl; + +- (double) getProgressPercentage; @end diff --git a/launchers/darwin/src/DownloadInterface.m b/launchers/darwin/src/DownloadInterface.m index 28980310c5..f0bdb645da 100644 --- a/launchers/darwin/src/DownloadInterface.m +++ b/launchers/darwin/src/DownloadInterface.m @@ -6,6 +6,8 @@ - (void) downloadInterface:(NSString*) downloadUrl { + self.progressPercentage = 0.0; + self.taskProgressPercentage = 0.0; NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:downloadUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; @@ -21,6 +23,14 @@ CGFloat prog = (float)totalBytesWritten/totalBytesExpectedToWrite; NSLog(@"interface downloaded %d%%", (int)(100.0*prog)); + self.progressPercentage = (100.0 * prog); + [[Launcher sharedLauncher] updateProgressIndicator]; + +} + +- (double) getProgressPercentage +{ + return (self.progressPercentage * 0.70) + (self.taskProgressPercentage * 0.30); } -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes { @@ -29,6 +39,11 @@ -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { NSLog(@"Did finish downloading to url"); + NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval: 0.1 + target: self + selector: @selector(updateTaskPercentage:) + userInfo:nil + repeats: YES]; NSError *error = nil; NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *destinationFileName = downloadTask.originalRequest.URL.lastPathComponent; @@ -44,6 +59,7 @@ if (error) { NSLog(@"Download Interface: failed to move file to destination -> error: %@", error); + [timer invalidate]; [sharedLauncher displayErrorPage]; return; } @@ -54,6 +70,7 @@ NSLog(@"extract interface zip"); BOOL success = [sharedLauncher extractZipFileAtDestination:appPath :[appPath stringByAppendingString:downloadFileName]]; if (!success) { + [timer invalidate]; [sharedLauncher displayErrorPage]; return; } @@ -71,6 +88,9 @@ NSString* launcherPath = [appPath stringByAppendingString:@"Launcher"]; [[Settings sharedSettings] setLauncherPath:launcherPath]; + [timer invalidate]; + self.taskProgressPercentage = 100.0; + [sharedLauncher updateProgressIndicator]; [sharedLauncher interfaceFinishedDownloading]; } @@ -81,5 +101,16 @@ } } +- (void) updateTaskPercentage:(NSTimer*) timer { + if (self.taskProgressPercentage < 100.0) { + self.taskProgressPercentage += 1.5; + + if (self.taskProgressPercentage > 100.0) { + self.taskProgressPercentage = 100.0; + } + } + [[Launcher sharedLauncher] updateProgressIndicator]; +} + @end diff --git a/launchers/darwin/src/ErrorViewController.m b/launchers/darwin/src/ErrorViewController.m index 0ae321763f..84dee95678 100644 --- a/launchers/darwin/src/ErrorViewController.m +++ b/launchers/darwin/src/ErrorViewController.m @@ -20,7 +20,7 @@ -(IBAction)resartLauncher:(id)sender { - [[Launcher sharedLauncher] showLoginScreen]; + [[Launcher sharedLauncher] restart]; } @end diff --git a/launchers/darwin/src/LatestBuildRequest.m b/launchers/darwin/src/LatestBuildRequest.m index 767c67eea1..deb6d9795b 100644 --- a/launchers/darwin/src/LatestBuildRequest.m +++ b/launchers/darwin/src/LatestBuildRequest.m @@ -32,13 +32,18 @@ // We're using an ephermeral session here to ensure the tags api response is never cached. NSURLSession * session = [NSURLSession sessionWithConfiguration:NSURLSessionConfiguration.ephemeralSessionConfiguration]; NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { - - NSLog(@"Latest Build Request error: %@", error); NSLog(@"Latest Build Request Data: %@", data); NSHTTPURLResponse *ne = (NSHTTPURLResponse *)response; NSLog(@"Latest Build Request Response: %ld", [ne statusCode]); Launcher* sharedLauncher = [Launcher sharedLauncher]; + + if ([ne statusCode] == 500) { + dispatch_async(dispatch_get_main_queue(), ^{ + [sharedLauncher displayErrorPage]; + }); + return; + } NSMutableData* webData = [NSMutableData data]; [webData appendData:data]; NSString* jsonString = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[data length] encoding:NSUTF8StringEncoding]; diff --git a/launchers/darwin/src/Launcher.h b/launchers/darwin/src/Launcher.h index 9eb1cbf3b5..de67850bfe 100644 --- a/launchers/darwin/src/Launcher.h +++ b/launchers/darwin/src/Launcher.h @@ -21,6 +21,12 @@ typedef enum LoginErrorTypes CREDENTIALS } LoginError; +struct LatestBuildInfo { + NSString* downloadURL; + BOOL shouldDownload; + BOOL requestBuildFinished; +}; + @interface Launcher : NSObject { } @property (nonatomic, retain) NSString* password; @@ -34,6 +40,7 @@ typedef enum LoginErrorTypes @property (nonatomic, retain) NSString* domainURL; @property (nonatomic, retain) NSString* domainContentUrl; @property (nonatomic, retain) NSString* domainScriptsUrl; +@property (nonatomic, retain) NSString* interfaceDownloadUrl; @property (nonatomic, retain) DownloadInterface* downloadInterface; @property (nonatomic, retain) CredentialsRequest* credentialsRequest; @property (nonatomic, retain) DownloadDomainContent* downloadDomainContent; @@ -44,9 +51,17 @@ typedef enum LoginErrorTypes @property (nonatomic) BOOL waitingForCredentialReponse; @property (nonatomic) BOOL gotCredentialResponse; @property (nonatomic) BOOL waitingForInterfaceToTerminate; +@property (nonatomic) BOOL shouldDownloadInterface; +@property (nonatomic) BOOL latestBuildRequestFinished; +@property (nonatomic, assign) NSTimer* updateProgressIndicatorTimer; @property (nonatomic, assign, readwrite) ProcessState processState; @property (nonatomic, assign, readwrite) LoginError loginError; +@property (nonatomic, assign) NSProgressIndicator* progressIndicator; +@property (nonatomic) double progressTarget; +@property (nonatomic) struct LatestBuildInfo buildInfo; +- (NSProgressIndicator*) getProgressView; +- (void) setProgressView:(NSProgressIndicator*) aProgressIndicator; - (void) displayNameEntered:(NSString*)aDisplayName; - (void) credentialsEntered:(NSString*)aOrginization :(NSString*)aUsername :(NSString*)aPassword; - (void) credentialsAccepted:(BOOL) aCredentialsAccepted; @@ -57,6 +72,7 @@ typedef enum LoginErrorTypes - (BOOL) loginShouldSetErrorState; - (void) displayErrorPage; - (void) showLoginScreen; +- (void) restart; - (NSString*) getLauncherPath; - (ProcessState) currentProccessState; - (void) setCurrentProcessState:(ProcessState) aProcessState; @@ -76,8 +92,13 @@ typedef enum LoginErrorTypes - (NSString*) getDownloadContentFilename; - (NSString*) getDownloadScriptsFilename; - (NSString*) getDownloadFilename; +- (void) startUpdateProgressIndicatorTimer; +- (void) endUpdateProgressIndicatorTimer; - (BOOL) isLoadedIn; - (NSString*) getAppPath; +- (void) updateProgressIndicator; +- (void) setLatestBuildInfo:(struct LatestBuildInfo) latestBuildInfo; +- (struct LatestBuildInfo) getLatestBuildInfo; + (id) sharedLauncher; @end diff --git a/launchers/darwin/src/Launcher.m b/launchers/darwin/src/Launcher.m index 209060d90d..71eb7828e9 100644 --- a/launchers/darwin/src/Launcher.m +++ b/launchers/darwin/src/Launcher.m @@ -17,6 +17,7 @@ static BOOL const DELETE_ZIP_FILES = TRUE; @implementation Launcher + + (id) sharedLauncher { static Launcher* sharedLauncher = nil; static dispatch_once_t onceToken; @@ -35,11 +36,18 @@ static BOOL const DELETE_ZIP_FILES = TRUE; self.latestBuildRequest = [LatestBuildRequest alloc]; self.organizationRequest = [OrganizationRequest alloc]; self.downloadScripts = [DownloadScripts alloc]; + struct LatestBuildInfo latestBuildInfo; + latestBuildInfo.downloadURL = nil; + latestBuildInfo.shouldDownload = FALSE; + latestBuildInfo.requestBuildFinished = FALSE; + self.buildInfo = latestBuildInfo; self.credentialsAccepted = TRUE; self.gotCredentialResponse = FALSE; self.waitingForCredentialReponse = FALSE; self.waitingForInterfaceToTerminate = FALSE; + self.latestBuildRequestFinished = FALSE; self.userToken = nil; + self.progressIndicator = nil; self.processState = DOWNLOADING_INTERFACE; } return self; @@ -79,6 +87,29 @@ static BOOL const DELETE_ZIP_FILES = TRUE; return [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/Contents/MacOS/"]; } +- (void) updateProgressIndicator +{ + double contentPercentage = [self.downloadDomainContent getProgressPercentage]; + double interfacePercentage = [self.downloadInterface getProgressPercentage]; + double currentTotalPercentage = self.progressTarget; + if (self.processState == DOWNLOADING_INTERFACE) { + if (self.shouldDownloadInterface) { + currentTotalPercentage = (contentPercentage * 0.5) + (interfacePercentage * 0.5); + } else { + currentTotalPercentage = contentPercentage; + } + } else { + currentTotalPercentage = interfacePercentage; + } + self.progressTarget = currentTotalPercentage; +} + +- (double) lerp:(double) pointA :(double) pointB :(double) interp +{ + double lerpValue = pointA + interp * (pointB - pointA); + return lerpValue; +} + - (BOOL) extractZipFileAtDestination:(NSString *)destination :(NSString*)file { NSTask* task = [[NSTask alloc] init]; @@ -101,6 +132,24 @@ static BOOL const DELETE_ZIP_FILES = TRUE; return TRUE; } +-(void) setProgressView:(NSProgressIndicator*) aProgressIndicator +{ + self.progressIndicator = aProgressIndicator; +} + +-(NSProgressIndicator*) getProgressView +{ + return self.progressIndicator; +} + +- (void) restart +{ + SplashScreen* splashScreen = [[SplashScreen alloc] initWithNibName:@"SplashScreen" bundle:nil]; + [[[[NSApplication sharedApplication] windows] objectAtIndex:0] setContentViewController: splashScreen]; + + [self checkLoginStatus]; +} + - (void) displayErrorPage { ErrorViewController* errorPage = [[ErrorViewController alloc] initWithNibName:@"ErrorScreen" bundle:nil]; @@ -109,19 +158,11 @@ static BOOL const DELETE_ZIP_FILES = TRUE; - (void) checkLoginStatus { - if ([self isLoadedIn]) { - Launcher* sharedLauncher = [Launcher sharedLauncher]; - [sharedLauncher setCurrentProcessState:CHECKING_UPDATE]; - ProcessScreen* processScreen = [[ProcessScreen alloc] initWithNibName:@"ProcessScreen" bundle:nil]; - [[[[NSApplication sharedApplication] windows] objectAtIndex:0] setContentViewController: processScreen]; - [self.latestBuildRequest requestLatestBuildInfo]; - } else { - [NSTimer scheduledTimerWithTimeInterval:2.0 - target:self - selector:@selector(onSplashScreenTimerFinished:) - userInfo:nil - repeats:NO]; - } + [NSTimer scheduledTimerWithTimeInterval:1.0 + target:self + selector:@selector(onSplashScreenTimerFinished:) + userInfo:nil + repeats:NO]; [[NSApplication sharedApplication] activateIgnoringOtherApps:TRUE]; } @@ -145,6 +186,31 @@ static BOOL const DELETE_ZIP_FILES = TRUE; return self.scriptsFilename; } +- (void) startUpdateProgressIndicatorTimer +{ + self.progressTarget = 0.0; + self.updateProgressIndicatorTimer = [NSTimer scheduledTimerWithTimeInterval: 0.0016 + target: self + selector: @selector(updateIndicator:) + userInfo:nil + repeats: YES]; + + [[NSRunLoop mainRunLoop] addTimer:self.updateProgressIndicatorTimer forMode:NSRunLoopCommonModes]; +} + +- (void) endUpdateProgressIndicatorTimer +{ + [self.updateProgressIndicatorTimer invalidate]; + self.updateProgressIndicatorTimer = nil; +} + +- (void) updateIndicator:(NSTimer*) timer +{ + NSProgressIndicator* progressIndicator = [self getProgressView]; + double oldValue = progressIndicator.doubleValue; + progressIndicator.doubleValue = [self lerp:oldValue :self.progressTarget :0.3]; +} + - (void)didTerminateApp:(NSNotification *)notification { if (self.waitingForInterfaceToTerminate) { NSString* appName = [notification.userInfo valueForKey:@"NSApplicationName"]; @@ -199,6 +265,7 @@ static BOOL const DELETE_ZIP_FILES = TRUE; - (void) displayNameEntered:(NSString*)aDiplayName { self.processState = DOWNLOADING_INTERFACE; + [self startUpdateProgressIndicatorTimer]; ProcessScreen* processScreen = [[ProcessScreen alloc] initWithNibName:@"ProcessScreen" bundle:nil]; [[[[NSApplication sharedApplication] windows] objectAtIndex:0] setContentViewController: processScreen]; [self.downloadDomainContent downloadDomainContent:self.domainContentUrl]; @@ -207,8 +274,11 @@ static BOOL const DELETE_ZIP_FILES = TRUE; - (void) domainContentDownloadFinished { - //.[self.downloadScripts downloadScripts:self.domainScriptsUrl]; - [self.latestBuildRequest requestLatestBuildInfo]; + if (self.shouldDownloadInterface) { + [self.downloadInterface downloadInterface: self.interfaceDownloadUrl]; + return; + } + [self interfaceFinishedDownloading]; } - (void) domainScriptsDownloadFinished @@ -235,14 +305,21 @@ static BOOL const DELETE_ZIP_FILES = TRUE; - (void) interfaceFinishedDownloading { - if (self.processState == DOWNLOADING_INTERFACE) { - self.processState = RUNNING_INTERFACE_AFTER_DOWNLOAD; + [self endUpdateProgressIndicatorTimer]; + NSProgressIndicator* progressIndicator = [self getProgressView]; + progressIndicator.doubleValue = self.progressTarget; + Launcher* sharedLauncher = [Launcher sharedLauncher]; + if ([sharedLauncher currentProccessState] == DOWNLOADING_INTERFACE) { + [sharedLauncher setCurrentProcessState: RUNNING_INTERFACE_AFTER_DOWNLOAD]; } else { - self.processState = RUNNING_INTERFACE_AFTER_UPDATE; + [sharedLauncher setCurrentProcessState: RUNNING_INTERFACE_AFTER_UPDATE]; } - ProcessScreen* processScreen = [[ProcessScreen alloc] initWithNibName:@"ProcessScreen" bundle:nil]; - [[[[NSApplication sharedApplication] windows] objectAtIndex:0] setContentViewController: processScreen]; - [self launchInterface]; + + [NSTimer scheduledTimerWithTimeInterval: 0.2 + target: self + selector: @selector(callLaunchInterface:) + userInfo:nil + repeats: NO]; } - (void) credentialsEntered:(NSString*)aOrginization :(NSString*)aUsername :(NSString*)aPassword @@ -269,6 +346,16 @@ static BOOL const DELETE_ZIP_FILES = TRUE; return YES; } +- (struct LatestBuildInfo) getLatestBuildInfo +{ + return self.buildInfo; +} + +- (void) setLatestBuildInfo:(struct LatestBuildInfo) latestBuildInfo +{ + self.buildInfo = latestBuildInfo; +} + -(void) showLoginScreen { LoginScreen* loginScreen = [[LoginScreen alloc] initWithNibName:@"LoginScreen" bundle:nil]; @@ -277,17 +364,29 @@ static BOOL const DELETE_ZIP_FILES = TRUE; - (void) shouldDownloadLatestBuild:(BOOL) shouldDownload :(NSString*) downloadUrl { - if (shouldDownload) { - [self.downloadInterface downloadInterface: downloadUrl]; - return; + self.shouldDownloadInterface = shouldDownload; + self.interfaceDownloadUrl = downloadUrl; + self.latestBuildRequestFinished = TRUE; + if ([self isLoadedIn]) { + Launcher* sharedLauncher = [Launcher sharedLauncher]; + [sharedLauncher setCurrentProcessState:CHECKING_UPDATE]; + if (shouldDownload) { + ProcessScreen* processScreen = [[ProcessScreen alloc] initWithNibName:@"ProcessScreen" bundle:nil]; + [[[[NSApplication sharedApplication] windows] objectAtIndex:0] setContentViewController: processScreen]; + [self startUpdateProgressIndicatorTimer]; + [self.downloadInterface downloadInterface: downloadUrl]; + return; + } + [self interfaceFinishedDownloading]; + } else { + [[NSApplication sharedApplication] activateIgnoringOtherApps:TRUE]; + [self showLoginScreen]; } - [self launchInterface]; } -(void)onSplashScreenTimerFinished:(NSTimer *)timer { - [[NSApplication sharedApplication] activateIgnoringOtherApps:TRUE]; - [self showLoginScreen]; + [self.latestBuildRequest requestLatestBuildInfo]; } -(void)setCurrentProcessState:(ProcessState)aProcessState @@ -369,7 +468,11 @@ static BOOL const DELETE_ZIP_FILES = TRUE; } [workspace launchApplicationAtURL:url options:NSWorkspaceLaunchNewInstance configuration:[NSDictionary dictionaryWithObject:arguments forKey:NSWorkspaceLaunchConfigurationArguments] error:&error]; - [NSApp terminate:self]; + [NSTimer scheduledTimerWithTimeInterval: 3.0 + target: self + selector: @selector(exitLauncher:) + userInfo:nil + repeats: NO]; } - (ProcessState) currentProccessState @@ -377,4 +480,17 @@ static BOOL const DELETE_ZIP_FILES = TRUE; return self.processState; } +- (void) callLaunchInterface:(NSTimer*) timer +{ + ProcessScreen* processScreen = [[ProcessScreen alloc] initWithNibName:@"ProcessScreen" bundle:nil]; + [[[[NSApplication sharedApplication] windows] objectAtIndex:0] setContentViewController: processScreen]; + [self launchInterface]; +} + + +- (void) exitLauncher:(NSTimer*) timer +{ + [NSApp terminate:self]; +} + @end diff --git a/launchers/darwin/src/LoginScreen.m b/launchers/darwin/src/LoginScreen.m index 4c83558160..d654a14f1b 100644 --- a/launchers/darwin/src/LoginScreen.m +++ b/launchers/darwin/src/LoginScreen.m @@ -38,25 +38,25 @@ [self.backgroundImage setImage:[NSImage imageNamed:hifiBackgroundFilename]]; [self.smallLogo setImage:[NSImage imageNamed:hifiSmallLogoFilename]]; - + NSMutableAttributedString* usernameString = [[NSMutableAttributedString alloc] initWithString:@"Username"]; - + [usernameString addAttribute:NSForegroundColorAttributeName value:[NSColor grayColor] range:NSMakeRange(0,8)]; [usernameString addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:18] range:NSMakeRange(0,8)]; - + NSMutableAttributedString* orgName = [[NSMutableAttributedString alloc] initWithString:@"Organization Name"]; [orgName addAttribute:NSForegroundColorAttributeName value:[NSColor grayColor] range:NSMakeRange(0,17)]; [orgName addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:18] range:NSMakeRange(0,17)]; - + NSMutableAttributedString* passwordString = [[NSMutableAttributedString alloc] initWithString:@"Password"]; - + [passwordString addAttribute:NSForegroundColorAttributeName value:[NSColor grayColor] range:NSMakeRange(0,8)]; [passwordString addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:18] range:NSMakeRange(0,8)]; - + [self.username setPlaceholderAttributedString:usernameString]; [self.orginization setPlaceholderAttributedString:orgName]; [self.password setPlaceholderAttributedString:passwordString]; - + [self.password setTarget:self]; [self.password setAction:@selector(goToLogin:)]; } diff --git a/launchers/darwin/src/ProcessScreen.m b/launchers/darwin/src/ProcessScreen.m index 4aeb8abda1..85ec5c8d5b 100644 --- a/launchers/darwin/src/ProcessScreen.m +++ b/launchers/darwin/src/ProcessScreen.m @@ -8,6 +8,7 @@ @property (nonatomic, assign) IBOutlet NSImageView* voxelImage; @property (nonatomic, assign) IBOutlet NSTextField* boldStatus; @property (nonatomic, assign) IBOutlet NSTextField* smallStatus; +@property (nonatomic, assign) IBOutlet NSProgressIndicator* progressView; @end @implementation ProcessScreen @@ -20,6 +21,7 @@ [self.smallStatus setStringValue:@"Set up may take several minutes."]; break; case RUNNING_INTERFACE_AFTER_DOWNLOAD: + [self.progressView setHidden: YES]; [self.boldStatus setStringValue:@"Your new HQ is all setup"]; [self.smallStatus setStringValue:@"Thanks for being patient."]; break; @@ -28,6 +30,7 @@ [self.smallStatus setStringValue:@"We're getting the latest and greatest for you, one sec."]; break; case RUNNING_INTERFACE_AFTER_UPDATE: + [self.progressView setHidden: YES]; [self.boldStatus setStringValue:@"You're good to go!"]; [self.smallStatus setStringValue:@"Thanks for being patient."]; break; @@ -37,10 +40,11 @@ [self.background setImage: [NSImage imageNamed:hifiBackgroundFilename]]; [self.smallLogo setImage: [NSImage imageNamed:hifiSmallLogoFilename]]; [self.voxelImage setImage: [NSImage imageNamed:hifiVoxelFilename]]; + if (self.progressView != nil) { + [sharedLauncher setProgressView: self.progressView]; + } self.imageRotation = 0; - //[self.voxelImage setFrameCenterRotation:90]; - [NSTimer scheduledTimerWithTimeInterval:0.016 target:self selector:@selector(rotateView:)