mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge pull request #15900 from danteruiz/launcher-progress-indicator
DEV-180: Lilypad Launcher: (Mac) Launcher progress indicator
This commit is contained in:
commit
fcd29d686b
13 changed files with 280 additions and 60 deletions
|
@ -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"/>
|
||||
|
|
|
@ -25,6 +25,6 @@ extern NSString* hifiBackgroundFilename;
|
|||
@end
|
||||
|
||||
@interface Hyperlink : NSTextField {
|
||||
|
||||
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
-(IBAction)resartLauncher:(id)sender
|
||||
{
|
||||
[[Launcher sharedLauncher] showLoginScreen];
|
||||
[[Launcher sharedLauncher] restart];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:)];
|
||||
}
|
||||
|
|
|
@ -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:)
|
||||
|
|
Loading…
Reference in a new issue