diff --git a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.h b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.h index 87aabe50b3..1e7cd2cd0a 100644 --- a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.h +++ b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.h @@ -51,6 +51,13 @@ typedef enum : NSUInteger } MXKRoomDataSourceBubblesPagination; +// Check filesize before sending: make RoomDataSource errors public +typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) { + MXKRoomDataSourceErrorResendGeneric = 10001, + MXKRoomDataSourceErrorResendInvalidMessageType = 10002, + MXKRoomDataSourceErrorResendInvalidLocalFilePath = 10003, + MXKRoomDataSourceErrorCantSendFileToBig = 10004, // Check filesize before sending: file to big error +}; #pragma mark - Cells identifiers diff --git a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m index 033aa93618..8399b4c2af 100644 --- a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m +++ b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m @@ -46,11 +46,12 @@ NSString * const MXKRoomDataSourceErrorDomain = @"kMXKRoomDataSourceErrorDomain"; -typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) { - MXKRoomDataSourceErrorResendGeneric = 10001, - MXKRoomDataSourceErrorResendInvalidMessageType = 10002, - MXKRoomDataSourceErrorResendInvalidLocalFilePath = 10003, -}; +// Check filesize before sending: make RoomDataSource errors public +//typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) { +// MXKRoomDataSourceErrorResendGeneric = 10001, +// MXKRoomDataSourceErrorResendInvalidMessageType = 10002, +// MXKRoomDataSourceErrorResendInvalidLocalFilePath = 10003, +//}; @interface MXKRoomDataSource () @@ -1923,6 +1924,67 @@ - (BOOL)canReplyToEventWithId:(NSString*)eventIdToReply return [self.room canReplyToEvent:eventToReply]; } +// Check filesize before sending: check file size before sending +- (BOOL)_isFilesizeOkToBeSent:(NSUInteger)filesize +{ + // Check maxUploadSize accepted by the home server before trying to upload. + NSUInteger maxUploadFileSize = self.mxSession.maxUploadSize; + if (filesize > maxUploadFileSize) + { + return NO; + } + else + { + return YES; + } +} + +- (BOOL)isFilesizeOkToBeSentForData:(NSData *)fileData +{ + return [self _isFilesizeOkToBeSent:fileData.length]; +} + +- (BOOL)isFilesizeOkToBeSentForLocalFileUrl:(NSURL *)localFileUrl +{ + NSDictionary *fileAttributes = [NSFileManager.defaultManager attributesOfItemAtPath:localFileUrl.path error:nil]; + if (fileAttributes) + { + return [self _isFilesizeOkToBeSent:fileAttributes.fileSize]; + } + else + { + return NO; + } +} + +- (BOOL)isFilesizeOkToBeSentForLocalAVAsset:(AVAsset *)asset +{ + // Check if asset points to a local file + if( ![asset isKindOfClass:AVURLAsset.class] ) + { + // If asset doesn't point to a local asset, we can't check size. + // Return YES to let the upload happens and get the result of the backend. + return YES; + } + + AVURLAsset *urlAsset = (AVURLAsset *)asset; + NSNumber *assetFilesize; + NSError *error; + + // Try to get asset filesize. + [urlAsset.URL getResourceValue:&assetFilesize forKey:NSURLFileSizeKey error:&error]; + + // If we can't check size, + if( error != NULL || assetFilesize == NULL ) + { + // return YES to let the upload happens and get the result of the backend. + return YES; + } + + return [self _isFilesizeOkToBeSent:assetFilesize.unsignedLongValue]; +} + + - (void)sendImage:(NSData *)imageData mimeType:(NSString *)mimetype success:(void (^)(NSString *))success failure:(void (^)(NSError *))failure { UIImage *image = [UIImage imageWithData:imageData]; @@ -1944,6 +2006,13 @@ - (void)sendImage:(NSData *)imageData mimeType:(NSString *)mimetype success:(voi - (void)sendImageData:(NSData*)imageData withImageSize:(CGSize)imageSize mimeType:(NSString*)mimetype andThumbnail:(UIImage*)thumbnail success:(void (^)(NSString *eventId))success failure:(void (^)(NSError *error))failure { + // Check filesize before sending: check fielsize before trying to send file + if( ![self isFilesizeOkToBeSentForData:imageData] ) + { + failure([NSError errorWithDomain:MXKRoomDataSourceErrorDomain code:MXKRoomDataSourceErrorCantSendFileToBig userInfo:nil]); + return; + } + __block MXEvent *localEchoEvent = nil; [_room sendImage:imageData withImageSize:imageSize mimeType:mimetype andThumbnail:thumbnail threadId:self.threadId localEcho:&localEchoEvent success:success failure:failure]; @@ -1964,6 +2033,13 @@ - (void)sendVideo:(NSURL *)videoLocalURL withThumbnail:(UIImage *)videoThumbnail - (void)sendVideoAsset:(AVAsset *)videoAsset withThumbnail:(UIImage *)videoThumbnail success:(void (^)(NSString *))success failure:(void (^)(NSError *))failure { + // Check filesize before sending: check fielsize before trying to send file + if( ![self isFilesizeOkToBeSentForLocalAVAsset:videoAsset] ) + { + failure([NSError errorWithDomain:MXKRoomDataSourceErrorDomain code:MXKRoomDataSourceErrorCantSendFileToBig userInfo:nil]); + return; + } + __block MXEvent *localEchoEvent = nil; [_room sendVideoAsset:videoAsset withThumbnail:videoThumbnail threadId:self.threadId localEcho:&localEchoEvent success:success failure:failure]; @@ -2013,6 +2089,13 @@ - (void)sendVoiceMessage:(NSURL *)audioFileLocalURL - (void)sendFile:(NSURL *)fileLocalURL mimeType:(NSString*)mimeType success:(void (^)(NSString *))success failure:(void (^)(NSError *))failure { + // Check filesize before sending: check fielsize before trying to send file + if( ![self isFilesizeOkToBeSentForLocalFileUrl:fileLocalURL] ) + { + failure([NSError errorWithDomain:MXKRoomDataSourceErrorDomain code:MXKRoomDataSourceErrorCantSendFileToBig userInfo:nil]); + return; + } + __block MXEvent *localEchoEvent = nil; [_room sendFile:fileLocalURL mimeType:mimeType threadId:self.threadId localEcho:&localEchoEvent success:success failure:failure]; diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index c94b41bedb..e429bb0a68 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -7721,15 +7721,6 @@ - (void)documentPickerPresenter:(MXKDocumentPickerPresenter *)presenter didPickD { self.documentPickerPresenter = nil; - // Check maxUploadSize accepted by the home server before trying to upload. - NSUInteger maxUploadFileSize = self.roomDataSource.mxSession.maxUploadSize; - NSDictionary *fileAttributes = [NSFileManager.defaultManager attributesOfItemAtPath:url.path error:nil]; - if (fileAttributes && fileAttributes.fileSize > maxUploadFileSize) { - [self showAlertWithTitle:[VectorL10n fileUploadErrorTooLargeTitle] - message:[VectorL10n fileUploadErrorTooLargeMessage:[NSByteCountFormatter stringFromByteCount:maxUploadFileSize countStyle:NSByteCountFormatterCountStyleFile]]]; - return; - } - MXKUTI *fileUTI = [[MXKUTI alloc] initWithLocalFileURL:url]; NSString *mimeType = fileUTI.mimeType; @@ -7756,6 +7747,17 @@ - (void)documentPickerPresenter:(MXKDocumentPickerPresenter *)presenter didPickD } } +// Check filesize before sending: if send file error is "File too big", display alert box to user +- (void)displayAlertIfErrorIsFileIsTooBig:(NSError *)error +{ + if( error.code == MXKRoomDataSourceErrorCantSendFileToBig ) + { + NSUInteger maxUploadFileSize = self.roomDataSource.mxSession.maxUploadSize; + [self showAlertWithTitle:[VectorL10n fileUploadErrorTooLargeTitle] + message:[VectorL10n fileUploadErrorTooLargeMessage:[NSByteCountFormatter stringFromByteCount:maxUploadFileSize countStyle:NSByteCountFormatterCountStyleFile]]]; + } +} + - (void)sendImage:(NSData *)imageData mimeType:(NSString *)mimeType { // Create before sending the message in case of a discussion (direct chat) MXWeakify(self); @@ -7767,7 +7769,9 @@ - (void)sendImage:(NSData *)imageData mimeType:(NSString *)mimeType { [self.roomDataSource sendImage:imageData mimeType:mimeType success:nil failure:^(NSError *error) { // Nothing to do. The image is marked as unsent in the room history by the datasource MXLogDebug(@"[MXKRoomViewController] sendImage failed."); - }]; + // Check filesize before sending: if error is "FileTooBig", display alert box. + [self displayAlertIfErrorIsFileIsTooBig:error]; + }]; } // Errors are handled at the request level. This should be improved in case of code rewriting. }]; @@ -7784,6 +7788,8 @@ - (void)sendVideo:(NSURL * _Nonnull)url { [(RoomDataSource*)self.roomDataSource sendVideo:url success:nil failure:^(NSError *error) { // Nothing to do. The video is marked as unsent in the room history by the datasource MXLogDebug(@"[MXKRoomViewController] sendVideo failed."); + // Check filesize before sending: if error is "FileTooBig", display alert box. + [self displayAlertIfErrorIsFileIsTooBig:error]; }]; } // Errors are handled at the request level. This should be improved in case of code rewriting. @@ -7801,6 +7807,8 @@ - (void)sendFile:(NSURL * _Nonnull)url mimeType:(NSString *)mimeType { [self.roomDataSource sendFile:url mimeType:mimeType success:nil failure:^(NSError *error) { // Nothing to do. The file is marked as unsent in the room history by the datasource MXLogDebug(@"[MXKRoomViewController] sendFile failed."); + // Check filesize before sending: if error is "FileTooBig", display alert box. + [self displayAlertIfErrorIsFileIsTooBig:error]; }]; } // Errors are handled at the request level. This should be improved in case of code rewriting.