VLCGoogleDriveTableViewController.m 13.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
/*****************************************************************************
 * VLCGoogleDriveTableViewController.m
 * VLC for iOS
 *****************************************************************************
 * Copyright (c) 2013 VideoLAN. All rights reserved.
 * $Id$
 *
 * Authors: Carola Nitz <nitz.carola # googlemail.com>
 *          Felix Paul Kühne <fkuehne # videolan.org>
 *
 * Refer to the COPYING file of the official project for license.
 *****************************************************************************/
Carola Nitz's avatar
Carola Nitz committed
13 14

#import "VLCGoogleDriveTableViewController.h"
15
#import "VLCCloudStorageTableViewCell.h"
Carola Nitz's avatar
Carola Nitz committed
16 17 18 19
#import "VLCGoogleDriveController.h"
#import "VLCAppDelegate.h"
#import "UIBarButtonItem+Theme.h"

20
@interface VLCGoogleDriveTableViewController () <VLCCloudStorageTableViewCell, VLCGoogleDriveController>
Carola Nitz's avatar
Carola Nitz committed
21
{
22
    GTLDriveFile *_selectedFile;
Carola Nitz's avatar
Carola Nitz committed
23
    GTMOAuth2ViewControllerTouch *_authController;
24

Carola Nitz's avatar
Carola Nitz committed
25 26
    NSString *_currentFolderId;

Carola Nitz's avatar
Carola Nitz committed
27 28 29 30 31
    UIBarButtonItem *_backButton;
    UIBarButtonItem *_backToMenuButton;

    UIBarButtonItem *_numberOfFilesBarButtonItem;
    UIBarButtonItem *_progressBarButtonItem;
32 33
    UIProgressView *_progressBar;
    UILabel *_progressLabel;
Carola Nitz's avatar
Carola Nitz committed
34 35

    UIActivityIndicatorView *_activityIndicator;
36

37
    BOOL _authorizationInProgress;
38
    VLCGoogleDriveController *_googleDriveController;
Carola Nitz's avatar
Carola Nitz committed
39 40 41 42 43 44 45 46 47 48 49
}

@end

@implementation VLCGoogleDriveTableViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.modalPresentationStyle = UIModalPresentationFormSheet;

50
    _googleDriveController = [VLCGoogleDriveController sharedInstance];
Carola Nitz's avatar
Carola Nitz committed
51 52
    _googleDriveController.delegate = self;
    [_googleDriveController startSession];
53 54 55

    _authorizationInProgress = NO;

Carola Nitz's avatar
Carola Nitz committed
56 57 58 59 60 61 62
    self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"DriveWhite"]];
    self.navigationItem.titleView.contentMode = UIViewContentModeScaleAspectFit;

    _backButton = [UIBarButtonItem themedBackButtonWithTarget:self andSelector:@selector(goBack:)];
    _backToMenuButton = [UIBarButtonItem themedRevealMenuButtonWithTarget:self andSelector:@selector(goBack:)];
    self.navigationItem.leftBarButtonItem = _backToMenuButton;

63
    self.tableView.rowHeight = [VLCCloudStorageTableViewCell heightOfCell];
Carola Nitz's avatar
Carola Nitz committed
64 65 66 67 68 69
    self.tableView.separatorColor = [UIColor colorWithWhite:.122 alpha:1.];
    self.view.backgroundColor = [UIColor colorWithWhite:.122 alpha:1.];

    _numberOfFilesBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:[NSString stringWithFormat:NSLocalizedString(@"NUM_OF_FILES", @""), 0] style:UIBarButtonItemStylePlain target:nil action:nil];
    [_numberOfFilesBarButtonItem setTitleTextAttributes:@{ UITextAttributeFont : [UIFont systemFontOfSize:11.] } forState:UIControlStateNormal];

70 71 72
    _progressBar = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
    _progressLabel = [[UILabel alloc] init];
    _progressLabel.textColor = [UIColor whiteColor];
73
    _progressLabel.backgroundColor = [UIColor clearColor];
74 75 76 77 78
    _progressLabel.font = [UIFont systemFontOfSize:11.];

    UIView *progressView = [[UIView alloc] init];
    [progressView addSubview:_progressBar];
    [progressView addSubview:_progressLabel];
79

