|
@@ -15,37 +15,49 @@
|
|
|
#import "VLCBoxController.h"
|
|
|
#import <SSKeychain/SSKeychain.h>
|
|
|
#import "UIDevice+VLC.h"
|
|
|
+#import "VLCPlaybackController.h"
|
|
|
|
|
|
#if TARGET_OS_IOS
|
|
|
-@interface VLCBoxTableViewController () <VLCCloudStorageTableViewCell, BoxAuthorizationViewControllerDelegate, VLCCloudStorageDelegate>
|
|
|
+@interface VLCBoxTableViewController () <VLCCloudStorageTableViewCell, BoxAuthorizationViewControllerDelegate, VLCCloudStorageDelegate, NSURLConnectionDataDelegate>
|
|
|
#else
|
|
|
-@interface VLCBoxTableViewController () <VLCCloudStorageTableViewCell, VLCCloudStorageDelegate>
|
|
|
+@interface VLCBoxTableViewController () <VLCCloudStorageTableViewCell, VLCCloudStorageDelegate, NSURLConnectionDataDelegate>
|
|
|
#endif
|
|
|
{
|
|
|
BoxFile *_selectedFile;
|
|
|
VLCBoxController *_boxController;
|
|
|
+ NSArray *_listOfFiles;
|
|
|
}
|
|
|
|
|
|
@end
|
|
|
|
|
|
@implementation VLCBoxTableViewController
|
|
|
|
|
|
+- (instancetype)initWithPath:(NSString *)path
|
|
|
+{
|
|
|
+ self = [super init];
|
|
|
+ if (self) {
|
|
|
+ self.currentPath = path;
|
|
|
+ }
|
|
|
+ return self;
|
|
|
+}
|
|
|
+
|
|
|
- (void)viewDidLoad
|
|
|
{
|
|
|
[super viewDidLoad];
|
|
|
|
|
|
- _boxController = (VLCBoxController *)[VLCBoxController sharedInstance];
|
|
|
- [_boxController startSession];
|
|
|
+ _boxController = [VLCBoxController sharedInstance];
|
|
|
self.controller = _boxController;
|
|
|
self.controller.delegate = self;
|
|
|
|
|
|
+#if TARGET_OS_IOS
|
|
|
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Box"]];
|
|
|
|
|
|
-#if TARGET_OS_IOS
|
|
|
[self.cloudStorageLogo setImage:[UIImage imageNamed:@"Box"]];
|
|
|
|
|
|
[self.cloudStorageLogo sizeToFit];
|
|
|
self.cloudStorageLogo.center = self.view.center;
|
|
|
+#else
|
|
|
+ self.title = @"Box";
|
|
|
#endif
|
|
|
|
|
|
// Handle logged in
|
|
@@ -93,8 +105,12 @@
|
|
|
- (void)viewWillAppear:(BOOL)animated
|
|
|
{
|
|
|
[super viewWillAppear:animated];
|
|
|
- self.currentPath = @"";
|
|
|
- if([_boxController.currentListFiles count] == 0)
|
|
|
+
|
|
|
+ _boxController = [VLCBoxController sharedInstance];
|
|
|
+ self.controller = _boxController;
|
|
|
+ self.controller.delegate = self;
|
|
|
+
|
|
|
+ if (!_listOfFiles || _listOfFiles.count == 0)
|
|
|
[self requestInformationForCurrentPath];
|
|
|
}
|
|
|
|
|
@@ -109,6 +125,12 @@
|
|
|
|
|
|
#pragma mark - Table view data source
|
|
|
|
|
|
+- (void)mediaListUpdated
|
|
|
+{
|
|
|
+ _listOfFiles = [[VLCBoxController sharedInstance].currentListFiles copy];
|
|
|
+ [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
|
|
|
+}
|
|
|
+
|
|
|
- (VLCCloudStorageTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
|
|
{
|
|
|
static NSString *CellIdentifier = @"BoxCell";
|
|
@@ -117,37 +139,102 @@
|
|
|
if (cell == nil)
|
|
|
cell = [VLCCloudStorageTableViewCell cellWithReuseIdentifier:CellIdentifier];
|
|
|
|
|
|
- cell.boxFile = _boxController.currentListFiles[indexPath.row];
|
|
|
- cell.delegate = self;
|
|
|
+ NSUInteger index = indexPath.row;
|
|
|
+ if (_listOfFiles) {
|
|
|
+ if (index < _listOfFiles.count) {
|
|
|
+ cell.boxFile = _listOfFiles[index];
|
|
|
+ cell.delegate = self;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
return cell;
|
|
|
}
|
|
|
|
|
|
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
|
|
+{
|
|
|
+ return _listOfFiles.count;
|
|
|
+}
|
|
|
+
|
|
|
#pragma mark - Table view delegate
|
|
|
|
|
|
|
|
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
|
|
{
|
|
|
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
|
|
|
- if (indexPath.row >= _boxController.currentListFiles.count)
|
|
|
+ if (indexPath.row >= _listOfFiles.count)
|
|
|
return;
|
|
|
|
|
|
- _selectedFile = _boxController.currentListFiles[indexPath.row];
|
|
|
+ _selectedFile = _listOfFiles[indexPath.row];
|
|
|
if (![_selectedFile.type isEqualToString:@"folder"])
|
|
|
- [_boxController streamFile:(BoxFile *)_selectedFile];
|
|
|
+ [self streamFile:(BoxFile *)_selectedFile];
|
|
|
else {
|
|
|
/* dive into subdirectory */
|
|
|
- if (![self.currentPath isEqualToString:@""])
|
|
|
- self.currentPath = [self.currentPath stringByAppendingString:@"/"];
|
|
|
- self.currentPath = [self.currentPath stringByAppendingString:_selectedFile.modelID];
|
|
|
+ NSString *path = self.currentPath;
|
|
|
+ if (![path isEqualToString:@""])
|
|
|
+ path = [path stringByAppendingString:@"/"];
|
|
|
+ path = [path stringByAppendingString:_selectedFile.modelID];
|
|
|
+
|
|
|
+#if TARGET_OS_TV
|
|
|
+ VLCBoxTableViewController *targetViewController = [[VLCBoxTableViewController alloc] initWithPath:path];
|
|
|
+ [self.navigationController pushViewController:targetViewController animated:YES];
|
|
|
+#else
|
|
|
+ self.currentPath = path;
|
|
|
[self requestInformationForCurrentPath];
|
|
|
+#endif
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+- (void)streamFile:(BoxFile *)file
|
|
|
+{
|
|
|
+ /* the Box API requires us to set an HTTP header to get the actual URL:
|
|
|
+ * curl -L https://api.box.com/2.0/files/FILE_ID/content -H "Authorization: Bearer ACCESS_TOKEN"
|
|
|
+ *
|
|
|
+ * ... however, libvlc does not support setting custom HTTP headers, so we are resolving the redirect ourselves with a NSURLConnection
|
|
|
+ * and pass the final location to libvlc, which does not require a custom HTTP header */
|
|
|
+
|
|
|
+ NSURL *baseURL = [[[BoxSDK sharedSDK] filesManager] URLWithResource:@"files"
|
|
|
+ ID:file.modelID
|
|
|
+ subresource:@"content"
|
|
|
+ subID:nil];
|
|
|
+
|
|
|
+ NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:baseURL
|
|
|
+ cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
|
|
|
+ timeoutInterval:60];
|
|
|
+
|
|
|
+ [urlRequest setValue:[NSString stringWithFormat:@"Bearer %@", [BoxSDK sharedSDK].OAuth2Session.accessToken] forHTTPHeaderField:@"Authorization"];
|
|
|
+
|
|
|
+ NSURLConnection *theTestConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
|
|
|
+ [theTestConnection start];
|
|
|
+}
|
|
|
+
|
|
|
+- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response
|
|
|
+{
|
|
|
+ if (response != nil) {
|
|
|
+ /* we have 1 redirect from the original URL, so as soon as we'd do that,
|
|
|
+ * we grab the URL and cancel the connection */
|
|
|
+ NSURL *theActualURL = request.URL;
|
|
|
+
|
|
|
+ [connection cancel];
|
|
|
+
|
|
|
+ /* now ask VLC to stream the URL we were just passed */
|
|
|
+ VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
|
|
|
+ [vpc playURL:theActualURL successCallback:nil errorCallback:nil];
|
|
|
+
|
|
|
+#if TARGET_OS_TV
|
|
|
+ VLCFullscreenMovieTVViewController *movieVC = [VLCFullscreenMovieTVViewController fullscreenMovieTVViewController];
|
|
|
+ [self presentViewController:movieVC
|
|
|
+ animated:YES
|
|
|
+ completion:nil];
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ return request;
|
|
|
+}
|
|
|
+
|
|
|
#if TARGET_OS_IOS
|
|
|
- (void)triggerDownloadForCell:(VLCCloudStorageTableViewCell *)cell
|
|
|
{
|
|
|
- _selectedFile = _boxController.currentListFiles[[self.tableView indexPathForCell:cell].row];
|
|
|
+ _selectedFile = _listOfFiles[[self.tableView indexPathForCell:cell].row];
|
|
|
|
|
|
if (_selectedFile.size.longLongValue < [[UIDevice currentDevice] freeDiskspace].longLongValue) {
|
|
|
/* selected item is a proper file, ask the user if s/he wants to download it */
|
|
@@ -203,7 +290,7 @@
|
|
|
|
|
|
- (void)boxDidGetLoggedOut
|
|
|
{
|
|
|
- [self showLoginPanel];
|
|
|
+ [self performSelectorOnMainThread:@selector(showLoginPanel) withObject:nil waitUntilDone:NO];
|
|
|
}
|
|
|
|
|
|
- (void)boxAPIAuthenticationDidFail
|
|
@@ -213,7 +300,7 @@
|
|
|
|
|
|
- (void)boxAPIInitiateLogin
|
|
|
{
|
|
|
- [self showLoginPanel];
|
|
|
+ [self performSelectorOnMainThread:@selector(showLoginPanel) withObject:nil waitUntilDone:NO];
|
|
|
}
|
|
|
|
|
|
- (void)authorizationViewControllerDidCancel:(BoxAuthorizationViewController *)authorizationViewController
|