diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 00fc9a6d1f..0611470b40 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -1717,6 +1717,8 @@ Tap the + to start adding people."; // MARK: File upload "file_upload_error_title" = "File upload"; "file_upload_error_unsupported_file_type_message" = "File type not supported."; +"file_upload_error_too_large_title" = "File too large"; +"file_upload_error_too_large_message" = "Maximum supported file size is %@MB"; // MARK: Emoji picker "emoji_picker_title" = "Reactions"; diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings index ee14358945..2c247b4769 100644 --- a/Riot/Assets/fr.lproj/Vector.strings +++ b/Riot/Assets/fr.lproj/Vector.strings @@ -778,6 +778,9 @@ // MARK: File upload "file_upload_error_title" = "Envoi de fichier"; "file_upload_error_unsupported_file_type_message" = "Type de fichier non pris en charge."; +"file_upload_error_too_large_title" = "Fichier trop lourd"; +"file_upload_error_too_large_message" = "La taille maximum autorisée est %@Mo"; + "auth_softlogout_signed_out" = "Vous êtes déconnecté"; "auth_softlogout_sign_in" = "Se connecter"; "auth_softlogout_reason" = "L’administrateur de votre serveur d’accueil (%1$@) vous a déconnecté de votre compte %2$@ (%3$@)."; 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 2eec3ea3d7..17b94d1058 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -7795,6 +7795,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); @@ -7806,7 +7817,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. }]; @@ -7823,6 +7836,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. @@ -7840,6 +7855,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. diff --git a/RiotSwiftUI/Modules/LocationSharing/StartLocationSharing/Coordinator/LocationSharingCoordinator.swift b/RiotSwiftUI/Modules/LocationSharing/StartLocationSharing/Coordinator/LocationSharingCoordinator.swift index 9cd5853c74..c2494be129 100644 --- a/RiotSwiftUI/Modules/LocationSharing/StartLocationSharing/Coordinator/LocationSharingCoordinator.swift +++ b/RiotSwiftUI/Modules/LocationSharing/StartLocationSharing/Coordinator/LocationSharingCoordinator.swift @@ -166,17 +166,16 @@ final class LocationSharingCoordinator: Coordinator, Presentable { // Check if user can send beacon info state event private func canShareLiveLocation() -> Bool { - guard let myUserId = parameters.roomDataSource.mxSession.myUserId else { + guard let myUserId = parameters.roomDataSource.mxSession.myUserId, + let roomPowerLevels = parameters.roomDataSource.roomState.powerLevels, + let userPowerLevel = RoomPowerLevel(rawValue: roomPowerLevels.powerLevelOfUser(withUserID: myUserId)) else { return false } - let userPowerLevelRawValue = parameters.roomDataSource.roomState.powerLevels.powerLevelOfUser(withUserID: myUserId) - - guard let userPowerLevel = RoomPowerLevel(rawValue: userPowerLevelRawValue) else { - return false - } - - return userPowerLevel.rawValue >= RoomPowerLevel.moderator.rawValue + // CHeck user power level in room against power level needed to post geolocation state event. + let liveSharingPowerLevel = roomPowerLevels.minimumPowerLevelForSendingStateEvent(.beaconInfo) + + return userPowerLevel.rawValue >= liveSharingPowerLevel } private func showLabFlagPromotionIfNeeded(completion: @escaping ((Bool) -> Void)) { diff --git a/changelog.d/pr-7778.change b/changelog.d/pr-7778.change new file mode 100644 index 0000000000..84c0e87b4f --- /dev/null +++ b/changelog.d/pr-7778.change @@ -0,0 +1 @@ +Check filesize before uploading file to server and display alert if file is too big. \ No newline at end of file diff --git a/changelog.d/pr-7808.change b/changelog.d/pr-7808.change new file mode 100644 index 0000000000..cc803849fb --- /dev/null +++ b/changelog.d/pr-7808.change @@ -0,0 +1 @@ +Check power level before starting live sharing location \ No newline at end of file