VLCGoogleDriveTableViewController.m 12.6 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's avatar
Carola committed
13
14

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

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

Carola's avatar
Carola committed
26
27
    NSString *_currentFolderId;

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

    UIBarButtonItem *_numberOfFilesBarButtonItem;
    UIBarButtonItem *_progressBarButtonItem;
33
34

    VLCProgressView *_progressView;
Carola's avatar
Carola committed
35
36

    UIActivityIndicatorView *_activityIndicator;
37

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

@end

@implementation VLCGoogleDriveTableViewController

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

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

    _authorizationInProgress = NO;

Carola's avatar
Carola committed
57
58
59
60
61
62
63
    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;

64
    self.tableView.rowHeight = [VLCCloudStorageTableViewCell heightOfCell];
65
66
    self.tableView.separatorColor = [UIColor VLCDarkBackgroundColor];
    self.view.backgroundColor = [UIColor VLCDarkBackgroundColor];
Carola's avatar
Carola committed
67

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

71
72
    _progressView = [VLCProgressView new];
    _progressBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_progressView];
Carola's avatar
Carola committed
73

74
    [self.cloudStorageLogo setImage:[UIImage imageNamed:@"DriveWhite"]];
75

76
77
    if (!SYSTEM_RUNS_IOS7_OR_LATER) {
        self.flatLoginButton.hidden = YES;
78
        [self.loginButton setTitle:NSLocalizedString(@"DROPBOX_LOGIN", nil) forState:UIControlStateNormal];
79
80
    } else {
        self.loginButton.hidden = YES;
81
        [self.flatLoginButton setTitle:NSLocalizedString(@"DROPBOX_LOGIN", nil) forState:UIControlStateNormal];
82
    }
Carola's avatar
Carola committed
83
84
85
86
87
88
89

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

    [self _showProgressInToolbar:NO];

    _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    _activityIndicator.hidesWhenStopped = YES;
90
    _activityIndicator.translatesAutoresizingMaskIntoConstraints = NO;
Carola's avatar
Carola committed
91
    [self.view addSubview:_activityIndicator];
92
93
94

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_activityIndicator attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_activityIndicator attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]];
Carola's avatar
Carola committed
95
96
97
98
}

- (GTMOAuth2ViewControllerTouch *)createAuthController
{
99
    _authController = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:kGTLAuthScopeDrive
Carola's avatar
Carola committed
100
101
102
103
104
105
106
107
                                                                clientID:kVLCGoogleDriveClientID
                                                            clientSecret:kVLCGoogleDriveClientSecret
                                                        keychainItemName:kKeychainItemName
                                                                delegate:self
                                                        finishedSelector:@selector(viewController:finishedWithAuth:error:)];
    return _authController;
}

108
- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController finishedWithAuth:(GTMOAuth2Authentication *)authResult error:(NSError *)error
Carola's avatar
Carola committed
109
{
110
    _authorizationInProgress = NO;
111
    if (error != nil) {
Carola's avatar
Carola committed
112
        _googleDriveController.driveService.authorizer = nil;
113
    } else {
Carola's avatar
Carola committed
114
115
116
117
118
119
120
121
122
123
124
125
126
        _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];

127
128
    [self.cloudStorageLogo sizeToFit];
    self.cloudStorageLogo.center = self.view.center;
Carola's avatar
Carola committed
129
130
131
132
133
}

- (void)viewWillDisappear:(BOOL)animated
{
    self.navigationController.toolbarHidden = YES;
134
135
136
137
    if ((VLCAppDelegate*)[UIApplication sharedApplication].delegate.window.rootViewController.presentedViewController == nil) {
        [_googleDriveController stopSession];
        [self.tableView reloadData];
    }
Carola's avatar
Carola committed
138
139
140
141
142
143
144
145
    [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 {
146
        _progressView.progressBar.progress = 0.;
147
        [self setToolbarItems:@[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], _progressBarButtonItem, [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]] animated:YES];
Carola's avatar
Carola committed
148
149
150
    }
}

Carola's avatar
Carola committed
151
- (void)_requestInformationForCurrentFolderId
Carola's avatar
Carola committed
152
153
{
    [_activityIndicator startAnimating];
Carola's avatar
Carola committed
154
    [_googleDriveController requestDirectoryListingWithFolderId:_currentFolderId];
Carola's avatar
Carola committed
155

Carola's avatar
Carola committed
156
    self.navigationItem.leftBarButtonItem = ![_currentFolderId isEqualToString:@""] ? _backButton : _backToMenuButton;
Carola's avatar
Carola committed
157
158
159
160
}

- (IBAction)goBack:(id)sender
{
Carola's avatar
Carola committed
161
162
163
164
165
    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's avatar
Carola committed
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
}

#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";

184
    VLCCloudStorageTableViewCell *cell = (VLCCloudStorageTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Carola's avatar
Carola committed
185
    if (cell == nil)
186
        cell = [VLCCloudStorageTableViewCell cellWithReuseIdentifier:CellIdentifier];
Carola's avatar
Carola committed
187

188
    cell.driveFile = _googleDriveController.currentListFiles[indexPath.row];
189
    cell.delegate = self;
Carola's avatar
Carola committed
190
191
192
193
194
195
196
197

    return cell;
}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
198
    cell.backgroundColor = (indexPath.row % 2 == 0)? [UIColor blackColor]: [UIColor VLCDarkBackgroundColor];
