mirror of https://github.com/perkeep/perkeep.git
Merge "Added an uploader progress view."
This commit is contained in:
commit
f676cc3374
|
@ -7,7 +7,7 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
D0180BEA185007C000E3487F /* credentials.plist in Resources */ = {isa = PBXBuildFile; fileRef = D0180BE9185007C000E3487F /* credentials.plist */; };
|
||||
D059B88F186944F2006BE899 /* ProgressViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D059B88E186944F2006BE899 /* ProgressViewController.m */; };
|
||||
D075B282184944330054FED3 /* LACamliUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = D075B281184944330054FED3 /* LACamliUtil.m */; };
|
||||
D075B28518494DB20054FED3 /* LACamliUploadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = D075B28418494DB20054FED3 /* LACamliUploadOperation.m */; };
|
||||
D095AE131814AF10008163F2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D095AE121814AF10008163F2 /* Foundation.framework */; };
|
||||
|
@ -43,7 +43,8 @@
|
|||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
D0180BE9185007C000E3487F /* credentials.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = credentials.plist; sourceTree = "<group>"; };
|
||||
D059B88D186944F2006BE899 /* ProgressViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProgressViewController.h; sourceTree = "<group>"; };
|
||||
D059B88E186944F2006BE899 /* ProgressViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProgressViewController.m; sourceTree = "<group>"; };
|
||||
D075B280184944330054FED3 /* LACamliUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LACamliUtil.h; sourceTree = "<group>"; };
|
||||
D075B281184944330054FED3 /* LACamliUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LACamliUtil.m; sourceTree = "<group>"; };
|
||||
D075B28318494DB20054FED3 /* LACamliUploadOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LACamliUploadOperation.h; sourceTree = "<group>"; };
|
||||
|
@ -146,11 +147,12 @@
|
|||
D0AC217018503A8E004BD4F3 /* CamliCollectionCell.m */,
|
||||
D0D45E9F185FE2BE00EBC0A2 /* SettingsViewController.h */,
|
||||
D0D45EA0185FE2BE00EBC0A2 /* SettingsViewController.m */,
|
||||
D059B88D186944F2006BE899 /* ProgressViewController.h */,
|
||||
D059B88E186944F2006BE899 /* ProgressViewController.m */,
|
||||
D095AE241814AF10008163F2 /* Main_iPhone.storyboard */,
|
||||
D095AE271814AF10008163F2 /* Main_iPad.storyboard */,
|
||||
D095AE2D1814AF10008163F2 /* Images.xcassets */,
|
||||
D095AE191814AF10008163F2 /* Supporting Files */,
|
||||
D0180BE9185007C000E3487F /* credentials.plist */,
|
||||
);
|
||||
path = photobackup;
|
||||
sourceTree = "<group>";
|
||||
|
@ -286,7 +288,6 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D095AE291814AF10008163F2 /* Main_iPad.storyboard in Resources */,
|
||||
D0180BEA185007C000E3487F /* credentials.plist in Resources */,
|
||||
D095AE2E1814AF10008163F2 /* Images.xcassets in Resources */,
|
||||
D095AE261814AF10008163F2 /* Main_iPhone.storyboard in Resources */,
|
||||
D095AE1D1814AF10008163F2 /* InfoPlist.strings in Resources */,
|
||||
|
@ -311,6 +312,7 @@
|
|||
D095AE1F1814AF10008163F2 /* main.m in Sources */,
|
||||
D095AE511814B1B9008163F2 /* LACamliClient.m in Sources */,
|
||||
D0AC217118503A8E004BD4F3 /* CamliCollectionCell.m in Sources */,
|
||||
D059B88F186944F2006BE899 /* ProgressViewController.m in Sources */,
|
||||
D095AE501814B1B9008163F2 /* LACamliFile.m in Sources */,
|
||||
D075B282184944330054FED3 /* LACamliUtil.m in Sources */,
|
||||
D095AE231814AF10008163F2 /* LAAppDelegate.m in Sources */,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="4514" systemVersion="13A598" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="SoI-nq-iat">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="4514" systemVersion="13B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="SoI-nq-iat">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
|
||||
</dependencies>
|
||||
|
@ -102,7 +102,7 @@
|
|||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<collectionView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" minimumZoomScale="0.0" maximumZoomScale="0.0" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="KRb-uW-c9w">
|
||||
<rect key="frame" x="0.0" y="109" width="320" height="459"/>
|
||||
<rect key="frame" x="0.0" y="65" width="320" height="503"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="Ruf-Wi-cOY">
|
||||
<size key="itemSize" width="100" height="100"/>
|
||||
|
@ -170,6 +170,46 @@
|
|||
</objects>
|
||||
<point key="canvasLocation" x="-50" y="112"/>
|
||||
</scene>
|
||||
<!--Progress View Controller-->
|
||||
<scene sceneID="kwd-3V-dLT">
|
||||
<objects>
|
||||
<viewController storyboardIdentifier="uploadBar" autoresizesArchivedViewToFullSize="NO" id="LJZ-RN-5bL" customClass="ProgressViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="ONX-4l-VhG"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="gTv-HF-xIn"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="W6C-gu-ahl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="60"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Uploading..." lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vPS-27-7Lj">
|
||||
<rect key="frame" x="14" y="13" width="286" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lXC-3o-YxX">
|
||||
<rect key="frame" x="14" y="46" width="286" height="2"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
</progressView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
|
||||
</view>
|
||||
<extendedEdge key="edgesForExtendedLayout"/>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="uploadLabel" destination="vPS-27-7Lj" id="PpL-8N-Py3"/>
|
||||
<outlet property="uploadProgress" destination="lXC-3o-YxX" id="hT7-gd-9XR"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="I8e-te-vX5" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="321" y="620"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
|
|
|
@ -23,7 +23,10 @@
|
|||
[self loadCredentials];
|
||||
|
||||
self.library = [[ALAssetsLibrary alloc] init];
|
||||
// TODO: request access to the library first
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:CamliNotificationUploadProgress object:nil queue:nil usingBlock:^(NSNotification *note) {
|
||||
[UIApplication sharedApplication].applicationIconBadgeNumber = [note.userInfo[@"remain"] intValue];
|
||||
}];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
@ -68,9 +71,7 @@
|
|||
|
||||
if (![weakSelf.client fileAlreadyUploaded:file]) {
|
||||
filesToUpload++;
|
||||
[weakSelf.client addFile:file withCompletion:^{
|
||||
[UIApplication sharedApplication].applicationIconBadgeNumber--;
|
||||
}];
|
||||
[weakSelf.client addFile:file withCompletion:nil];
|
||||
} else {
|
||||
LALog(@"file already uploaded: %@",file.blobRef);
|
||||
}
|
||||
|
|
|
@ -11,15 +11,20 @@
|
|||
|
||||
@interface LACamliClient : NSObject <NSURLSessionDelegate>
|
||||
|
||||
extern NSString *const CamliNotificationUploadStart;
|
||||
extern NSString *const CamliNotificationUploadProgress;
|
||||
extern NSString *const CamliNotificationUploadEnd;
|
||||
extern NSString *const CamliBlobRootComponent;
|
||||
|
||||
@property NSURLSession *session;
|
||||
|
||||
@property NSURL *serverURL;
|
||||
@property NSString *username;
|
||||
@property NSString *password;
|
||||
|
||||
@property NSString *blobRoot;
|
||||
@property NSURL *uploadUrl;
|
||||
@property NSOperationQueue *uploadQueue;
|
||||
@property NSUInteger totalUploads;
|
||||
|
||||
@property NSMutableArray *uploadedBlobRefs;
|
||||
@property UIBackgroundTaskIdentifier backgroundID;
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
|
||||
@implementation LACamliClient
|
||||
|
||||
NSString *const CamliNotificationUploadStart = @"camli-upload-start";
|
||||
NSString *const CamliNotificationUploadProgress = @"camli-upload-progress";
|
||||
NSString *const CamliNotificationUploadEnd = @"camli-upload-end";
|
||||
NSString *const CamliBlobRootComponent = @"bs-recv";
|
||||
|
||||
- (id)initWithServer:(NSURL *)server username:(NSString *)username andPassword:(NSString *)password
|
||||
{
|
||||
NSParameterAssert(server);
|
||||
|
@ -32,6 +37,7 @@
|
|||
|
||||
self.uploadQueue = [[NSOperationQueue alloc] init];
|
||||
self.uploadQueue.maxConcurrentOperationCount = 1;
|
||||
self.totalUploads = 0;
|
||||
|
||||
self.isAuthorized = false;
|
||||
self.authorizing = false;
|
||||
|
@ -63,7 +69,6 @@
|
|||
|
||||
#pragma mark - discovery
|
||||
|
||||
// if we don't have blobroot with which to make these requests, we need to find it first
|
||||
- (void)discoveryWithUsername:(NSString *)user andPassword:(NSString *)pass
|
||||
{
|
||||
self.authorizing = YES;
|
||||
|
@ -86,10 +91,6 @@
|
|||
if (res.statusCode != 200) {
|
||||
LALog(@"error with discovery: %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
|
||||
} else {
|
||||
NSError *parseError;
|
||||
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
|
||||
|
||||
self.blobRoot = json[@"blobRoot"];
|
||||
self.isAuthorized = YES;
|
||||
[self.uploadQueue setSuspended:NO];
|
||||
|
||||
|
@ -118,6 +119,12 @@
|
|||
- (void)addFile:(LACamliFile *)file withCompletion:(void (^)())completion
|
||||
{
|
||||
NSParameterAssert(file);
|
||||
|
||||
if (self.totalUploads == 0) {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:CamliNotificationUploadStart object:nil];
|
||||
}
|
||||
|
||||
self.totalUploads++;
|
||||
|
||||
if (![self isAuthorized]) {
|
||||
[self.uploadQueue setSuspended:YES];
|
||||
|
@ -133,7 +140,16 @@
|
|||
[self.uploadedBlobRefs addObject:file.blobRef];
|
||||
[self.uploadedBlobRefs writeToFile:[self uploadedBlobRefArchivePath] atomically:YES];
|
||||
|
||||
completion();
|
||||
// let others know about upload progress
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:CamliNotificationUploadProgress object:nil userInfo:@{@"total": @(self.totalUploads), @"remain": @([self.uploadQueue operationCount])}];
|
||||
|
||||
if (![self.uploadQueue operationCount]) {
|
||||
self.totalUploads = 0;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:CamliNotificationUploadEnd object:nil];
|
||||
}
|
||||
if (completion) {
|
||||
completion();
|
||||
}
|
||||
};
|
||||
|
||||
[self.uploadQueue addOperation:op];
|
||||
|
@ -141,7 +157,7 @@
|
|||
|
||||
- (NSURL *)statUrl
|
||||
{
|
||||
return [[self.serverURL URLByAppendingPathComponent:self.blobRoot] URLByAppendingPathComponent:@"camli/stat"];
|
||||
return [[self blobRoot] URLByAppendingPathComponent:@"camli/stat"];
|
||||
}
|
||||
|
||||
#pragma mark - getting stuff
|
||||
|
@ -173,6 +189,11 @@
|
|||
|
||||
#pragma mark - utility
|
||||
|
||||
- (NSURL *)blobRoot
|
||||
{
|
||||
return [self.serverURL URLByAppendingPathComponent:CamliBlobRootComponent];
|
||||
}
|
||||
|
||||
- (NSString *)encodedAuth
|
||||
{
|
||||
NSString *auth = [NSString stringWithFormat:@"%@:%@",self.username,self.password];
|
||||
|
|
|
@ -64,7 +64,7 @@ static NSString *const multipartBoundary = @"Qe43VdbVVaGtkkMd";
|
|||
for (NSString *key in params) {
|
||||
formValues = [formValues stringByAppendingString:[NSString stringWithFormat:@"%@=%@&",key,params[key]]];
|
||||
}
|
||||
|
||||
|
||||
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[self.client statUrl]];
|
||||
[req setHTTPMethod:@"POST"];
|
||||
[req setHTTPBody:[formValues dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class LACamliClient;
|
||||
@class LACamliClient,ProgressViewController;
|
||||
|
||||
@interface LAViewController : UIViewController
|
||||
|
||||
@property LACamliClient *client;
|
||||
@property ProgressViewController *progress;
|
||||
|
||||
- (void)dismissSettings;
|
||||
|
||||
|
|
|
@ -11,10 +11,7 @@
|
|||
#import "LAAppDelegate.h"
|
||||
#import "LACamliUtil.h"
|
||||
#import "SettingsViewController.h"
|
||||
|
||||
@interface LAViewController ()
|
||||
|
||||
@end
|
||||
#import "ProgressViewController.h"
|
||||
|
||||
@implementation LAViewController
|
||||
|
||||
|
@ -26,7 +23,6 @@
|
|||
|
||||
[self.navigationItem setRightBarButtonItem:settingsItem];
|
||||
|
||||
// show the
|
||||
NSURL *serverURL = [NSURL URLWithString:[[NSUserDefaults standardUserDefaults] stringForKey:CamliServerKey]];
|
||||
NSString *username = [[NSUserDefaults standardUserDefaults] stringForKey:CamliUsernameKey];
|
||||
|
||||
|
@ -39,6 +35,41 @@
|
|||
[self showSettings];
|
||||
}
|
||||
|
||||
self.progress = [[self storyboard] instantiateViewControllerWithIdentifier:@"uploadBar"];
|
||||
self.progress.view.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height+self.progress.view.frame.size.height, self.progress.view.frame.size.width, self.progress.view.frame.size.height);
|
||||
|
||||
[self.view addSubview:self.progress.view];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:CamliNotificationUploadStart object:nil queue:nil usingBlock:^(NSNotification *note) {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[UIView animateWithDuration:1.0 animations:^{
|
||||
self.progress.view.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height-self.progress.view.frame.size.height, self.progress.view.frame.size.width, self.progress.view.frame.size.height);
|
||||
}];
|
||||
});
|
||||
}];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:CamliNotificationUploadProgress object:nil queue:nil usingBlock:^(NSNotification *note) {
|
||||
LALog(@"got progress %@ %@",note.userInfo[@"total"],note.userInfo[@"remain"]);
|
||||
|
||||
NSUInteger total = [note.userInfo[@"total"] intValue];
|
||||
NSUInteger remain = [note.userInfo[@"remain"] intValue];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.progress.uploadLabel.text = [NSString stringWithFormat:@"Uploading %d of %d",total-remain,total];
|
||||
self.progress.uploadProgress.progress = (float)(total-remain)/(float)total;
|
||||
});
|
||||
}];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:CamliNotificationUploadEnd object:nil queue:nil usingBlock:^(NSNotification *note) {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[UIView animateWithDuration:1.0 animations:^{
|
||||
self.progress.view.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height+self.progress.view.frame.size.height, self.progress.view.frame.size.width, self.progress.view.frame.size.height);
|
||||
}];
|
||||
});
|
||||
}];
|
||||
|
||||
// [self.client getRecentItemsWithCompletion:^(NSArray *objects) {
|
||||
// LALog(@"got objects: %@",objects);
|
||||
// }];
|
||||
|
@ -86,4 +117,9 @@
|
|||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// ProgressViewController.h
|
||||
// photobackup
|
||||
//
|
||||
// Created by Nick O'Neill on 12/23/13.
|
||||
// Copyright (c) 2013 The Camlistore Authors. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ProgressViewController : UIViewController
|
||||
|
||||
@property IBOutlet UILabel *uploadLabel;
|
||||
@property IBOutlet UIProgressView *uploadProgress;
|
||||
|
||||
@end
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// ProgressViewController.m
|
||||
// photobackup
|
||||
//
|
||||
// Created by Nick O'Neill on 12/23/13.
|
||||
// Copyright (c) 2013 The Camlistore Authors. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ProgressViewController.h"
|
||||
|
||||
@implementation ProgressViewController
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning
|
||||
{
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
@end
|
Loading…
Reference in New Issue