diff --git a/CHANGES.rst b/CHANGES.rst index 7d86c104c..dac886b66 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 8e18f3d92..a68710c06 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 @@ { 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 78465b325..0367f2436 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 @@ { 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 f846a114d..b88a3e32b 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 @@ - (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 @@ 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 9b437c1ee..12164d8d8 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 0d442232c..d956cecce 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 @@ static const CGFloat kButtonSize = 80.0; 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 @@ static const CGFloat kButtonSize = 80.0; 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 62397db77..247b49521 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 @@ ]; // 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]; + // 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; - 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]; - } - - return [NSString stringWithFormat:@"file://%@", cacheFilePath]; }]; } else @@ -701,22 +741,25 @@ __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 e57156b52..ea0d153b4 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 @@ { _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 b4761f589..3c40ccb57 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 @@ __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 @@ 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 3b81c28d5..f39daa444 100644 --- a/Riot/Modules/GlobalSearch/Files/CellData/FilesSearchCellData.m +++ b/Riot/Modules/GlobalSearch/Files/CellData/FilesSearchCellData.m @@ -41,7 +41,7 @@ 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 de045e5fb..29f8ccb5d 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 @@ 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 5cd611a52..a8fbca4cc 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 @@ { _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 ca861c7dc..24a60e6fd 100644 --- a/Riot/Modules/Room/DataSources/RoomDataSource.m +++ b/Riot/Modules/Room/DataSources/RoomDataSource.m @@ -304,7 +304,7 @@ 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 aedc8c202..5b88317b3 100644 --- a/Riot/Modules/Room/Members/Detail/RoomMemberDetailsViewController.m +++ b/Riot/Modules/Room/Members/Detail/RoomMemberDetailsViewController.m @@ -1101,38 +1101,31 @@ } 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]; - } - }]; + [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]; + }]; - NSString *avatarURL = nil; - if (self.mxRoomMember.avatarUrl) - { - avatarURL = [self.mainSession.matrixRestClient urlOfContent:self.mxRoomMember.avatarUrl]; - } - - [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 28f0a10a5..09ffafd0c 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 @@ id kRiotDesignValuesDidChangeThemeNotificationObserver; } -@property (nonatomic) MXRestClient* restClient; @property (nonatomic) MXSession *session; @property (nonatomic) NSArray *roomMembers; @@ -48,7 +48,6 @@ + (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 @@ 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 ea535c7c4..fea0b3ca0 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -1426,14 +1426,16 @@ 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 @@ // 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 @@ selectedEvent.sentState == MXEventSentStateSending) { // Upload id is stored in attachment url (nasty trick) - NSString *uploadId = roomBubbleTableViewCell.bubbleData.attachment.actualURL; + NSString *uploadId = roomBubbleTableViewCell.bubbleData.attachment.contentURL; if ([MXMediaManager existingUploaderWithId:uploadId]) { [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_cancel_send", @"Vector", nil) @@ -2357,7 +2357,7 @@ // Remove the outgoing message and its related cached file. [[NSFileManager defaultManager] removeItemAtPath:roomBubbleTableViewCell.bubbleData.attachment.cacheFilePath error:nil]; - [[NSFileManager defaultManager] removeItemAtPath:roomBubbleTableViewCell.bubbleData.attachment.cacheThumbnailPath error:nil]; + [[NSFileManager defaultManager] removeItemAtPath:roomBubbleTableViewCell.bubbleData.attachment.thumbnailCachePath error:nil]; // Cancel and remove the outgoing message [self.roomDataSource.room cancelSendingOperation:selectedEvent.eventId]; @@ -2418,8 +2418,8 @@ // Check whether download is in progress if (level == 0 && selectedEvent.isMediaAttachment) { - NSString *cacheFilePath = roomBubbleTableViewCell.bubbleData.attachment.cacheFilePath; - if ([MXMediaManager existingDownloaderWithOutputFilePath:cacheFilePath]) + NSString *downloadId = roomBubbleTableViewCell.bubbleData.attachment.downloadId; + if ([MXMediaManager existingDownloaderWithIdentifier:downloadId]) { [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_cancel_download", @"Vector", nil) style:UIAlertActionStyleDefault @@ -2432,7 +2432,7 @@ [self cancelEventSelection]; // Get again the loader - MXMediaLoader *loader = [MXMediaManager existingDownloaderWithOutputFilePath:cacheFilePath]; + MXMediaLoader *loader = [MXMediaManager existingDownloaderWithIdentifier:downloadId]; if (loader) { [loader cancel]; diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedBubbleCell.m index b24f91fac..0c6bd06e4 100644 --- a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedBubbleCell.m +++ b/Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedBubbleCell.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. @@ -65,14 +66,8 @@ { MXKImageView *avatarView = [[MXKImageView alloc] initWithFrame:CGRectMake(12 * self.avatarsView.subviews.count, 0, 16, 16)]; - // Handle user's picture - NSString *avatarThumbURL = nil; - if (nextBubbleData.senderAvatarUrl) - { - // Suppose this url is a matrix content uri, we use SDK to get the well adapted thumbnail from server - avatarThumbURL = [nextBubbleData.mxSession.matrixRestClient urlOfContentThumbnail:nextBubbleData.senderAvatarUrl toFitViewSize:avatarView.frame.size withMethod:MXThumbnailingMethodCrop]; - } - + // Handle user's picture by considering it is stored unencrypted on Matrix media repository + // Use the Riot style placeholder if (!nextBubbleData.senderAvatarPlaceholder) { @@ -80,7 +75,13 @@ } avatarView.enableInMemoryCache = YES; - [avatarView setImageURL:avatarThumbURL withType:nil andImageOrientation:UIImageOrientationUp previewImage: nextBubbleData.senderAvatarPlaceholder]; + [avatarView setImageURI:nextBubbleData.senderAvatarUrl + withType:nil + andImageOrientation:UIImageOrientationUp + toFitViewSize:avatarView.frame.size + withMethod:MXThumbnailingMethodCrop + previewImage:nextBubbleData.senderAvatarPlaceholder + mediaManager:nextBubbleData.mxSession.mediaManager]; // Clear the default background color of a MXKImageView instance avatarView.defaultBackgroundColor = [UIColor clearColor]; diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomSelectedStickerBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/RoomSelectedStickerBubbleCell.m index 6df642c36..18a757bbb 100644 --- a/Riot/Modules/Room/Views/BubbleCells/RoomSelectedStickerBubbleCell.m +++ b/Riot/Modules/Room/Views/BubbleCells/RoomSelectedStickerBubbleCell.m @@ -86,16 +86,17 @@ self.paginationTitleView.hidden = YES; } - // Hanlde sender avatar + // Hanlde sender avatar (Supposed his avatar is stored unencrypted on Matrix media repo) self.pictureView.hidden = NO; - NSString *avatarThumbURL = nil; - if (bubbleData.senderAvatarUrl) - { - // Suppose this url is a matrix content uri, we use SDK to get the well adapted thumbnail from server - avatarThumbURL = [bubbleData.mxSession.matrixRestClient urlOfContentThumbnail:bubbleData.senderAvatarUrl toFitViewSize:self.pictureView.frame.size withMethod:MXThumbnailingMethodCrop]; - } + self.pictureView.enableInMemoryCache = YES; - [self.pictureView setImageURL:avatarThumbURL withType:nil andImageOrientation:UIImageOrientationUp previewImage: bubbleData.senderAvatarPlaceholder ? bubbleData.senderAvatarPlaceholder : self.picturePlaceholder]; + [self.pictureView setImageURI:bubbleData.senderAvatarUrl + withType:nil + andImageOrientation:UIImageOrientationUp + toFitViewSize:self.pictureView.frame.size + withMethod:MXThumbnailingMethodCrop + previewImage:bubbleData.senderAvatarPlaceholder ? bubbleData.senderAvatarPlaceholder : self.picturePlaceholder + mediaManager:bubbleData.mxSession.mediaManager]; // Display sender's name except if the name appears in the displayed text (see emote and membership events) if (bubbleData.shouldHideSenderName == NO) @@ -139,8 +140,6 @@ // Display the sticker self.attachmentView.backgroundColor = [UIColor clearColor]; - self.attachmentView.mediaFolder = bubbleData.roomId; - self.attachmentView.enableInMemoryCache = YES; [self.attachmentView setAttachmentThumb:bubbleData.attachment]; // Set the description diff --git a/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.m b/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.m index 63c436cf0..d1c155736 100644 --- a/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.m +++ b/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.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. @@ -96,7 +97,13 @@ { if (self.roomAvatarURL) { - [self.roomAvatar setImageURL:self.roomAvatarURL withType:nil andImageOrientation:UIImageOrientationUp previewImage:[UIImage imageNamed:@"placeholder"]]; + [self.roomAvatar setImageURI:self.roomAvatarURL + withType:nil + andImageOrientation:UIImageOrientationUp + toFitViewSize:self.roomAvatar.frame.size + withMethod:MXThumbnailingMethodCrop + previewImage:[UIImage imageNamed:@"placeholder"] + mediaManager:self.mxRoom.mxSession.mediaManager]; } else { diff --git a/Riot/Modules/Rooms/DirectoryPicker/Views/DirectoryServerTableViewCell.m b/Riot/Modules/Rooms/DirectoryPicker/Views/DirectoryServerTableViewCell.m index 0cf810c26..617b0b400 100644 --- a/Riot/Modules/Rooms/DirectoryPicker/Views/DirectoryServerTableViewCell.m +++ b/Riot/Modules/Rooms/DirectoryPicker/Views/DirectoryServerTableViewCell.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. @@ -49,7 +50,20 @@ } 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 9fc346cd5..04acf5dc6 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -1451,7 +1451,13 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); { 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 7cae6fac4..541b5892d 100644 --- a/RiotShareExtension/Managers/ShareExtensionManager.m +++ b/RiotShareExtension/Managers/ShareExtensionManager.m @@ -58,7 +58,7 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) 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 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) #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; } }