talk-ios/NextcloudTalk/DirectoryTableViewController.m

397 строки
17 KiB
Objective-C

/**
* @copyright Copyright (c) 2020 Ivan Sein <ivan@nextcloud.com>
*
* @author Ivan Sein <ivan@nextcloud.com>
*
* @license GNU GPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#import "DirectoryTableViewController.h"
@import NCCommunication;
#import "UIImageView+AFNetworking.h"
#import "DirectoryTableViewCell.h"
#import "NCAPIController.h"
#import "NCDatabaseManager.h"
#import "NCAppBranding.h"
#import "NCSettingsController.h"
#import "NCUtils.h"
#import "PlaceholderView.h"
@interface DirectoryTableViewController ()
{
NSString *_path;
NSString *_token;
NSMutableArray *_itemsInDirectory;
NSIndexPath *_selectedItem;
UIBarButtonItem *_sortingButton;
PlaceholderView *_directoryBackgroundView;
UIActivityIndicatorView *_sharingFileView;
}
@end
@implementation DirectoryTableViewController
- (instancetype)initWithPath:(NSString *)path inRoom:(nonnull NSString *)token
{
self = [super init];
if (self) {
_path = path;
_token = token;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self configureNavigationBar];
_sharingFileView = [[UIActivityIndicatorView alloc] init];
_sharingFileView.color = [NCAppBranding themeTextColor];
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
// Directory placeholder view
_directoryBackgroundView = [[PlaceholderView alloc] init];
[_directoryBackgroundView setImage:[UIImage imageNamed:@"folder-placeholder"]];
[_directoryBackgroundView.placeholderTextView setText:NSLocalizedString(@"No files in here", nil)];
[_directoryBackgroundView.placeholderView setHidden:YES];
[_directoryBackgroundView.loadingView startAnimating];
self.tableView.backgroundView = _directoryBackgroundView;
[self.navigationController.navigationBar setTitleTextAttributes:
@{NSForegroundColorAttributeName:[NCAppBranding themeTextColor]}];
self.navigationController.navigationBar.tintColor = [NCAppBranding themeTextColor];
self.navigationController.navigationBar.barTintColor = [NCAppBranding themeColor];
self.tabBarController.tabBar.tintColor = [NCAppBranding themeColor];
self.navigationController.navigationBar.translucent = NO;
if (@available(iOS 13.0, *)) {
UIColor *themeColor = [NCAppBranding themeColor];
UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
[appearance configureWithOpaqueBackground];
appearance.backgroundColor = themeColor;
appearance.titleTextAttributes = @{NSForegroundColorAttributeName:[NCAppBranding themeTextColor]};
self.navigationItem.standardAppearance = appearance;
self.navigationItem.compactAppearance = appearance;
self.navigationItem.scrollEdgeAppearance = appearance;
}
self.tableView.separatorInset = UIEdgeInsetsMake(0, 64, 0, 0);
[self.tableView registerNib:[UINib nibWithNibName:kDirectoryTableCellNibName bundle:nil] forCellReuseIdentifier:kDirectoryCellIdentifier];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self getItemsInDirectory];
}
- (void)cancelButtonPressed
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)shareButtonPressed
{
[self showConfirmationDialogForSharingItemWithPath:_path andName:[_path lastPathComponent]];
}
- (void)showSortingOptions
{
UIAlertController *optionsActionSheet =
[UIAlertController alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *alphabetical = [UIAlertAction actionWithTitle:NSLocalizedString(@"Alphabetical order", nil)
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
[[NCSettingsController sharedInstance] setPreferredFileSorting:NCAlphabeticalSorting];
[self sortItemsInDirectory];
}];
[optionsActionSheet addAction:alphabetical];
UIAlertAction *modificationDate = [UIAlertAction actionWithTitle:NSLocalizedString(@"Modification date", nil)
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
[[NCSettingsController sharedInstance] setPreferredFileSorting:NCModificationDateSorting];
[self sortItemsInDirectory];
}];
[optionsActionSheet addAction:modificationDate];
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil]];
UIAlertAction *selectedAction = modificationDate;
switch ([[NCSettingsController sharedInstance] getPreferredFileSorting]) {
case NCAlphabeticalSorting:
selectedAction = alphabetical;
break;
case NCModificationDateSorting:
selectedAction = modificationDate;
break;
default:
break;
}
[selectedAction setValue:[[UIImage imageNamed:@"checkmark"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forKey:@"image"];
// Presentation on iPads
optionsActionSheet.popoverPresentationController.barButtonItem = _sortingButton;
[self presentViewController:optionsActionSheet animated:YES completion:nil];
}
#pragma mark - Files
- (void)getItemsInDirectory
{
[[NCAPIController sharedInstance] readFolderForAccount:[[NCDatabaseManager sharedInstance] activeAccount] atPath:_path depth:@"1" withCompletionBlock:^(NSArray *items, NSError *error) {
if (!error) {
NSMutableArray *itemsInDirectory = [NSMutableArray new];
for (NCCommunicationFile *item in items) {
NSString *currentDirectory = [self->_path isEqualToString:@""] ? @"webdav" : [self->_path lastPathComponent];
if ([[item.path lastPathComponent] isEqualToString:currentDirectory] && !item.e2eEncrypted) {
[itemsInDirectory addObject:item];
}
}
self->_itemsInDirectory = itemsInDirectory;
[self sortItemsInDirectory];
[self->_directoryBackgroundView.loadingView stopAnimating];
[self->_directoryBackgroundView.loadingView setHidden:YES];
[self->_directoryBackgroundView.placeholderView setHidden:(itemsInDirectory.count > 0)];
}
}];
}
- (void)sortItemsInDirectory
{
NSSortDescriptor *valueDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO];
switch ([[NCSettingsController sharedInstance] getPreferredFileSorting]) {
case NCAlphabeticalSorting:
valueDescriptor = [[NSSortDescriptor alloc] initWithKey:@"fileName" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
break;
case NCModificationDateSorting:
valueDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO];
break;
default:
break;
}
NSArray *descriptors = [NSArray arrayWithObjects:valueDescriptor, nil];
[_itemsInDirectory sortUsingDescriptors:descriptors];
[self.tableView reloadData];
}
- (void)shareFileWithPath:(NSString *)path
{
[self setSharingFileUI];
[[NCAPIController sharedInstance] shareFileOrFolderForAccount:[[NCDatabaseManager sharedInstance] activeAccount] atPath:path toRoom:_token talkMetaData:nil withCompletionBlock:^(NSError *error) {
if (!error) {
[self dismissViewControllerAnimated:YES completion:nil];
} else {
[self removeSharingFileUI];
[self showErrorSharingItem];
NSLog(@"Error sharing file or folder: %@", [error description]);
}
}];
}
#pragma mark - Utils
- (void)configureNavigationBar
{
// Sorting button
_sortingButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"sorting"]
style:UIBarButtonItemStylePlain
target:self
action:@selector(showSortingOptions)];
// Home folder
if ([_path isEqualToString:@""]) {
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self action:@selector(cancelButtonPressed)];
self.navigationItem.leftBarButtonItem = cancelButton;
self.navigationItem.rightBarButtonItem = _sortingButton;
UIImage *navigationLogo = [UIImage imageNamed:@"navigation-home"];
UIImageView *navigationImageView = [[UIImageView alloc] initWithImage:navigationLogo];
navigationImageView.image = [navigationImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[navigationImageView setTintColor:[NCAppBranding themeTextColor]];
self.navigationItem.titleView = navigationImageView;
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:navigationLogo style:UIBarButtonItemStylePlain
target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
// Other directories
} else {
UIBarButtonItem *shareButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"sharing"]
style:UIBarButtonItemStylePlain
target:self
action:@selector(shareButtonPressed)];
self.navigationItem.rightBarButtonItems = @[shareButton, _sortingButton];
self.navigationItem.title = [_path lastPathComponent];
}
}
- (void)setSharingFileUI
{
[_sharingFileView startAnimating];
UIBarButtonItem *sharingFileButton = [[UIBarButtonItem alloc] initWithCustomView:_sharingFileView];
self.navigationItem.rightBarButtonItems = @[sharingFileButton];
self.navigationController.navigationBar.userInteractionEnabled = NO;
self.tableView.userInteractionEnabled = NO;
}
- (void)removeSharingFileUI
{
[_sharingFileView stopAnimating];
[self configureNavigationBar];
self.navigationController.navigationBar.userInteractionEnabled = YES;
self.tableView.userInteractionEnabled = YES;
}
- (void)showConfirmationDialogForSharingItemWithPath:(NSString *)path andName:(NSString *)name
{
UIAlertController *confirmDialog =
[UIAlertController alertControllerWithTitle:name
message:[NSString stringWithFormat:NSLocalizedString(@"Do you want to share '%@' in the conversation?", nil), name]
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Share", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self shareFileWithPath:path];
}];
[confirmDialog addAction:confirmAction];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil];
[confirmDialog addAction:cancelAction];
[self presentViewController:confirmDialog animated:YES completion:nil];
}
- (void)showErrorSharingItem
{
UIAlertController *confirmDialog =
[UIAlertController alertControllerWithTitle:NSLocalizedString(@"Could not share file", nil)
message:NSLocalizedString(@"An error occurred while sharing the file", nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) style:UIAlertActionStyleDefault handler:nil];
[confirmDialog addAction:confirmAction];
[self presentViewController:confirmDialog animated:YES completion:nil];
}
- (NSString *)dateDiff:(NSDate *) convertedDate
{
NSDate *todayDate = [NSDate date];
double ti = [convertedDate timeIntervalSinceDate:todayDate];
ti = ti * -1;
if (ti < 60) {
// This minute
return NSLocalizedString(@"less than a minute ago", nil);
} else if (ti < 3600) {
// This hour
int diff = round(ti / 60);
return [NSString stringWithFormat:NSLocalizedString(@"%d minutes ago", nil), diff];
} else if (ti < 86400) {
// This day
int diff = round(ti / 60 / 60);
return[NSString stringWithFormat:NSLocalizedString(@"%d hours ago", nil), diff];
} else if (ti < 86400 * 30) {
// This month
int diff = round(ti / 60 / 60 / 24);
return[NSString stringWithFormat:NSLocalizedString(@"%d days ago", nil), diff];
} else {
// Older than one month
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setFormatterBehavior:NSDateFormatterBehavior10_4];
[df setDateStyle:NSDateFormatterMediumStyle];
return [df stringFromDate:convertedDate];
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _itemsInDirectory.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return kDirectoryTableCellHeight;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NCCommunicationFile *item = [_itemsInDirectory objectAtIndex:indexPath.row];
DirectoryTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kDirectoryCellIdentifier];
if (!cell) {
cell = [[DirectoryTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kDirectoryCellIdentifier];
}
// Name and modification date
cell.fileNameLabel.text = item.fileName;
cell.fileInfoLabel.text = [self dateDiff:item.date];
// Icon or preview
NSString *imageName = [NCUtils previewImageForFileMIMEType:item.contentType];
UIImage *filePreviewImage = [UIImage imageNamed:imageName];
if (item.directory) {
cell.fileImageView.image = [UIImage imageNamed:@"folder"];
} else if (item.hasPreview) {
NSString *fileId = [NSString stringWithFormat:@"%@", item.fileId];
[cell.fileImageView setImageWithURLRequest:[[NCAPIController sharedInstance] createPreviewRequestForFile:fileId width:40 height:40 usingAccount:[[NCDatabaseManager sharedInstance] activeAccount]]
placeholderImage:filePreviewImage success:nil failure:nil];
} else {
cell.fileImageView.image = filePreviewImage;
}
// Disclosure indicator
if (item.directory) {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NCCommunicationFile *item = [_itemsInDirectory objectAtIndex:indexPath.row];
NSString *selectedItemPath = [NSString stringWithFormat:@"%@/%@", _path, item.fileName];
if (item.directory) {
DirectoryTableViewController *directoryVC = [[DirectoryTableViewController alloc] initWithPath:selectedItemPath inRoom:_token];
[self.navigationController pushViewController:directoryVC animated:YES];
} else {
[self showConfirmationDialogForSharingItemWithPath:selectedItemPath andName:item.fileName];
}
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
@end