80
    [progressView addConstraint:[NSLayoutConstraint constraintWithItem:progressView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_progressLabel attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0.0f]];
81 82 83
    [progressView addConstraint:[NSLayoutConstraint constraintWithItem:_progressBar attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_progressLabel attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0.0f]];
    [progressView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_progressBar]-[_progressLabel]-|" options:NSLayoutFormatAlignAllCenterX metrics:nil views:NSDictionaryOfVariableBindings(_progressBar, _progressLabel)]];

84
    progressView.translatesAutoresizingMaskIntoConstraints = NO;
85 86
    _progressLabel.translatesAutoresizingMaskIntoConstraints = NO;
    _progressBar.translatesAutoresizingMaskIntoConstraints = NO;
87 88

    _progressBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:progressView];
Carola Nitz's avatar
Carola Nitz committed
89

90
    [self.cloudStorageLogo setImage:[UIImage imageNamed:@"DriveWhite"]];
91

92 93 94 95 96 97 98
    if (!SYSTEM_RUNS_IOS7_OR_LATER) {
        self.flatLoginButton.hidden = YES;
        [self.loginButton setTitle:NSLocalizedString(@"DROPBOX_LOGIN", @"") forState:UIControlStateNormal];
    } else {
        self.loginButton.hidden = YES;
        [self.flatLoginButton setTitle:NSLocalizedString(@"DROPBOX_LOGIN", @"") forState:UIControlStateNormal];
    }
Carola Nitz's avatar
Carola Nitz committed
99 100 101 102 103 104 105 106 107 108 109 110 111

    [self.navigationController.toolbar setBackgroundImage:[UIImage imageNamed:@"sudHeaderBg"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];

    [self _showProgressInToolbar:NO];

    _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    _activityIndicator.hidesWhenStopped = YES;

    [self.view addSubview:_activityIndicator];
}

- (GTMOAuth2ViewControllerTouch *)createAuthController
{
112
    _authController = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:kGTLAuthScopeDrive
Carola Nitz's avatar
Carola Nitz committed
113 114 115 116 117 118 119 120
                                                                clientID:kVLCGoogleDriveClientID
                                                            clientSecret:kVLCGoogleDriveClientSecret
                                                        keychainItemName:kKeychainItemName
                                                                delegate:self
                                                        finishedSelector:@selector(viewController:finishedWithAuth:error:)];
    return _authController;
}

121
- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController finishedWithAuth:(GTMOAuth2Authentication *)authResult error:(NSError *)error
Carola Nitz's avatar
Carola Nitz committed
122
{
123
    _authorizationInProgress = NO;
124
    if (error != nil) {
Carola Nitz's avatar
Carola Nitz committed
125
        _googleDriveController.driveService.authorizer = nil;
126
    } else {
Carola Nitz's avatar
Carola Nitz committed
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
        _googleDriveController.driveService.authorizer = authResult;
    }
    [self updateViewAfterSessionChange];
}

- (void)viewWillAppear:(BOOL)animated
{
    self.navigationController.toolbarHidden = NO;
    self.navigationController.toolbar.barStyle = UIBarStyleBlack;
    [self.navigationController.toolbar setBackgroundImage:[UIImage imageNamed:@"bottomBlackBar"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
    [self updateViewAfterSessionChange];
    [super viewWillAppear:animated];

    CGRect aiFrame = _activityIndicator.frame;
    CGSize tvSize = self.tableView.frame.size;
    aiFrame.origin.x = (tvSize.width - aiFrame.size.width) / 2.;
    aiFrame.origin.y = (tvSize.height - aiFrame.size.height) / 2.;
    _activityIndicator.frame = aiFrame;
145 146 147

    [self.cloudStorageLogo sizeToFit];
    self.cloudStorageLogo.center = self.view.center;
Carola Nitz's avatar
Carola Nitz committed
148 149 150 151 152
}

- (void)viewWillDisappear:(BOOL)animated
{
    self.navigationController.toolbarHidden = YES;
153 154 155 156
    if ((VLCAppDelegate*)[UIApplication sharedApplication].delegate.window.rootViewController.presentedViewController == nil) {
        [_googleDriveController stopSession];
        [self.tableView reloadData];
    }
Carola Nitz's avatar
Carola Nitz committed
157 158 159 160 161 162 163 164
    [super viewWillDisappear:animated];
}

- (void)_showProgressInToolbar:(BOOL)value
{
    if (!value)
        [self setToolbarItems:@[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], _numberOfFilesBarButtonItem, [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]] animated:YES];
    else {
165 166
        _progressBar.progress = 0.;
        [self setToolbarItems:@[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], _progressBarButtonItem, [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]] animated:YES];
Carola Nitz's avatar
Carola Nitz committed
167 168 169
    }
}