Carola's avatar
Carola committed
199
200
201
202
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
203
    _selectedFile = _googleDriveController.currentListFiles[indexPath.row];
Carola's avatar
Carola committed
204
    if (![_selectedFile.mimeType isEqualToString:@"application/vnd.google-apps.folder"]) {
Carola's avatar
Carola committed
205
        [_googleDriveController streamFile:_selectedFile];
Carola's avatar
Carola committed
206
207
208
209
210
211
212
    } else {
        /* dive into subdirectory */
        if (![_currentFolderId isEqualToString:@""])
            _currentFolderId = [_currentFolderId stringByAppendingString:@"/"];
        _currentFolderId = [_currentFolderId stringByAppendingString:_selectedFile.identifier];
        [self _requestInformationForCurrentFolderId];
    }
Carola's avatar
Carola committed
213
214
215
    [self.tableView deselectRowAtIndexPath:indexPath animated:NO];
}

Carola's avatar
Carola committed
216
217
218
219
220
- (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 */
221
    UIAlertView * alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"DROPBOX_DOWNLOAD", nil) message:[NSString stringWithFormat:NSLocalizedString(@"DROPBOX_DL_LONG", nil), _selectedFile.title, [[UIDevice currentDevice] model]] delegate:self cancelButtonTitle:NSLocalizedString(@"BUTTON_CANCEL", nil) otherButtonTitles:NSLocalizedString(@"BUTTON_DOWNLOAD", nil), nil];
Carola's avatar
Carola committed
222
223
224
    [alert show];
}

225
226
227
228
229
230
231
- (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's avatar
Carola committed
232
            [self _requestInformationForCurrentFolderId];
233
234
235
236
        }
    }
}

Carola's avatar
Carola committed
237
238
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
239
240
241
    if (buttonIndex == 1)
        [_googleDriveController downloadFileToDocumentFolder:_selectedFile];
    _selectedFile = nil;
Carola's avatar
Carola committed
242
243
}

244
#pragma mark - google drive controller delegate
Carola's avatar
Carola committed
245
246
247
248
249
250
251
252
253

- (void)mediaListUpdated
{
    [_activityIndicator stopAnimating];

    [self.tableView reloadData];

    NSUInteger count = _googleDriveController.currentListFiles.count;
    if (count == 0)
254
        _numberOfFilesBarButtonItem.title = NSLocalizedString(@"NO_FILES", nil);
Carola's avatar
Carola committed
255
    else if (count != 1)
256
        _numberOfFilesBarButtonItem.title = [NSString stringWithFormat:NSLocalizedString(@"NUM_OF_FILES", nil), count];
Carola's avatar
Carola committed
257
    else
258
        _numberOfFilesBarButtonItem.title = NSLocalizedString(@"ONE_FILE", nil);
Carola's avatar
Carola committed
259
260
261
262
263
264
265
}

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

266
- (void)updateRemainingTime:(NSString *)time
Carola's avatar
Carola committed
267
{
268
    [_progressView updateTime:time];
269
270
271
}

- (void)currentProgressInformation:(float)progress {
272
    [_progressView.progressBar setProgress:progress animated:YES];
Carola's avatar
Carola committed
273
274
275
276
277
278
279
280
281
282
283
}

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

#pragma mark - communication with app delegate

- (void)updateViewAfterSessionChange
{
284
    if(_authorizationInProgress) {
285
286
        if (self.loginToCloudStorageView.superview)
            [self.loginToCloudStorageView removeFromSuperview];
287
288
        return;
    }
Carola's avatar
Carola committed
289
290
291
    if (![_googleDriveController isAuthorized]) {
        [self _showLoginPanel];
        return;
292
293
    } else if (self.loginToCloudStorageView.superview)
        [self.loginToCloudStorageView removeFromSuperview];
294

295
    //reload if we didn't come back from streaming
Carola's avatar
Carola committed
296
    _currentFolderId = @"";
297
    if([_googleDriveController.currentListFiles count] == 0)
Carola's avatar
Carola committed
298
        [self _requestInformationForCurrentFolderId];
Carola's avatar
Carola committed
299
300
301
302
303
304
}

#pragma mark - login dialog

- (void)_showLoginPanel
{
305
306
    self.loginToCloudStorageView.frame = self.tableView.frame;
    [self.view addSubview:self.loginToCloudStorageView];
Carola's avatar
Carola committed
307
308
}

309
- (IBAction)loginAction:(id)sender
Carola's avatar
Carola committed
310
311
{
    if (![_googleDriveController isAuthorized]) {
312
        _authorizationInProgress = YES;
Carola's avatar
Carola committed
313
314
315
316
317
318
319
        [self.navigationController pushViewController:[self createAuthController] animated:YES];
    } else {
        [_googleDriveController logout];
    }
}

@end