Progress towards in-launcher download ui. Works, but is very fragile.
This commit is contained in:
@@ -8,14 +8,6 @@
|
|||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
Initializing,
|
|
||||||
Downloading,
|
|
||||||
Complete,
|
|
||||||
Cancelled,
|
|
||||||
Error
|
|
||||||
} DownloadStatus;
|
|
||||||
|
|
||||||
@class GameInstall;
|
@class GameInstall;
|
||||||
@interface Download : NSObject
|
@interface Download : NSObject
|
||||||
{
|
{
|
||||||
@@ -24,12 +16,12 @@ typedef enum {
|
|||||||
NSString *filename;
|
NSString *filename;
|
||||||
GameInstall *game;
|
GameInstall *game;
|
||||||
NSTask *task;
|
NSTask *task;
|
||||||
DownloadStatus status;
|
NSString * status;
|
||||||
int bytesCompleted;
|
int bytesCompleted;
|
||||||
int bytesTotal;
|
int bytesTotal;
|
||||||
}
|
}
|
||||||
@property(readonly) NSString *key;
|
@property(readonly) NSString *key;
|
||||||
@property(readonly) DownloadStatus status;
|
@property(readonly) NSString *status;
|
||||||
@property(readonly) int bytesCompleted;
|
@property(readonly) int bytesCompleted;
|
||||||
@property(readonly) int bytesTotal;
|
@property(readonly) int bytesTotal;
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
filename = [aFilename retain];
|
filename = [aFilename retain];
|
||||||
key = [aKey retain];
|
key = [aKey retain];
|
||||||
game = [aGame retain];
|
game = [aGame retain];
|
||||||
status = Initializing;
|
status = @"Initializing";
|
||||||
bytesCompleted = -1;
|
bytesCompleted = -1;
|
||||||
bytesTotal = -1;
|
bytesTotal = -1;
|
||||||
|
|
||||||
@@ -65,17 +65,17 @@
|
|||||||
|
|
||||||
if ([type isEqualToString:@"Error"])
|
if ([type isEqualToString:@"Error"])
|
||||||
{
|
{
|
||||||
status = Error;
|
status = @"Error";
|
||||||
}
|
}
|
||||||
else if ([type isEqualToString:@"Status"])
|
else if ([type isEqualToString:@"Status"])
|
||||||
{
|
{
|
||||||
if ([message isEqualToString:@"Initializing"])
|
if ([message isEqualToString:@"Initializing"])
|
||||||
{
|
{
|
||||||
status = Initializing;
|
status = @"Initializing";
|
||||||
}
|
}
|
||||||
else if ([message isEqualToString:@"Completed"])
|
else if ([message isEqualToString:@"Completed"])
|
||||||
{
|
{
|
||||||
status = Complete;
|
status = @"Complete";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse download status info
|
// Parse download status info
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
- (void)cancel
|
- (void)cancel
|
||||||
{
|
{
|
||||||
NSLog(@"Cancelling");
|
NSLog(@"Cancelling");
|
||||||
status = Cancelled;
|
status = @"Cancelled";
|
||||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||||
[nc removeObserver:self name:NSFileHandleReadCompletionNotification object:[[task standardOutput] fileHandleForReading]];
|
[nc removeObserver:self name:NSFileHandleReadCompletionNotification object:[[task standardOutput] fileHandleForReading]];
|
||||||
[nc removeObserver:self name:NSTaskDidTerminateNotification object:task];
|
[nc removeObserver:self name:NSTaskDidTerminateNotification object:task];
|
||||||
|
|||||||
@@ -42,13 +42,13 @@ static JSBridge *SharedInstance;
|
|||||||
methods = [[NSDictionary dictionaryWithObjectsAndKeys:
|
methods = [[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
@"launchMod", NSStringFromSelector(@selector(launchMod:)),
|
@"launchMod", NSStringFromSelector(@selector(launchMod:)),
|
||||||
@"log", NSStringFromSelector(@selector(log:)),
|
@"log", NSStringFromSelector(@selector(log:)),
|
||||||
@"existsInMod", NSStringFromSelector(@selector(exists:inMod:)),
|
@"existsInMod", NSStringFromSelector(@selector(fileExists:inMod:)),
|
||||||
|
|
||||||
// File downloading
|
// File downloading
|
||||||
@"existsInCache", NSStringFromSelector(@selector(existsInCache:)),
|
@"existsInCache", NSStringFromSelector(@selector(existsInCache:)),
|
||||||
@"downloadToCache", NSStringFromSelector(@selector(downloadUrl:withName:key:)),
|
@"downloadToCache", NSStringFromSelector(@selector(downloadUrl:withName:key:)),
|
||||||
@"cancelDownload", NSStringFromSelector(@selector(cancelDownload:)),
|
@"cancelDownload", NSStringFromSelector(@selector(cancelDownload:)),
|
||||||
@"isDownloading", NSStringFromSelector(@selector(isDownloading:)),
|
@"downloadStatus", NSStringFromSelector(@selector(downloadStatus:)),
|
||||||
@"bytesCompleted", NSStringFromSelector(@selector(bytesCompleted:)),
|
@"bytesCompleted", NSStringFromSelector(@selector(bytesCompleted:)),
|
||||||
@"bytesTotal", NSStringFromSelector(@selector(bytesTotal:)),
|
@"bytesTotal", NSStringFromSelector(@selector(bytesTotal:)),
|
||||||
nil] retain];
|
nil] retain];
|
||||||
@@ -124,9 +124,13 @@ static JSBridge *SharedInstance;
|
|||||||
[controller cancelDownload:key];
|
[controller cancelDownload:key];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isDownloading:(NSString *)key
|
- (NSString *)downloadStatus:(NSString *)key
|
||||||
{
|
{
|
||||||
return [controller downloadWithKey:key] != nil;
|
Download *d = [controller downloadWithKey:key];
|
||||||
|
if (d == nil)
|
||||||
|
return @"Invalid";
|
||||||
|
|
||||||
|
return [d status];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int)bytesCompleted:(NSString *)key
|
- (int)bytesCompleted:(NSString *)key
|
||||||
|
|||||||
@@ -90,10 +90,9 @@
|
|||||||
// Returns 2 if basic files plus music are installed
|
// Returns 2 if basic files plus music are installed
|
||||||
function packagesInstalled()
|
function packagesInstalled()
|
||||||
{
|
{
|
||||||
if (window.external.existsInMod('packages/conquer.mix','cnc') != 1)
|
if (window.external.existsInMod("packages/conquer.mix","cnc") != 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
return (window.external.existsInMod("packages/scores.mix","cnc") == 1) ? 2 : 1;
|
||||||
return (window.external.existsInMod('packages/scores.mix','cnc') == 1) ? 2 : 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function play()
|
function play()
|
||||||
@@ -101,39 +100,71 @@
|
|||||||
window.external.launchMod("cnc");
|
window.external.launchMod("cnc");
|
||||||
}
|
}
|
||||||
|
|
||||||
function download1()
|
function download()
|
||||||
{
|
{
|
||||||
window.external.downloadToCache("http://localhost/~paul/cnc-packages.zip","test.zip","cnc-packages");
|
window.external.downloadToCache("http://localhost/~paul/cnc-packages.zip","cnc-packages.zip","cnc-packages");
|
||||||
|
document.getElementById("install-download").style.display = "none";
|
||||||
|
document.getElementById("install-downloading").style.display = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function download2()
|
function cancel()
|
||||||
{
|
|
||||||
window.external.downloadToCache("http://localhost/~paul/ra-packages.zip","test2.zip","ra-packages");
|
|
||||||
}
|
|
||||||
|
|
||||||
function cancel1()
|
|
||||||
{
|
{
|
||||||
window.external.cancelDownload("cnc-packages");
|
window.external.cancelDownload("cnc-packages");
|
||||||
|
// TODO: Remove incomplete file from cache
|
||||||
|
// TODO: Restore buttons to the before-downloading state
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancel2()
|
function extract()
|
||||||
{
|
{
|
||||||
window.external.cancelDownload("ra-packages");
|
window.external.log("Todo: Extract package");
|
||||||
}
|
}
|
||||||
|
|
||||||
function onLoad()
|
function onLoad()
|
||||||
{
|
{
|
||||||
document.getElementById("buttons-install").style.display = (packagesInstalled() == 0) ? "" : "none";
|
var installed = packagesInstalled();
|
||||||
document.getElementById("buttons-upgrade").style.display = (packagesInstalled() == 1) ? "" : "none";
|
document.getElementById("buttons-install").style.display = (installed == 0) ? "" : "none";
|
||||||
document.getElementById("buttons-play").style.display = (packagesInstalled() == 2) ? "" : "none";
|
document.getElementById("buttons-upgrade").style.display = (installed == 1) ? "" : "none";
|
||||||
|
document.getElementById("buttons-play").style.display = (installed == 2) ? "" : "none";
|
||||||
|
|
||||||
|
window.external.log("installed: "+installed);
|
||||||
|
// Select the correct subsection
|
||||||
|
if (installed == 0)
|
||||||
|
{
|
||||||
|
var downloaded = window.external.existsInCache("cnc-packages.zip");
|
||||||
|
window.external.log("downloaded: "+downloaded);
|
||||||
|
document.getElementById("install-extract").style.display = downloaded ? "" : "none";
|
||||||
|
document.getElementById("install-download").style.display = !downloaded ? "" : "none";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function downloadProgressed(file)
|
function downloadProgressed(file)
|
||||||
{
|
{
|
||||||
var total = window.external.bytesTotal(file);
|
if (file != "cnc-packages")
|
||||||
var downloaded = window.external.bytesCompleted(file);
|
return;
|
||||||
var percent = (100*downloaded/total).toPrecision(3);
|
|
||||||
window.external.log("file: "+file+" "+downloaded+"/"+total+" ("+percent+"%)");
|
var status = window.external.downloadStatus(file);
|
||||||
|
if (status == "Complete")
|
||||||
|
{
|
||||||
|
document.getElementById("install-extract").style.display = "";
|
||||||
|
document.getElementById("install-downloading").style.display = "none";
|
||||||
|
}
|
||||||
|
var total = window.external.bytesTotal(file);
|
||||||
|
var downloaded = window.external.bytesCompleted(file);
|
||||||
|
|
||||||
|
var multiplier = 1/1024.0;
|
||||||
|
var unit = "kB";
|
||||||
|
|
||||||
|
var max = max(total,downloaded); // total may be -1 if the server doesn't supply a size
|
||||||
|
if (max > 1.1*1024*1024)
|
||||||
|
{
|
||||||
|
multiplier /= 1024;
|
||||||
|
unit = "MB";
|
||||||
|
}
|
||||||
|
total = (total*multiplier).toPrecision(2);
|
||||||
|
downloaded = (downloaded*multiplier).toPrecision(2);
|
||||||
|
|
||||||
|
document.getElementById("download-status").value = downloaded+"/"+total+" "+unit;
|
||||||
|
window.external.log("file: "+file+" "+downloaded+"/"+total+" ("+percent+"%)");
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -144,7 +175,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="main">
|
<div id="main">
|
||||||
<div id="content">
|
<!-- div id="content">
|
||||||
<h2>Latest News</h2>
|
<h2>Latest News</h2>
|
||||||
<div>
|
<div>
|
||||||
<h3>Version XXYYZZ Available</h3>
|
<h3>Version XXYYZZ Available</h3>
|
||||||
@@ -154,17 +185,21 @@
|
|||||||
<li>Bugfixes!!!</li>
|
<li>Bugfixes!!!</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div -->
|
||||||
<div id="buttons-install" class="buttons">
|
<div id="buttons-install" class="buttons">
|
||||||
<div class="desc">The original game data is required before you can play this mod.<br />
|
<div class="desc">The original game data is required before you can play this mod.<br />
|
||||||
Installing from web will install the minimal files required to play.<br />
|
Installing from web will install the minimal files required to play.
|
||||||
Installing from CD will also install the music and movie files for an improved game experience.
|
</div>
|
||||||
|
<div id="install-download">
|
||||||
|
<input type="button" class="button" onclick="download();" value="Download" />
|
||||||
|
</div>
|
||||||
|
<div id="install-downloading" style="display:none">
|
||||||
|
<input type="button" class="button" id="download-status" value="Initializing..." />
|
||||||
|
<input type="button" class="button" onclick="cancel();" value="Cancel" />
|
||||||
|
</div>
|
||||||
|
<div id="install-extract">
|
||||||
|
<input type="button" class="button" onclick="install();" value="Install" />
|
||||||
</div>
|
</div>
|
||||||
<input type="button" class="button" onclick="download1();" value="Download1" />
|
|
||||||
<input type="button" class="button" onclick="cancel1();" value="Cancel1" />
|
|
||||||
<input type="button" class="button" onclick="download2();" value="Download2" />
|
|
||||||
<input type="button" class="button" onclick="cancel2();" value="Cancel2" />
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div id="buttons-upgrade" class="buttons" style="display:none">
|
<div id="buttons-upgrade" class="buttons" style="display:none">
|
||||||
<div class="desc">
|
<div class="desc">
|
||||||
|
|||||||
Reference in New Issue
Block a user