download manager improvements

- better dark mode support
- open roms button
- refresh button
- UI to specify file location and file extension
- check for 404, etc errors which aren't auto converted to an NSError.
This commit is contained in:
Kelvin Sherlock 2020-10-04 00:16:32 -04:00
parent f9d4489e48
commit d06bf9b1d6
2 changed files with 115 additions and 42 deletions

View File

@ -154,7 +154,7 @@
</connections>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Fhd-vr-Q2G">
<rect key="frame" x="20" y="19" width="124" height="23"/>
<rect key="frame" x="192" y="18" width="124" height="23"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<buttonCell key="cell" type="roundTextured" title="Download Missing" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="AKx-eg-iLS">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -169,6 +169,52 @@
</binding>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d2z-4T-Wh1">
<rect key="frame" x="10" y="104" width="30" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="URL" id="lcZ-R4-WsS">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZXO-bJ-btp">
<rect key="frame" x="10" y="66" width="34" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Type" id="KGI-t9-OMF">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="AuM-pD-Gul">
<rect key="frame" x="12" y="52" width="368" height="5"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
</box>
<button verticalHuggingPriority="750" fixedFrame="YES" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dpY-qZ-2Nk">
<rect key="frame" x="90" y="13" width="100" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="ROMs" bezelStyle="rounded" image="NSFolder" imagePosition="leading" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="E0t-sX-rgE">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showRomFolder:" target="-2" id="bys-Vs-b4m"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Lnv-mh-zAr">
<rect key="frame" x="6" y="13" width="87" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Refresh" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="mYS-h7-GUa">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent">r</string>
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</buttonCell>
<connections>
<action selector="refreshROMs:" target="-2" id="E7j-Fa-IN1"/>
</connections>
</button>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2Rg-eX-DUq">
<rect key="frame" x="49" y="60" width="98" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
@ -191,28 +237,6 @@
</binding>
</connections>
</popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d2z-4T-Wh1">
<rect key="frame" x="10" y="104" width="30" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="URL" id="lcZ-R4-WsS">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZXO-bJ-btp">
<rect key="frame" x="11" y="66" width="34" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Type" id="KGI-t9-OMF">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="AuM-pD-Gul">
<rect key="frame" x="12" y="52" width="368" height="5"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
</box>
</subviews>
</view>
<connections>
@ -248,4 +272,7 @@
</menu>
<userDefaultsController representsSharedInstance="YES" id="721-9N-Bma"/>
</objects>
<resources>
<image name="NSFolder" width="32" height="32"/>
</resources>
</document>

View File

@ -177,7 +177,6 @@ enum {
NSDictionary *d = [NSDictionary dictionaryWithContentsOfURL: url];
NSURL *sd = SupportDirectory();
NSString *romdir = [SupportDirectoryPath() stringByAppendingPathComponent: @"roms"];
_romFolder = [sd URLByAppendingPathComponent: @"roms"];
@ -215,26 +214,11 @@ enum {
[item setIndex: ix++];
[tmp addObject: item];
// check if the file exists.
NSString *s = [romdir stringByAppendingPathComponent: name];
NSString *path;
path = [s stringByAppendingPathExtension: @"zip"];
if ([fm fileExistsAtPath: path]) {
[item setStatus: ItemFound];
[item setLocalURL: [NSURL fileURLWithPath: path]];
continue;
}
path = [s stringByAppendingPathExtension: @"7z"];
if ([fm fileExistsAtPath: path]) {
[item setStatus: ItemFound];
[item setLocalURL: [NSURL fileURLWithPath: path]];
continue;
}
}
_items = tmp;
[self refreshROMs: nil];
//[_tableView reloadData];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
_session = [NSURLSession sessionWithConfiguration: config delegate: self delegateQueue: nil];
_taskIndex = [NSMutableDictionary dictionaryWithCapacity: [_items count]];
@ -242,6 +226,8 @@ enum {
//[self download];
}
#if 0
-(void)validateURL: (NSString *)url {
NSURL *v;
@ -385,6 +371,40 @@ enum {
[_tableView reloadData];
}
}
- (IBAction)showRomFolder:(id)sender {
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
[ws openURL: _romFolder];
}
-(IBAction)refreshROMs: (id)sender {
NSString *romdir = [SupportDirectoryPath() stringByAppendingPathComponent: @"roms"];
NSFileManager *fm = [NSFileManager defaultManager];
for (DownloadItem *item in _items) {
NSString *name = [item name];
NSString *s = [romdir stringByAppendingPathComponent: name];
NSString *path;
path = [s stringByAppendingPathExtension: @"zip"];
if ([fm fileExistsAtPath: path]) {
[item setStatus: ItemFound];
[item setLocalURL: [NSURL fileURLWithPath: path]];
continue;
}
path = [s stringByAppendingPathExtension: @"7z"];
if ([fm fileExistsAtPath: path]) {
[item setStatus: ItemFound];
[item setLocalURL: [NSURL fileURLWithPath: path]];
continue;
}
}
// only needed if items aren't bound.
[_tableView reloadData];
}
- (IBAction)showInFinder:(id)sender {
DownloadItem *item = [self clickedItem];
@ -431,11 +451,31 @@ enum {
#pragma mark - NSURLSessionDelegate
static NSInteger TaskStatusCode(NSURLSessionTask *task) {
NSURLResponse *response = [task response];
if ([response isKindOfClass: [NSHTTPURLResponse class]]) {
return [(NSHTTPURLResponse *)response statusCode];
}
return -1;
}
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
if (error) NSLog(@"Download error: %@", error);
NSInteger statusCode = TaskStatusCode(task);
if (!error && statusCode != 200) {
// treat as an error.
NSDictionary *info = @{
NSURLErrorKey: [[task originalRequest] URL],
NSLocalizedDescriptionKey: [NSHTTPURLResponse localizedStringForStatusCode: statusCode],
};
error = [NSError errorWithDomain: NSURLErrorDomain code: NSURLErrorFileDoesNotExist userInfo: info];
}
// not sure if strictly necessary but this happens in a background thread
// and these are used in KVO binding. Also, main thread only
// means no race conditions.
@ -465,7 +505,13 @@ enum {
- (void)URLSession:(NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)task didFinishDownloadingToURL:(nonnull NSURL *)location {
// NSLog(@"%@", task);
// NSLog(@"%@", [task response]);
if (TaskStatusCode(task) != 200) return;
// need to move to the destination directory...
// file deleted after this function returns, so can't move asynchronously.
NSFileManager *fm = [NSFileManager defaultManager];
@ -585,7 +631,7 @@ enum {
@"Canceled",
@"Error"
};
if (_error) return [_error description];
if (_error) return [_error localizedDescription];
if (_status > sizeof(Names)/sizeof(Names[0])) return @"Unknown";
return Names[_status];