зеркало из https://github.com/nextcloud/talk-ios.git
Merge pull request #434 from nextcloud/share-improvements
Share improvements
This commit is contained in:
Коммит
cad08183d0
|
@ -25,6 +25,17 @@
|
|||
2C06BF6420AC64370031EB46 /* DateHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C06BF6320AC64370031EB46 /* DateHeaderView.xib */; };
|
||||
2C06BF6720AC647A0031EB46 /* DateHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C06BF6620AC647A0031EB46 /* DateHeaderView.m */; };
|
||||
2C06BF6C20AEB0030031EB46 /* RoundedNumberView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C06BF6A20AEB0030031EB46 /* RoundedNumberView.m */; };
|
||||
2C1ABD8625769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1ABD8025769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.m */; };
|
||||
2C1ABD8725769E7D00AEDFB6 /* ShareItemController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1ABD8225769E7D00AEDFB6 /* ShareItemController.m */; };
|
||||
2C1ABD8825769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C1ABD8425769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.xib */; };
|
||||
2C1ABD8925769E7D00AEDFB6 /* ShareItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1ABD8525769E7D00AEDFB6 /* ShareItem.m */; };
|
||||
2C1ABD8D25769F4E00AEDFB6 /* ShareConfirmationCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1ABD8025769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.m */; };
|
||||
2C1ABD9125769F4F00AEDFB6 /* ShareConfirmationCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1ABD8025769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.m */; };
|
||||
2C1ABD9525769F6900AEDFB6 /* ShareConfirmationCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C1ABD8425769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.xib */; };
|
||||
2C1ABD9925769F7500AEDFB6 /* ShareItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1ABD8525769E7D00AEDFB6 /* ShareItem.m */; };
|
||||
2C1ABD9D25769F7500AEDFB6 /* ShareItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1ABD8525769E7D00AEDFB6 /* ShareItem.m */; };
|
||||
2C1ABDA125769F8400AEDFB6 /* ShareItemController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1ABD8225769E7D00AEDFB6 /* ShareItemController.m */; };
|
||||
2C1ABDA525769F8600AEDFB6 /* ShareItemController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1ABD8225769E7D00AEDFB6 /* ShareItemController.m */; };
|
||||
2C1D13A3253760EE00EC0533 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C1D13A1253760EE00EC0533 /* LaunchScreen.xib */; };
|
||||
2C1EF36B25505DCE007C9768 /* NCNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1EF36A25505DCE007C9768 /* NCNavigationController.m */; };
|
||||
2C1EF36C25505DCE007C9768 /* NCNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C1EF36A25505DCE007C9768 /* NCNavigationController.m */; };
|
||||
|
@ -475,6 +486,13 @@
|
|||
2C06BF6620AC647A0031EB46 /* DateHeaderView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DateHeaderView.m; sourceTree = "<group>"; };
|
||||
2C06BF6A20AEB0030031EB46 /* RoundedNumberView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoundedNumberView.m; sourceTree = "<group>"; };
|
||||
2C06BF6B20AEB0030031EB46 /* RoundedNumberView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoundedNumberView.h; sourceTree = "<group>"; };
|
||||
2C1ABD7F25769E7C00AEDFB6 /* ShareItemController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareItemController.h; sourceTree = "<group>"; };
|
||||
2C1ABD8025769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShareConfirmationCollectionViewCell.m; sourceTree = "<group>"; };
|
||||
2C1ABD8125769E7D00AEDFB6 /* ShareItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareItem.h; sourceTree = "<group>"; };
|
||||
2C1ABD8225769E7D00AEDFB6 /* ShareItemController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShareItemController.m; sourceTree = "<group>"; };
|
||||
2C1ABD8325769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareConfirmationCollectionViewCell.h; sourceTree = "<group>"; };
|
||||
2C1ABD8425769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ShareConfirmationCollectionViewCell.xib; sourceTree = "<group>"; };
|
||||
2C1ABD8525769E7D00AEDFB6 /* ShareItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShareItem.m; sourceTree = "<group>"; };
|
||||
2C1D13A2253760EE00EC0533 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
2C1EF36925505DCE007C9768 /* NCNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NCNavigationController.h; sourceTree = "<group>"; };
|
||||
2C1EF36A25505DCE007C9768 /* NCNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NCNavigationController.m; sourceTree = "<group>"; };
|
||||
|
@ -1163,6 +1181,13 @@
|
|||
2C62AFA424C08845007E460A /* ShareExtension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2C1ABD8325769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.h */,
|
||||
2C1ABD8025769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.m */,
|
||||
2C1ABD8425769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.xib */,
|
||||
2C1ABD8125769E7D00AEDFB6 /* ShareItem.h */,
|
||||
2C1ABD8525769E7D00AEDFB6 /* ShareItem.m */,
|
||||
2C1ABD7F25769E7C00AEDFB6 /* ShareItemController.h */,
|
||||
2C1ABD8225769E7D00AEDFB6 /* ShareItemController.m */,
|
||||
2C3195BB24C1F58A0066F221 /* ShareExtension.entitlements */,
|
||||
2C62AFAB24C08845007E460A /* Info.plist */,
|
||||
2C62AFB524C1A449007E460A /* Share.storyboard */,
|
||||
|
@ -1698,6 +1723,7 @@
|
|||
2CA1CCAC1F067F35002FE6A2 /* Images.xcassets in Resources */,
|
||||
2CA1CCD71F1E664C002FE6A2 /* ContactsTableViewCell.xib in Resources */,
|
||||
2C05748E1EDD9E8E00D9E7F2 /* Main.storyboard in Resources */,
|
||||
2C1ABD9525769F6900AEDFB6 /* ShareConfirmationCollectionViewCell.xib in Resources */,
|
||||
2C7A245D24FE7B5300921A21 /* ShareConfirmationViewController.xib in Resources */,
|
||||
2CC7158920B837140045C789 /* PlaceholderView.xib in Resources */,
|
||||
2C7A12432017872600864818 /* AddParticipantsTableViewController.xib in Resources */,
|
||||
|
@ -1710,6 +1736,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2C3195BC24C599130066F221 /* PlaceholderView.xib in Resources */,
|
||||
2C1ABD8825769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.xib in Resources */,
|
||||
2C7A245E24FE7B5300921A21 /* ShareConfirmationViewController.xib in Resources */,
|
||||
2C3195C324C5E2100066F221 /* ShareTableViewCell.xib in Resources */,
|
||||
2C3195BE24C5A7410066F221 /* Images.xcassets in Resources */,
|
||||
|
@ -1912,6 +1939,7 @@
|
|||
2C06BF6720AC647A0031EB46 /* DateHeaderView.m in Sources */,
|
||||
2CD5F3242142781A006B71BF /* NCExternalSignalingController.m in Sources */,
|
||||
2C0574851EDD9E8E00D9E7F2 /* AppDelegate.m in Sources */,
|
||||
2C1ABDA125769F8400AEDFB6 /* ShareItemController.m in Sources */,
|
||||
2C4987BD21E640E20060AC27 /* CallKitManager.m in Sources */,
|
||||
2C78EFA91F87EF39008AFA74 /* NBMPeersFlowLayout.m in Sources */,
|
||||
C1292B8C237313590004C3B7 /* CCBKPasscode.m in Sources */,
|
||||
|
@ -1943,6 +1971,7 @@
|
|||
2CC007BD20D8F24B0096D91F /* RoomCreation2TableViewController.m in Sources */,
|
||||
2C961E212216BF4B00F5C23F /* NSString+Encode.m in Sources */,
|
||||
2CBF82BD1FD5AE0A00636459 /* NCImageSessionManager.m in Sources */,
|
||||
2C1ABD9925769F7500AEDFB6 /* ShareItem.m in Sources */,
|
||||
2C2E64251F3462AF00D39CE8 /* NCSignalingMessage.m in Sources */,
|
||||
2CA1554B208F2E5700CE8EF0 /* NCMessageTextView.m in Sources */,
|
||||
2C961E202216BF4B00F5C23F /* OCXMLSharedParser.m in Sources */,
|
||||
|
@ -1973,6 +2002,7 @@
|
|||
2C78E9E325120DE600E3D4CA /* NCUserStatus.m in Sources */,
|
||||
2C0574A41EDDA2E300D9E7F2 /* LoginViewController.m in Sources */,
|
||||
2C961E132216BF4B00F5C23F /* OCNotificationsAction.m in Sources */,
|
||||
2C1ABD8D25769F4E00AEDFB6 /* ShareConfirmationCollectionViewCell.m in Sources */,
|
||||
2C78EFA51F86FF4A008AFA74 /* CallParticipantViewCell.m in Sources */,
|
||||
2C78EF991F80F81E008AFA74 /* NCSignalingController.m in Sources */,
|
||||
2CB304202264775E0053078A /* UIResponder+SLKAdditions.m in Sources */,
|
||||
|
@ -2045,6 +2075,7 @@
|
|||
2C62AFC924C1BD78007E460A /* OCCapabilities.m in Sources */,
|
||||
2C62AFBC24C1BD69007E460A /* FTPopOverMenu.m in Sources */,
|
||||
2C62AFEA24C1BD99007E460A /* NCCallController.m in Sources */,
|
||||
2C1ABD8625769E7D00AEDFB6 /* ShareConfirmationCollectionViewCell.m in Sources */,
|
||||
2C62AFC724C1BD78007E460A /* NCRichDocumentTemplate.m in Sources */,
|
||||
1F3D3B24255F109E00230DAE /* BarButtonItemWithActivity.m in Sources */,
|
||||
2C62AFF324C1BD9F007E460A /* MessageSeparatorTableViewCell.m in Sources */,
|
||||
|
@ -2070,6 +2101,7 @@
|
|||
2C62AFDA24C1BD83007E460A /* OCXMLShareByLinkParser.m in Sources */,
|
||||
2C62AFD124C1BD78007E460A /* OCShareUser.m in Sources */,
|
||||
2C62AFBE24C1BD74007E460A /* SLKTextInput+Implementation.m in Sources */,
|
||||
2C1ABD8925769E7D00AEDFB6 /* ShareItem.m in Sources */,
|
||||
2C62AFCA24C1BD78007E460A /* OCCommunication.m in Sources */,
|
||||
2C62B01324C1BDC5007E460A /* NCRoomsManager.m in Sources */,
|
||||
2C62AFF424C1BDA5007E460A /* DateHeaderView.m in Sources */,
|
||||
|
@ -2113,6 +2145,7 @@
|
|||
2C62AFBF24C1BD74007E460A /* SLKTextInputbar.m in Sources */,
|
||||
2C62AFCF24C1BD78007E460A /* OCRichObjectStrings.m in Sources */,
|
||||
2C62AFE424C1BD91007E460A /* ARDUtilities.m in Sources */,
|
||||
2C1ABD8725769E7D00AEDFB6 /* ShareItemController.m in Sources */,
|
||||
2C62AFFF24C1BDAA007E460A /* NCUser.m in Sources */,
|
||||
2C62AFC124C1BD74007E460A /* SLKTextView.m in Sources */,
|
||||
2C62AFEC24C1BD99007E460A /* CallKitManager.m in Sources */,
|
||||
|
@ -2212,6 +2245,7 @@
|
|||
2CC001E324A37ADB00A20167 /* HeaderWithButton.m in Sources */,
|
||||
2CC001AC24A37A8F00A20167 /* GroupedChatMessageTableViewCell.m in Sources */,
|
||||
2CC001C124A37AC500A20167 /* NCNotification.m in Sources */,
|
||||
2C1ABD9125769F4F00AEDFB6 /* ShareConfirmationCollectionViewCell.m in Sources */,
|
||||
2CC001E124A37AD400A20167 /* VideoResolutionsViewController.m in Sources */,
|
||||
2CC001AD24A37A8F00A20167 /* SystemMessageTableViewCell.m in Sources */,
|
||||
2CC001E824A37ADF00A20167 /* NCSignalingMessage.m in Sources */,
|
||||
|
@ -2238,7 +2272,9 @@
|
|||
2CC001A924A37A8F00A20167 /* ChatTableViewCell.m in Sources */,
|
||||
2CC0017924A37A4200A20167 /* SLKTextInput+Implementation.m in Sources */,
|
||||
2CC001A824A37A8B00A20167 /* NCAudioController.m in Sources */,
|
||||
2C1ABD9D25769F7500AEDFB6 /* ShareItem.m in Sources */,
|
||||
2CC001A524A37A8B00A20167 /* NCCallController.m in Sources */,
|
||||
2C1ABDA525769F8600AEDFB6 /* ShareItemController.m in Sources */,
|
||||
2CC0018324A37A5E00A20167 /* NCRichDocumentTemplate.m in Sources */,
|
||||
2CC001BD24A37ABD00A20167 /* AuthenticationViewController.m in Sources */,
|
||||
2CC001DB24A37AD000A20167 /* CCCertificate.m in Sources */,
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#import "UIImageView+Letters.h"
|
||||
#import "UIView+Toast.h"
|
||||
#import "BarButtonItemWithActivity.h"
|
||||
#import "ShareItem.h"
|
||||
|
||||
typedef enum NCChatMessageAction {
|
||||
kNCChatMessageActionReply = 1,
|
||||
|
@ -908,21 +909,18 @@ NSString * const NCChatViewControllerReplyPrivatelyNotification = @"NCChatViewCo
|
|||
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
|
||||
if ([mediaType isEqualToString:@"public.image"]) {
|
||||
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
|
||||
NSString *imageName = [NSString stringWithFormat:@"IMG_%.f.jpg", [[NSDate date] timeIntervalSince1970] * 1000];
|
||||
|
||||
[self dismissViewControllerAnimated:YES completion:^{
|
||||
[self presentViewController:navigationController animated:YES completion:^{
|
||||
[shareConfirmationVC setSharedImage:image withImageName:imageName];
|
||||
[shareConfirmationVC.shareItemController addItemWithImage:image];
|
||||
}];
|
||||
}];
|
||||
} else if ([mediaType isEqualToString:@"public.movie"]) {
|
||||
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
|
||||
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
|
||||
__block NSError *error;
|
||||
[coordinator coordinateReadingItemAtURL:videoURL options:NSFileCoordinatorReadingForUploading error:&error byAccessor:^(NSURL *newURL) {
|
||||
NSString *fileName = [NSString stringWithFormat:@"IMG_%.f.%@", [[NSDate date] timeIntervalSince1970] * 1000, [videoURL pathExtension]];
|
||||
[shareConfirmationVC setSharedFileWithFileURL:newURL andFileName:fileName];
|
||||
[self dismissViewControllerAnimated:YES completion:^{
|
||||
[self presentViewController:navigationController animated:YES completion:nil];
|
||||
|
||||
[self dismissViewControllerAnimated:YES completion:^{
|
||||
[self presentViewController:navigationController animated:YES completion:^{
|
||||
[shareConfirmationVC.shareItemController addItemWithURL:videoURL];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
@ -937,25 +935,15 @@ NSString * const NCChatViewControllerReplyPrivatelyNotification = @"NCChatViewCo
|
|||
|
||||
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url
|
||||
{
|
||||
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
|
||||
ServerCapabilities *serverCapabilities = [[NCDatabaseManager sharedInstance] serverCapabilitiesForAccountId:activeAccount.accountId];
|
||||
ShareConfirmationViewController *shareConfirmationVC = [[ShareConfirmationViewController alloc] initWithRoom:_room account:activeAccount serverCapabilities:serverCapabilities];
|
||||
shareConfirmationVC.delegate = self;
|
||||
shareConfirmationVC.isModal = YES;
|
||||
NCNavigationController *navigationController = [[NCNavigationController alloc] initWithRootViewController:shareConfirmationVC];
|
||||
|
||||
if (controller.documentPickerMode == UIDocumentPickerModeImport) {
|
||||
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
|
||||
__block NSError *error;
|
||||
[coordinator coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingForUploading error:&error byAccessor:^(NSURL *newURL) {
|
||||
[shareConfirmationVC setSharedFileWithFileURL:newURL];
|
||||
[self presentViewController:navigationController animated:YES completion:nil];
|
||||
}];
|
||||
}
|
||||
[self shareDocumentsWithURLs:@[url] fromController:controller];
|
||||
}
|
||||
|
||||
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls
|
||||
{
|
||||
[self shareDocumentsWithURLs:urls fromController:controller];
|
||||
}
|
||||
|
||||
- (void)shareDocumentsWithURLs:(NSArray<NSURL *> *)urls fromController:(UIDocumentPickerViewController *)controller {
|
||||
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
|
||||
ServerCapabilities *serverCapabilities = [[NCDatabaseManager sharedInstance] serverCapabilitiesForAccountId:activeAccount.accountId];
|
||||
ShareConfirmationViewController *shareConfirmationVC = [[ShareConfirmationViewController alloc] initWithRoom:_room account:activeAccount serverCapabilities:serverCapabilities];
|
||||
|
@ -963,15 +951,11 @@ NSString * const NCChatViewControllerReplyPrivatelyNotification = @"NCChatViewCo
|
|||
shareConfirmationVC.isModal = YES;
|
||||
NCNavigationController *navigationController = [[NCNavigationController alloc] initWithRootViewController:shareConfirmationVC];
|
||||
|
||||
// Just grab the first item for now
|
||||
NSURL *url = urls.firstObject;
|
||||
|
||||
if (controller.documentPickerMode == UIDocumentPickerModeImport) {
|
||||
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
|
||||
__block NSError *error;
|
||||
[coordinator coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingForUploading error:&error byAccessor:^(NSURL *newURL) {
|
||||
[shareConfirmationVC setSharedFileWithFileURL:newURL];
|
||||
[self presentViewController:navigationController animated:YES completion:nil];
|
||||
[self presentViewController:navigationController animated:YES completion:^{
|
||||
for (NSURL* url in urls) {
|
||||
[shareConfirmationVC.shareItemController addItemWithURL:url];
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,13 +27,13 @@
|
|||
<key>NSExtensionActivationRule</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationSupportsAttachmentsWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<integer>5</integer>
|
||||
<key>NSExtensionActivationSupportsFileWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<integer>5</integer>
|
||||
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<integer>5</integer>
|
||||
<key>NSExtensionActivationSupportsMovieWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<integer>5</integer>
|
||||
<key>NSExtensionActivationSupportsText</key>
|
||||
<true/>
|
||||
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* @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 <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern NSString *const kShareConfirmationCellIdentifier;
|
||||
extern NSString *const kShareConfirmationTableCellNibName;
|
||||
|
||||
@interface ShareConfirmationCollectionViewCell : UICollectionViewCell
|
||||
|
||||
@property (strong, nonatomic) IBOutlet UIImageView *previewView;
|
||||
@property (strong, nonatomic) IBOutlet UIImageView *placeholderImageView;
|
||||
@property (strong, nonatomic) IBOutlet UITextView *placeholderTextView;
|
||||
|
||||
- (void)setPlaceHolderImage:(UIImage *)image;
|
||||
- (void)setPlaceHolderText:(NSString *)text;
|
||||
- (void)setPreviewImage:(UIImage *)image;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* @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 "ShareConfirmationCollectionViewCell.h"
|
||||
|
||||
NSString *const kShareConfirmationCellIdentifier = @"ShareConfirmationCellIdentifier";
|
||||
NSString *const kShareConfirmationTableCellNibName = @"ShareConfirmationCollectionViewCell";
|
||||
|
||||
@implementation ShareConfirmationCollectionViewCell
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[super awakeFromNib];
|
||||
}
|
||||
|
||||
|
||||
- (void)prepareForReuse
|
||||
{
|
||||
[super prepareForReuse];
|
||||
|
||||
self.previewView.image = nil;
|
||||
self.placeholderImageView.image = nil;
|
||||
self.placeholderTextView.text = @"";
|
||||
|
||||
self.placeholderImageView.hidden = NO;
|
||||
self.placeholderTextView.hidden = NO;
|
||||
}
|
||||
|
||||
- (void)setPreviewImage:(UIImage *)image
|
||||
{
|
||||
[self.previewView setImage:image];
|
||||
|
||||
self.placeholderImageView.hidden = YES;
|
||||
self.placeholderTextView.hidden = YES;
|
||||
}
|
||||
|
||||
- (void)setPlaceHolderImage:(UIImage *)image
|
||||
{
|
||||
[self.placeholderImageView setImage:image];
|
||||
}
|
||||
|
||||
- (void)setPlaceHolderText:(NSString *)text
|
||||
{
|
||||
[self.placeholderTextView setText:text];
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17506" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17505"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ShareConfirmationCollectionViewCell"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="ShareConfirmationCollectionViewCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="682"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="682"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" id="jUv-Qc-6mk">
|
||||
<rect key="frame" x="20" y="20" width="120" height="120"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES"/>
|
||||
</imageView>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="BBL-0Q-Diy">
|
||||
<rect key="frame" x="20" y="160" width="374" height="502"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<color key="textColor" systemColor="labelColor"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
</textView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Vrf-tE-ZXU">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="682"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<edgeInsets key="layoutMargins" top="0.0" left="0.0" bottom="0.0" right="0.0"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
</view>
|
||||
<viewLayoutGuide key="safeArea" id="SEy-5g-ep8"/>
|
||||
<size key="customSize" width="457" height="818"/>
|
||||
<connections>
|
||||
<outlet property="placeholderImageView" destination="jUv-Qc-6mk" id="Bbw-Qk-dYZ"/>
|
||||
<outlet property="placeholderTextView" destination="BBL-0Q-Diy" id="8PN-hk-qOS"/>
|
||||
<outlet property="previewView" destination="Vrf-tE-ZXU" id="1Ti-ki-NOr"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="434.78260869565219" y="102.45535714285714"/>
|
||||
</collectionViewCell>
|
||||
</objects>
|
||||
<resources>
|
||||
<systemColor name="labelColor">
|
||||
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
|
@ -21,17 +21,19 @@
|
|||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <UIKit/UIPageControl.h>
|
||||
|
||||
#import "NCRoom.h"
|
||||
#import "NCDatabaseManager.h"
|
||||
#import "ShareConfirmationCollectionViewCell.h"
|
||||
#import "ShareItem.h"
|
||||
#import "ShareItemController.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef enum ShareConfirmationType {
|
||||
ShareConfirmationTypeText = 0,
|
||||
ShareConfirmationTypeImage,
|
||||
ShareConfirmationTypeFile,
|
||||
ShareConfirmationTypeImageFile
|
||||
ShareConfirmationTypeItem
|
||||
} ShareConfirmationType;
|
||||
|
||||
@class ShareConfirmationViewController;
|
||||
|
@ -50,27 +52,18 @@ typedef enum ShareConfirmationType {
|
|||
@property (strong, nonatomic) TalkAccount *account;
|
||||
@property (strong, nonatomic) ServerCapabilities *serverCapabilities;
|
||||
@property (assign, nonatomic) ShareConfirmationType type;
|
||||
@property (strong, nonatomic) NSString *sharedText;
|
||||
@property (strong, nonatomic) NSString *sharedImageName;
|
||||
@property (strong, nonatomic) UIImage *sharedImage;
|
||||
@property (strong, nonatomic) NSString *sharedFileName;
|
||||
@property (strong, nonatomic) UIImage *sharedFileImage;
|
||||
@property (strong, nonatomic) NSURL *sharedFileURL;
|
||||
@property (strong, nonatomic) NSData *sharedFile;
|
||||
@property (assign, nonatomic) BOOL isModal;
|
||||
@property (strong, nonatomic) ShareItemController *shareItemController;
|
||||
|
||||
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomSpacer;
|
||||
@property (weak, nonatomic) IBOutlet UIView *toBackgroundView;
|
||||
@property (weak, nonatomic) IBOutlet UITextView *toTextView;
|
||||
@property (weak, nonatomic) IBOutlet UITextView *shareTextView;
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *shareImageView;
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *shareFileImageView;
|
||||
@property (weak, nonatomic) IBOutlet UITextView *shareFileTextView;
|
||||
@property (weak, nonatomic) IBOutlet UICollectionView *shareCollectionView;
|
||||
@property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
|
||||
|
||||
- (id)initWithRoom:(NCRoom *)room account:(TalkAccount *)account serverCapabilities:(ServerCapabilities *)serverCapabilities;
|
||||
- (void)setSharedFileWithFileURL:(NSURL *)fileURL;
|
||||
- (void)setSharedFileWithFileURL:(NSURL *)fileURL andFileName:(NSString *_Nullable)fileName;
|
||||
- (void)setSharedImage:(UIImage *)image withImageName:(NSString *)imageName;
|
||||
- (void)shareText:(NSString *)text;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#import "ShareConfirmationViewController.h"
|
||||
#import "ShareConfirmationCollectionViewCell.h"
|
||||
|
||||
#import <NCCommunication/NCCommunication.h>
|
||||
|
||||
|
@ -30,12 +31,16 @@
|
|||
#import "NCSettingsController.h"
|
||||
#import "NCUtils.h"
|
||||
#import "MBProgressHUD.h"
|
||||
#import <QuickLook/QuickLook.h>
|
||||
#import <QuickLookThumbnailing/QuickLookThumbnailing.h>
|
||||
|
||||
@interface ShareConfirmationViewController () <NCCommunicationCommonDelegate>
|
||||
@interface ShareConfirmationViewController () <NCCommunicationCommonDelegate, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, QLPreviewControllerDataSource, QLPreviewControllerDelegate, ShareItemControllerDelegate>
|
||||
{
|
||||
UIBarButtonItem *_sendButton;
|
||||
UIActivityIndicatorView *_sharingIndicatorView;
|
||||
MBProgressHUD *_hud;
|
||||
dispatch_group_t _uploadGroup;
|
||||
BOOL _uploadFailed;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -75,6 +80,11 @@
|
|||
self.navigationItem.scrollEdgeAppearance = appearance;
|
||||
}
|
||||
|
||||
self.pageControl.currentPageIndicatorTintColor = [NCAppBranding themeColor];
|
||||
self.pageControl.pageIndicatorTintColor = [NCAppBranding placeholderColor];
|
||||
self.pageControl.hidesForSinglePage = YES;
|
||||
self.pageControl.numberOfPages = 1;
|
||||
|
||||
if (_isModal) {
|
||||
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
|
||||
target:self action:@selector(cancelButtonPressed)];
|
||||
|
@ -106,8 +116,29 @@
|
|||
NSMutableAttributedString *toString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:NSLocalizedString(@"To: %@", nil), _room.displayName] attributes:attributes];
|
||||
[toString addAttributes:subAttribute range:NSMakeRange(0, 3)];
|
||||
self.toTextView.attributedText = toString;
|
||||
|
||||
self.shareCollectionView.delegate = self;
|
||||
|
||||
[self setUIForShareType:_type];
|
||||
self.shareItemController = [[ShareItemController alloc] init];
|
||||
self.shareItemController.delegate = self;
|
||||
|
||||
NSBundle *bundle = [NSBundle bundleForClass:[ShareConfirmationCollectionViewCell class]];
|
||||
[self.shareCollectionView registerNib:[UINib nibWithNibName:kShareConfirmationTableCellNibName bundle:bundle] forCellWithReuseIdentifier:kShareConfirmationCellIdentifier];
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(keyboardWillShow:)
|
||||
name:UIKeyboardWillShowNotification
|
||||
object:nil];
|
||||
|
||||
_type = ShareConfirmationTypeItem;
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
if (_type == ShareConfirmationTypeText) {
|
||||
[self.shareTextView becomeFirstResponder];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancelButtonPressed
|
||||
|
@ -119,61 +150,22 @@
|
|||
{
|
||||
if (_type == ShareConfirmationTypeText) {
|
||||
[self sendSharedText];
|
||||
} else if (_type == ShareConfirmationTypeImage ||
|
||||
_type == ShareConfirmationTypeFile ||
|
||||
_type == ShareConfirmationTypeImageFile) {
|
||||
[self uploadAndShareFile];
|
||||
} else {
|
||||
[self uploadAndShareFiles];
|
||||
}
|
||||
|
||||
[self startAnimatingSharingIndicator];
|
||||
}
|
||||
|
||||
- (void)setSharedText:(NSString *)sharedText
|
||||
- (void)shareText:(NSString *)sharedText
|
||||
{
|
||||
_sharedText = sharedText;
|
||||
|
||||
_type = ShareConfirmationTypeText;
|
||||
[self setUIForShareType:_type];
|
||||
}
|
||||
|
||||
- (void)setSharedFileWithFileURL:(NSURL *)fileURL
|
||||
{
|
||||
[self setSharedFileWithFileURL:fileURL andFileName:nil];
|
||||
}
|
||||
|
||||
- (void)setSharedFileWithFileURL:(NSURL *)fileURL andFileName:(NSString *_Nullable)fileName
|
||||
{
|
||||
_sharedFileURL = fileURL;
|
||||
_sharedFileName = fileName ? fileName : [fileURL lastPathComponent];
|
||||
_sharedFile = [NSData dataWithContentsOfURL:fileURL];
|
||||
|
||||
_type = ShareConfirmationTypeFile;
|
||||
|
||||
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:fileURL]];
|
||||
if (image) {
|
||||
_type = ShareConfirmationTypeImageFile;
|
||||
_sharedImage = image;
|
||||
}
|
||||
|
||||
CFStringRef fileExtension = (__bridge CFStringRef)[fileURL pathExtension];
|
||||
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
|
||||
CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType);
|
||||
CFRelease(UTI);
|
||||
|
||||
NSString *mimeType = (__bridge NSString *)MIMEType;
|
||||
NSString *imageName = [[NCUtils previewImageForFileMIMEType:mimeType] stringByAppendingString:@"-chat-preview"];
|
||||
_sharedFileImage = [UIImage imageNamed:imageName];
|
||||
|
||||
[self setUIForShareType:_type];
|
||||
}
|
||||
|
||||
- (void)setSharedImage:(UIImage *)image withImageName:(NSString *)imageName
|
||||
{
|
||||
_sharedImage = image;
|
||||
_sharedImageName = imageName;
|
||||
|
||||
_type = ShareConfirmationTypeImage;
|
||||
[self setUIForShareType:_type];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.shareCollectionView.hidden = YES;
|
||||
self.shareTextView.hidden = NO;
|
||||
self.shareTextView.text = sharedText;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)setIsModal:(BOOL)isModal
|
||||
|
@ -185,7 +177,7 @@
|
|||
|
||||
- (void)sendSharedText
|
||||
{
|
||||
[[NCAPIController sharedInstance] sendChatMessage:_sharedText toRoom:_room.token displayName:nil replyTo:-1 referenceId:nil forAccount:_account withCompletionBlock:^(NSError *error) {
|
||||
[[NCAPIController sharedInstance] sendChatMessage:self.shareTextView.text toRoom:_room.token displayName:nil replyTo:-1 referenceId:nil forAccount:_account withCompletionBlock:^(NSError *error) {
|
||||
if (error) {
|
||||
[self.delegate shareConfirmationViewControllerDidFailed:self];
|
||||
NSLog(@"Failed to send shared item");
|
||||
|
@ -196,50 +188,79 @@
|
|||
}];
|
||||
}
|
||||
|
||||
- (void)uploadAndShareFile
|
||||
- (void)updateHudProgress
|
||||
{
|
||||
NSString *fileName = (_type == ShareConfirmationTypeImage) ? _sharedImageName : _sharedFileName;
|
||||
NSString *fileLocalPath = [self localFilePath];
|
||||
if (_type == ShareConfirmationTypeImage) {
|
||||
NSData *pngData = UIImageJPEGRepresentation(_sharedImage, 0.7);
|
||||
[pngData writeToFile:fileLocalPath atomically:YES];
|
||||
} else {
|
||||
[_sharedFile writeToFile:fileLocalPath atomically:YES];
|
||||
if (!_hud) {
|
||||
return;
|
||||
}
|
||||
|
||||
_hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
|
||||
_hud.mode = MBProgressHUDModeAnnularDeterminate;
|
||||
_hud.label.text = NSLocalizedString(@"Uploading file", nil);
|
||||
if (_type == ShareConfirmationTypeImage || _type == ShareConfirmationTypeImageFile) {
|
||||
_hud.label.text = NSLocalizedString(@"Uploading image", nil);
|
||||
}
|
||||
|
||||
[self checkForUniqueNameAndUploadFileWithName:fileName withOriginalName:YES];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
CGFloat progress = 0;
|
||||
long items = 0;
|
||||
|
||||
for (ShareItem *item in self->_shareItemController.shareItems) {
|
||||
progress += item.uploadProgress;
|
||||
items++;
|
||||
}
|
||||
|
||||
self->_hud.progress = (progress / items);
|
||||
});
|
||||
}
|
||||
|
||||
- (void)checkForUniqueNameAndUploadFileWithName:(NSString *)fileName withOriginalName:(BOOL)isOriginalName
|
||||
- (void)uploadAndShareFiles
|
||||
{
|
||||
NSString *filePath = [self serverFilePathForFileName:fileName];
|
||||
NSString *fileServerURL = [self serverFileURLForFilePath:filePath];
|
||||
NSString *fileLocalPath = [self localFilePath];
|
||||
_hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
|
||||
_hud.mode = MBProgressHUDModeAnnularDeterminate;
|
||||
_hud.label.text = [NSString stringWithFormat:NSLocalizedString(@"Uploading %ld elements", nil), [self.shareItemController.shareItems count]];
|
||||
|
||||
_uploadGroup = dispatch_group_create();
|
||||
_uploadFailed = NO;
|
||||
|
||||
for (ShareItem *item in self.shareItemController.shareItems) {
|
||||
NSLog(@"Uploading %@", item.fileURL);
|
||||
|
||||
dispatch_group_enter(_uploadGroup);
|
||||
[self checkForUniqueNameAndUploadFileWithName:item.fileName withItem:item withOriginalName:YES];
|
||||
}
|
||||
|
||||
dispatch_group_notify(_uploadGroup, dispatch_get_main_queue(),^{
|
||||
[self stopAnimatingSharingIndicator];
|
||||
[self->_hud hideAnimated:YES];
|
||||
|
||||
[self->_shareItemController removeAllItems];
|
||||
|
||||
// TODO: Do error reporting per item
|
||||
if (self->_uploadFailed) {
|
||||
[self.delegate shareConfirmationViewControllerDidFailed:self];
|
||||
} else {
|
||||
[self.delegate shareConfirmationViewControllerDidFinish:self];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)checkForUniqueNameAndUploadFileWithName:(NSString *)fileName withItem:(ShareItem *)item withOriginalName:(BOOL)isOriginalName
|
||||
{
|
||||
NSString *fileServerPath = [self serverFilePathForFileName:fileName];
|
||||
NSString *fileServerURL = [self serverFileURLForFilePath:fileServerPath];
|
||||
|
||||
[[NCCommunication shared] readFileOrFolderWithServerUrlFileName:fileServerURL depth:@"0" showHiddenFiles:NO requestBody:nil customUserAgent:nil addCustomHeaders:nil completionHandler:^(NSString *accounts, NSArray<NCCommunicationFile *> *files, NSData *responseData, NSInteger errorCode, NSString *errorDescription) {
|
||||
// File already exist
|
||||
// File already exists
|
||||
if (errorCode == 0 && files.count == 1) {
|
||||
NSString *alternativeName = [self alternativeNameForFileName:fileName original:isOriginalName];
|
||||
[self checkForUniqueNameAndUploadFileWithName:alternativeName withOriginalName:NO];
|
||||
// File do not exist
|
||||
[self checkForUniqueNameAndUploadFileWithName:alternativeName withItem:item withOriginalName:NO];
|
||||
// File does not exist
|
||||
} else if (errorCode == 404) {
|
||||
[self uploadFileToServerURL:fileServerURL withFilePath:filePath locatedInLocalPath:fileLocalPath];
|
||||
[self uploadFileToServerURL:fileServerURL withFilePath:fileServerPath withItem:item];
|
||||
} else {
|
||||
NSLog(@"Error checking file name");
|
||||
[self stopAnimatingSharingIndicator];
|
||||
[self.delegate shareConfirmationViewControllerDidFailed:self];
|
||||
|
||||
self->_uploadFailed = YES;
|
||||
dispatch_group_leave(self->_uploadGroup);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)checkAttachmentFolderAndUploadFileToServerURL:(NSString *)fileServerURL withFilePath:(NSString *)filePath locatedInLocalPath:(NSString *)fileLocalPath
|
||||
- (void)checkAttachmentFolderAndUploadFileToServerURL:(NSString *)fileServerURL withFilePath:(NSString *)filePath withItem:(ShareItem *)item
|
||||
{
|
||||
NSString *attachmentFolderServerURL = [self attachmentFolderServerURL];
|
||||
[[NCCommunication shared] readFileOrFolderWithServerUrlFileName:attachmentFolderServerURL depth:@"0" showHiddenFiles:NO requestBody:nil customUserAgent:nil addCustomHeaders:nil completionHandler:^(NSString *accounts, NSArray<NCCommunicationFile *> *files, NSData *responseData, NSInteger errorCode, NSString *errorDescription) {
|
||||
|
@ -247,40 +268,43 @@
|
|||
if (errorCode == 404) {
|
||||
[[NCCommunication shared] createFolder:attachmentFolderServerURL customUserAgent:nil addCustomHeaders:nil completionHandler:^(NSString *account, NSString *nose, NSDate *date, NSInteger errorCode, NSString *errorDescription) {
|
||||
if (errorCode == 0) {
|
||||
[self uploadFileToServerURL:fileServerURL withFilePath:filePath locatedInLocalPath:fileLocalPath];
|
||||
[self uploadFileToServerURL:fileServerURL withFilePath:filePath withItem:item];
|
||||
}
|
||||
}];
|
||||
} else {
|
||||
NSLog(@"Error checking attachment folder");
|
||||
[self stopAnimatingSharingIndicator];
|
||||
[self.delegate shareConfirmationViewControllerDidFailed:self];
|
||||
|
||||
self->_uploadFailed = YES;
|
||||
dispatch_group_leave(self->_uploadGroup);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)uploadFileToServerURL:(NSString *)fileServerURL withFilePath:(NSString *)filePath locatedInLocalPath:(NSString *)fileLocalPath
|
||||
- (void)uploadFileToServerURL:(NSString *)fileServerURL withFilePath:(NSString *)filePath withItem:(ShareItem *)item
|
||||
{
|
||||
[[NCCommunication shared] uploadWithServerUrlFileName:fileServerURL fileNameLocalPath:fileLocalPath dateCreationFile:nil dateModificationFile:nil customUserAgent:nil addCustomHeaders:nil progressHandler:^(NSProgress * progress) {
|
||||
self->_hud.progress = progress.fractionCompleted;
|
||||
[[NCCommunication shared] uploadWithServerUrlFileName:fileServerURL fileNameLocalPath:item.filePath dateCreationFile:nil dateModificationFile:nil customUserAgent:nil addCustomHeaders:nil progressHandler:^(NSProgress * progress) {
|
||||
item.uploadProgress = progress.fractionCompleted;
|
||||
[self updateHudProgress];
|
||||
} completionHandler:^(NSString *account, NSString *ocId, NSString *etag, NSDate *date, int64_t size, NSDictionary *allHeaderFields, NSInteger errorCode, NSString *errorDescription) {
|
||||
NSLog(@"Upload completed with error code: %ld", (long)errorCode);
|
||||
[self->_hud hideAnimated:YES];
|
||||
|
||||
if (errorCode == 0) {
|
||||
[[NCAPIController sharedInstance] shareFileOrFolderForAccount:self->_account atPath:filePath toRoom:self->_room.token withCompletionBlock:^(NSError *error) {
|
||||
if (error) {
|
||||
[self.delegate shareConfirmationViewControllerDidFailed:self];
|
||||
NSLog(@"Failed to send shared file");
|
||||
|
||||
self->_uploadFailed = YES;
|
||||
dispatch_group_leave(self->_uploadGroup);
|
||||
} else {
|
||||
[self.delegate shareConfirmationViewControllerDidFinish:self];
|
||||
dispatch_group_leave(self->_uploadGroup);
|
||||
}
|
||||
[self stopAnimatingSharingIndicator];
|
||||
}];
|
||||
} else if (errorCode == 404) {
|
||||
[self checkAttachmentFolderAndUploadFileToServerURL:fileServerURL withFilePath:filePath locatedInLocalPath:fileLocalPath];
|
||||
[self checkAttachmentFolderAndUploadFileToServerURL:fileServerURL withFilePath:filePath withItem:item];
|
||||
} else {
|
||||
[self.delegate shareConfirmationViewControllerDidFailed:self];
|
||||
self->_uploadFailed = YES;
|
||||
dispatch_group_leave(self->_uploadGroup);
|
||||
}
|
||||
[self stopAnimatingSharingIndicator];
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -303,14 +327,6 @@
|
|||
return [NSString stringWithFormat:@"%@/%@%@", _account.server, _serverCapabilities.webDAVRoot, filePath];
|
||||
}
|
||||
|
||||
- (NSString *)localFilePath
|
||||
{
|
||||
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
|
||||
NSURL *fileLocalURL = [[tmpDirURL URLByAppendingPathComponent:@"file"] URLByAppendingPathExtension:@"data"];
|
||||
|
||||
return [fileLocalURL path];
|
||||
}
|
||||
|
||||
- (NSString *)alternativeNameForFileName:(NSString *)fileName original:(BOOL)isOriginal
|
||||
{
|
||||
NSString *extension = [fileName pathExtension];
|
||||
|
@ -355,47 +371,148 @@
|
|||
});
|
||||
}
|
||||
|
||||
- (void)setUIForShareType:(ShareConfirmationType)shareConfirmationType
|
||||
-(void)keyboardWillShow:(NSNotification *)notification
|
||||
{
|
||||
// see https://stackoverflow.com/a/22719225/2512312
|
||||
NSDictionary *info = notification.userInfo;
|
||||
NSValue *value = info[UIKeyboardFrameEndUserInfoKey];
|
||||
|
||||
CGRect rawFrame = [value CGRectValue];
|
||||
CGRect keyboardFrame = [self.view convertRect:rawFrame fromView:nil];
|
||||
|
||||
[UIView animateWithDuration:0.3 animations:^{
|
||||
self.bottomSpacer.constant = keyboardFrame.size.height;
|
||||
[self.view layoutIfNeeded];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - ScrollView/CollectionView
|
||||
|
||||
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
ShareConfirmationCollectionViewCell *cell = (ShareConfirmationCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:kShareConfirmationCellIdentifier forIndexPath:indexPath];
|
||||
ShareItem *item = [self.shareItemController.shareItems objectAtIndex:indexPath.row];
|
||||
|
||||
// Setting placeholder here in case we can't generate any other preview
|
||||
[cell setPlaceHolderImage:item.placeholderImage];
|
||||
[cell setPlaceHolderText:item.fileName];
|
||||
|
||||
// Check if we got an image
|
||||
NSData *fileData = [NSData dataWithContentsOfURL:item.fileURL];
|
||||
UIImage *image = [UIImage imageWithData:fileData];
|
||||
|
||||
if (image) {
|
||||
// We're able to get an image directly from the fileURL -> use it
|
||||
[cell setPreviewImage:image];
|
||||
} else {
|
||||
// We need to generate our own preview/thumbnail here
|
||||
[self generatePreviewForCell:cell withCollectionView:collectionView withItem:item];
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)generatePreviewForCell:(ShareConfirmationCollectionViewCell *)cell withCollectionView:(UICollectionView *)collectionView withItem:(ShareItem *)item
|
||||
{
|
||||
if (@available(iOS 13.0, *)) {
|
||||
CGSize size = CGSizeMake(collectionView.bounds.size.width, collectionView.bounds.size.height);
|
||||
CGFloat scale = [UIScreen mainScreen].scale;
|
||||
|
||||
// updateHandler might be called multiple times, starting from low quality representation to high-quality
|
||||
QLThumbnailGenerationRequest *request = [[QLThumbnailGenerationRequest alloc] initWithFileAtURL:item.fileURL size:size scale:scale representationTypes:(QLThumbnailGenerationRequestRepresentationTypeLowQualityThumbnail | QLThumbnailGenerationRequestRepresentationTypeThumbnail)];
|
||||
[QLThumbnailGenerator.sharedGenerator generateRepresentationsForRequest:request updateHandler:^(QLThumbnailRepresentation * _Nullable thumbnail, QLThumbnailRepresentationType type, NSError * _Nullable error) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[cell setPreviewImage:thumbnail.UIImage];
|
||||
});
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)collectionView:(nonnull UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
||||
return [self.shareItemController.shareItems count];
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
return CGSizeMake(collectionView.bounds.size.width, collectionView.bounds.size.height);
|
||||
}
|
||||
|
||||
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
|
||||
{
|
||||
// see: https://stackoverflow.com/a/46181277/2512312
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
switch (shareConfirmationType) {
|
||||
case ShareConfirmationTypeText:
|
||||
{
|
||||
self.shareTextView.hidden = NO;
|
||||
self.shareImageView.hidden = YES;
|
||||
self.shareFileImageView.hidden = YES;
|
||||
self.shareFileTextView.hidden = YES;
|
||||
|
||||
self.shareTextView.text = self->_sharedText;
|
||||
self.shareTextView.editable = NO;
|
||||
}
|
||||
break;
|
||||
case ShareConfirmationTypeImage:
|
||||
case ShareConfirmationTypeImageFile:
|
||||
{
|
||||
self.shareTextView.hidden = YES;
|
||||
self.shareImageView.hidden = NO;
|
||||
self.shareFileImageView.hidden = YES;
|
||||
self.shareFileTextView.hidden = YES;
|
||||
|
||||
[self.shareImageView setImage:self->_sharedImage];
|
||||
}
|
||||
break;
|
||||
case ShareConfirmationTypeFile:
|
||||
{
|
||||
self.shareTextView.hidden = YES;
|
||||
self.shareImageView.hidden = YES;
|
||||
self.shareFileImageView.hidden = NO;
|
||||
self.shareFileTextView.hidden = NO;
|
||||
|
||||
[self.shareFileImageView setImage:self->_sharedFileImage];
|
||||
self.shareFileTextView.text = self->_sharedFileName;
|
||||
self.shareFileTextView.editable = NO;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
self.pageControl.currentPage = scrollView.contentOffset.x / scrollView.frame.size.width;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
QLPreviewController * preview = [[QLPreviewController alloc] init];
|
||||
preview.currentPreviewItemIndex = indexPath.row;
|
||||
preview.dataSource = self;
|
||||
preview.delegate = self;
|
||||
|
||||
preview.navigationController.navigationBar.tintColor = [NCAppBranding themeTextColor];
|
||||
preview.navigationController.navigationBar.barTintColor = [NCAppBranding themeColor];
|
||||
preview.tabBarController.tabBar.tintColor = [NCAppBranding themeColor];
|
||||
|
||||
UIColor *themeColor = [NCAppBranding 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 - PreviewController
|
||||
|
||||
- (nonnull id<QLPreviewItem>)previewController:(nonnull QLPreviewController *)controller previewItemAtIndex:(NSInteger)index {
|
||||
// Don't use index here, as this relates to numberOfPreviewItems
|
||||
// When we have numberOfPreviewItema > 1 this will show an additional list of items
|
||||
ShareItem *item = [self.shareItemController.shareItems objectAtIndex:self.shareCollectionView.indexPathsForSelectedItems.firstObject.row];
|
||||
|
||||
if (item && item.fileURL) {
|
||||
return item.fileURL;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (QLPreviewItemEditingMode)previewController:(QLPreviewController *)controller editingModeForPreviewItem:(id<QLPreviewItem>)previewItem API_AVAILABLE(ios(13.0)) {
|
||||
return QLPreviewItemEditingModeCreateCopy;
|
||||
}
|
||||
|
||||
- (void)previewController:(QLPreviewController *)controller didSaveEditedCopyOfPreviewItem:(id<QLPreviewItem>)previewItem atURL:(NSURL *)modifiedContentsURL {
|
||||
ShareItem *item = [self.shareItemController.shareItems objectAtIndex:self.shareCollectionView.indexPathsForSelectedItems.firstObject.row];
|
||||
|
||||
if (item) {
|
||||
[self.shareItemController updateItem:item withURL:modifiedContentsURL];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - ShareItemController Delegate
|
||||
|
||||
- (void)shareItemControllerItemsChanged:(nonnull ShareItemController *)shareItemController {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.shareCollectionView reloadData];
|
||||
self.pageControl.numberOfPages = [self.shareItemController.shareItems count];
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -411,5 +528,4 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17506" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17125"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17505"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
|
@ -11,10 +11,10 @@
|
|||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ShareConfirmationViewController">
|
||||
<connections>
|
||||
<outlet property="shareFileImageView" destination="5QM-q4-3rz" id="bRC-rU-qqg"/>
|
||||
<outlet property="shareFileTextView" destination="Dak-dL-eGs" id="Xgp-xQ-TAz"/>
|
||||
<outlet property="shareImageView" destination="MWY-NH-jyC" id="VP1-ek-up2"/>
|
||||
<outlet property="shareTextView" destination="nd6-Tq-h5e" id="Dzc-cu-QJt"/>
|
||||
<outlet property="bottomSpacer" destination="zBa-uc-p45" id="Hng-Vo-rq0"/>
|
||||
<outlet property="pageControl" destination="82n-bL-hfY" id="qyS-on-PM3"/>
|
||||
<outlet property="shareCollectionView" destination="uJR-VI-6WE" id="5ga-Ah-u1s"/>
|
||||
<outlet property="shareTextView" destination="QKC-YS-SNr" id="EY7-7j-ubB"/>
|
||||
<outlet property="toBackgroundView" destination="ZlP-A7-sH2" id="DFl-6K-ybn"/>
|
||||
<outlet property="toTextView" destination="zFH-sS-bfQ" id="coA-l6-J3O"/>
|
||||
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
|
||||
|
@ -25,10 +25,12 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="414" height="808"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZlP-A7-sH2">
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZlP-A7-sH2">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="36"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" white="0.94876391267123283" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="36" id="6e8-hc-OT7"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" editable="NO" text="To:" textAlignment="natural" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zFH-sS-bfQ">
|
||||
<rect key="frame" x="20" y="0.0" width="374" height="36"/>
|
||||
|
@ -37,33 +39,56 @@
|
|||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
</textView>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="nd6-Tq-h5e">
|
||||
<rect key="frame" x="20" y="56" width="374" height="718"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<textView hidden="YES" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="QKC-YS-SNr">
|
||||
<rect key="frame" x="20" y="56" width="374" height="698"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<color key="textColor" systemColor="labelColor"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
</textView>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="Dak-dL-eGs">
|
||||
<rect key="frame" x="20" y="184" width="374" height="622"/>
|
||||
<pageControl opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" numberOfPages="2" translatesAutoresizingMaskIntoConstraints="NO" id="82n-bL-hfY">
|
||||
<rect key="frame" x="20" y="746" width="374" height="28"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<color key="pageIndicatorTintColor" systemColor="secondaryLabelColor"/>
|
||||
<color key="currentPageIndicatorTintColor" systemColor="labelColor"/>
|
||||
</pageControl>
|
||||
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" pagingEnabled="YES" showsVerticalScrollIndicator="NO" dataMode="none" translatesAutoresizingMaskIntoConstraints="NO" id="uJR-VI-6WE">
|
||||
<rect key="frame" x="0.0" y="56" width="414" height="682"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<color key="textColor" systemColor="labelColor"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
</textView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" id="5QM-q4-3rz">
|
||||
<rect key="frame" x="20" y="56" width="120" height="120"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
</imageView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MWY-NH-jyC">
|
||||
<rect key="frame" x="20" y="44" width="374" height="730"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</imageView>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="0.0" minimumInteritemSpacing="0.0" id="l35-ib-MXz">
|
||||
<size key="itemSize" width="300" height="700"/>
|
||||
<size key="headerReferenceSize" width="0.0" height="0.0"/>
|
||||
<size key="footerReferenceSize" width="0.0" height="0.0"/>
|
||||
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
</collectionViewFlowLayout>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="-1" id="0DN-Yc-6ng"/>
|
||||
<outlet property="delegate" destination="-1" id="tfq-Xf-WwY"/>
|
||||
</connections>
|
||||
</collectionView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7Tz-V8-nzC">
|
||||
<rect key="frame" x="80" y="774" width="254" height="0.0"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" id="zBa-uc-p45"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="Q5M-cg-NOt"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="7Tz-V8-nzC" firstAttribute="bottom" secondItem="Q5M-cg-NOt" secondAttribute="bottom" id="1Sa-Qp-h6d"/>
|
||||
<constraint firstItem="QKC-YS-SNr" firstAttribute="top" secondItem="ZlP-A7-sH2" secondAttribute="bottom" constant="20" id="7ld-4t-a7i"/>
|
||||
<constraint firstItem="Q5M-cg-NOt" firstAttribute="trailing" secondItem="QKC-YS-SNr" secondAttribute="trailing" constant="20" id="8al-lO-vQR"/>
|
||||
<constraint firstItem="ZlP-A7-sH2" firstAttribute="leading" secondItem="Q5M-cg-NOt" secondAttribute="leading" id="D5G-RT-0po"/>
|
||||
<constraint firstItem="QKC-YS-SNr" firstAttribute="leading" secondItem="Q5M-cg-NOt" secondAttribute="leading" constant="20" id="Fca-UI-irX"/>
|
||||
<constraint firstItem="7Tz-V8-nzC" firstAttribute="leading" secondItem="Q5M-cg-NOt" secondAttribute="leading" constant="80" id="PdK-CR-8Pj"/>
|
||||
<constraint firstItem="7Tz-V8-nzC" firstAttribute="top" secondItem="QKC-YS-SNr" secondAttribute="bottom" constant="20" id="RMR-5S-FnI"/>
|
||||
<constraint firstItem="ZlP-A7-sH2" firstAttribute="trailing" secondItem="Q5M-cg-NOt" secondAttribute="trailing" id="bHi-tw-Hdl"/>
|
||||
<constraint firstItem="ZlP-A7-sH2" firstAttribute="top" secondItem="Q5M-cg-NOt" secondAttribute="top" id="fCt-jr-xcs"/>
|
||||
<constraint firstItem="Q5M-cg-NOt" firstAttribute="trailing" secondItem="7Tz-V8-nzC" secondAttribute="trailing" constant="80" id="fYg-Iw-9i2"/>
|
||||
</constraints>
|
||||
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" translucent="NO" prompted="NO"/>
|
||||
<point key="canvasLocation" x="137.68115942028987" y="124.55357142857142"/>
|
||||
</view>
|
||||
|
@ -72,6 +97,9 @@
|
|||
<systemColor name="labelColor">
|
||||
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="secondaryLabelColor">
|
||||
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
|
|
|
@ -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 <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ShareItem : NSObject
|
||||
|
||||
@property (nonatomic, strong) NSURL *fileURL;
|
||||
@property (nonatomic, strong) NSString *filePath;
|
||||
@property (nonatomic, strong) NSString *fileName;
|
||||
@property (nonatomic, strong) UIImage *placeholderImage;
|
||||
@property (nonatomic, assign) CGFloat uploadProgress;
|
||||
|
||||
+ (instancetype)initWithURL:(NSURL *)fileURL withName:(NSString *)fileName withPlaceholderImage:(UIImage *)placeholderImage;
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* @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 "ShareItem.h"
|
||||
|
||||
@implementation ShareItem
|
||||
|
||||
|
||||
+ (instancetype)initWithURL:(NSURL *)fileURL withName:(NSString *)fileName withPlaceholderImage:(UIImage *)placeholderImage
|
||||
{
|
||||
ShareItem* item = [[ShareItem alloc] init];
|
||||
item.fileURL = fileURL;
|
||||
item.filePath = fileURL.path;
|
||||
item.fileName = fileName;
|
||||
item.placeholderImage = placeholderImage;
|
||||
item.uploadProgress = 0;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* @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>
|
||||
#import "ShareItem.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class ShareItemController;
|
||||
@protocol ShareItemControllerDelegate <NSObject>
|
||||
|
||||
- (void)shareItemControllerItemsChanged:(ShareItemController *)shareItemController;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface ShareItemController : NSObject
|
||||
|
||||
@property (nonatomic, weak) id<ShareItemControllerDelegate> delegate;
|
||||
@property (strong, nonatomic) NSMutableArray *shareItems;
|
||||
|
||||
- (void)addItemWithURL:(NSURL *)fileURL;
|
||||
- (void)addItemWithURLAndName:(NSURL *)fileURL withName:(NSString *)fileName;
|
||||
- (void)addItemWithImage:(UIImage *)image;
|
||||
- (void)addItemWithImageAndName:(UIImage *)image withName:(NSString *)imageName;
|
||||
- (void)updateItem:(ShareItem *)item withURL:(NSURL *)fileURL;
|
||||
- (void)removeItem:(ShareItem *)item;
|
||||
- (void)removeAllItems;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,165 @@
|
|||
/**
|
||||
* @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 <MobileCoreServices/MobileCoreServices.h>
|
||||
|
||||
#import "ShareItemController.h"
|
||||
#import "NCUtils.h"
|
||||
|
||||
@interface ShareItemController ()
|
||||
|
||||
@property (nonatomic, strong) NSString *tempDirectoryPath;
|
||||
@property (nonatomic, strong) NSURL *tempDirectoryURL;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ShareItemController
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.shareItems = [[NSMutableArray alloc] init];
|
||||
[self initTempDirectory];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)initTempDirectory
|
||||
{
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
self.tempDirectoryPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"/upload/"];
|
||||
|
||||
if (![fileManager fileExistsAtPath:self.tempDirectoryPath]) {
|
||||
// Make sure our upload directory exists
|
||||
[fileManager createDirectoryAtPath:self.tempDirectoryPath withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
} else {
|
||||
// Clean up any temporary files from a previous upload
|
||||
NSArray *previousFiles = [fileManager contentsOfDirectoryAtPath:self.tempDirectoryPath error:nil];
|
||||
|
||||
for (NSString *previousFile in previousFiles) {
|
||||
[fileManager removeItemAtPath:[self.tempDirectoryPath stringByAppendingPathComponent:previousFile] error:nil];
|
||||
}
|
||||
}
|
||||
|
||||
self.tempDirectoryURL = [NSURL fileURLWithPath:self.tempDirectoryPath isDirectory:YES];
|
||||
}
|
||||
|
||||
|
||||
- (void)addItemWithURL:(NSURL *)fileURL
|
||||
{
|
||||
[self addItemWithURLAndName:fileURL withName:fileURL.lastPathComponent];
|
||||
}
|
||||
|
||||
- (void)addItemWithURLAndName:(NSURL *)fileURL withName:(NSString *)fileName
|
||||
{
|
||||
NSURL *fileLocalURL = [self.tempDirectoryURL URLByAppendingPathComponent:fileName];
|
||||
|
||||
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
|
||||
__block NSError *error;
|
||||
|
||||
// Make a local copy to prevent bug where file is removed after some time from inbox
|
||||
// See: https://stackoverflow.com/a/48007752/2512312
|
||||
[coordinator coordinateReadingItemAtURL:fileURL options:NSFileCoordinatorReadingForUploading error:&error byAccessor:^(NSURL *newURL) {
|
||||
if ([NSFileManager.defaultManager fileExistsAtPath:fileLocalURL.path]) {
|
||||
[NSFileManager.defaultManager removeItemAtPath:fileLocalURL.path error:nil];
|
||||
}
|
||||
|
||||
[NSFileManager.defaultManager moveItemAtPath:newURL.path toPath:fileLocalURL.path error:nil];
|
||||
}];
|
||||
|
||||
NSLog(@"Adding shareItem: %@ %@", fileName, fileLocalURL);
|
||||
|
||||
ShareItem* item = [ShareItem initWithURL:fileLocalURL withName:fileName withPlaceholderImage:[self getPlaceholderImageForFileURL:fileLocalURL]];
|
||||
[self.shareItems addObject:item];
|
||||
[self.delegate shareItemControllerItemsChanged:self];
|
||||
}
|
||||
|
||||
- (void)addItemWithImage:(UIImage *)image
|
||||
{
|
||||
NSString *imageName = [NSString stringWithFormat:@"IMG_%.f.jpg", [[NSDate date] timeIntervalSince1970] * 1000];
|
||||
[self addItemWithImageAndName:image withName:imageName];
|
||||
}
|
||||
|
||||
- (void)addItemWithImageAndName:(UIImage *)image withName:(NSString *)imageName
|
||||
{
|
||||
NSURL *fileLocalURL = [self.tempDirectoryURL URLByAppendingPathComponent:imageName];
|
||||
|
||||
//TODO: Should the quality be user-selectable?
|
||||
NSData *jpegData = UIImageJPEGRepresentation(image, 0.7);
|
||||
|
||||
[jpegData writeToFile:fileLocalURL.path atomically:YES];
|
||||
|
||||
NSLog(@"Adding shareItem with image: %@ %@", imageName, fileLocalURL);
|
||||
|
||||
ShareItem* item = [ShareItem initWithURL:fileLocalURL withName:imageName withPlaceholderImage:[self getPlaceholderImageForFileURL:fileLocalURL]];
|
||||
|
||||
[self.shareItems addObject:item];
|
||||
[self.delegate shareItemControllerItemsChanged:self];
|
||||
}
|
||||
|
||||
- (void)updateItem:(ShareItem *)item withURL:(NSURL *)fileURL
|
||||
{
|
||||
// This is called when an item was edited in quicklook and we want to use the edited image
|
||||
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
|
||||
__block NSError *error;
|
||||
|
||||
[coordinator coordinateReadingItemAtURL:fileURL options:NSFileCoordinatorReadingForUploading error:&error byAccessor:^(NSURL *newURL) {
|
||||
if ([NSFileManager.defaultManager fileExistsAtPath:item.filePath]) {
|
||||
[NSFileManager.defaultManager removeItemAtPath:item.filePath error:nil];
|
||||
}
|
||||
|
||||
[NSFileManager.defaultManager moveItemAtPath:newURL.path toPath:item.filePath error:nil];
|
||||
}];
|
||||
|
||||
NSLog(@"Updating shareItem: %@ %@", item.fileName, item.fileURL);
|
||||
|
||||
[self.delegate shareItemControllerItemsChanged:self];
|
||||
}
|
||||
|
||||
- (void)removeItem:(ShareItem *)item
|
||||
{
|
||||
if ([NSFileManager.defaultManager fileExistsAtPath:item.filePath]) {
|
||||
[NSFileManager.defaultManager removeItemAtPath:item.filePath error:nil];
|
||||
}
|
||||
|
||||
NSLog(@"Removing shareItem: %@ %@", item.fileName, item.fileURL);
|
||||
|
||||
[self.shareItems removeObject:item];
|
||||
[self.delegate shareItemControllerItemsChanged:self];
|
||||
}
|
||||
|
||||
- (void)removeAllItems
|
||||
{
|
||||
for (ShareItem *item in self.shareItems) {
|
||||
[self removeItem:item];
|
||||
}
|
||||
}
|
||||
|
||||
- (UIImage *)getPlaceholderImageForFileURL:(NSURL *)fileURL
|
||||
{
|
||||
NSString *previewImage = [NCUtils previewImageForFileExtension:[fileURL pathExtension]];
|
||||
NSString *imageName = [previewImage stringByAppendingString:@"-chat-preview"];
|
||||
return [UIImage imageNamed:imageName];
|
||||
}
|
||||
|
||||
@end
|
|
@ -207,11 +207,8 @@
|
|||
if ([(NSObject *)item isKindOfClass:[NSURL class]]) {
|
||||
NSLog(@"Shared Video = %@", item);
|
||||
NSURL *videoURL = (NSURL *)item;
|
||||
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
|
||||
__block NSError *error;
|
||||
[coordinator coordinateReadingItemAtURL:videoURL options:NSFileCoordinatorReadingForUploading error:&error byAccessor:^(NSURL *newURL) {
|
||||
[shareConfirmationVC setSharedFileWithFileURL:newURL];
|
||||
}];
|
||||
|
||||
[shareConfirmationVC.shareItemController addItemWithURL:videoURL];
|
||||
}
|
||||
}];
|
||||
return;
|
||||
|
@ -224,12 +221,9 @@
|
|||
completionHandler:^(id<NSSecureCoding> _Nullable item, NSError * _Null_unspecified error) {
|
||||
if ([(NSObject *)item isKindOfClass:[NSURL class]]) {
|
||||
NSLog(@"Shared File URL = %@", item);
|
||||
NSURL *fileUrl = (NSURL *)item;
|
||||
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
|
||||
__block NSError *error;
|
||||
[coordinator coordinateReadingItemAtURL:fileUrl options:NSFileCoordinatorReadingForUploading error:&error byAccessor:^(NSURL *newURL) {
|
||||
[shareConfirmationVC setSharedFileWithFileURL:newURL];
|
||||
}];
|
||||
NSURL *fileURL = (NSURL *)item;
|
||||
|
||||
[shareConfirmationVC.shareItemController addItemWithURL:fileURL];
|
||||
}
|
||||
}];
|
||||
return;
|
||||
|
@ -242,13 +236,12 @@
|
|||
if ([(NSObject *)item isKindOfClass:[NSURL class]]) {
|
||||
NSLog(@"Shared Image = %@", item);
|
||||
NSURL *imageURL = (NSURL *)item;
|
||||
[shareConfirmationVC setSharedFileWithFileURL:imageURL];
|
||||
[shareConfirmationVC.shareItemController addItemWithURL:imageURL];
|
||||
} else if ([(NSObject *)item isKindOfClass:[UIImage class]]) {
|
||||
// Occurs when sharing a screenshot
|
||||
NSLog(@"Shared UIImage = %@", item);
|
||||
UIImage *image = (UIImage *)item;
|
||||
NSString *imageName = [NSString stringWithFormat:@"IMG_%.f.jpg", [[NSDate date] timeIntervalSince1970] * 1000];
|
||||
[shareConfirmationVC setSharedImage:image withImageName:imageName];
|
||||
[shareConfirmationVC.shareItemController addItemWithImage:image];
|
||||
}
|
||||
}];
|
||||
return;
|
||||
|
@ -261,7 +254,7 @@
|
|||
if ([(NSObject *)item isKindOfClass:[NSURL class]]) {
|
||||
NSLog(@"Shared URL = %@", item);
|
||||
NSURL *sharedURL = (NSURL *)item;
|
||||
[shareConfirmationVC setSharedText:sharedURL.absoluteString];
|
||||
[shareConfirmationVC shareText:sharedURL.absoluteString];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
@ -273,7 +266,7 @@
|
|||
if ([(NSObject *)item isKindOfClass:[NSString class]]) {
|
||||
NSLog(@"Shared Text = %@", item);
|
||||
NSString *sharedText = (NSString *)item;
|
||||
[shareConfirmationVC setSharedText:sharedText];
|
||||
[shareConfirmationVC shareText:sharedText];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче