diff --git a/CHANGES.rst b/CHANGES.rst index 7d86c104c8..dac886b66c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,49 +1,56 @@ +Changes in 0.7.x (2018-xx-xx) +=============================================== + +Improvements: + * Replace the deprecated MXMediaManager and MXMediaLoader interfaces use (see matrix-org/matrix-ios-sdk/pull/593). + * Replace the deprecated MXKAttachment and MXKImageView interfaces use (see matrix-org/matrix-ios-kit/pull/487). + Changes in 0.7.7 (2018-10-31) =============================================== Improvements: -* Upgrade MatrixKit version (v0.8.6). + * Upgrade MatrixKit version (v0.8.6). Bug fix: -* Notifications: old notifications can reappear (#1985). + * Notifications: old notifications can reappear (#1985). Changes in 0.7.6 (2018-10-05) =============================================== Bug fix: -* Wrong version number. + * Wrong version number. Changes in 0.7.5 (2018-10-05) =============================================== Improvements: -* Upgrade MatrixKit version (v0.8.5). -* Server Quota Notices: Implement the blue banner (#1937). + * Upgrade MatrixKit version (v0.8.5). + * Server Quota Notices: Implement the blue banner (#1937). Changes in 0.7.4 (2018-09-26) =============================================== Improvements: -* Upgrade MatrixKit version (v0.8.4). -* Lazy loading: Enable it by default (if the homeserver supports it). -* i18n: Add Spanish (sp). -* Settings: Make advanced info copyable (#2023). -* Settings: Made cryptography info copyable, thanks to @daverPL (PR #1999). -* Room settings: Anyone can now set a room alias (#2033). + * Upgrade MatrixKit version (v0.8.4). + * Lazy loading: Enable it by default (if the homeserver supports it). + * i18n: Add Spanish (sp). + * Settings: Make advanced info copyable (#2023). + * Settings: Made cryptography info copyable, thanks to @daverPL (PR #1999). + * Room settings: Anyone can now set a room alias (#2033). Bug fix: -* Fix missing read receipts when lazy-loading room members. -* Weird text color when selecting a message (#2046). + * Fix missing read receipts when lazy-loading room members. + * Weird text color when selecting a message (#2046). Changes in 0.7.3 (2018-08-27) =============================================== Improvements: -* Upgrade MatrixKit version (v0.8.3). + * Upgrade MatrixKit version (v0.8.3). Bug fix: -* Fix input toolbar reset in RoomViewController on MXSession state change (#2006 and #2008). -* Fix user interaction disabled in master view of UISplitViewContoller when selecting a room (#2005). + * Fix input toolbar reset in RoomViewController on MXSession state change (#2006 and #2008). + * Fix user interaction disabled in master view of UISplitViewContoller when selecting a room (#2005). Changes in 0.7.2 (2018-08-24) =============================================== diff --git a/Riot/Categories/MXGroup+Riot.m b/Riot/Categories/MXGroup+Riot.m index 8e18f3d92b..a68710c06e 100644 --- a/Riot/Categories/MXGroup+Riot.m +++ b/Riot/Categories/MXGroup+Riot.m @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd + Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -30,7 +31,13 @@ - (void)setGroupAvatarImageIn:(MXKImageView*)mxkImageView matrixSession:(MXSessi { mxkImageView.enableInMemoryCache = YES; - [mxkImageView setImageURL:[mxSession.matrixRestClient urlOfContentThumbnail:self.profile.avatarUrl toFitViewSize:mxkImageView.frame.size withMethod:MXThumbnailingMethodCrop] withType:nil andImageOrientation:UIImageOrientationUp previewImage:avatarImage]; + [mxkImageView setImageURI:self.profile.avatarUrl + withType:nil + andImageOrientation:UIImageOrientationUp + toFitViewSize:mxkImageView.frame.size + withMethod:MXThumbnailingMethodCrop + previewImage:avatarImage + mediaManager:mxSession.mediaManager]; } else { diff --git a/Riot/Categories/MXRoomSummary+Riot.m b/Riot/Categories/MXRoomSummary+Riot.m index 78465b325f..0367f2436f 100644 --- a/Riot/Categories/MXRoomSummary+Riot.m +++ b/Riot/Categories/MXRoomSummary+Riot.m @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd + Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -30,7 +31,13 @@ - (void)setRoomAvatarImageIn:(MXKImageView*)mxkImageView { mxkImageView.enableInMemoryCache = YES; - [mxkImageView setImageURL:[self.mxSession.matrixRestClient urlOfContentThumbnail:self.avatar toFitViewSize:mxkImageView.frame.size withMethod:MXThumbnailingMethodCrop] withType:nil andImageOrientation:UIImageOrientationUp previewImage:avatarImage]; + [mxkImageView setImageURI:self.avatar + withType:nil + andImageOrientation:UIImageOrientationUp + toFitViewSize:mxkImageView.frame.size + withMethod:MXThumbnailingMethodCrop + previewImage:avatarImage + mediaManager:self.mxSession.mediaManager]; } else { diff --git a/Riot/Modules/Call/CallViewController.m b/Riot/Modules/Call/CallViewController.m index f846a114dc..b88a3e32b2 100644 --- a/Riot/Modules/Call/CallViewController.m +++ b/Riot/Modules/Call/CallViewController.m @@ -1,6 +1,7 @@ /* Copyright 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd + Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -199,20 +200,17 @@ - (void)destroy - (UIView *)createIncomingCallView { - NSString *avatarThumbURL = [self.mainSession.matrixRestClient urlOfContentThumbnail:self.peer.avatarUrl - toFitViewSize:IncomingCallView.callerAvatarSize - withMethod:MXThumbnailingMethodCrop]; - NSString *callInfo; if (self.mxCall.isVideoCall) callInfo = NSLocalizedStringFromTable(@"call_incoming_video", @"Vector", nil); else callInfo = NSLocalizedStringFromTable(@"call_incoming_voice", @"Vector", nil); - IncomingCallView *incomingCallView = [[IncomingCallView alloc] initWithCallerAvatarURL:avatarThumbURL - placeholderImage:self.picturePlaceholder - callerName:self.peer.displayname - callInfo:callInfo]; + IncomingCallView *incomingCallView = [[IncomingCallView alloc] initWithCallerAvatar:self.peer.avatarUrl + mediaManager:self.mainSession.mediaManager + placeholderImage:self.picturePlaceholder + callerName:self.peer.displayname + callInfo:callInfo]; // Incoming call is retained by call vc so use weak to avoid retain cycle __weak typeof(self) weakSelf = self; @@ -396,8 +394,11 @@ - (void)updatePeerInfoDisplay if (peerAvatarURL) { // Retrieve the avatar in full resolution - NSString *avatarThumbURL = [self.mainSession.matrixRestClient urlOfContent:peerAvatarURL]; - [self.callerImageView setImageURL:avatarThumbURL withType:nil andImageOrientation:UIImageOrientationUp previewImage:self.picturePlaceholder]; + [self.callerImageView setImageURI:peerAvatarURL + withType:nil + andImageOrientation:UIImageOrientationUp + previewImage:self.picturePlaceholder + mediaManager:self.mainSession.mediaManager]; } else { diff --git a/Riot/Modules/Call/Views/IncomingCallView.h b/Riot/Modules/Call/Views/IncomingCallView.h index 9b437c1ee9..12164d8d81 100644 --- a/Riot/Modules/Call/Views/IncomingCallView.h +++ b/Riot/Modules/Call/Views/IncomingCallView.h @@ -19,6 +19,7 @@ NS_ASSUME_NONNULL_BEGIN typedef void (^IncomingCallViewAction)(); +@class MXMediaManager; @interface IncomingCallView : UIView @@ -37,10 +38,20 @@ typedef void (^IncomingCallViewAction)(); */ @property (nonatomic, nullable, copy) IncomingCallViewAction onReject; -- (instancetype)initWithCallerAvatarURL:(NSString *)callerAvatarURL - placeholderImage:(UIImage *)placeholderImage - callerName:(NSString *)callerName - callInfo:(NSString *)callInfo; +/** + Contructors. + + @param mxcAvatarURI the Matrix Content URI of the caller avatar. + @param mediaManager the media manager used to download this avatar if it is not cached yet. + @param placeholderImage + @param callerName + @param callInfo + */ +- (instancetype)initWithCallerAvatar:(NSString *)mxcAvatarURI + mediaManager:(MXMediaManager *)mediaManager + placeholderImage:(UIImage *)placeholderImage + callerName:(NSString *)callerName + callInfo:(NSString *)callInfo; @end diff --git a/Riot/Modules/Call/Views/IncomingCallView.m b/Riot/Modules/Call/Views/IncomingCallView.m index 0d442232c6..d956ceccef 100644 --- a/Riot/Modules/Call/Views/IncomingCallView.m +++ b/Riot/Modules/Call/Views/IncomingCallView.m @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd + Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -46,7 +47,11 @@ + (CGSize)callerAvatarSize return CGSizeMake(kAvatarSize, kAvatarSize); } -- (instancetype)initWithCallerAvatarURL:(NSString *)callerAvatarURL placeholderImage:(UIImage *)placeholderImage callerName:(NSString *)callerName callInfo:(NSString *)callInfo +- (instancetype)initWithCallerAvatar:(NSString *)mxcAvatarURI + mediaManager:(MXMediaManager *)mediaManager + placeholderImage:(UIImage *)placeholderImage + callerName:(NSString *)callerName + callInfo:(NSString *)callInfo { self = [super initWithFrame:CGRectZero]; if (self) @@ -59,10 +64,13 @@ - (instancetype)initWithCallerAvatarURL:(NSString *)callerAvatarURL placeholderI self.callerImageView.clipsToBounds = YES; self.callerImageView.mediaFolder = kMXMediaManagerAvatarThumbnailFolder; self.callerImageView.enableInMemoryCache = YES; - [self.callerImageView setImageURL:callerAvatarURL + [self.callerImageView setImageURI:mxcAvatarURI withType:nil andImageOrientation:UIImageOrientationUp - previewImage:placeholderImage]; + toFitViewSize:IncomingCallView.callerAvatarSize + withMethod:MXThumbnailingMethodCrop + previewImage:placeholderImage + mediaManager:mediaManager]; self.callerNameLabel = [[UILabel alloc] init]; self.callerNameLabel.backgroundColor = kRiotPrimaryBgColor; diff --git a/Riot/Modules/Communities/Home/GroupHomeViewController.m b/Riot/Modules/Communities/Home/GroupHomeViewController.m index 62397db77d..247b495213 100644 --- a/Riot/Modules/Communities/Home/GroupHomeViewController.m +++ b/Riot/Modules/Communities/Home/GroupHomeViewController.m @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd + Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -497,39 +498,78 @@ - (void)refreshGroupLongDescription ]; // Do some sanitisation by handling the potential image + MXWeakify(self); sanitisedGroupLongDescription = [MXKTools sanitiseHTML:_group.summary.profile.longDescription withAllowedHTMLTags:allowedHTMLTags imageHandler:^NSString *(NSString *sourceURL, CGFloat width, CGFloat height) { - NSString *imageURL; + MXStrongifyAndReturnValueIfNil(self, nil); + NSString *localSourcePath; if (width != -1 && height != -1) { CGSize size = CGSizeMake(width, height); - imageURL = [self.mxSession.matrixRestClient urlOfContentThumbnail:sourceURL toFitViewSize:size withMethod:MXThumbnailingMethodScale]; + // Build the cache path for the a thumbnail of this image. + NSString *cacheFilePath = [MXMediaManager thumbnailCachePathForMatrixContentURI:sourceURL + andType:nil + inFolder:kMXMediaManagerDefaultCacheFolder + toFitViewSize:size + withMethod:MXThumbnailingMethodScale]; + // Check whether the provided URL is a valid Matrix Content URI. + if (cacheFilePath) + { + // Download the thumbnail if it is not already stored in the cache. + if (![[NSFileManager defaultManager] fileExistsAtPath:cacheFilePath]) + { + MXWeakify(self); + [self.mxSession.mediaManager downloadThumbnailFromMatrixContentURI:sourceURL + withType:nil + inFolder:kMXMediaManagerDefaultCacheFolder + toFitViewSize:size + withMethod:MXThumbnailingMethodScale + success:^(NSString *outputFilePath) { + MXStrongifyAndReturnIfNil(self); + [self refreshGroupLongDescription]; + } + failure:nil]; + } + else + { + // Update the local path + localSourcePath = [NSString stringWithFormat:@"file://%@", cacheFilePath]; + } + } } else { - imageURL = [self.mxSession.matrixRestClient urlOfContent:sourceURL]; - } - - NSString *mimeType = nil; - // Check if the extension could not be deduced from url - if (![imageURL pathExtension].length) - { - // Set default mime type if no information is available - mimeType = @"image/jpeg"; - } - - NSString *cacheFilePath = [MXMediaManager cachePathForMediaWithURL:imageURL andType:mimeType inFolder:kMXMediaManagerDefaultCacheFolder]; - if (![[NSFileManager defaultManager] fileExistsAtPath:cacheFilePath]) - { - [MXMediaManager downloadMediaFromURL:imageURL andSaveAtFilePath:cacheFilePath success:^{ - - [self renderGroupLongDescription]; - - } failure:nil]; + // Build the cache path for this image. + NSString* cacheFilePath = [MXMediaManager cachePathForMatrixContentURI:sourceURL + andType:nil + inFolder:kMXMediaManagerDefaultCacheFolder]; + + // Check whether the provided URL is a valid Matrix Content URI. + if (cacheFilePath) + { + // Download the image if it is not already stored in the cache. + if (![[NSFileManager defaultManager] fileExistsAtPath:cacheFilePath]) + { + MXWeakify(self); + [self.mxSession.mediaManager downloadMediaFromMatrixContentURI:sourceURL + withType:nil + inFolder:kMXMediaManagerDefaultCacheFolder + success:^(NSString *outputFilePath) { + MXStrongifyAndReturnIfNil(self); + [self refreshGroupLongDescription]; + } + failure:nil]; + } + else + { + // Update the local path + localSourcePath = [NSString stringWithFormat:@"file://%@", cacheFilePath]; + } + } } + return localSourcePath; - return [NSString stringWithFormat:@"file://%@", cacheFilePath]; }]; } else @@ -701,22 +741,25 @@ - (void)handleTapGesture:(UITapGestureRecognizer*)tapGestureRecognizer __block MXKImageView * avatarFullScreenView = [[MXKImageView alloc] initWithFrame:CGRectZero]; avatarFullScreenView.stretchable = YES; + MXWeakify(self); [avatarFullScreenView setRightButtonTitle:[NSBundle mxk_localizedStringForKey:@"ok"] handler:^(MXKImageView* imageView, NSString* buttonTitle) { + + MXStrongifyAndReturnIfNil(self); [avatarFullScreenView dismissSelection]; [avatarFullScreenView removeFromSuperview]; avatarFullScreenView = nil; - isStatusBarHidden = NO; + self->isStatusBarHidden = NO; // Trigger status bar update [self setNeedsStatusBarAppearanceUpdate]; }]; - NSString *avatarURL = [self.mainSession.matrixRestClient urlOfContent:_group.summary.profile.avatarUrl]; - [avatarFullScreenView setImageURL:avatarURL + [avatarFullScreenView setImageURI:_group.summary.profile.avatarUrl withType:nil andImageOrientation:UIImageOrientationUp - previewImage:self.groupAvatar.image]; + previewImage:self.groupAvatar.image + mediaManager:_mxSession.mediaManager]; [avatarFullScreenView showFullScreen]; isStatusBarHidden = YES; diff --git a/Riot/Modules/Communities/Rooms/Views/GroupRoomTableViewCell.m b/Riot/Modules/Communities/Rooms/Views/GroupRoomTableViewCell.m index e57156b523..ea0d153b40 100644 --- a/Riot/Modules/Communities/Rooms/Views/GroupRoomTableViewCell.m +++ b/Riot/Modules/Communities/Rooms/Views/GroupRoomTableViewCell.m @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd + Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -75,11 +76,13 @@ - (void)render:(MXGroupRoom *)groupRoom withMatrixSession:(MXSession*)mxSession { _roomAvatar.enableInMemoryCache = YES; - [_roomAvatar setImageURL:[mxSession.matrixRestClient urlOfContentThumbnail:groupRoom.avatarUrl - toFitViewSize:_roomAvatar.frame.size - withMethod:MXThumbnailingMethodCrop] + [_roomAvatar setImageURI:groupRoom.avatarUrl withType:nil - andImageOrientation:UIImageOrientationUp previewImage:avatarImage]; + andImageOrientation:UIImageOrientationUp + toFitViewSize:_roomAvatar.frame.size + withMethod:MXThumbnailingMethodCrop + previewImage:avatarImage + mediaManager:mxSession.mediaManager]; } else { diff --git a/Riot/Modules/Contacts/Details/ContactDetailsViewController.m b/Riot/Modules/Contacts/Details/ContactDetailsViewController.m index b4761f589a..3c40ccb572 100644 --- a/Riot/Modules/Contacts/Details/ContactDetailsViewController.m +++ b/Riot/Modules/Contacts/Details/ContactDetailsViewController.m @@ -1,6 +1,7 @@ /* Copyright 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd + Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -1153,13 +1154,16 @@ - (void)handleTapGesture:(UITapGestureRecognizer*)tapGestureRecognizer __block MXKImageView * avatarFullScreenView = [[MXKImageView alloc] initWithFrame:CGRectZero]; avatarFullScreenView.stretchable = YES; + MXWeakify(self); [avatarFullScreenView setRightButtonTitle:[NSBundle mxk_localizedStringForKey:@"ok"] handler:^(MXKImageView* imageView, NSString* buttonTitle) { + + MXStrongifyAndReturnIfNil(self); [avatarFullScreenView dismissSelection]; [avatarFullScreenView removeFromSuperview]; avatarFullScreenView = nil; - isStatusBarHidden = NO; + self->isStatusBarHidden = NO; // Trigger status bar update [self setNeedsStatusBarAppearanceUpdate]; }]; @@ -1168,15 +1172,16 @@ - (void)handleTapGesture:(UITapGestureRecognizer*)tapGestureRecognizer if (self.firstMatrixId) { MXUser *user = [self.mainSession userWithUserId:self.firstMatrixId]; - avatarURL = [self.mainSession.matrixRestClient urlOfContent:user.avatarUrl]; + avatarURL = user.avatarUrl; } // TODO: Display the orignal contact avatar when the contast is not a Matrix user - [avatarFullScreenView setImageURL:avatarURL + [avatarFullScreenView setImageURI:avatarURL withType:nil andImageOrientation:UIImageOrientationUp - previewImage:self.contactAvatar.image]; + previewImage:self.contactAvatar.image + mediaManager:self.mainSession.mediaManager]; [avatarFullScreenView showFullScreen]; isStatusBarHidden = YES; diff --git a/Riot/Modules/GlobalSearch/Files/CellData/FilesSearchCellData.m b/Riot/Modules/GlobalSearch/Files/CellData/FilesSearchCellData.m index 3b81c28d5a..f39daa4449 100644 --- a/Riot/Modules/GlobalSearch/Files/CellData/FilesSearchCellData.m +++ b/Riot/Modules/GlobalSearch/Files/CellData/FilesSearchCellData.m @@ -41,7 +41,7 @@ - (instancetype)initWithSearchResult:(MXSearchResult *)searchResult2 andSearchDa if ([searchDataSource.eventFormatter isSupportedAttachment:event]) { // Note: event.eventType may be equal here to MXEventTypeRoomMessage or MXEventTypeSticker - attachment = [[MXKAttachment alloc] initWithEvent:event andMatrixSession:searchDataSource.mxSession]; + attachment = [[MXKAttachment alloc] initWithEvent:event andMediaManager:searchDataSource.mxSession.mediaManager]; } // Append the file size if any diff --git a/Riot/Modules/GlobalSearch/Files/Views/FilesSearchTableViewCell.m b/Riot/Modules/GlobalSearch/Files/Views/FilesSearchTableViewCell.m index de045e5fb9..29f8ccb5dc 100644 --- a/Riot/Modules/GlobalSearch/Files/Views/FilesSearchTableViewCell.m +++ b/Riot/Modules/GlobalSearch/Files/Views/FilesSearchTableViewCell.m @@ -1,6 +1,7 @@ /* Copyright 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd + Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -74,29 +75,8 @@ - (void)render:(MXKCellData*)cellData if (bubbleData.isAttachmentWithThumbnail) { - // Set attached media folders - self.attachmentImageView.mediaFolder = bubbleData.roomId; - - NSString *mimetype = nil; - if (bubbleData.attachment.thumbnailInfo) - { - mimetype = bubbleData.attachment.thumbnailInfo[@"mimetype"]; - } - else if (bubbleData.attachment.contentInfo) - { - mimetype = bubbleData.attachment.contentInfo[@"mimetype"]; - } - - NSString *url = bubbleData.attachment.thumbnailURL; - UIImage *preview = bubbleData.attachment.previewImage; - - if (url.length || preview) - { - self.attachmentImageView.enableInMemoryCache = YES; - [self.attachmentImageView setImageURL:url withType:mimetype andImageOrientation:bubbleData.attachment.thumbnailOrientation previewImage:preview]; - - self.attachmentImageView.backgroundColor = kRiotPrimaryBgColor; - } + self.attachmentImageView.backgroundColor = kRiotPrimaryBgColor; + [self.attachmentImageView setAttachmentThumb:bubbleData.attachment]; } self.iconImage.image = [self attachmentIcon:bubbleData.attachment.type]; diff --git a/Riot/Modules/PublicRoomList/Views/PublicRoomTableViewCell.m b/Riot/Modules/PublicRoomList/Views/PublicRoomTableViewCell.m index 5cd611a528..a8fbca4cc9 100644 --- a/Riot/Modules/PublicRoomList/Views/PublicRoomTableViewCell.m +++ b/Riot/Modules/PublicRoomList/Views/PublicRoomTableViewCell.m @@ -1,6 +1,7 @@ /* Copyright 2015 OpenMarket Ltd Copyright 2017 Vector Creations Ltd + Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -61,11 +62,13 @@ - (void)render:(MXPublicRoom *)publicRoom withMatrixSession:(MXSession*)mxSessio { _roomAvatar.enableInMemoryCache = YES; - [_roomAvatar setImageURL:[mxSession.matrixRestClient urlOfContentThumbnail:publicRoom.avatarUrl - toFitViewSize:_roomAvatar.frame.size - withMethod:MXThumbnailingMethodCrop] + [_roomAvatar setImageURI:publicRoom.avatarUrl withType:nil - andImageOrientation:UIImageOrientationUp previewImage:avatarImage]; + andImageOrientation:UIImageOrientationUp + toFitViewSize:_roomAvatar.frame.size + withMethod:MXThumbnailingMethodCrop + previewImage:avatarImage + mediaManager:mxSession.mediaManager]; } else { diff --git a/Riot/Modules/Room/DataSources/RoomDataSource.m b/Riot/Modules/Room/DataSources/RoomDataSource.m index ca861c7dc2..24a60e6fd4 100644 --- a/Riot/Modules/Room/DataSources/RoomDataSource.m +++ b/Riot/Modules/Room/DataSources/RoomDataSource.m @@ -304,7 +304,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if (roomMembers.count) { // Define the read receipts container, positioned on the right border of the bubble cell (Note the right margin 6 pts). - MXKReceiptSendersContainer* avatarsContainer = [[MXKReceiptSendersContainer alloc] initWithFrame:CGRectMake(bubbleCell.frame.size.width - 156, bottomPositionY - 13, 150, 12) andRestClient:self.mxSession.matrixRestClient]; + MXKReceiptSendersContainer* avatarsContainer = [[MXKReceiptSendersContainer alloc] initWithFrame:CGRectMake(bubbleCell.frame.size.width - 156, bottomPositionY - 13, 150, 12) andMediaManager:self.mxSession.mediaManager]; // Custom avatar display avatarsContainer.maxDisplayedAvatars = 5; diff --git a/Riot/Modules/Room/Members/Detail/RoomMemberDetailsViewController.m b/Riot/Modules/Room/Members/Detail/RoomMemberDetailsViewController.m index aedc8c2026..5b88317b38 100644 --- a/Riot/Modules/Room/Members/Detail/RoomMemberDetailsViewController.m +++ b/Riot/Modules/Room/Members/Detail/RoomMemberDetailsViewController.m @@ -1101,38 +1101,31 @@ - (void)handleTapGesture:(UITapGestureRecognizer*)tapGestureRecognizer } else if (view == memberTitleView.memberAvatarMask || view == self.roomMemberAvatarMask) { - __weak typeof(self) weakSelf = self; + MXWeakify(self); // Show the avatar in full screen __block MXKImageView * avatarFullScreenView = [[MXKImageView alloc] initWithFrame:CGRectZero]; avatarFullScreenView.stretchable = YES; - [avatarFullScreenView setRightButtonTitle:[NSBundle mxk_localizedStringForKey:@"ok"] handler:^(MXKImageView* imageView, NSString* buttonTitle) - { - [avatarFullScreenView dismissSelection]; - [avatarFullScreenView removeFromSuperview]; - - avatarFullScreenView = nil; - - if (weakSelf) - { - // Restore the status bar - isStatusBarHidden = NO; - typeof(self) self = weakSelf; - [self setNeedsStatusBarAppearanceUpdate]; - } - }]; - - NSString *avatarURL = nil; - if (self.mxRoomMember.avatarUrl) - { - avatarURL = [self.mainSession.matrixRestClient urlOfContent:self.mxRoomMember.avatarUrl]; - } + [avatarFullScreenView setRightButtonTitle:[NSBundle mxk_localizedStringForKey:@"ok"] + handler:^(MXKImageView* imageView, NSString* buttonTitle) { + + MXStrongifyAndReturnIfNil(self); + [avatarFullScreenView dismissSelection]; + [avatarFullScreenView removeFromSuperview]; + + avatarFullScreenView = nil; + + // Restore the status bar + self->isStatusBarHidden = NO; + [self setNeedsStatusBarAppearanceUpdate]; + }]; - [avatarFullScreenView setImageURL:avatarURL + [avatarFullScreenView setImageURI:self.mxRoomMember.avatarUrl withType:nil andImageOrientation:UIImageOrientationUp - previewImage:self.memberThumbnail.image]; + previewImage:self.memberThumbnail.image + mediaManager:self.mainSession.mediaManager]; [avatarFullScreenView showFullScreen]; diff --git a/Riot/Modules/Room/ReadReceiptsDetail/ReadReceiptsViewController.m b/Riot/Modules/Room/ReadReceiptsDetail/ReadReceiptsViewController.m index 28f0a10a5f..09ffafd0c5 100644 --- a/Riot/Modules/Room/ReadReceiptsDetail/ReadReceiptsViewController.m +++ b/Riot/Modules/Room/ReadReceiptsDetail/ReadReceiptsViewController.m @@ -1,5 +1,6 @@ /* Copyright 2017 Aram Sargsyan + Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -26,7 +27,6 @@ @interface ReadReceiptsViewController () *roomMembers; @@ -48,7 +48,6 @@ @implementation ReadReceiptsViewController + (void)openInViewController:(UIViewController *)viewController fromContainer:(MXKReceiptSendersContainer *)receiptSendersContainer withSession:(MXSession *)session { ReadReceiptsViewController *receiptsController = [[[self class] alloc] initWithNibName:NSStringFromClass([self class]) bundle:nil]; - receiptsController.restClient = receiptSendersContainer.restClient; receiptsController.session = session; receiptsController.roomMembers = receiptSendersContainer.roomMembers; @@ -210,12 +209,14 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if (indexPath.row < self.placeholders.count) { NSString *avatarUrl = self.roomMembers[indexPath.row].avatarUrl; - if (self.restClient && avatarUrl) - { - CGFloat side = CGRectGetWidth(cell.avatarImageView.frame); - avatarUrl = [self.restClient urlOfContentThumbnail:avatarUrl toFitViewSize:CGSizeMake(side, side) withMethod:MXThumbnailingMethodCrop]; - } - [cell.avatarImageView setImageURL:avatarUrl withType:nil andImageOrientation:UIImageOrientationUp previewImage:self.placeholders[indexPath.row]]; + CGFloat side = CGRectGetWidth(cell.avatarImageView.frame); + [cell.avatarImageView setImageURI:avatarUrl + withType:nil + andImageOrientation:UIImageOrientationUp + toFitViewSize:CGSizeMake(side, side) + withMethod:MXThumbnailingMethodCrop + previewImage:self.placeholders[indexPath.row] + mediaManager:self.session.mediaManager]; } if (indexPath.row < self.receipts.count) { diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index ea535c7c49..fea0b3ca0e 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -1426,14 +1426,16 @@ - (void)refreshRoomInputToolbar if (userPictureView) { UIImage *preview = [AvatarGenerator generateAvatarForMatrixItem:self.mainSession.myUser.userId withDisplayName:self.mainSession.myUser.displayname]; - NSString *avatarThumbURL = nil; - if (self.mainSession.myUser.avatarUrl) - { - // Suppose this url is a matrix content uri, we use SDK to get the well adapted thumbnail from server - avatarThumbURL = [self.mainSession.matrixRestClient urlOfContentThumbnail:self.mainSession.myUser.avatarUrl toFitViewSize:userPictureView.frame.size withMethod:MXThumbnailingMethodCrop]; - } + + // Suppose the avatar is stored unencrypted on the Matrix media repository. userPictureView.enableInMemoryCache = YES; - [userPictureView setImageURL:avatarThumbURL withType:nil andImageOrientation:UIImageOrientationUp previewImage:preview]; + [userPictureView setImageURI:self.mainSession.myUser.avatarUrl + withType:nil + andImageOrientation:UIImageOrientationUp + toFitViewSize:userPictureView.frame.size + withMethod:MXThumbnailingMethodCrop + previewImage:preview + mediaManager:self.mainSession.mediaManager]; [userPictureView.layer setCornerRadius:userPictureView.frame.size.width / 2]; userPictureView.clipsToBounds = YES; } @@ -1731,9 +1733,7 @@ - (void)refreshPreviewHeader:(BOOL)isLandscapeOriented // Set the avatar provided in preview data if (roomPreviewData.roomAvatarUrl) { - NSString *roomAvatarUrl = [self.mainSession.matrixRestClient urlOfContentThumbnail:roomPreviewData.roomAvatarUrl toFitViewSize:previewHeader.roomAvatar.frame.size withMethod:MXThumbnailingMethodCrop]; - - previewHeader.roomAvatarURL = roomAvatarUrl; + previewHeader.roomAvatarURL = roomPreviewData.roomAvatarUrl; } else if (roomPreviewData.roomId && roomPreviewData.roomName) { @@ -2333,7 +2333,7 @@ - (void)showEditButtonAlertMenuForEvent:(MXEvent*)selectedEvent inCell:(id)cellData } else if (cellData.thirdPartyProtocolInstance.icon) { - [self.iconImageView setImageURL:cellData.thirdPartyProtocolInstance.icon withType:nil andImageOrientation:UIImageOrientationUp previewImage:[UIImage imageNamed:@"placeholder"]]; + // Presently the thirdPartyProtocolInstance.icon is not a Matrix Content URI (https://github.com/matrix-org/synapse/issues/4175). + // Patch: We extract the expected URI from the URL + NSString *iconURL = cellData.thirdPartyProtocolInstance.icon; + NSString *mxMediaPrefix = [NSString stringWithFormat:@"/%@/download/", kMXContentPrefixPath]; + NSRange range = [iconURL rangeOfString:mxMediaPrefix]; + if (range.location != NSNotFound) + { + iconURL = [NSString stringWithFormat:@"%@%@", kMXContentUriScheme, [iconURL substringFromIndex:range.location + range.length]]; + } + [self.iconImageView setImageURI:iconURL + withType:nil + andImageOrientation:UIImageOrientationUp + previewImage:[UIImage imageNamed:@"placeholder"] + mediaManager:cellData.mediaManager]; } else { diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 9fc346cd58..04acf5dc6b 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -1451,7 +1451,13 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N { profileCell.mxkImageView.enableInMemoryCache = YES; - [profileCell.mxkImageView setImageURL:[session.matrixRestClient urlOfContentThumbnail:myUser.avatarUrl toFitViewSize:profileCell.mxkImageView.frame.size withMethod:MXThumbnailingMethodCrop] withType:nil andImageOrientation:UIImageOrientationUp previewImage:avatarImage]; + [profileCell.mxkImageView setImageURI:myUser.avatarUrl + withType:nil + andImageOrientation:UIImageOrientationUp + toFitViewSize:profileCell.mxkImageView.frame.size + withMethod:MXThumbnailingMethodCrop + previewImage:avatarImage + mediaManager:session.mediaManager]; } else { diff --git a/RiotShareExtension/Managers/ShareExtensionManager.m b/RiotShareExtension/Managers/ShareExtensionManager.m index 7cae6fac41..541b5892d9 100644 --- a/RiotShareExtension/Managers/ShareExtensionManager.m +++ b/RiotShareExtension/Managers/ShareExtensionManager.m @@ -58,7 +58,7 @@ + (instancetype)sharedManager sharedInstance.pendingImages = [NSMutableArray array]; sharedInstance.imageUploadProgresses = [NSMutableDictionary dictionary]; - [[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(onMediaUploadProgress:) name:kMXMediaUploadProgressNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(onMediaLoaderStateDidChange:) name:kMXMediaLoaderStateDidChangeNotification object:nil]; // Add observer to handle logout [[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(checkUserAccount) name:kMXKAccountManagerDidRemoveAccountNotification object:nil]; @@ -503,21 +503,30 @@ - (BOOL)areAttachmentsFullyLoaded #pragma mark - Notifications -- (void)onMediaUploadProgress:(NSNotification *)notification +- (void)onMediaLoaderStateDidChange:(NSNotification *)notification { - self.imageUploadProgresses[notification.object] = (NSNumber *)notification.userInfo[kMXMediaLoaderProgressValueKey]; - - if ([self.delegate respondsToSelector:@selector(shareExtensionManager:mediaUploadProgress:)]) - { - const NSInteger totalImagesCount = self.pendingImages.count; - CGFloat totalProgress = 0.0; - - for (NSNumber *progress in self.imageUploadProgresses.allValues) + MXMediaLoader *loader = (MXMediaLoader*)notification.object; + // Consider only upload progress + switch (loader.state) { + case MXMediaLoaderStateUploadInProgress: { - totalProgress += progress.floatValue/totalImagesCount; + self.imageUploadProgresses[loader.uploadId] = (NSNumber *)loader.statisticsDict[kMXMediaLoaderProgressValueKey]; + if ([self.delegate respondsToSelector:@selector(shareExtensionManager:mediaUploadProgress:)]) + { + const NSInteger totalImagesCount = self.pendingImages.count; + CGFloat totalProgress = 0.0; + + for (NSNumber *progress in self.imageUploadProgresses.allValues) + { + totalProgress += progress.floatValue/totalImagesCount; + } + + [self.delegate shareExtensionManager:self mediaUploadProgress:totalProgress]; + } + break; } - - [self.delegate shareExtensionManager:self mediaUploadProgress:totalProgress]; + default: + break; } }