Merge pull request #15900 from danteruiz/launcher-progress-indicator

DEV-180: Lilypad Launcher: (Mac) Launcher progress indicator
This commit is contained in:
Shannon Romano 2019-07-09 17:53:39 -07:00 committed by GitHub
commit fcd29d686b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 280 additions and 60 deletions

View file

@ -22,12 +22,12 @@
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="Abr-HV-cKq"/>
</imageView>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Nrc-t3-PSh">
<rect key="frame" x="192" y="190" width="131" height="112"/>
<rect key="frame" x="192" y="235" width="131" height="112"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="LNv-HQ-3gb"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="EMF-E4-qLL">
<rect key="frame" x="30" y="109" width="454" height="41"/>
<rect key="frame" x="30" y="161" width="454" height="41"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Setup will take a moment" id="y9y-tH-HjJ">
<font key="font" metaFont="systemBold" size="28"/>
@ -36,7 +36,7 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="BSg-lp-njL">
<rect key="frame" x="33" y="84" width="448" height="17"/>
<rect key="frame" x="33" y="136" width="448" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="We're getting your headquaters ready" id="HeV-5p-9FI">
<font key="font" metaFont="system"/>
@ -49,6 +49,10 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="6NP-7q-Mhj"/>
</imageView>
<progressIndicator wantsLayer="YES" fixedFrame="YES" maxValue="100" doubleValue="50" style="bar" translatesAutoresizingMaskIntoConstraints="NO" id="aEr-fi-fkV">
<rect key="frame" x="68" y="78" width="394" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</progressIndicator>
</subviews>
<point key="canvasLocation" x="138.5" y="154"/>
</customView>
@ -56,6 +60,7 @@
<connections>
<outlet property="background" destination="kuY-e2-Hqb" id="CBc-bD-ux7"/>
<outlet property="boldStatus" destination="EMF-E4-qLL" id="udm-8B-7lt"/>
<outlet property="progressView" destination="aEr-fi-fkV" id="OUy-Qp-tiP"/>
<outlet property="smallLogo" destination="uh2-4K-n56" id="pYg-hP-nr5"/>
<outlet property="smallStatus" destination="BSg-lp-njL" id="ziz-ek-Lq4"/>
<outlet property="voxelImage" destination="Nrc-t3-PSh" id="J81-ex-qbE"/>

View file

@ -25,6 +25,6 @@ extern NSString* hifiBackgroundFilename;
@end
@interface Hyperlink : NSTextField {
}
@end

View file

@ -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];
}

View file

@ -2,7 +2,10 @@
@interface DownloadDomainContent : NSObject<NSURLSessionDataDelegate, NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLDownloadDelegate> {
}
@property (nonatomic, assign) double progressPercentage;
@property (nonatomic, assign) double taskProgressPercentage;
- (void) downloadDomainContent:(NSString*) domainContentUrl;
- (double) getProgressPercentage;
@end

View file

@ -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

View file

@ -3,6 +3,10 @@
@interface DownloadInterface : NSObject<NSURLSessionDataDelegate, NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLDownloadDelegate> {
}
@property (nonatomic, assign) NSString* finalFilePath;
@property (nonatomic, assign) double progressPercentage;
@property (nonatomic, assign) double taskProgressPercentage;
- (void) downloadInterface:(NSString*) downloadUrl;
- (double) getProgressPercentage;
@end

View file

@ -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

View file

@ -20,7 +20,7 @@
-(IBAction)resartLauncher:(id)sender
{
[[Launcher sharedLauncher] showLoginScreen];
[[Launcher sharedLauncher] restart];
}
@end

View file

@ -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];

View file

@ -21,6 +21,12 @@ typedef enum LoginErrorTypes
CREDENTIALS
} LoginError;
struct LatestBuildInfo {
NSString* downloadURL;
BOOL shouldDownload;
BOOL requestBuildFinished;
};
@interface Launcher : NSObject <NSApplicationDelegate, NSWindowDelegate, NSURLDownloadDelegate> {
}
@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

View file

@ -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

View file

@ -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:)];
}

View file

@ -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:)