Carola Nitz's avatar
Carola Nitz committed
170
- (void)_requestInformationForCurrentFolderId
Carola Nitz's avatar
Carola Nitz committed
171 172
{
    [_activityIndicator startAnimating];
Carola Nitz's avatar
Carola Nitz committed
173
    [_googleDriveController requestDirectoryListingWithFolderId:_currentFolderId];
Carola Nitz's avatar
Carola Nitz committed
174

Carola Nitz's avatar
Carola Nitz committed
175
    self.navigationItem.leftBarButtonItem = ![_currentFolderId isEqualToString:@""] ? _backButton : _backToMenuButton;
Carola Nitz's avatar
Carola Nitz committed
176 177 178 179
}

- (IBAction)goBack:(id)sender
{
Carola Nitz's avatar
Carola Nitz committed
180 181 182 183 184
    if (![_currentFolderId isEqualToString:@""] && [_currentFolderId length] > 0) {
        _currentFolderId = [_currentFolderId stringByDeletingLastPathComponent];
        [self _requestInformationForCurrentFolderId];
    } else
        [[(VLCAppDelegate*)[UIApplication sharedApplication].delegate revealController] toggleSidebar:![(VLCAppDelegate*)[UIApplication sharedApplication].delegate revealController].sidebarShowing duration:kGHRevealSidebarDefaultAnimationDuration];
Carola Nitz's avatar
Carola Nitz committed
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _googleDriveController.currentListFiles.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"GoogleDriveCell";

203
    VLCCloudStorageTableViewCell *cell = (VLCCloudStorageTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Carola Nitz's avatar
Carola Nitz committed
204
    if (cell == nil)
205
        cell = [VLCCloudStorageTableViewCell cellWithReuseIdentifier:CellIdentifier];
Carola Nitz's avatar
Carola Nitz committed
206

207
    cell.driveFile = _googleDriveController.currentListFiles[indexPath.row];
208
    cell.delegate = self;
Carola Nitz's avatar
Carola Nitz committed
209 210 211 212 213 214 215 216 217 218 219 220 221

    return cell;
}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    cell.backgroundColor = (indexPath.row % 2 == 0)? [UIColor blackColor]: [UIColor colorWithWhite:.122 alpha:1.];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
222
    _selectedFile = _googleDriveController.currentListFiles[indexPath.row];
Carola Nitz's avatar
Carola Nitz committed
223
    if (![_selectedFile.mimeType isEqualToString:@"application/vnd.google-apps.folder"]) {
Carola Nitz's avatar
Carola Nitz committed
224
        [_googleDriveController streamFile:_selectedFile];
Carola Nitz's avatar
Carola Nitz committed
225 226 227 228 229 230 231
    } else {
        /* dive into subdirectory */
        if (![_currentFolderId isEqualToString:@""])
            _currentFolderId = [_currentFolderId stringByAppendingString:@"/"];
        _currentFolderId = [_currentFolderId stringByAppendingString:_selectedFile.identifier];
        [self _requestInformationForCurrentFolderId];
    }
Carola Nitz's avatar
Carola Nitz committed
232 233 234
    [self.tableView deselectRowAtIndexPath:indexPath animated:NO];
}

Carola Nitz's avatar
Carola Nitz committed
235 236 237 238 239 240 241 242 243
- (void)triggerDownloadForCell:(VLCCloudStorageTableViewCell *)cell
{
    _selectedFile = _googleDriveController.currentListFiles[[self.tableView indexPathForCell:cell].row];

    /* selected item is a proper file, ask the user if s/he wants to download it */
    UIAlertView * alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"DROPBOX_DOWNLOAD", @"") message:[NSString stringWithFormat:NSLocalizedString(@"DROPBOX_DL_LONG", @""), _selectedFile.title, [[UIDevice currentDevice] model]] delegate:self cancelButtonTitle:NSLocalizedString(@"BUTTON_CANCEL", @"") otherButtonTitles:NSLocalizedString(@"BUTTON_DOWNLOAD", @""), nil];
    [alert show];
}

