зеркало из https://github.com/nextcloud/talk-ios.git
Implement preview for file-rooms
Use NCChatFileStatus instead NCMessageFileParameter to store download-related information Correctly set creation date on downloaded files for caching Signed-off-by: Marcel Müller <marcel-mueller@gmx.de>
This commit is contained in:
Родитель
ef6f29fa0b
Коммит
e5627c52c8
|
@ -13,6 +13,9 @@
|
|||
1F4DD3EB2571C688007DC98E /* EmojiUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4DD3EA2571C688007DC98E /* EmojiUtils.swift */; };
|
||||
1F4DD3EC2571C688007DC98E /* EmojiUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4DD3EA2571C688007DC98E /* EmojiUtils.swift */; };
|
||||
1F4DD3ED2571C688007DC98E /* EmojiUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4DD3EA2571C688007DC98E /* EmojiUtils.swift */; };
|
||||
1F5CDF642584E78900B0026E /* NCChatFileStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F5CDF632584E78900B0026E /* NCChatFileStatus.m */; };
|
||||
1F5CDF652584E78900B0026E /* NCChatFileStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F5CDF632584E78900B0026E /* NCChatFileStatus.m */; };
|
||||
1F5CDF662584E78900B0026E /* NCChatFileStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F5CDF632584E78900B0026E /* NCChatFileStatus.m */; };
|
||||
1FEDE3C6257D439500853F79 /* NCChatFileController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FEDE3C4257D439500853F79 /* NCChatFileController.m */; };
|
||||
1FEDE3C7257D439500853F79 /* NCChatFileController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FEDE3C4257D439500853F79 /* NCChatFileController.m */; };
|
||||
1FEDE3C8257D439500853F79 /* NCChatFileController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FEDE3C4257D439500853F79 /* NCChatFileController.m */; };
|
||||
|
@ -470,6 +473,8 @@
|
|||
1F3D3B20255F109E00230DAE /* BarButtonItemWithActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BarButtonItemWithActivity.m; sourceTree = "<group>"; };
|
||||
1F3D3B21255F109E00230DAE /* BarButtonItemWithActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BarButtonItemWithActivity.h; sourceTree = "<group>"; };
|
||||
1F4DD3EA2571C688007DC98E /* EmojiUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiUtils.swift; sourceTree = "<group>"; };
|
||||
1F5CDF622584E78900B0026E /* NCChatFileStatus.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NCChatFileStatus.h; sourceTree = "<group>"; };
|
||||
1F5CDF632584E78900B0026E /* NCChatFileStatus.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NCChatFileStatus.m; sourceTree = "<group>"; };
|
||||
1FEDE3C4257D439500853F79 /* NCChatFileController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NCChatFileController.m; sourceTree = "<group>"; };
|
||||
1FEDE3C5257D439500853F79 /* NCChatFileController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NCChatFileController.h; sourceTree = "<group>"; };
|
||||
1FEDE3CC257D43AB00853F79 /* NCMessageFileParameter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NCMessageFileParameter.m; sourceTree = "<group>"; };
|
||||
|
@ -1556,6 +1561,8 @@
|
|||
2C42ADB320B58E6300296DEA /* NCChatController.m */,
|
||||
1FEDE3C5257D439500853F79 /* NCChatFileController.h */,
|
||||
1FEDE3C4257D439500853F79 /* NCChatFileController.m */,
|
||||
1F5CDF622584E78900B0026E /* NCChatFileStatus.h */,
|
||||
1F5CDF632584E78900B0026E /* NCChatFileStatus.m */,
|
||||
2CA15543208E41B500CE8EF0 /* NCChatViewController.h */,
|
||||
2CA15544208E41B500CE8EF0 /* NCChatViewController.m */,
|
||||
2C43BA7421309A1000B3068A /* NCMessageParameter.h */,
|
||||
|
@ -2036,6 +2043,7 @@
|
|||
2CBF82B61FD0939600636459 /* NCAPISessionManager.m in Sources */,
|
||||
2CA155562099E07700CE8EF0 /* GroupedChatMessageTableViewCell.m in Sources */,
|
||||
2CA15548208EA1EA00CE8EF0 /* ChatMessageTableViewCell.m in Sources */,
|
||||
1F5CDF642584E78900B0026E /* NCChatFileStatus.m in Sources */,
|
||||
2CBF82C11FD5AE3F00636459 /* NCPushProxySessionManager.m in Sources */,
|
||||
2C961E152216BF4B00F5C23F /* OCSharedDto.m in Sources */,
|
||||
2C78EF951F7E70EB008AFA74 /* NCPeerConnection.m in Sources */,
|
||||
|
@ -2148,6 +2156,7 @@
|
|||
2C78E9E52512136100E3D4CA /* NCUserStatus.m in Sources */,
|
||||
2C62B00D24C1BDC1007E460A /* NCPushNotification.m in Sources */,
|
||||
2C62AFCD24C1BD78007E460A /* OCNotifications.m in Sources */,
|
||||
1F5CDF662584E78900B0026E /* NCChatFileStatus.m in Sources */,
|
||||
2C62B01C24C1BDC9007E460A /* CCCertificate.m in Sources */,
|
||||
2C62B01424C1BDC5007E460A /* RoomCreationTableViewController.m in Sources */,
|
||||
2C62AFCB24C1BD78007E460A /* OCExternalSites.m in Sources */,
|
||||
|
@ -2305,6 +2314,7 @@
|
|||
2CC001E224A37AD400A20167 /* VideoSettingsViewController.m in Sources */,
|
||||
2CC001AA24A37A8F00A20167 /* ChatMessageTableViewCell.m in Sources */,
|
||||
2C78E9E42512136000E3D4CA /* NCUserStatus.m in Sources */,
|
||||
1F5CDF652584E78900B0026E /* NCChatFileStatus.m in Sources */,
|
||||
2CC001BA24A37A9A00A20167 /* ResultMultiSelectionTableViewController.m in Sources */,
|
||||
2CC001B824A37A9A00A20167 /* SearchTableViewController.m in Sources */,
|
||||
2CC001D324A37ACA00A20167 /* RoomCreation2TableViewController.m in Sources */,
|
||||
|
|
|
@ -160,7 +160,7 @@
|
|||
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
|
||||
[self.avatarView setImageWithURLRequest:[[NCAPIController sharedInstance] createAvatarRequestForUser:message.actorId andSize:96 usingAccount:activeAccount]
|
||||
placeholderImage:nil success:nil failure:nil];
|
||||
|
||||
|
||||
NSString *imageName = [[NCUtils previewImageForFileMIMEType:message.file.mimetype] stringByAppendingString:@"-chat-preview"];
|
||||
UIImage *filePreviewImage = [UIImage imageNamed:imageName];
|
||||
__weak FilePreviewImageView *weakPreviewImageView = self.previewImageView;
|
||||
|
@ -177,8 +177,10 @@
|
|||
[self.statusView addSubview:errorView];
|
||||
} else if (message.isTemporary) {
|
||||
[self addActivityIndicator:0];
|
||||
} else if (message.file.isDownloading && message.file.downloadProgress < 1) {
|
||||
[self addActivityIndicator:message.file.downloadProgress];
|
||||
} else if (message.file.fileStatus) {
|
||||
if (message.file.fileStatus.isDownloading && message.file.fileStatus.downloadProgress < 1) {
|
||||
[self addActivityIndicator:message.file.fileStatus.downloadProgress];
|
||||
}
|
||||
}
|
||||
|
||||
self.fileParameter = message.file;
|
||||
|
@ -187,9 +189,9 @@
|
|||
- (void)didChangeIsDownloading:(NSNotification *)notification
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NCMessageFileParameter *receivedParameter = [notification.userInfo objectForKey:@"fileParameter"];
|
||||
NCChatFileStatus *receivedStatus = [notification.userInfo objectForKey:@"fileStatus"];
|
||||
|
||||
if (receivedParameter.parameterId != self->_fileParameter.parameterId || ![receivedParameter.path isEqualToString:self->_fileParameter.path]) {
|
||||
if (![receivedStatus.fileId isEqualToString:self->_fileParameter.parameterId] || ![receivedStatus.filePath isEqualToString:self->_fileParameter.path]) {
|
||||
// Received a notification for a different cell
|
||||
return;
|
||||
}
|
||||
|
@ -207,9 +209,9 @@
|
|||
- (void)didChangeDownloadProgress:(NSNotification *)notification
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NCMessageFileParameter *receivedParameter = [notification.userInfo objectForKey:@"fileParameter"];
|
||||
NCChatFileStatus *receivedStatus = [notification.userInfo objectForKey:@"fileStatus"];
|
||||
|
||||
if (receivedParameter.parameterId != self->_fileParameter.parameterId || ![receivedParameter.path isEqualToString:self->_fileParameter.path]) {
|
||||
if (![receivedStatus.fileId isEqualToString:self->_fileParameter.parameterId] || ![receivedStatus.filePath isEqualToString:self->_fileParameter.path]) {
|
||||
// Received a notification for a different cell
|
||||
return;
|
||||
}
|
||||
|
|
23
NextcloudTalk/Images.xcassets/preview-file-settings.imageset/Contents.json
поставляемый
Normal file
23
NextcloudTalk/Images.xcassets/preview-file-settings.imageset/Contents.json
поставляемый
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "preview-file-settings@1x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "preview-file-settings@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "preview-file-settings@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Двоичные данные
NextcloudTalk/Images.xcassets/preview-file-settings.imageset/preview-file-settings@1x.png
поставляемый
Normal file
Двоичные данные
NextcloudTalk/Images.xcassets/preview-file-settings.imageset/preview-file-settings@1x.png
поставляемый
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 731 B |
Двоичные данные
NextcloudTalk/Images.xcassets/preview-file-settings.imageset/preview-file-settings@2x.png
поставляемый
Normal file
Двоичные данные
NextcloudTalk/Images.xcassets/preview-file-settings.imageset/preview-file-settings@2x.png
поставляемый
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.4 KiB |
Двоичные данные
NextcloudTalk/Images.xcassets/preview-file-settings.imageset/preview-file-settings@3x.png
поставляемый
Normal file
Двоичные данные
NextcloudTalk/Images.xcassets/preview-file-settings.imageset/preview-file-settings@3x.png
поставляемый
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 2.1 KiB |
|
@ -23,6 +23,7 @@
|
|||
|
||||
#import "NCDatabaseManager.h"
|
||||
#import "NCMessageFileParameter.h"
|
||||
#import "NCChatFileStatus.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
@ -33,7 +34,7 @@ extern NSString * const NCChatFileControllerDidChangeDownloadProgressNotificatio
|
|||
|
||||
@protocol NCChatFileControllerDelegate<NSObject>
|
||||
|
||||
- (void)fileControllerDidLoadFile:(NCChatFileController *)fileController withFileParameter:(NCMessageFileParameter *)parameter withFilePath:(NSString *)path;
|
||||
- (void)fileControllerDidLoadFile:(NCChatFileController *)fileController withFileStatus:(NCChatFileStatus *)fileStatus;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -42,6 +43,7 @@ extern NSString * const NCChatFileControllerDidChangeDownloadProgressNotificatio
|
|||
@property (nonatomic, weak) id<NCChatFileControllerDelegate> delegate;
|
||||
|
||||
- (void)downloadFileFromMessage:(NCMessageFileParameter *)fileParameter;
|
||||
- (void)downloadFileWithFileId:(NSString *)fileId;
|
||||
- (void)deleteDownloadDirectoryForAccount:(TalkAccount *)account;
|
||||
|
||||
@end
|
||||
|
|
|
@ -32,10 +32,8 @@ int const kNCChatFileControllerDeleteFilesOlderThanDays = 7;
|
|||
|
||||
@interface NCChatFileController ()
|
||||
|
||||
@property (nonatomic, strong) TalkAccount *account;
|
||||
@property (nonatomic, strong) NCMessageFileParameter *fileParameter;
|
||||
@property (nonatomic, strong) NCChatFileStatus *fileStatus;
|
||||
@property (nonatomic, strong) NSString *tempDirectoryPath;
|
||||
@property (nonatomic, strong) NSString *fileLocalPath;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -44,8 +42,6 @@ int const kNCChatFileControllerDeleteFilesOlderThanDays = 7;
|
|||
|
||||
- (void)initDownloadDirectoryForAccount:(TalkAccount *)account
|
||||
{
|
||||
_account = account;
|
||||
|
||||
NSString *encodedAccountId = [account.accountId stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLHostAllowedCharacterSet];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
_tempDirectoryPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"/download/"];
|
||||
|
@ -113,13 +109,21 @@ int const kNCChatFileControllerDeleteFilesOlderThanDays = 7;
|
|||
return YES;
|
||||
}
|
||||
|
||||
// At this point there's a file in our cache but there's a newer one available
|
||||
// At this point there's a file in our cache but there's a different one on the server
|
||||
NSLog(@"Deleting file from cache: %@", filePath);
|
||||
[fileManager removeItemAtPath:filePath error:nil];
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)setCreationDateOnFile:(NSString *)filePath withCreationDate:(NSDate *)date
|
||||
{
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
|
||||
NSDictionary *creationDateAttr = [NSDictionary dictionaryWithObjectsAndKeys:date, NSFileCreationDate, nil];
|
||||
[fileManager setAttributes:creationDateAttr ofItemAtPath:filePath error:nil];
|
||||
}
|
||||
|
||||
- (void)setModificationDateOnFile:(NSString *)filePath withModificationDate:(NSDate *)date
|
||||
{
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
|
@ -129,6 +133,33 @@ int const kNCChatFileControllerDeleteFilesOlderThanDays = 7;
|
|||
}
|
||||
|
||||
- (void)downloadFileFromMessage:(NCMessageFileParameter *)fileParameter
|
||||
{
|
||||
_fileStatus = [NCChatFileStatus initWithFileName:fileParameter.name withFilePath:fileParameter.path withFileId:fileParameter.parameterId];
|
||||
fileParameter.fileStatus = _fileStatus;
|
||||
|
||||
[self startDownload];
|
||||
}
|
||||
|
||||
- (void)downloadFileWithFileId:(NSString *)fileId
|
||||
{
|
||||
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
|
||||
|
||||
[[NCAPIController sharedInstance] getFileByFileId:activeAccount fileId:fileId withCompletionBlock:^(NCCommunicationFile *file, NSInteger error, NSString *errorDescription) {
|
||||
if (file) {
|
||||
NSString *remoteDavPrefix = [NSString stringWithFormat:@"/remote.php/dav/files/%@/", activeAccount.userId];
|
||||
NSString *directoryPath = [file.path componentsSeparatedByString:remoteDavPrefix].lastObject;
|
||||
|
||||
NSString *filePath = [NSString stringWithFormat:@"%@%@", directoryPath, file.fileName];
|
||||
|
||||
self->_fileStatus = [NCChatFileStatus initWithFileName:file.fileName withFilePath:filePath withFileId:file.fileId];
|
||||
[self startDownload];
|
||||
} else {
|
||||
NSLog(@"An error occurred while getting file with fileId %@: %@", fileId, errorDescription);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)startDownload
|
||||
{
|
||||
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
|
||||
ServerCapabilities *serverCapabilities = [[NCDatabaseManager sharedInstance] serverCapabilitiesForAccountId:activeAccount.accountId];
|
||||
|
@ -136,10 +167,8 @@ int const kNCChatFileControllerDeleteFilesOlderThanDays = 7;
|
|||
[[NCAPIController sharedInstance] setupNCCommunicationForAccount:activeAccount];
|
||||
[self initDownloadDirectoryForAccount:activeAccount];
|
||||
|
||||
NSString *serverUrlFileName = [NSString stringWithFormat:@"%@/%@/%@", activeAccount.server, serverCapabilities.webDAVRoot, fileParameter.path];
|
||||
_account = activeAccount;
|
||||
_fileParameter = fileParameter;
|
||||
_fileLocalPath = [_tempDirectoryPath stringByAppendingPathComponent:fileParameter.name];
|
||||
NSString *serverUrlFileName = [NSString stringWithFormat:@"%@/%@/%@", activeAccount.server, serverCapabilities.webDAVRoot, _fileStatus.filePath];
|
||||
_fileStatus.fileLocalPath = [_tempDirectoryPath stringByAppendingPathComponent:_fileStatus.fileName];
|
||||
|
||||
// Setting just isDownloading without a concrete progress will show an indeterminate activity indicator
|
||||
[self didChangeIsDownloadingNotification:YES];
|
||||
|
@ -149,22 +178,27 @@ int const kNCChatFileControllerDeleteFilesOlderThanDays = 7;
|
|||
if (errorCode == 0 && files.count == 1) {
|
||||
// File exists on server -> check our cache
|
||||
NCCommunicationFile *file = files.firstObject;
|
||||
|
||||
if ([self isFileInCache:self->_fileLocalPath withModificationDate:file.date withSize:file.size]) {
|
||||
NSLog(@"Found file in cache: %@", self->_fileLocalPath);
|
||||
|
||||
if ([self isFileInCache:self->_fileStatus.fileLocalPath withModificationDate:file.date withSize:file.size]) {
|
||||
NSLog(@"Found file in cache: %@", self->_fileStatus.fileLocalPath);
|
||||
|
||||
[self.delegate fileControllerDidLoadFile:self withFileStatus:self->_fileStatus];
|
||||
[self didChangeIsDownloadingNotification:NO];
|
||||
[self.delegate fileControllerDidLoadFile:self withFileParameter:self->_fileParameter withFilePath:self->_fileLocalPath];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
[[NCCommunication shared] downloadWithServerUrlFileName:serverUrlFileName fileNameLocalPath:self->_fileLocalPath customUserAgent:nil addCustomHeaders:nil progressHandler:^(NSProgress *progress) {
|
||||
[[NCCommunication shared] downloadWithServerUrlFileName:serverUrlFileName fileNameLocalPath:self->_fileStatus.fileLocalPath customUserAgent:nil addCustomHeaders:nil progressHandler:^(NSProgress *progress) {
|
||||
[self didChangeDownloadProgressNotification:progress.fractionCompleted];
|
||||
} completionHandler:^(NSString *account, NSString *etag, NSDate *date, double length, NSDictionary *allHeaderFields, NSInteger errorCode, NSString * errorDescription) {
|
||||
[self setModificationDateOnFile:self->_fileLocalPath withModificationDate:file.date];
|
||||
// Set modification date to invalidate our cache
|
||||
[self setModificationDateOnFile:self->_fileStatus.fileLocalPath withModificationDate:file.date];
|
||||
|
||||
// Set creation date to delete older files from cache
|
||||
[self setCreationDateOnFile:self->_fileStatus.fileLocalPath withCreationDate:[NSDate date]];
|
||||
|
||||
[self.delegate fileControllerDidLoadFile:self withFileStatus:self->_fileStatus];
|
||||
[self didChangeIsDownloadingNotification:NO];
|
||||
[self.delegate fileControllerDidLoadFile:self withFileParameter:self->_fileParameter withFilePath:self->_fileLocalPath];
|
||||
}];
|
||||
} else {
|
||||
[self didChangeIsDownloadingNotification:NO];
|
||||
|
@ -175,13 +209,11 @@ int const kNCChatFileControllerDeleteFilesOlderThanDays = 7;
|
|||
|
||||
- (void)didChangeIsDownloadingNotification:(BOOL)isDownloading
|
||||
{
|
||||
_fileParameter.isDownloading = isDownloading;
|
||||
_fileStatus.isDownloading = isDownloading;
|
||||
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary new];
|
||||
[userInfo setObject:_account forKey:@"account"];
|
||||
[userInfo setObject:_fileParameter forKey:@"fileParameter"];
|
||||
[userInfo setObject:_fileStatus forKey:@"fileStatus"];
|
||||
[userInfo setObject:@(isDownloading) forKey:@"isDownloading"];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:NCChatFileControllerDidChangeIsDownloadingNotification
|
||||
object:self
|
||||
userInfo:userInfo];
|
||||
|
@ -189,11 +221,10 @@ int const kNCChatFileControllerDeleteFilesOlderThanDays = 7;
|
|||
|
||||
- (void)didChangeDownloadProgressNotification:(double)progress
|
||||
{
|
||||
_fileParameter.downloadProgress = progress;
|
||||
_fileStatus.downloadProgress = progress;
|
||||
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary new];
|
||||
[userInfo setObject:_account forKey:@"account"];
|
||||
[userInfo setObject:_fileParameter forKey:@"fileParameter"];
|
||||
[userInfo setObject:_fileStatus forKey:@"fileStatus"];
|
||||
[userInfo setObject:@(progress) forKey:@"progress"];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:NCChatFileControllerDidChangeDownloadProgressNotification
|
||||
object:self
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2020 Marcel Müller <marcel-mueller@gmx.de>
|
||||
*
|
||||
* @author Marcel Müller <marcel-mueller@gmx.de>
|
||||
*
|
||||
* @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 <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface NCChatFileStatus : NSObject
|
||||
|
||||
@property (nonatomic, strong) NSString *fileId;
|
||||
@property (nonatomic, strong) NSString *fileName;
|
||||
@property (nonatomic, strong) NSString *filePath;
|
||||
@property (nonatomic, strong) NSString *fileLocalPath;
|
||||
@property (nonatomic, assign) BOOL isDownloading;
|
||||
@property (nonatomic, assign) CGFloat downloadProgress;
|
||||
|
||||
+ (instancetype)initWithFileName:(NSString *)fileName withFilePath:(NSString *)filePath withFileId:(NSString *)fileId;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2020 Marcel Müller <marcel-mueller@gmx.de>
|
||||
*
|
||||
* @author Marcel Müller <marcel-mueller@gmx.de>
|
||||
*
|
||||
* @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 "NCChatFileStatus.h"
|
||||
|
||||
@implementation NCChatFileStatus
|
||||
|
||||
+ (instancetype)initWithFileName:(NSString *)fileName withFilePath:(NSString *)filePath withFileId:(NSString *)fileId
|
||||
{
|
||||
NCChatFileStatus *fileStatus = [[NCChatFileStatus alloc] init];
|
||||
|
||||
fileStatus.fileName = fileName;
|
||||
fileStatus.filePath = filePath;
|
||||
fileStatus.fileId = fileId;
|
||||
|
||||
return fileStatus;
|
||||
}
|
||||
|
||||
@end
|
|
@ -2244,7 +2244,7 @@ NSString * const NCChatViewControllerReplyPrivatelyNotification = @"NCChatViewCo
|
|||
|
||||
- (void)cellWantsToDownloadFile:(NCMessageFileParameter *)fileParameter
|
||||
{
|
||||
if (fileParameter.isDownloading) {
|
||||
if (fileParameter.fileStatus && fileParameter.fileStatus.isDownloading) {
|
||||
NSLog(@"File already downloading -> skipping new download");
|
||||
return;
|
||||
}
|
||||
|
@ -2256,7 +2256,7 @@ NSString * const NCChatViewControllerReplyPrivatelyNotification = @"NCChatViewCo
|
|||
|
||||
#pragma mark - NCChatFileControllerDelegate
|
||||
|
||||
- (void)fileControllerDidLoadFile:(NCChatFileController *)fileController withFileParameter:(NCMessageFileParameter *)parameter withFilePath:(NSString *)path
|
||||
- (void)fileControllerDidLoadFile:(NCChatFileController *)fileController withFileStatus:(NCChatFileStatus *)fileStatus
|
||||
{
|
||||
if (_isPreviewControllerShown) {
|
||||
// We are showing a file already, no need to open another one
|
||||
|
@ -2269,7 +2269,7 @@ NSString * const NCChatViewControllerReplyPrivatelyNotification = @"NCChatViewCo
|
|||
NSDate *sectionDate = [_dateSections objectAtIndex:indexPath.section];
|
||||
NCChatMessage *message = [[_messages objectForKey:sectionDate] objectAtIndex:indexPath.row];
|
||||
|
||||
if (message.file && message.file.parameterId == parameter.parameterId && [message.file.path isEqualToString:parameter.path]) {
|
||||
if (message.file && [message.file.parameterId isEqualToString:fileStatus.fileId] && [message.file.path isEqualToString:fileStatus.filePath]) {
|
||||
isFileCellStillVisible = YES;
|
||||
break;
|
||||
}
|
||||
|
@ -2282,7 +2282,7 @@ NSString * const NCChatViewControllerReplyPrivatelyNotification = @"NCChatViewCo
|
|||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self->_isPreviewControllerShown = YES;
|
||||
self->_previewControllerFilePath = path;
|
||||
self->_previewControllerFilePath = fileStatus.fileLocalPath;
|
||||
|
||||
QLPreviewController * preview = [[QLPreviewController alloc] init];
|
||||
UIColor *themeColor = [NCAppBranding themeColor];
|
||||
|
@ -2304,7 +2304,7 @@ NSString * const NCChatViewControllerReplyPrivatelyNotification = @"NCChatViewCo
|
|||
preview.navigationItem.scrollEdgeAppearance = appearance;
|
||||
}
|
||||
|
||||
[self presentViewController:preview animated:YES completion:nil];
|
||||
[self.navigationController pushViewController:preview animated:YES];
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "NCMessageParameter.h"
|
||||
#import "NCChatFileStatus.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
@ -32,8 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@property (nonatomic, strong) NSString *path;
|
||||
@property (nonatomic, strong) NSString *mimetype;
|
||||
@property (nonatomic, assign) BOOL previewAvailable;
|
||||
@property (nonatomic, assign) BOOL isDownloading;
|
||||
@property (nonatomic, assign) CGFloat downloadProgress;
|
||||
@property (nonatomic, strong) NCChatFileStatus *fileStatus;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
self.path = [parameterDict objectForKey:@"path"];
|
||||
self.mimetype = [parameterDict objectForKey:@"mimetype"];
|
||||
self.previewAvailable = [[parameterDict objectForKey:@"preview-available"] boolValue];
|
||||
self.isDownloading = NO;
|
||||
self.downloadProgress = 0;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#import "RoomInfoTableViewController.h"
|
||||
|
||||
#import <QuickLook/QuickLook.h>
|
||||
|
||||
#import "AddParticipantsTableViewController.h"
|
||||
#import "ContactsTableViewCell.h"
|
||||
|
@ -38,6 +39,7 @@
|
|||
#import "NCUtils.h"
|
||||
#import "UIImageView+Letters.h"
|
||||
#import "UIImageView+AFNetworking.h"
|
||||
#import "NCChatFileController.h"
|
||||
|
||||
typedef enum RoomInfoSection {
|
||||
kRoomInfoSectionName = 0,
|
||||
|
@ -45,14 +47,14 @@ typedef enum RoomInfoSection {
|
|||
kRoomInfoSectionPublic,
|
||||
kRoomInfoSectionWebinar,
|
||||
kRoomInfoSectionParticipants,
|
||||
kRoomInfoSectionDestructive
|
||||
kRoomInfoSectionDestructive,
|
||||
kRoomInfoSectionFile
|
||||
} RoomInfoSection;
|
||||
|
||||
typedef enum RoomAction {
|
||||
kRoomActionFavorite = 0,
|
||||
kRoomActionNotifications,
|
||||
kRoomActionSendLink,
|
||||
kRoomActionGotoFile
|
||||
kRoomActionSendLink
|
||||
} RoomAction;
|
||||
|
||||
typedef enum PublicAction {
|
||||
|
@ -84,9 +86,14 @@ typedef enum ModificationError {
|
|||
kModificationErrorDelete
|
||||
} ModificationError;
|
||||
|
||||
typedef enum FileAction {
|
||||
kFileActionPreview = 0,
|
||||
kFileActionOpenInFilesApp
|
||||
} FileAction;
|
||||
|
||||
#define k_set_password_textfield_tag 98
|
||||
|
||||
@interface RoomInfoTableViewController () <UITextFieldDelegate, UIGestureRecognizerDelegate, AddParticipantsTableViewControllerDelegate>
|
||||
@interface RoomInfoTableViewController () <UITextFieldDelegate, UIGestureRecognizerDelegate, AddParticipantsTableViewControllerDelegate, NCChatFileControllerDelegate, QLPreviewControllerDelegate, QLPreviewControllerDataSource>
|
||||
|
||||
@property (nonatomic, strong) NCRoom *room;
|
||||
@property (nonatomic, strong) NCChatViewController *chatViewController;
|
||||
|
@ -100,6 +107,8 @@ typedef enum ModificationError {
|
|||
@property (nonatomic, strong) UIActivityIndicatorView *modifyingRoomView;
|
||||
@property (nonatomic, strong) HeaderWithButton *headerView;
|
||||
@property (nonatomic, strong) UIAlertAction *setPasswordAction;
|
||||
@property (nonatomic, strong) UIActivityIndicatorView *fileDownloadIndicator;
|
||||
@property (nonatomic, strong) NSString *previewControllerFilePath;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -228,6 +237,10 @@ typedef enum ModificationError {
|
|||
[sections addObject:[NSNumber numberWithInt:kRoomInfoSectionName]];
|
||||
// Room actions section
|
||||
[sections addObject:[NSNumber numberWithInt:kRoomInfoSectionActions]];
|
||||
// File actions section
|
||||
if ([_room.objectType isEqualToString:NCRoomObjectTypeFile]) {
|
||||
[sections addObject:[NSNumber numberWithInt:kRoomInfoSectionFile]];
|
||||
}
|
||||
// Moderator sections
|
||||
if (_room.canModerate) {
|
||||
// Public room section
|
||||
|
@ -267,11 +280,6 @@ typedef enum ModificationError {
|
|||
[actions addObject:[NSNumber numberWithInt:kRoomActionSendLink]];
|
||||
}
|
||||
|
||||
// Action for file-rooms
|
||||
if ([_room.objectType isEqualToString:NCRoomObjectTypeFile]) {
|
||||
[actions addObject:[NSNumber numberWithInt:kRoomActionGotoFile]];
|
||||
}
|
||||
|
||||
return [NSArray arrayWithArray:actions];
|
||||
}
|
||||
|
||||
|
@ -285,6 +293,17 @@ typedef enum ModificationError {
|
|||
return actionIndexPath;
|
||||
}
|
||||
|
||||
- (NSArray *)getFileActions
|
||||
{
|
||||
NSMutableArray *actions = [[NSMutableArray alloc] init];
|
||||
// File preview
|
||||
[actions addObject:[NSNumber numberWithInt:kFileActionPreview]];
|
||||
// Open file in nextcloud app
|
||||
[actions addObject:[NSNumber numberWithInt:kFileActionOpenInFilesApp]];
|
||||
|
||||
return [NSArray arrayWithArray:actions];
|
||||
}
|
||||
|
||||
- (NSArray *)getPublicActions
|
||||
{
|
||||
NSMutableArray *actions = [[NSMutableArray alloc] init];
|
||||
|
@ -680,7 +699,25 @@ typedef enum ModificationError {
|
|||
};
|
||||
}
|
||||
|
||||
- (void)gotoRoomFileFromIndexPath:(NSIndexPath *)indexPath
|
||||
- (void)previewRoomFile:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (_fileDownloadIndicator) {
|
||||
// Already downloading a file
|
||||
return;
|
||||
}
|
||||
|
||||
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
|
||||
_fileDownloadIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 24, 24)];
|
||||
|
||||
[_fileDownloadIndicator startAnimating];
|
||||
[cell setAccessoryView:_fileDownloadIndicator];
|
||||
|
||||
NCChatFileController *downloader = [[NCChatFileController alloc] init];
|
||||
downloader.delegate = self;
|
||||
[downloader downloadFileWithFileId:_room.objectId];
|
||||
}
|
||||
|
||||
- (void)openRoomFileInFilesApp:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
|
||||
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 24, 24)];
|
||||
|
@ -725,8 +762,6 @@ typedef enum ModificationError {
|
|||
[[NCUserInterfaceController sharedInstance] presentAlertViewController:alert];
|
||||
}
|
||||
}];
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (void)leaveRoom
|
||||
|
@ -1035,6 +1070,10 @@ typedef enum ModificationError {
|
|||
return [self getRoomActions].count;
|
||||
break;
|
||||
|
||||
case kRoomInfoSectionFile:
|
||||
return [self getFileActions].count;
|
||||
break;
|
||||
|
||||
case kRoomInfoSectionPublic:
|
||||
return [self getPublicActions].count;
|
||||
break;
|
||||
|
@ -1079,6 +1118,9 @@ typedef enum ModificationError {
|
|||
NSArray *sections = [self getRoomInfoSections];
|
||||
RoomInfoSection infoSection = [[sections objectAtIndex:section] intValue];
|
||||
switch (infoSection) {
|
||||
case kRoomInfoSectionFile:
|
||||
return NSLocalizedString(@"Linked file", nil);
|
||||
break;
|
||||
case kRoomInfoSectionPublic:
|
||||
return NSLocalizedString(@"Guests", nil);
|
||||
break;
|
||||
|
@ -1121,6 +1163,7 @@ typedef enum ModificationError {
|
|||
case kRoomInfoSectionActions:
|
||||
return 10;
|
||||
break;
|
||||
case kRoomInfoSectionFile:
|
||||
case kRoomInfoSectionPublic:
|
||||
case kRoomInfoSectionWebinar:
|
||||
return 36;
|
||||
|
@ -1140,7 +1183,8 @@ typedef enum ModificationError {
|
|||
static NSString *shareLinkCellIdentifier = @"ShareLinkCellIdentifier";
|
||||
static NSString *passwordCellIdentifier = @"PasswordCellIdentifier";
|
||||
static NSString *sendLinkCellIdentifier = @"SendLinkCellIdentifier";
|
||||
static NSString *gotoFileCellIdentifier = @"GotoFileCellIdentifier";
|
||||
static NSString *previewFileCellIdentifier = @"PreviewFileCellIdentifier";
|
||||
static NSString *openFileCellIdentifier = @"OpenFileCellIdentifier";
|
||||
static NSString *lobbyCellIdentifier = @"LobbyCellIdentifier";
|
||||
static NSString *lobbyTimerCellIdentifier = @"LobbyTimerCellIdentifier";
|
||||
static NSString *leaveRoomCellIdentifier = @"LeaveRoomCellIdentifier";
|
||||
|
@ -1257,28 +1301,46 @@ typedef enum ModificationError {
|
|||
return cell;
|
||||
}
|
||||
break;
|
||||
case kRoomActionGotoFile:
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kRoomInfoSectionFile:
|
||||
{
|
||||
NSArray *actions = [self getFileActions];
|
||||
FileAction action = [[actions objectAtIndex:indexPath.row] intValue];
|
||||
switch (action) {
|
||||
case kFileActionPreview:
|
||||
{
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:gotoFileCellIdentifier];
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:previewFileCellIdentifier];
|
||||
if (!cell) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:gotoFileCellIdentifier];
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:previewFileCellIdentifier];
|
||||
}
|
||||
|
||||
cell.textLabel.text = NSLocalizedString(@"Go to file", nil);
|
||||
NSString *fileName = _room.name;
|
||||
NSString *fileExt = [fileName pathExtension];
|
||||
cell.textLabel.text = NSLocalizedString(@"Preview", nil);
|
||||
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
|
||||
[cell.imageView setImage:[UIImage imageNamed:@"preview-file-settings"]];
|
||||
|
||||
[cell.imageView setImage:[UIImage imageNamed:[NCUtils previewImageForFileExtension:fileExt]]];
|
||||
if (_fileDownloadIndicator) {
|
||||
// Set download indicator in case we're already downloading a file
|
||||
[cell setAccessoryView:_fileDownloadIndicator];
|
||||
}
|
||||
|
||||
// Make sure the file icon has the same size as all other cell-images
|
||||
// https://stackoverflow.com/questions/2788028/
|
||||
CGSize itemSize = CGSizeMake(24, 24);
|
||||
UIGraphicsBeginImageContextWithOptions(itemSize, NO, UIScreen.mainScreen.scale);
|
||||
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
|
||||
[cell.imageView.image drawInRect:imageRect];
|
||||
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return cell;
|
||||
}
|
||||
break;
|
||||
case kFileActionOpenInFilesApp:
|
||||
{
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:openFileCellIdentifier];
|
||||
if (!cell) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:openFileCellIdentifier];
|
||||
}
|
||||
|
||||
cell.textLabel.text = [NSString stringWithFormat:NSLocalizedString(@"Open in %@", nil), filesAppName];
|
||||
|
||||
UIImage *nextcloudActionImage = [[UIImage imageNamed:@"logo-action"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
||||
[cell.imageView setImage:nextcloudActionImage];
|
||||
cell.imageView.tintColor = [UIColor colorWithRed:0.43 green:0.43 blue:0.45 alpha:1];
|
||||
|
||||
return cell;
|
||||
}
|
||||
break;
|
||||
|
@ -1477,8 +1539,19 @@ typedef enum ModificationError {
|
|||
case kRoomActionSendLink:
|
||||
[self shareRoomLinkFromIndexPath:indexPath];
|
||||
break;
|
||||
case kRoomActionGotoFile:
|
||||
[self gotoRoomFileFromIndexPath:indexPath];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kRoomInfoSectionFile:
|
||||
{
|
||||
NSArray *actions = [self getFileActions];
|
||||
FileAction action = [[actions objectAtIndex:indexPath.row] intValue];
|
||||
switch (action) {
|
||||
case kFileActionPreview:
|
||||
[self previewRoomFile:indexPath];
|
||||
break;
|
||||
case kFileActionOpenInFilesApp:
|
||||
[self openRoomFileInFilesApp:indexPath];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1517,4 +1590,64 @@ typedef enum ModificationError {
|
|||
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark - NCChatFileControllerDelegate
|
||||
|
||||
- (void)fileControllerDidLoadFile:(NCChatFileController *)fileController withFileStatus:(NCChatFileStatus *)fileStatus
|
||||
{
|
||||
if (_fileDownloadIndicator) {
|
||||
[_fileDownloadIndicator stopAnimating];
|
||||
[_fileDownloadIndicator removeFromSuperview];
|
||||
_fileDownloadIndicator = nil;
|
||||
}
|
||||
|
||||
NSInteger fileSection = [[self getRoomInfoSections] indexOfObject:@(kRoomInfoSectionFile)];
|
||||
NSInteger previewRow = [[self getFileActions] indexOfObject:@(kFileActionPreview)];
|
||||
NSIndexPath *previewActionIndexPath = [NSIndexPath indexPathForRow:previewRow inSection:fileSection];
|
||||
|
||||
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:previewActionIndexPath];
|
||||
|
||||
if (cell) {
|
||||
// Make sure disclosure indicator is visible again (otherwise accessoryView is empty)
|
||||
cell.accessoryView = nil;
|
||||
|
||||
// Only show preview controller if cell is still visible
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self->_previewControllerFilePath = fileStatus.fileLocalPath;
|
||||
|
||||
QLPreviewController * preview = [[QLPreviewController alloc] init];
|
||||
UIColor *themeColor = [NCAppBranding themeColor];
|
||||
|
||||
preview.dataSource = self;
|
||||
preview.delegate = self;
|
||||
|
||||
preview.navigationController.navigationBar.tintColor = [NCAppBranding themeTextColor];
|
||||
preview.navigationController.navigationBar.barTintColor = themeColor;
|
||||
preview.tabBarController.tabBar.tintColor = themeColor;
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
|
||||
[appearance configureWithOpaqueBackground];
|
||||
appearance.backgroundColor = themeColor;
|
||||
appearance.titleTextAttributes = @{NSForegroundColorAttributeName:[NCAppBranding themeTextColor]};
|
||||
preview.navigationItem.standardAppearance = appearance;
|
||||
preview.navigationItem.compactAppearance = appearance;
|
||||
preview.navigationItem.scrollEdgeAppearance = appearance;
|
||||
}
|
||||
|
||||
[self.navigationController pushViewController:preview animated:YES];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - QLPreviewControllerDelegate/DataSource
|
||||
|
||||
- (NSInteger)numberOfPreviewItemsInPreviewController:(nonnull QLPreviewController *)controller {
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (nonnull id<QLPreviewItem>)previewController:(nonnull QLPreviewController *)controller previewItemAtIndex:(NSInteger)index {
|
||||
return [NSURL fileURLWithPath:_previewControllerFilePath];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
Загрузка…
Ссылка в новой задаче