diff --git a/CHANGES.rst b/CHANGES.rst index 467d22e0f..aae9c5887 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,14 @@ +Changes in MatrixKit in 0.12.x (2020-xx-xx) +========================================= + +Improvements: + * MXKAttachmentsViewController: MPMoviePlayerController replaced with AVPlayerViewController (PR #651). + * MXKCallViewController: Fix incoming call view for ringing state (PR #669). + +Bug fix: + * MXKImageView: Consider safe area insets when displayed fullscreen (PR #649). + * MXKRoomDataSource: Convert one-time observers to block variables to avoid releasing (vector-im/riot-ios/issues/3337). + Changes in MatrixKit in 0.12.7 (2020-05-xx) ========================================= diff --git a/MatrixKit/Controllers/MXKAttachmentsViewController.m b/MatrixKit/Controllers/MXKAttachmentsViewController.m index 71c7199ad..a72a1238e 100644 --- a/MatrixKit/Controllers/MXKAttachmentsViewController.m +++ b/MatrixKit/Controllers/MXKAttachmentsViewController.m @@ -251,7 +251,8 @@ - (void)viewWillDisappear:(BOOL)animated // Stop playing any video for (MXKMediaCollectionViewCell *cell in self.attachmentsCollection.visibleCells) { - [cell.moviePlayer stop]; + [cell.moviePlayer.player pause]; + cell.moviePlayer.player = nil; } // Restore audio category @@ -845,7 +846,7 @@ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPa { [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; - selectedCell.moviePlayer = [[MPMoviePlayerController alloc] init]; + selectedCell.moviePlayer = [[AVPlayerViewController alloc] init]; if (selectedCell.moviePlayer != nil) { // Switch in custom view @@ -860,7 +861,7 @@ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPa previewImage.center = selectedCell.customView.center; [selectedCell.customView addSubview:previewImage]; - selectedCell.moviePlayer.scalingMode = MPMovieScalingModeAspectFit; + selectedCell.moviePlayer.videoGravity = AVLayerVideoGravityResizeAspect; selectedCell.moviePlayer.view.frame = selectedCell.customView.frame; selectedCell.moviePlayer.view.center = selectedCell.customView.center; selectedCell.moviePlayer.view.hidden = YES; @@ -915,15 +916,15 @@ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPa } [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(moviePlayerPlaybackDidFinishNotification:) - name:MPMoviePlayerPlaybackDidFinishNotification + selector:@selector(moviePlayerPlaybackDidFinishWithErrorNotification:) + name:AVPlayerItemFailedToPlayToEndTimeNotification object:nil]; } } if (selectedCell.moviePlayer) { - if (selectedCell.moviePlayer.playbackState == MPMoviePlaybackStatePlaying) + if (selectedCell.moviePlayer.player.status == AVPlayerStatusReadyToPlay) { // Show or hide the navigation bar @@ -1007,8 +1008,8 @@ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPa { selectedCell.moviePlayer.view.hidden = NO; selectedCell.centerIcon.hidden = YES; - selectedCell.moviePlayer.contentURL = [NSURL fileURLWithPath:self->videoFile]; - [selectedCell.moviePlayer play]; + selectedCell.moviePlayer.player = [AVPlayer playerWithURL:[NSURL fileURLWithPath:self->videoFile]]; + [selectedCell.moviePlayer.player play]; [pieChartView removeFromSuperview]; @@ -1070,7 +1071,8 @@ - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:( { // This cell concerns an attached video. // We stop the player, and restore the default display based on the video thumbnail - [mediaCollectionViewCell.moviePlayer stop]; + [mediaCollectionViewCell.moviePlayer.player pause]; + mediaCollectionViewCell.moviePlayer.player = nil; mediaCollectionViewCell.moviePlayer = nil; mediaCollectionViewCell.mxkImageView.hidden = NO; @@ -1125,26 +1127,20 @@ - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollection #pragma mark - Movie Player -- (void)moviePlayerPlaybackDidFinishNotification:(NSNotification *)notification +- (void)moviePlayerPlaybackDidFinishWithErrorNotification:(NSNotification *)notification { NSDictionary *notificationUserInfo = [notification userInfo]; - NSNumber *resultValue = [notificationUserInfo objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey]; - MPMovieFinishReason reason = [resultValue intValue]; - - // error cases - if (reason == MPMovieFinishReasonPlaybackError) + + NSError *mediaPlayerError = [notificationUserInfo objectForKey:AVPlayerItemFailedToPlayToEndTimeErrorKey]; + if (mediaPlayerError) { - NSError *mediaPlayerError = [notificationUserInfo objectForKey:@"error"]; - if (mediaPlayerError) - { - NSLog(@"[MXKAttachmentsVC] Playback failed with error description: %@", [mediaPlayerError localizedDescription]); - - // Display the navigation bar so that the user can leave this screen - self.navigationBar.hidden = NO; + NSLog(@"[MXKAttachmentsVC] Playback failed with error description: %@", [mediaPlayerError localizedDescription]); - // Notify MatrixKit user - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:mediaPlayerError]; - } + // Display the navigation bar so that the user can leave this screen + self.navigationBar.hidden = NO; + + // Notify MatrixKit user + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:mediaPlayerError]; } } diff --git a/MatrixKit/Controllers/MXKCallViewController.m b/MatrixKit/Controllers/MXKCallViewController.m index e92840955..2c441e1fd 100644 --- a/MatrixKit/Controllers/MXKCallViewController.m +++ b/MatrixKit/Controllers/MXKCallViewController.m @@ -563,51 +563,7 @@ - (void)call:(MXCall *)call stateDidChange:(MXCallState)state reason:(MXEvent *) [localPreviewActivityView startAnimating]; // Try to show a special view for incoming view - if (call.isIncoming && !self.incomingCallView) - { - UIView *incomingCallView = [self createIncomingCallView]; - if (incomingCallView) - { - self.incomingCallView = incomingCallView; - [self.view addSubview:incomingCallView]; - - incomingCallView.translatesAutoresizingMaskIntoConstraints = NO; - - [NSLayoutConstraint activateConstraints:@[ - [NSLayoutConstraint constraintWithItem:incomingCallView - attribute:NSLayoutAttributeTop - relatedBy:NSLayoutRelationEqual - toItem:self.view - attribute:NSLayoutAttributeTop - multiplier:1.0 - constant:0.0], - - [NSLayoutConstraint constraintWithItem:incomingCallView - attribute:NSLayoutAttributeLeading - relatedBy:NSLayoutRelationEqual - toItem:self.view - attribute:NSLayoutAttributeLeading - multiplier:1.0 - constant:0.0], - - [NSLayoutConstraint constraintWithItem:incomingCallView - attribute:NSLayoutAttributeBottom - relatedBy:NSLayoutRelationEqual - toItem:self.view - attribute:NSLayoutAttributeBottom - multiplier:1.0 - constant:0.0], - - [NSLayoutConstraint constraintWithItem:incomingCallView - attribute:NSLayoutAttributeTrailing - relatedBy:NSLayoutRelationEqual - toItem:self.view - attribute:NSLayoutAttributeTrailing - multiplier:1.0 - constant:0.0] - ]]; - } - } + [self configureIncomingCallViewIfRequiredWith:call]; break; case MXCallStateCreateOffer: @@ -627,6 +583,7 @@ - (void)call:(MXCall *)call stateDidChange:(MXCallState)state reason:(MXEvent *) } case MXCallStateRinging: self.isRinging = YES; + speakerButton.selected = call.audioToSpeaker; if (call.isVideoCall) { callStatusLabel.text = [NSBundle mxk_localizedStringForKey:@"incoming_video_call"]; @@ -639,6 +596,10 @@ - (void)call:(MXCall *)call stateDidChange:(MXCallState)state reason:(MXEvent *) endCallButton.hidden = YES; rejectCallButton.hidden = NO; answerCallButton.hidden = NO; + + // Try to show a special view for incoming view + [self configureIncomingCallViewIfRequiredWith:call]; + break; case MXCallStateConnecting: self.isRinging = NO; @@ -870,6 +831,25 @@ - (void)handleAudioSessionActivationNotification #pragma mark - UI methods +- (void)configureIncomingCallViewIfRequiredWith:(MXCall *)call +{ + if (call.isIncoming && !self.incomingCallView) + { + UIView *incomingCallView = [self createIncomingCallView]; + if (incomingCallView) + { + self.incomingCallView = incomingCallView; + [self.view addSubview:incomingCallView]; + + incomingCallView.translatesAutoresizingMaskIntoConstraints = NO; + [incomingCallView.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:0].active = YES; + [incomingCallView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:0].active = YES; + [incomingCallView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor constant:0].active = YES; + [incomingCallView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:0].active = YES; + } + } +} + - (void)updateLocalPreviewLayout { // On IOS 8 and later, the screen size is oriented. diff --git a/MatrixKit/Controllers/MXKRoomViewController.m b/MatrixKit/Controllers/MXKRoomViewController.m index 5febd9d35..f78813c59 100644 --- a/MatrixKit/Controllers/MXKRoomViewController.m +++ b/MatrixKit/Controllers/MXKRoomViewController.m @@ -3656,6 +3656,11 @@ - (void)showAttachmentInCell:(UITableViewCell*)cell // "Initializing" closedAttachmentEventId so it is equal to openedAttachmentEventId at the beginning self.closedAttachmentEventId = self.openedAttachmentEventId; + + if (@available(iOS 13.0, *)) + { + attachmentsViewer.modalPresentationStyle = UIModalPresentationFullScreen; + } [self presentViewController:attachmentsViewer animated:YES completion:nil]; diff --git a/MatrixKit/Models/Room/MXKRoomDataSource.m b/MatrixKit/Models/Room/MXKRoomDataSource.m index b94d4271b..b5acda867 100644 --- a/MatrixKit/Models/Room/MXKRoomDataSource.m +++ b/MatrixKit/Models/Room/MXKRoomDataSource.m @@ -205,8 +205,7 @@ + (void)ensureSessionStateForDataSource:(MXKRoomDataSource*)roomDataSource initi else { // wait for session state to be store data ready - id sessionStateObserver = nil; - sessionStateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:mxSession queue:nil usingBlock:^(NSNotification * _Nonnull note) { + __block id sessionStateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:mxSession queue:nil usingBlock:^(NSNotification * _Nonnull note) { if (mxSession.state >= MXSessionStateStoreDataReady) { [[NSNotificationCenter defaultCenter] removeObserver:sessionStateObserver]; @@ -241,8 +240,7 @@ + (void)ensureInitialEventExistenceForDataSource:(MXKRoomDataSource*)roomDataSou { // give a chance for the specific event to be existent, for only one sync // use kMXSessionDidSyncNotification here instead of MXSessionStateRunning, because session does not send this state update if it's already in this state - id syncObserver = nil; - syncObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionDidSyncNotification object:mxSession queue:nil usingBlock:^(NSNotification * _Nonnull note) { + __block id syncObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionDidSyncNotification object:mxSession queue:nil usingBlock:^(NSNotification * _Nonnull note) { [[NSNotificationCenter defaultCenter] removeObserver:syncObserver]; [self finalizeRoomDataSource:roomDataSource onComplete:onComplete]; }]; diff --git a/MatrixKit/Views/MXKCollectionViewCell/MXKMediaCollectionViewCell.h b/MatrixKit/Views/MXKCollectionViewCell/MXKMediaCollectionViewCell.h index 7480a5ba9..932a2b4b7 100644 --- a/MatrixKit/Views/MXKCollectionViewCell/MXKMediaCollectionViewCell.h +++ b/MatrixKit/Views/MXKCollectionViewCell/MXKMediaCollectionViewCell.h @@ -16,7 +16,7 @@ #import "MXKCollectionViewCell.h" -#import +#import #import "MXKImageView.h" @@ -35,7 +35,7 @@ /** A potential player used in the cell. */ -@property (nonatomic) MPMoviePlayerController *moviePlayer; +@property (nonatomic) AVPlayerViewController *moviePlayer; /** A potential observer used to update cell display. diff --git a/MatrixKit/Views/MXKCollectionViewCell/MXKMediaCollectionViewCell.m b/MatrixKit/Views/MXKCollectionViewCell/MXKMediaCollectionViewCell.m index c8c48b1b5..2f19de586 100644 --- a/MatrixKit/Views/MXKCollectionViewCell/MXKMediaCollectionViewCell.m +++ b/MatrixKit/Views/MXKCollectionViewCell/MXKMediaCollectionViewCell.m @@ -23,7 +23,8 @@ @implementation MXKMediaCollectionViewCell - (void)prepareForReuse { [super prepareForReuse]; - [self.moviePlayer stop]; + [self.moviePlayer.player pause]; + self.moviePlayer.player = nil; self.moviePlayer = nil; // Restore the cell in reusable state @@ -64,7 +65,8 @@ - (void)prepareForReuse - (void)dealloc { - [self.moviePlayer stop]; + [self.moviePlayer.player pause]; + self.moviePlayer.player = nil; } @end diff --git a/Podfile.lock b/Podfile.lock index a5f8bb12a..1099c5b8d 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,18 +1,18 @@ PODS: - - AFNetworking (4.0.1): - - AFNetworking/NSURLSession (= 4.0.1) - - AFNetworking/Reachability (= 4.0.1) - - AFNetworking/Security (= 4.0.1) - - AFNetworking/Serialization (= 4.0.1) - - AFNetworking/UIKit (= 4.0.1) - - AFNetworking/NSURLSession (4.0.1): + - AFNetworking (3.2.1): + - AFNetworking/NSURLSession (= 3.2.1) + - AFNetworking/Reachability (= 3.2.1) + - AFNetworking/Security (= 3.2.1) + - AFNetworking/Serialization (= 3.2.1) + - AFNetworking/UIKit (= 3.2.1) + - AFNetworking/NSURLSession (3.2.1): - AFNetworking/Reachability - AFNetworking/Security - AFNetworking/Serialization - - AFNetworking/Reachability (4.0.1) - - AFNetworking/Security (4.0.1) - - AFNetworking/Serialization (4.0.1) - - AFNetworking/UIKit (4.0.1): + - AFNetworking/Reachability (3.2.1) + - AFNetworking/Security (3.2.1) + - AFNetworking/Serialization (3.2.1) + - AFNetworking/UIKit (3.2.1): - AFNetworking/NSURLSession - cmark (0.24.1) - DTCoreText (1.6.23): @@ -46,15 +46,15 @@ PODS: - GZIP (~> 1.2.2) - libbase58 (~> 0.1.4) - OLMKit (~> 3.1.0) - - Realm (~> 4.4.0) + - Realm (~> 3.17.3) - OLMKit (3.1.0): - OLMKit/olmc (= 3.1.0) - OLMKit/olmcpp (= 3.1.0) - OLMKit/olmc (3.1.0) - OLMKit/olmcpp (3.1.0) - - Realm (4.4.1): - - Realm/Headers (= 4.4.1) - - Realm/Headers (4.4.1) + - Realm (3.17.3): + - Realm/Headers (= 3.17.3) + - Realm/Headers (3.17.3) DEPENDENCIES: - cmark (~> 0.24.1) @@ -81,7 +81,7 @@ SPEC REPOS: - Realm SPEC CHECKSUMS: - AFNetworking: 7864c38297c79aaca1500c33288e429c3451fdce + AFNetworking: b6f891fdfaed196b46c7a83cf209e09697b94057 cmark: 1d9ad0375e3b9fa281732e992467903606015520 DTCoreText: 67023bb51b26711d5f640c851f4845aea14c24c9 DTFoundation: 25aa19bb7c6e225b1dfae195604fb8cf1da0ab4c @@ -93,7 +93,7 @@ SPEC CHECKSUMS: libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75 MatrixSDK: efe87af67440a67781be871b07e80b1f12ef5d48 OLMKit: 4ee0159d63feeb86d836fdcfefe418e163511639 - Realm: 4eb04d7487bd43c0581256f40b424eafb711deff + Realm: 5a1d9d47bfc101dd597668b1a8af4288a2557f6d PODFILE CHECKSUM: a82870f848ff79928c09549dbbaadc1f9a3cb525