244 245 246 247 248 249 250
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    NSInteger currentOffset = scrollView.contentOffset.y;
    NSInteger maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height;

    if (maximumOffset - currentOffset <= - self.tableView.rowHeight) {
        if (_googleDriveController.hasMoreFiles && !_activityIndicator.isAnimating) {
Carola Nitz's avatar
Carola Nitz committed
251
            [self _requestInformationForCurrentFolderId];
252 253 254 255
        }
    }
}

Carola Nitz's avatar
Carola Nitz committed
256 257
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
258 259 260
    if (buttonIndex == 1)
        [_googleDriveController downloadFileToDocumentFolder:_selectedFile];
    _selectedFile = nil;
Carola Nitz's avatar
Carola Nitz committed
261 262
}

263
#pragma mark - google drive controller delegate
Carola Nitz's avatar
Carola Nitz committed
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284

- (void)mediaListUpdated
{
    [_activityIndicator stopAnimating];

    [self.tableView reloadData];

    NSUInteger count = _googleDriveController.currentListFiles.count;
    if (count == 0)
        _numberOfFilesBarButtonItem.title = NSLocalizedString(@"NO_FILES", @"");
    else if (count != 1)
        _numberOfFilesBarButtonItem.title = [NSString stringWithFormat:NSLocalizedString(@"NUM_OF_FILES", @""), count];
    else
        _numberOfFilesBarButtonItem.title = NSLocalizedString(@"ONE_FILE", @"");
}

- (void)operationWithProgressInformationStarted
{
    [self _showProgressInToolbar:YES];
}

285
- (void)updateRemainingTime:(NSString *)time
Carola Nitz's avatar
Carola Nitz committed
286
{
287 288
    [_progressLabel setText:[NSString stringWithFormat:NSLocalizedString(@"REMAINING_TIME", nil), time]];
    CGSize size = [_progressLabel.text sizeWithFont:_progressLabel.font];
289
    [_progressLabel setFrame:CGRectMake(_progressLabel.frame.origin.x, _progressLabel.frame.origin.y, size.width, size.height)];
290 291 292 293
}

- (void)currentProgressInformation:(float)progress {
    [_progressBar setProgress:progress animated:YES];
Carola Nitz's avatar
Carola Nitz committed
294 295 296 297 298 299 300 301 302 303 304
}

- (void)operationWithProgressInformationStopped
{
    [self _showProgressInToolbar:NO];
}

#pragma mark - communication with app delegate

- (void)updateViewAfterSessionChange
{
305
    if(_authorizationInProgress) {
306 307
        if (self.loginToCloudStorageView.superview)
            [self.loginToCloudStorageView removeFromSuperview];
308 309
        return;
    }
Carola Nitz's avatar
Carola Nitz committed
310 311 312
    if (![_googleDriveController isAuthorized]) {
        [self _showLoginPanel];
        return;
313 314
    } else if (self.loginToCloudStorageView.superview)
        [self.loginToCloudStorageView removeFromSuperview];
315

316
    //reload if we didn't come back from streaming
Carola Nitz's avatar
Carola Nitz committed
317
    _currentFolderId = @"";
318
    if([_googleDriveController.currentListFiles count] == 0)
Carola Nitz's avatar
Carola Nitz committed
319
        [self _requestInformationForCurrentFolderId];
Carola Nitz's avatar
Carola Nitz committed
320 321 322 323 324 325
}

#pragma mark - login dialog

- (void)_showLoginPanel
{
326 327
    self.loginToCloudStorageView.frame = self.tableView.frame;
    [self.view addSubview:self.loginToCloudStorageView];
Carola Nitz's avatar
Carola Nitz committed
328 329
}

330
- (IBAction)loginAction:(id)sender
Carola Nitz's avatar
Carola Nitz committed
331 332
{
    if (![_googleDriveController isAuthorized]) {
333
        _authorizationInProgress = YES;
Carola Nitz's avatar
Carola Nitz committed
334 335 336 337 338 339 340
        [self.navigationController pushViewController:[self createAuthController] animated:YES];
    } else {
        [_googleDriveController logout];
    }
}

@end