From 6526b2ad28229f0f4cfdb5232e0ab276a7102af1 Mon Sep 17 00:00:00 2001 From: Ekaterina Gerasimova Date: Tue, 12 Oct 2021 10:28:30 +0100 Subject: [PATCH 01/57] Update defect issue template to improve wording Improve wording around rageshakes based on feedback. Fixes #4987 Signed-off-by: Ekaterina Gerasimova --- .github/ISSUE_TEMPLATE/bug.yml | 4 ++-- changelog.d/4987.misc | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelog.d/4987.misc diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index d50712529..c105f7ebf 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -64,9 +64,9 @@ body: - type: dropdown id: rageshake attributes: - label: Have you submitted a rageshake? + label: Will you send logs? description: | - Did you know that you can shake your phone to submit logs for this issue? Trigger the defect, then shake your phone and you will see a popup asking if you would like to open the bug report screen. Click YES, and describe the issue, mentioning that you have also filed a bug. Submit the report to send anonymous logs to the developers. + Did you know that you can shake your phone to submit logs for this issue? Trigger the defect, then shake your phone and you will see a popup asking if you would like to open the bug report screen. Click YES, and describe the issue, mentioning that you have also filed a bug (it's helpful if you can include a link to the bug). Send the report to submit anonymous logs to the developers. options: - 'Yes' - 'No' diff --git a/changelog.d/4987.misc b/changelog.d/4987.misc new file mode 100644 index 000000000..ac7a294f3 --- /dev/null +++ b/changelog.d/4987.misc @@ -0,0 +1 @@ +Improve wording around rageshakes in the defect issue template. From 3a43929e8efc4f5c80a5a97f6570f09ec1b1a5d5 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 21 Oct 2021 20:33:33 +0200 Subject: [PATCH 02/57] Prepare for new sprint --- Config/AppVersion.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index 6dab241e0..5e6c9928e 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 1.6.6 -CURRENT_PROJECT_VERSION = 1.6.6 +MARKETING_VERSION = 1.6.7 +CURRENT_PROJECT_VERSION = 1.6.7 From 91190f8de3126702f52c927948cccd90e672d04f Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Mon, 25 Oct 2021 13:45:41 +0300 Subject: [PATCH 03/57] vector-im/element-ios/issues/5041 - Fixed share extension and message forwarding room list accessory view icon. --- .../radio-button-default.imageset/Contents.json | 3 +++ .../radio-button-selected.imageset/Contents.json | 3 +++ .../Shared/View/RecentRoomTableViewCell.m | 1 + .../Shared/View/RecentRoomTableViewCell.xib | 11 ++++++----- changelog.d/5041.bugfix | 1 + 5 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 changelog.d/5041.bugfix diff --git a/Riot/Assets/SharedImages.xcassets/radio-button-default.imageset/Contents.json b/Riot/Assets/SharedImages.xcassets/radio-button-default.imageset/Contents.json index 35812152a..74d91f39d 100644 --- a/Riot/Assets/SharedImages.xcassets/radio-button-default.imageset/Contents.json +++ b/Riot/Assets/SharedImages.xcassets/radio-button-default.imageset/Contents.json @@ -19,5 +19,8 @@ "info" : { "author" : "xcode", "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" } } diff --git a/Riot/Assets/SharedImages.xcassets/radio-button-selected.imageset/Contents.json b/Riot/Assets/SharedImages.xcassets/radio-button-selected.imageset/Contents.json index a69d70fe6..a7cfab75b 100644 --- a/Riot/Assets/SharedImages.xcassets/radio-button-selected.imageset/Contents.json +++ b/Riot/Assets/SharedImages.xcassets/radio-button-selected.imageset/Contents.json @@ -19,5 +19,8 @@ "info" : { "author" : "xcode", "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" } } diff --git a/RiotShareExtension/Shared/View/RecentRoomTableViewCell.m b/RiotShareExtension/Shared/View/RecentRoomTableViewCell.m index 31beb9cbf..b6fc0d27c 100644 --- a/RiotShareExtension/Shared/View/RecentRoomTableViewCell.m +++ b/RiotShareExtension/Shared/View/RecentRoomTableViewCell.m @@ -57,6 +57,7 @@ self.roomTitleLabel.textColor = ThemeService.shared.theme.textPrimaryColor; self.contentView.backgroundColor = ThemeService.shared.theme.backgroundColor; + self.selectionButton.tintColor = ThemeService.shared.theme.tintColor; [self.selectionButton setImage:[UIImage imageNamed:@"radio-button-default"] forState:UIControlStateNormal]; [self.selectionButton setImage:[UIImage imageNamed:@"radio-button-selected"] forState:UIControlStateSelected]; diff --git a/RiotShareExtension/Shared/View/RecentRoomTableViewCell.xib b/RiotShareExtension/Shared/View/RecentRoomTableViewCell.xib index fe39d2a67..a61bc36e6 100644 --- a/RiotShareExtension/Shared/View/RecentRoomTableViewCell.xib +++ b/RiotShareExtension/Shared/View/RecentRoomTableViewCell.xib @@ -1,9 +1,9 @@ - + - + @@ -40,14 +40,15 @@ - diff --git a/changelog.d/5041.bugfix b/changelog.d/5041.bugfix new file mode 100644 index 000000000..07882c073 --- /dev/null +++ b/changelog.d/5041.bugfix @@ -0,0 +1 @@ +Fixed share extension and message forwarding room list accessory view icon. \ No newline at end of file From 2cd1097786b14a14fd850758465032cf31c9d702 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Mon, 25 Oct 2021 15:27:27 +0300 Subject: [PATCH 04/57] Fixes vector-im/element-ios/issues/5042 - Message composer doesn't follow keyboard when swiping to dismiss. --- Riot/Modules/Room/RoomViewController.xib | 2 +- Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m | 4 ++++ changelog.d/5042.bugfix | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changelog.d/5042.bugfix diff --git a/Riot/Modules/Room/RoomViewController.xib b/Riot/Modules/Room/RoomViewController.xib index 1c8f83913..b1f933efe 100644 --- a/Riot/Modules/Room/RoomViewController.xib +++ b/Riot/Modules/Room/RoomViewController.xib @@ -163,7 +163,7 @@ - + diff --git a/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m b/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m index 8cc889940..06c509632 100644 --- a/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m +++ b/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m @@ -85,6 +85,10 @@ const CGFloat kComposerContainerTrailingPadding = 12; [self updateUIWithTextMessage:nil animated:NO]; self.textView.toolbarDelegate = self; + + // Add an accessory view to the text view in order to retrieve keyboard view. + inputAccessoryView = [[UIView alloc] initWithFrame:CGRectZero]; + self.textView.inputAccessoryView = inputAccessoryView; } - (void)setVoiceMessageToolbarView:(UIView *)voiceMessageToolbarView diff --git a/changelog.d/5042.bugfix b/changelog.d/5042.bugfix new file mode 100644 index 000000000..481c4c053 --- /dev/null +++ b/changelog.d/5042.bugfix @@ -0,0 +1 @@ +Fixed message composer not following keyboard when swiping to dismiss. \ No newline at end of file From ae5bbf9cbe75dc114acdccc7cf94a1f3c97474ba Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Mon, 25 Oct 2021 17:49:35 +0300 Subject: [PATCH 05/57] vector-im/element-ios/issues/4384 - Using mutable room list fetch sort options after chaning them to be a structure. --- .../Common/Recents/Service/MatrixSDK/RecentsListService.swift | 2 +- changelog.d/4384.change | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/4384.change diff --git a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift index cda8f716d..1fbc04371 100644 --- a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift +++ b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift @@ -440,7 +440,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { case .home: fetcher.fetchOptions.sortOptions = sortOptions case .favourites: - let newSortOptions = sortOptions + var newSortOptions = sortOptions newSortOptions.favoriteTag = true fetcher.fetchOptions.sortOptions = newSortOptions default: diff --git a/changelog.d/4384.change b/changelog.d/4384.change new file mode 100644 index 000000000..9103529a3 --- /dev/null +++ b/changelog.d/4384.change @@ -0,0 +1 @@ +Using mutable room list fetch sort options after chaning them to be a structure. \ No newline at end of file From 6df70a3ec3331c8d244282de59a7e9984e380931 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 26 Oct 2021 16:27:51 +0300 Subject: [PATCH 06/57] vector-im/element-ios/issues/4976 - Replaced GrowingTextView with simpler, custom implementation. Cleaned up the RoomInputToolbar header. --- Podfile | 1 - .../RoomInputToolbarTextView.swift | 115 ++++++++++++++++-- .../Views/InputToolbar/RoomInputToolbarView.h | 44 +++---- .../Views/InputToolbar/RoomInputToolbarView.m | 98 +++++++-------- changelog.d/4976.change | 1 + 5 files changed, 172 insertions(+), 87 deletions(-) create mode 100644 changelog.d/4976.change diff --git a/Podfile b/Podfile index dec1aaefb..f2fab251b 100644 --- a/Podfile +++ b/Podfile @@ -73,7 +73,6 @@ abstract_target 'RiotPods' do pod 'SideMenu', '~> 6.5' pod 'DSWaveformImage', '~> 6.1.1' pod 'ffmpeg-kit-ios-audio', '~> 4.5' - pod 'GrowingTextView', '~> 0.7.2' pod 'FLEX', '~> 4.5.0', :configurations => ['Debug'] diff --git a/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarTextView.swift b/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarTextView.swift index 729b3c2e7..4e8916e54 100644 --- a/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarTextView.swift +++ b/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarTextView.swift @@ -14,26 +14,91 @@ // limitations under the License. // -import GrowingTextView - @objc protocol RoomInputToolbarTextViewDelegate: AnyObject { + func textView(_ textView: RoomInputToolbarTextView, didChangeHeight height: CGFloat) func textView(_ textView: RoomInputToolbarTextView, didReceivePasteForMediaFromSender sender: Any?) } -class RoomInputToolbarTextView: GrowingTextView { +@objcMembers +class RoomInputToolbarTextView: UITextView { - @objc weak var toolbarDelegate: RoomInputToolbarTextViewDelegate? + private var heightConstraint: NSLayoutConstraint! + + weak var toolbarDelegate: RoomInputToolbarTextViewDelegate? + + var placeholder: String? + var placeholderColor: UIColor = UIColor(white: 0.8, alpha: 1.0) - override var keyCommands: [UIKeyCommand]? { - return [UIKeyCommand(input: "\r", modifierFlags: [], action: #selector(keyCommandSelector(_:)))] + var minHeight: CGFloat = 30.0 { + didSet { + updateUI() + } } - @objc private func keyCommandSelector(_ keyCommand: UIKeyCommand) { - guard keyCommand.input == "\r", let delegate = (self.delegate as? RoomInputToolbarView) else { + var maxHeight: CGFloat = 0.0 { + didSet { + updateUI() + } + } + + override var text: String! { + didSet { + updateUI() + } + } + + override init(frame: CGRect, textContainer: NSTextContainer?) { + super.init(frame: frame, textContainer: textContainer) + commonInit() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + commonInit() + } + + private func commonInit() { + contentMode = .redraw + + NotificationCenter.default.addObserver(self, selector: #selector(textDidChange), name: UITextView.textDidChangeNotification, object: self) + + if let heightConstraint = constraints.filter({ $0.firstAttribute == .height && $0.relation == .equal }).first { + self.heightConstraint = heightConstraint + } else { + heightConstraint = self.heightAnchor.constraint(equalToConstant: minHeight) + addConstraint(heightConstraint) + } + } + + // MARK: - Overrides + + override func layoutSubviews() { + super.layoutSubviews() + updateUI() + } + + override func draw(_ rect: CGRect) { + super.draw(rect) + + guard text.isEmpty, let placeholder = placeholder else { return } - delegate.onTouchUp(inside: delegate.rightInputToolbarButton) + var attributes: [NSAttributedString.Key: Any] = [.foregroundColor: placeholderColor] + if let font = font { + attributes[.font] = font + } + + let frame = rect.inset(by: .init(top: textContainerInset.top, + left: textContainerInset.left + textContainer.lineFragmentPadding, + bottom: textContainerInset.bottom, + right: textContainerInset.right)) + + placeholder.draw(in: frame, withAttributes: attributes) + } + + override var keyCommands: [UIKeyCommand]? { + return [UIKeyCommand(input: "\r", modifierFlags: [], action: #selector(keyCommandSelector(_:)))] } /// Overrides paste to handle images pasted from Safari, passing them up to the input toolbar. @@ -49,4 +114,36 @@ class RoomInputToolbarTextView: GrowingTextView { super.paste(sender) } } + + // MARK: - Private + + @objc private func textDidChange(notification: Notification) { + if let sender = notification.object as? RoomInputToolbarTextView, sender == self { + updateUI() + } + } + + private func updateUI() { + var height = sizeThatFits(CGSize(width: bounds.size.width, height: CGFloat.greatestFiniteMagnitude)).height + height = minHeight > 0 ? max(height, minHeight) : height + height = maxHeight > 0 ? min(height, maxHeight) : height + + // Update placeholder + self.setNeedsDisplay() + + guard height != heightConstraint.constant else { + return + } + + heightConstraint.constant = height + toolbarDelegate?.textView(self, didChangeHeight: height) + } + + @objc private func keyCommandSelector(_ keyCommand: UIKeyCommand) { + guard keyCommand.input == "\r", let delegate = (self.delegate as? RoomInputToolbarView) else { + return + } + + delegate.onTouchUp(inside: delegate.rightInputToolbarButton) + } } diff --git a/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.h b/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.h index 3099fd50f..d126ba22f 100644 --- a/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.h +++ b/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.h @@ -60,28 +60,10 @@ typedef enum : NSUInteger */ @property (nonatomic, weak) id delegate; -@property (weak, nonatomic) IBOutlet UIView *mainToolbarView; - -@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainToolbarMinHeightConstraint; -@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainToolbarHeightConstraint; - -@property (weak, nonatomic) IBOutlet NSLayoutConstraint *messageComposerContainerTrailingConstraint; - -@property (weak, nonatomic) IBOutlet UIButton *attachMediaButton; - -@property (weak, nonatomic) IBOutlet UIImageView *inputTextBackgroundView; - -@property (weak, nonatomic) IBOutlet NSLayoutConstraint *inputContextViewHeightConstraint; -@property (weak, nonatomic) IBOutlet UIImageView *inputContextImageView; -@property (weak, nonatomic) IBOutlet UILabel *inputContextLabel; -@property (weak, nonatomic) IBOutlet UIButton *inputContextButton; -@property (weak, nonatomic) IBOutlet RoomActionsBar *actionsBar; -@property (weak, nonatomic) UIView *voiceMessageToolbarView; - /** Tell whether the filled data will be sent encrypted. NO by default. */ -@property (nonatomic) BOOL isEncryptionEnabled; +@property (nonatomic, assign) BOOL isEncryptionEnabled; /** Sender of the event being edited / replied. @@ -91,11 +73,31 @@ typedef enum : NSUInteger /** Destination of the message in the composer. */ -@property (nonatomic) RoomInputToolbarViewSendMode sendMode; +@property (nonatomic, assign) RoomInputToolbarViewSendMode sendMode; /** YES if action menu is opened. NO otherwise */ -@property (nonatomic, getter=isActionMenuOpened) BOOL actionMenuOpened; +@property (nonatomic, assign) BOOL actionMenuOpened; + +/** + The input toolbar's main height constraint + */ +@property (nonatomic, weak, readonly) NSLayoutConstraint *mainToolbarHeightConstraint; + +/** + The input toolbar's action bar + */ +@property (nonatomic, weak, readonly) RoomActionsBar *actionsBar; + +/** + The attach media button + */ +@property (nonatomic, weak, readonly) UIButton *attachMediaButton; + +/** + Adds a voice message toolbar view to be displayed inside this input toolbar + */ +- (void)setVoiceMessageToolbarView:(UIView *)toolbarView; @end diff --git a/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m b/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m index 06c509632..bf1bda55c 100644 --- a/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m +++ b/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarView.m @@ -17,34 +17,40 @@ #import "RoomInputToolbarView.h" -#import "ThemeService.h" #import "Riot-Swift.h" - #import "GBDeviceInfo_iOS.h" -#import "UINavigationController+Riot.h" +static const CGFloat kContextBarHeight = 24; +static const CGFloat kActionMenuAttachButtonSpringVelocity = 7; +static const CGFloat kActionMenuAttachButtonSpringDamping = .45; -#import "WidgetManager.h" -#import "IntegrationManagerViewController.h" +static const NSTimeInterval kSendModeAnimationDuration = .15; +static const NSTimeInterval kActionMenuAttachButtonAnimationDuration = .4; +static const NSTimeInterval kActionMenuContentAlphaAnimationDuration = .2; +static const NSTimeInterval kActionMenuComposerHeightAnimationDuration = .3; -@import GrowingTextView; +@interface RoomInputToolbarView() -const double kContextBarHeight = 24; -const NSTimeInterval kSendModeAnimationDuration = .15; -const NSTimeInterval kActionMenuAttachButtonAnimationDuration = .4; -const CGFloat kActionMenuAttachButtonSpringVelocity = 7; -const CGFloat kActionMenuAttachButtonSpringDamping = .45; -const NSTimeInterval kActionMenuContentAlphaAnimationDuration = .2; -const NSTimeInterval kActionMenuComposerHeightAnimationDuration = .3; -const CGFloat kComposerContainerTrailingPadding = 12; +@property (nonatomic, weak) IBOutlet UIView *mainToolbarView; -@interface RoomInputToolbarView() -{ - // The intermediate action sheet - UIAlertController *actionSheet; -} +@property (nonatomic, weak) IBOutlet UIButton *attachMediaButton; @property (nonatomic, weak) IBOutlet RoomInputToolbarTextView *textView; +@property (nonatomic, weak) IBOutlet UIImageView *inputTextBackgroundView; + +@property (nonatomic, weak) IBOutlet UIImageView *inputContextImageView; +@property (nonatomic, weak) IBOutlet UILabel *inputContextLabel; +@property (nonatomic, weak) IBOutlet UIButton *inputContextButton; + +@property (nonatomic, weak) IBOutlet RoomActionsBar *actionsBar; + +@property (nonatomic, weak) IBOutlet NSLayoutConstraint *mainToolbarMinHeightConstraint; +@property (nonatomic, weak) IBOutlet NSLayoutConstraint *mainToolbarHeightConstraint; +@property (nonatomic, weak) IBOutlet NSLayoutConstraint *messageComposerContainerTrailingConstraint; +@property (nonatomic, weak) IBOutlet NSLayoutConstraint *inputContextViewHeightConstraint; + +@property (nonatomic, weak) UIView *voiceMessageToolbarView; + @property (nonatomic, assign) CGFloat expandedMainToolbarHeight; @end @@ -52,22 +58,10 @@ const CGFloat kComposerContainerTrailingPadding = 12; @implementation RoomInputToolbarView @dynamic delegate; -+ (UINib *)nib -{ - return [UINib nibWithNibName:NSStringFromClass([RoomInputToolbarView class]) - bundle:[NSBundle bundleForClass:[RoomInputToolbarView class]]]; -} - + (instancetype)roomInputToolbarView { - if ([[self class] nib]) - { - return [[[self class] nib] instantiateWithOwner:nil options:nil].firstObject; - } - else - { - return [[self alloc] init]; - } + UINib *nib = [UINib nibWithNibName:NSStringFromClass([RoomInputToolbarView class]) bundle:nil]; + return [nib instantiateWithOwner:nil options:nil].firstObject; } - (void)awakeFromNib @@ -315,6 +309,11 @@ const CGFloat kComposerContainerTrailingPadding = 12; self.textView.placeholder = inPlaceholder; } +- (void)pasteText:(NSString *)text +{ + self.textMessage = [self.textView.text stringByReplacingCharactersInRange:self.textView.selectedRange withString:text]; +} + #pragma mark - Actions - (IBAction)cancelAction:(id)sender @@ -325,7 +324,7 @@ const CGFloat kComposerContainerTrailingPadding = 12; } } -#pragma mark - GrowingTextViewDelegate +#pragma mark - UITextViewDelegate - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { @@ -351,7 +350,9 @@ const CGFloat kComposerContainerTrailingPadding = 12; [self.delegate roomInputToolbarViewDidChangeTextMessage:self]; } -- (void)textViewDidChangeHeight:(GrowingTextView *)textView height:(CGFloat)height +#pragma mark - RoomInputToolbarTextViewDelegate + +- (void)textView:(RoomInputToolbarTextView *)textView didChangeHeight:(CGFloat)height { // Update height of the main toolbar (message composer) CGFloat updatedHeight = height + (self.messageComposerContainerTopConstraint.constant + self.messageComposerContainerBottomConstraint.constant) + self.inputContextViewHeightConstraint.constant; @@ -376,13 +377,18 @@ const CGFloat kComposerContainerTrailingPadding = 12; } } +- (void)textView:(RoomInputToolbarTextView *)textView didReceivePasteForMediaFromSender:(id)sender +{ + [self paste:sender]; +} + #pragma mark - Override MXKRoomInputToolbarView - (IBAction)onTouchUpInside:(UIButton*)button { if (button == self.attachMediaButton) { - self.actionMenuOpened = !self.isActionMenuOpened; + self.actionMenuOpened = !self.actionMenuOpened; } [super onTouchUpInside:button]; @@ -400,12 +406,6 @@ const CGFloat kComposerContainerTrailingPadding = 12; - (void)destroy { - if (actionSheet) - { - [actionSheet dismissViewControllerAnimated:NO completion:nil]; - actionSheet = nil; - } - [super destroy]; } @@ -462,20 +462,6 @@ const CGFloat kComposerContainerTrailingPadding = 12; } } -#pragma mark - Clipboard - Handle image/data paste from general pasteboard - -- (void)paste:(id)sender -{ - // TODO Custom here the validation screen for each available item - - [super paste:sender]; -} - -- (void)textView:(GrowingTextView *)textView didReceivePasteForMediaFromSender:(id)sender -{ - [self paste:sender]; -} - #pragma mark - Private - (void)updateUIWithTextMessage:(NSString *)textMessage animated:(BOOL)animated diff --git a/changelog.d/4976.change b/changelog.d/4976.change new file mode 100644 index 000000000..7c52865d3 --- /dev/null +++ b/changelog.d/4976.change @@ -0,0 +1 @@ +Replaced GrowingTextView with simpler, custom implementation. Cleaned up the RoomInputToolbar header. \ No newline at end of file From 95e9ace5d4ada00f14f67bc4cc6993bf50ad6ed2 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 27 Oct 2021 10:15:57 +0300 Subject: [PATCH 07/57] vector-im/element-ios/issues/4976 - Fixed placeholder not displaying after being hidden for resize animations. --- .../InputToolbar/RoomInputToolbarTextView.swift | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarTextView.swift b/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarTextView.swift index 4e8916e54..8a1097647 100644 --- a/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarTextView.swift +++ b/Riot/Modules/Room/Views/InputToolbar/RoomInputToolbarTextView.swift @@ -26,8 +26,17 @@ class RoomInputToolbarTextView: UITextView { weak var toolbarDelegate: RoomInputToolbarTextViewDelegate? - var placeholder: String? - var placeholderColor: UIColor = UIColor(white: 0.8, alpha: 1.0) + var placeholder: String? { + didSet { + setNeedsDisplay() + } + } + + var placeholderColor: UIColor = UIColor(white: 0.8, alpha: 1.0) { + didSet { + setNeedsDisplay() + } + } var minHeight: CGFloat = 30.0 { didSet { From bcaed3f572a9d15dc698e60bc416a004a3869b54 Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 28 Oct 2021 11:26:34 +0100 Subject: [PATCH 08/57] Send original data when when the compression prompt is disabled. Rebase changes on develop. --- RiotShareExtension/Shared/ShareManager.m | 41 ++++++++++++------------ changelog.d/4815.change | 1 + 2 files changed, 22 insertions(+), 20 deletions(-) create mode 100644 changelog.d/4815.change diff --git a/RiotShareExtension/Shared/ShareManager.m b/RiotShareExtension/Shared/ShareManager.m index 5ca23a2b1..f061565ec 100644 --- a/RiotShareExtension/Shared/ShareManager.m +++ b/RiotShareExtension/Shared/ShareManager.m @@ -314,30 +314,41 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) if ([self.shareItemProvider areAllItemsImages]) { + // When all items are images, they're processed together from the + // pending list, immediately after the final image has been loaded. [self.pendingImages addObject:imageData]; } else { - CGSize imageSize = [self imageSizeFromImageData:imageData]; + // Otherwise, the image is sent as is, without prompting for a resize + // as that wouldn't make much sense with multiple content types. self.imageCompressionMode = ImageCompressionModeNone; - self.actualLargeSize = MAX(imageSize.width, imageSize.height); - [self sendImageData:imageData toRooms:rooms success:requestSuccess failure:requestFailure]; } - // Only prompt for image resize if all items are images - // Ignore showMediaCompressionPrompt setting due to memory constraints with full size images. + // When there are multiple content types the image will have been sent above. + // Otherwise, if we have loaded all of the images we can send them all together. if ([self.shareItemProvider areAllItemsImages]) { if ([self.shareItemProvider areAllItemsLoaded]) { - UIAlertController *compressionPrompt = [self compressionPromptForPendingImagesWithShareBlock:^{ + void (^sendPendingImages)(void) = ^void() { [self sendImageDatas:self.pendingImages.copy toRooms:rooms success:requestSuccess failure:requestFailure]; - }]; + }; - if (compressionPrompt) + if (RiotSettings.shared.showMediaCompressionPrompt) { - [self presentCompressionPrompt:compressionPrompt]; + // Create a compression prompt which will be nil when the sizes can't be determined or if there are no pending images. + UIAlertController *compressionPrompt = [self compressionPromptForPendingImagesWithShareBlock:sendPendingImages]; + if (compressionPrompt) + { + [self presentCompressionPrompt:compressionPrompt]; + } + } + else + { + self.imageCompressionMode = ImageCompressionModeNone; + sendPendingImages(); } } else @@ -1021,17 +1032,7 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) break; } - if (CGSizeEqualToSize(newImageSize, CGSizeZero)) - { - // No resize to make - // Make sure the uploaded image orientation is up - if ([self isImageOrientationNotUpOrUndeterminedForImageData:imageData]) - { - UIImage *image = [UIImage imageWithData:imageData]; - convertedImage = [MXKTools forceImageOrientationUp:image]; - } - } - else + if (!CGSizeEqualToSize(newImageSize, CGSizeZero)) { // Resize the image and set image in right orientation too convertedImage = [MXKTools resizeImageWithData:imageData toFitInSize:newImageSize]; diff --git a/changelog.d/4815.change b/changelog.d/4815.change new file mode 100644 index 000000000..757ff6d22 --- /dev/null +++ b/changelog.d/4815.change @@ -0,0 +1 @@ +Share Extension: Remove the image compression prompt when the showMediaSizeSelection setting is disabled. \ No newline at end of file From 434a9b5e771edea6158aac84f936a81cd4af21a0 Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 28 Oct 2021 11:56:08 +0100 Subject: [PATCH 09/57] Re-order UTI types to prevent URLs being sent as text. --- .../Sources/ShareExtensionShareItemProvider.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/RiotShareExtension/Sources/ShareExtensionShareItemProvider.swift b/RiotShareExtension/Sources/ShareExtensionShareItemProvider.swift index df80ab563..6a83e25c5 100644 --- a/RiotShareExtension/Sources/ShareExtensionShareItemProvider.swift +++ b/RiotShareExtension/Sources/ShareExtensionShareItemProvider.swift @@ -28,18 +28,18 @@ private class ShareExtensionItem: ShareItemProtocol { } var type: ShareItemType { - if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.text.rawValue) { - return .text - } else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.url.rawValue) { - return .URL - } else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.fileUrl.rawValue) { - return .fileURL - } else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.image.rawValue) { + if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.image.rawValue) { return .image } else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.video.rawValue) { return .video } else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.movie.rawValue) { return .movie + } else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.fileUrl.rawValue) { + return .fileURL + } else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.url.rawValue) { + return .URL + } else if itemProvider.hasItemConformingToTypeIdentifier(MXKUTI.text.rawValue) { + return .text } return .unknown From 16762d846d75daf2a12f468128f926f7df92788f Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 28 Oct 2021 12:17:46 +0100 Subject: [PATCH 10/57] Remove image orientation checks. Images are still reoriented when resizing, but when sending the original data this isn't necessary. --- RiotShareExtension/Shared/ShareManager.m | 82 +++--------------------- 1 file changed, 9 insertions(+), 73 deletions(-) diff --git a/RiotShareExtension/Shared/ShareManager.m b/RiotShareExtension/Shared/ShareManager.m index f061565ec..6906f444b 100644 --- a/RiotShareExtension/Shared/ShareManager.m +++ b/RiotShareExtension/Shared/ShareManager.m @@ -32,6 +32,8 @@ static const CGFloat kLargeImageSizeMaxDimension = 2048.0; static const CGSize kThumbnailSize = {800.0, 600.0}; +/// A safe maximum file size for an image to send the original. +static const NSUInteger kImageMaxFileSize = 20 * 1024 * 1024; typedef NS_ENUM(NSInteger, ImageCompressionMode) { @@ -427,22 +429,6 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) [self.imageUploadProgresses removeAllObjects]; } -- (BOOL)isAPendingImageNotOrientedUp -{ - BOOL isAPendingImageNotOrientedUp = NO; - - for (NSData *imageData in self.pendingImages) - { - if ([self isImageOrientationNotUpOrUndeterminedForImageData:imageData]) - { - isAPendingImageNotOrientedUp = YES; - break; - } - } - - return isAPendingImageNotOrientedUp; -} - // TODO: When select multiple images: // - Enhance prompt to display sum of all file sizes for each compression. // - Find a way to choose compression sizes for all images. @@ -453,8 +439,6 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) return nil; } - BOOL isAPendingImageNotOrientedUp = [self isAPendingImageNotOrientedUp]; - NSData *firstImageData = self.pendingImages.firstObject; UIImage *firstImage = [UIImage imageWithData:firstImageData]; @@ -462,16 +446,8 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) if (compressionSizes.small.fileSize == 0 && compressionSizes.medium.fileSize == 0 && compressionSizes.large.fileSize == 0) { - if (isAPendingImageNotOrientedUp && self.pendingImages.count > 1) - { - self.imageCompressionMode = ImageCompressionModeSmall; - } - else - { - self.imageCompressionMode = ImageCompressionModeNone; - } - - MXLogDebug(@"[ShareManager] Send %lu image(s) without compression prompt using compression mode: %ld", (unsigned long)self.pendingImages.count, (long)self.imageCompressionMode); + self.imageCompressionMode = ImageCompressionModeNone; + MXLogDebug(@"[ShareManager] Bypass compression prompt and send originals for %lu image(s) due to undetermined file sizes", (unsigned long)self.pendingImages.count); shareBlock(); @@ -491,7 +467,7 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) MXStrongifyAndReturnIfNil(self); self.imageCompressionMode = ImageCompressionModeSmall; - [self logCompressionSizeChoice:compressionSizes.large]; + [self logCompressionSizeChoice:compressionSizes.small]; shareBlock(); }]]; @@ -506,7 +482,7 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) MXStrongifyAndReturnIfNil(self); self.imageCompressionMode = ImageCompressionModeMedium; - [self logCompressionSizeChoice:compressionSizes.large]; + [self logCompressionSizeChoice:compressionSizes.medium]; shareBlock(); }]]; @@ -531,8 +507,8 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) }]]; } - // To limit memory consumption, we suggest the original resolution only if the image orientation is up, or if the image size is moderate - if (!isAPendingImageNotOrientedUp || !compressionSizes.large.fileSize) + // To limit memory consumption when encrypting, we suggest the original resolution only if the image size is moderate + if (compressionSizes.original.fileSize < kImageMaxFileSize) { NSString *fileSizeString = [MXTools fileSizeToString:compressionSizes.original.fileSize]; @@ -543,7 +519,7 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) MXStrongifyAndReturnIfNil(self); self.imageCompressionMode = ImageCompressionModeNone; - [self logCompressionSizeChoice:compressionSizes.large]; + [self logCompressionSizeChoice:compressionSizes.original]; shareBlock(); }]]; @@ -637,46 +613,6 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) return CGSizeMake(width, height); } -- (NSNumber*)cgImageimageOrientationNumberFromImageData:(NSData*)imageData -{ - NSNumber *orientationNumber; - - CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)imageData, NULL); - - CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL); - - CFRelease(imageSource); - - if (imageProperties != NULL) - { - CFNumberRef orientationNum = CFDictionaryGetValue(imageProperties, kCGImagePropertyOrientation); - - // Check orientation and flip size if required - if (orientationNum != NULL) - { - orientationNumber = (__bridge NSNumber *)orientationNum; - } - - CFRelease(imageProperties); - } - - return orientationNumber; -} - -- (BOOL)isImageOrientationNotUpOrUndeterminedForImageData:(NSData*)imageData -{ - BOOL isImageNotOrientedUp = YES; - - NSNumber *cgImageOrientationNumber = [self cgImageimageOrientationNumberFromImageData:imageData]; - - if (cgImageOrientationNumber && cgImageOrientationNumber.unsignedIntegerValue == (NSUInteger)kCGImagePropertyOrientationUp) - { - isImageNotOrientedUp = NO; - } - - return isImageNotOrientedUp; -} - - (void)logCompressionSizeChoice:(MXKImageCompressionSize)compressionSize { NSString *fileSize = [MXTools fileSizeToString:compressionSize.fileSize round:NO]; From 0b746046da43c45ac48a8136849c3b7583e690f0 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 28 Oct 2021 17:28:56 +0200 Subject: [PATCH 11/57] RecentsViewController: Prevent retain cycles. --- .../Common/Recents/RecentsViewController.m | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Riot/Modules/Common/Recents/RecentsViewController.m b/Riot/Modules/Common/Recents/RecentsViewController.m index f47f08a9d..7a722a191 100644 --- a/Riot/Modules/Common/Recents/RecentsViewController.m +++ b/Riot/Modules/Common/Recents/RecentsViewController.m @@ -50,13 +50,13 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro NSIndexPath* lastPotentialCellPath; // Observe UIApplicationDidEnterBackgroundNotification to cancel editing mode when app leaves the foreground state. - id UIApplicationDidEnterBackgroundNotificationObserver; + __weak id UIApplicationDidEnterBackgroundNotificationObserver; // Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar. - id kAppDelegateDidTapStatusBarNotificationObserver; + __weak id kAppDelegateDidTapStatusBarNotificationObserver; // Observe kMXNotificationCenterDidUpdateRules to update missed messages counts. - id kMXNotificationCenterDidUpdateRulesObserver; + __weak id kMXNotificationCenterDidUpdateRulesObserver; MXHTTPOperation *currentRequest; @@ -65,7 +65,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro UISearchBar *tableSearchBar; // Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change. - id kThemeServiceDidChangeThemeNotificationObserver; + __weak id kThemeServiceDidChangeThemeNotificationObserver; } @property (nonatomic, strong) CreateRoomCoordinatorBridgePresenter *createRoomCoordinatorBridgePresenter; @@ -156,11 +156,15 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro // Apply dragging settings self.enableDragging = _enableDragging; + MXWeakify(self); + // Observe UIApplicationDidEnterBackgroundNotification to refresh bubbles when app leaves the foreground state. UIApplicationDidEnterBackgroundNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + // Leave potential editing mode - [self cancelEditionMode:isRefreshPending]; + [self cancelEditionMode:self->isRefreshPending]; }]; @@ -170,6 +174,8 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro // Observe user interface theme change. kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self userInterfaceThemeDidChange]; }]; @@ -268,16 +274,22 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro [self.recentsTableView deselectRowAtIndexPath:indexPath animated:NO]; } + MXWeakify(self); + // Observe kAppDelegateDidTapStatusBarNotificationObserver. kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self scrollToTop:YES]; }]; - + // Observe kMXNotificationCenterDidUpdateRules to refresh missed messages counts kMXNotificationCenterDidUpdateRulesObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXNotificationCenterDidUpdateRules object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { + MXStrongifyAndReturnIfNil(self); + [self refreshRecentsTable]; }]; From 9f6c716165eb48cf82a8975d32d0a9b33ddfa3b9 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 28 Oct 2021 17:41:16 +0200 Subject: [PATCH 12/57] RoomVC: Prevent retain cycles. --- .../Modules/Room/DataSources/RoomDataSource.m | 2 +- Riot/Modules/Room/RoomViewController.m | 68 +++++++++++++------ 2 files changed, 50 insertions(+), 20 deletions(-) diff --git a/Riot/Modules/Room/DataSources/RoomDataSource.m b/Riot/Modules/Room/DataSources/RoomDataSource.m index 9817f503d..a83ba10da 100644 --- a/Riot/Modules/Room/DataSources/RoomDataSource.m +++ b/Riot/Modules/Room/DataSources/RoomDataSource.m @@ -44,7 +44,7 @@ const CGFloat kTypingCellHeight = 24; // Timer used to debounce cells refresh @property (nonatomic, strong) NSTimer *refreshCellsTimer; -@property (nonatomic, readonly) id roomDataSourceDelegate; +@property (nonatomic, weak, readonly) id roomDataSourceDelegate; @property(nonatomic, readwrite) RoomEncryptionTrustLevel encryptionTrustLevel; diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 5b4ad0c2b..232414654 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -144,7 +144,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; { // The preview header - PreviewRoomTitleView *previewHeader; + __weak PreviewRoomTitleView *previewHeader; // The customized room data source for Vector RoomDataSource *customizedRoomDataSource; @@ -156,7 +156,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; NSArray *currentTypingUsers; // Typing notifications listener. - id typingNotifListener; + __weak id typingNotifListener; // The position of the first touch down event stored in case of scrolling when the expanded header is visible. CGPoint startScrollingPoint; @@ -168,33 +168,33 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; UIView *missedDiscussionsDotView; // Potential encryption details view. - EncryptionInfoView *encryptionInfoView; + __weak EncryptionInfoView *encryptionInfoView; // The list of unknown devices that prevent outgoing messages from being sent MXUsersDevicesMap *unknownDevices; // Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar. - id kAppDelegateDidTapStatusBarNotificationObserver; + __weak id kAppDelegateDidTapStatusBarNotificationObserver; // Observe kAppDelegateNetworkStatusDidChangeNotification to handle network status change. - id kAppDelegateNetworkStatusDidChangeNotificationObserver; + __weak id kAppDelegateNetworkStatusDidChangeNotificationObserver; // Observers to manage MXSession state (and sync errors) - id kMXSessionStateDidChangeObserver; + __weak id kMXSessionStateDidChangeObserver; // Observers to manage ongoing conference call banner - id kMXCallStateDidChangeObserver; - id kMXCallManagerConferenceStartedObserver; - id kMXCallManagerConferenceFinishedObserver; + __weak id kMXCallStateDidChangeObserver; + __weak id kMXCallManagerConferenceStartedObserver; + __weak id kMXCallManagerConferenceFinishedObserver; // Observers to manage widgets - id kMXKWidgetManagerDidUpdateWidgetObserver; + __weak id kMXKWidgetManagerDidUpdateWidgetObserver; // Observer kMXRoomSummaryDidChangeNotification to keep updated the missed discussion count - id mxRoomSummaryDidChangeObserver; + __weak id mxRoomSummaryDidChangeObserver; // Observer for removing the re-request explanation/waiting dialog - id mxEventDidDecryptNotificationObserver; + __weak id mxEventDidDecryptNotificationObserver; // The table view cell in which the read marker is displayed (nil by default). MXKRoomBubbleTableViewCell *readMarkerTableViewCell; @@ -209,13 +209,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; NSArray *rightBarButtonItems; // Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change. - id kThemeServiceDidChangeThemeNotificationObserver; + __weak id kThemeServiceDidChangeThemeNotificationObserver; // Observe URL preview updates to refresh cells. - id URLPreviewDidUpdateNotificationObserver; + __weak id URLPreviewDidUpdateNotificationObserver; // Listener for `m.room.tombstone` event type - id tombstoneEventNotificationsListener; + __weak id tombstoneEventNotificationsListener; // Homeserver notices MXServerNotices *serverNotices; @@ -454,9 +454,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; self.jumpToLastUnreadLabel.text = [VectorL10n roomJumpToFirstUnread]; + MXWeakify(self); + // Observe user interface theme change. kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self userInterfaceThemeDidChange]; }]; @@ -587,9 +591,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; [self listenTombstoneEventNotifications]; [self listenMXSessionStateChangeNotifications]; + MXWeakify(self); + // Observe kAppDelegateDidTapStatusBarNotification. kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self setBubbleTableViewContentOffset:CGPointMake(-self.bubblesTableView.adjustedContentInset.left, -self.bubblesTableView.adjustedContentInset.top) animated:YES]; }]; @@ -661,9 +669,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; [AppDelegate theDelegate].visibleRoomId = self.roomDataSource.roomId; } + MXWeakify(self); + // Observe network reachability kAppDelegateNetworkStatusDidChangeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateNetworkStatusDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self refreshActivitiesViewDisplay]; }]; @@ -673,6 +685,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; // Observe missed notifications mxRoomSummaryDidChangeObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXRoomSummaryDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + MXRoomSummary *roomSummary = notif.object; if ([roomSummary.roomId isEqualToString:self.roomDataSource.roomId]) @@ -1399,7 +1413,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; if (URLPreviewDidUpdateNotificationObserver) { [NSNotificationCenter.defaultCenter removeObserver:URLPreviewDidUpdateNotificationObserver]; - URLPreviewDidUpdateNotificationObserver = nil; + (URLPreviewDidUpdateNotificationObserver) = nil; } [self removeCallNotificationsListeners]; @@ -1555,8 +1569,12 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; - (void)registerURLPreviewNotifications { + MXWeakify(self); + URLPreviewDidUpdateNotificationObserver = [NSNotificationCenter.defaultCenter addObserverForName:URLPreviewDidUpdateNotification object:nil queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification * _Nonnull notification) { + MXStrongifyAndReturnIfNil(self); + // Ensure this is the correct room if (![(NSString*)notification.userInfo[@"roomId"] isEqualToString:self.roomDataSource.roomId]) { @@ -4768,10 +4786,14 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; - (void)listenCallNotifications { + MXWeakify(self); + kMXCallStateDidChangeObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXCallStateDidChange object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + MXCall *call = notif.object; - if ([call.room.roomId isEqualToString:customizedRoomDataSource.roomId]) + if ([call.room.roomId isEqualToString:self->customizedRoomDataSource.roomId]) { [self refreshActivitiesViewDisplay]; [self refreshRoomInputToolbar]; @@ -4779,16 +4801,20 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]; kMXCallManagerConferenceStartedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXCallManagerConferenceStarted object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + NSString *roomId = notif.object; - if ([roomId isEqualToString:customizedRoomDataSource.roomId]) + if ([roomId isEqualToString:self->customizedRoomDataSource.roomId]) { [self refreshActivitiesViewDisplay]; } }]; kMXCallManagerConferenceFinishedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXCallManagerConferenceFinished object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + NSString *roomId = notif.object; - if ([roomId isEqualToString:customizedRoomDataSource.roomId]) + if ([roomId isEqualToString:self->customizedRoomDataSource.roomId]) { [self refreshActivitiesViewDisplay]; [self refreshRoomInputToolbar]; @@ -5839,8 +5865,12 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; - (void)listenMXSessionStateChangeNotifications { + MXWeakify(self); + kMXSessionStateDidChangeObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:self.roomDataSource.mxSession queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + if (self.roomDataSource.mxSession.state == MXSessionStateSyncError || self.roomDataSource.mxSession.state == MXSessionStateRunning) { From 67695ccce7afe0d94d3772829561d4c39d5b1236 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 28 Oct 2021 17:55:01 +0200 Subject: [PATCH 13/57] NavigationRouter: in didPopViewController call run completion after sending notification in order to send the right module instance. --- Riot/Routers/NavigationRouter.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Riot/Routers/NavigationRouter.swift b/Riot/Routers/NavigationRouter.swift index 880dbd9ee..25a0aa333 100755 --- a/Riot/Routers/NavigationRouter.swift +++ b/Riot/Routers/NavigationRouter.swift @@ -299,13 +299,12 @@ final class NavigationRouter: NSObject, NavigationRouterType { self.postNotification(withName: NavigationRouter.willPopModule, for: viewController) } - private func didPopViewController(_ viewController: UIViewController) { + private func didPopViewController(_ viewController: UIViewController) { + self.postNotification(withName: NavigationRouter.didPopModule, for: viewController) // Call completion closure associated to the view controller // So associated coordinator can be deallocated runCompletion(for: viewController) - - self.postNotification(withName: NavigationRouter.didPopModule, for: viewController) self.removeModule(for: viewController) } From c22d2a7aa607e220dac59e26b2f48444f62b4622 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 28 Oct 2021 18:01:30 +0200 Subject: [PATCH 14/57] RoomCoordinator: Fix RoomVC reatin issue. --- Riot/Modules/Room/RoomCoordinator.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Riot/Modules/Room/RoomCoordinator.swift b/Riot/Modules/Room/RoomCoordinator.swift index dd3ca7d2f..4764e03e9 100644 --- a/Riot/Modules/Room/RoomCoordinator.swift +++ b/Riot/Modules/Room/RoomCoordinator.swift @@ -77,6 +77,10 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol { super.init() } + + deinit { + roomViewController.destroy() + } // MARK: - Public @@ -90,7 +94,8 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol { self.roomViewController.delegate = self // Detect when view controller has been dismissed by gesture when presented modally (not in full screen). - self.roomViewController.presentationController?.delegate = self + // FIXME: Find a better way to manage modal dismiss. This makes the `roomViewController` to never be released + // self.roomViewController.presentationController?.delegate = self if let eventId = self.selectedEventId { self.loadRoom(withId: self.parameters.roomId, and: eventId, completion: completion) From 9e6d15fc5338505cfb6809cb5968586184e58cf9 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 28 Oct 2021 18:15:46 +0200 Subject: [PATCH 15/57] TabBarCoordinator: Prevent to update master tab bar controllers when not needed. --- Riot/Modules/TabBar/TabBarCoordinator.swift | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Riot/Modules/TabBar/TabBarCoordinator.swift b/Riot/Modules/TabBar/TabBarCoordinator.swift index cb8fbaa6c..5cd3f634f 100644 --- a/Riot/Modules/TabBar/TabBarCoordinator.swift +++ b/Riot/Modules/TabBar/TabBarCoordinator.swift @@ -105,9 +105,11 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType { versionCheckCoordinator.start() add(childCoordinator: versionCheckCoordinator) } + + self.updateMasterTabBarController(with: spaceId, forceReload: true) + } else { + self.updateMasterTabBarController(with: spaceId) } - - self.updateMasterTabBarController(with: spaceId) } func toPresentable() -> UIViewController { @@ -280,7 +282,11 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType { gesture.delegate = self } - private func updateMasterTabBarController(with spaceId: String?) { + private func updateMasterTabBarController(with spaceId: String?, forceReload: Bool = false) { + + if !forceReload && spaceId == self.currentSpaceId { + return + } self.updateTabControllers(for: self.masterTabBarController, showCommunities: spaceId == nil) self.masterTabBarController.filterRooms(withParentId: spaceId, inMatrixSession: self.currentMatrixSession) From 39ab510bb95ca15cb237965b8c0454ccc7be1711 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 28 Oct 2021 18:18:34 +0200 Subject: [PATCH 16/57] Add changes --- changelog.d/5055.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5055.bugfix diff --git a/changelog.d/5055.bugfix b/changelog.d/5055.bugfix new file mode 100644 index 000000000..a969f4fef --- /dev/null +++ b/changelog.d/5055.bugfix @@ -0,0 +1 @@ +RoomVC: Fix retain cycles that prevents `RoomViewController` to be deallocated. \ No newline at end of file From b6ab35f013963c6471d39439a85df8177e49f886 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 28 Oct 2021 18:47:59 +0200 Subject: [PATCH 17/57] Update Riot/Modules/Common/Recents/RecentsViewController.m Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com> --- Riot/Modules/Common/Recents/RecentsViewController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/Common/Recents/RecentsViewController.m b/Riot/Modules/Common/Recents/RecentsViewController.m index 7a722a191..585f79c5f 100644 --- a/Riot/Modules/Common/Recents/RecentsViewController.m +++ b/Riot/Modules/Common/Recents/RecentsViewController.m @@ -284,7 +284,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro [self scrollToTop:YES]; }]; - + // Observe kMXNotificationCenterDidUpdateRules to refresh missed messages counts kMXNotificationCenterDidUpdateRulesObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXNotificationCenterDidUpdateRules object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { From 372e2d8b23868c684d8d728662e6871b67d01960 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 28 Oct 2021 18:48:19 +0200 Subject: [PATCH 18/57] Update Riot/Modules/TabBar/TabBarCoordinator.swift Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com> --- Riot/Modules/TabBar/TabBarCoordinator.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Riot/Modules/TabBar/TabBarCoordinator.swift b/Riot/Modules/TabBar/TabBarCoordinator.swift index 5cd3f634f..662bfaf4c 100644 --- a/Riot/Modules/TabBar/TabBarCoordinator.swift +++ b/Riot/Modules/TabBar/TabBarCoordinator.swift @@ -284,9 +284,7 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType { private func updateMasterTabBarController(with spaceId: String?, forceReload: Bool = false) { - if !forceReload && spaceId == self.currentSpaceId { - return - } + guard forceReload || spaceId != self.currentSpaceId else { return } self.updateTabControllers(for: self.masterTabBarController, showCommunities: spaceId == nil) self.masterTabBarController.filterRooms(withParentId: spaceId, inMatrixSession: self.currentMatrixSession) From ed919d340fb9342d30ee8ef75f86147765cff72e Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 28 Oct 2021 18:50:35 +0200 Subject: [PATCH 19/57] TabBarCoordinator: Fix space switching. --- Riot/Modules/TabBar/TabBarCoordinator.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Riot/Modules/TabBar/TabBarCoordinator.swift b/Riot/Modules/TabBar/TabBarCoordinator.swift index 662bfaf4c..0f11fd17d 100644 --- a/Riot/Modules/TabBar/TabBarCoordinator.swift +++ b/Riot/Modules/TabBar/TabBarCoordinator.swift @@ -77,8 +77,7 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType { } func start(with spaceId: String?) { - self.currentSpaceId = spaceId - + // If start has been done once do not setup view controllers again if self.hasStartedOnce == false { let masterTabBarController = self.createMasterTabBarController() @@ -108,8 +107,10 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType { self.updateMasterTabBarController(with: spaceId, forceReload: true) } else { - self.updateMasterTabBarController(with: spaceId) + self.updateMasterTabBarController(with: spaceId) } + + self.currentSpaceId = spaceId } func toPresentable() -> UIViewController { From 428b0f25a579905279f10d7537d955da197330f9 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 28 Oct 2021 18:51:25 +0200 Subject: [PATCH 20/57] RoomVC: Fix typo. --- Riot/Modules/Room/RoomViewController.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 232414654..063f37ff7 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -1412,8 +1412,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; } if (URLPreviewDidUpdateNotificationObserver) { - [NSNotificationCenter.defaultCenter removeObserver:URLPreviewDidUpdateNotificationObserver]; - (URLPreviewDidUpdateNotificationObserver) = nil; + [NSNotificationCenter.defaultCenter removeObserver:URLPreviewDidUpdateNotificationObserver]; } [self removeCallNotificationsListeners]; From a941df3079cbadd65b0752ea4c5e98cd188fdbf8 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 10:46:26 +0200 Subject: [PATCH 21/57] GroupsViewController: Prevent retain cycles. --- .../Modules/Communities/GroupsViewController.m | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Riot/Modules/Communities/GroupsViewController.m b/Riot/Modules/Communities/GroupsViewController.m index 916c344ee..d58d78c2f 100644 --- a/Riot/Modules/Communities/GroupsViewController.m +++ b/Riot/Modules/Communities/GroupsViewController.m @@ -27,10 +27,10 @@ BOOL isRefreshPending; // Observe UIApplicationDidEnterBackgroundNotification to cancel editing mode when app leaves the foreground state. - id UIApplicationDidEnterBackgroundNotificationObserver; + __weak id UIApplicationDidEnterBackgroundNotificationObserver; // Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar. - id kAppDelegateDidTapStatusBarNotificationObserver; + __weak id kAppDelegateDidTapStatusBarNotificationObserver; MXHTTPOperation *currentRequest; @@ -39,7 +39,7 @@ UISearchBar *tableSearchBar; // Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change. - id kThemeServiceDidChangeThemeNotificationObserver; + __weak id kThemeServiceDidChangeThemeNotificationObserver; } @end @@ -98,11 +98,15 @@ self.groupsTableView.estimatedSectionHeaderHeight = 30; self.groupsTableView.estimatedSectionFooterHeight = 0; + MXWeakify(self); + // Observe UIApplicationDidEnterBackgroundNotification to refresh bubbles when app leaves the foreground state. UIApplicationDidEnterBackgroundNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + // Leave potential editing mode - [self cancelEditionMode:isRefreshPending]; + [self cancelEditionMode:self->isRefreshPending]; }]; @@ -117,6 +121,8 @@ // Observe user interface theme change. kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self userInterfaceThemeDidChange]; }]; @@ -207,9 +213,13 @@ [self.groupsTableView deselectRowAtIndexPath:indexPath animated:NO]; } + MXWeakify(self); + // Observe kAppDelegateDidTapStatusBarNotificationObserver. kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self scrollToTop:YES]; }]; From 4341441d776612a741ff30f75d2fb6d8f3287a38 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 10:47:00 +0200 Subject: [PATCH 22/57] SegmentedViewController: Prevent retain cycles. --- .../SegmentedViewController/SegmentedViewController.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Riot/Modules/Common/SegmentedViewController/SegmentedViewController.m b/Riot/Modules/Common/SegmentedViewController/SegmentedViewController.m index 8480205af..56b3caf91 100644 --- a/Riot/Modules/Common/SegmentedViewController/SegmentedViewController.m +++ b/Riot/Modules/Common/SegmentedViewController/SegmentedViewController.m @@ -50,7 +50,7 @@ NSLayoutConstraint *leftMarkerViewConstraint; // Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change. - id kThemeServiceDidChangeThemeNotificationObserver; + __weak id kThemeServiceDidChangeThemeNotificationObserver; } @end @@ -183,9 +183,13 @@ [self createSegmentedViews]; + MXWeakify(self); + // Observe user interface theme change. kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self userInterfaceThemeDidChange]; }]; From 0c9fea5f6c84ece35cb6bfc54bbddae0c7a3a539 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 10:48:45 +0200 Subject: [PATCH 23/57] ContactDetailsViewController: Prevent retain cycles. --- .../Details/ContactDetailsViewController.m | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Riot/Modules/Contacts/Details/ContactDetailsViewController.m b/Riot/Modules/Contacts/Details/ContactDetailsViewController.m index e26c94ab1..dda2d7fa2 100644 --- a/Riot/Modules/Contacts/Details/ContactDetailsViewController.m +++ b/Riot/Modules/Contacts/Details/ContactDetailsViewController.m @@ -47,12 +47,12 @@ /** Observe UIApplicationWillChangeStatusBarOrientationNotification to hide/show bubbles bg. */ - id UIApplicationWillChangeStatusBarOrientationNotificationObserver; + __weak id UIApplicationWillChangeStatusBarOrientationNotificationObserver; /** The observer of the presence for matrix user. */ - id mxPresenceObserver; + __weak id mxPresenceObserver; /** List of the basic actions on this contact. @@ -79,7 +79,7 @@ /** Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change. */ - id kThemeServiceDidChangeThemeNotificationObserver; + __weak id kThemeServiceDidChangeThemeNotificationObserver; /** The current visibility of the status bar in this view controller. @@ -182,9 +182,13 @@ self.bottomImageView.hidden = (orientation.integerValue == UIInterfaceOrientationLandscapeLeft || orientation.integerValue == UIInterfaceOrientationLandscapeRight); }]; + MXWeakify(self); + // Observe user interface theme change. kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self userInterfaceThemeDidChange]; }]; @@ -379,9 +383,13 @@ // Be warned when the thumbnail is updated [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onThumbnailUpdate:) name:kMXKContactThumbnailUpdateNotification object:nil]; + MXWeakify(self); + // Observe contact presence change mxPresenceObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKContactManagerMatrixUserPresenceChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + NSString* matrixId = self.firstMatrixId; if (matrixId && [matrixId isEqualToString:notif.object]) From f48fb23071cff4b836417a8bf453db3d1bdf1edb Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 10:49:29 +0200 Subject: [PATCH 24/57] SettingsViewController: Prevent retain cycles. --- .../Modules/Settings/SettingsViewController.m | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 0a5acf57c..7ecfcb533 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -178,16 +178,16 @@ ServiceTermsModalCoordinatorBridgePresenterDelegate, TableViewSectionsDelegate> { // Current alert (if any). - UIAlertController *currentAlert; + __weak UIAlertController *currentAlert; // listener - id removedAccountObserver; - id accountUserInfoObserver; - id pushInfoUpdateObserver; + __weak id removedAccountObserver; + __weak id accountUserInfoObserver; + __weak id pushInfoUpdateObserver; - id notificationCenterWillUpdateObserver; - id notificationCenterDidUpdateObserver; - id notificationCenterDidFailObserver; + __weak id notificationCenterWillUpdateObserver; + __weak id notificationCenterDidUpdateObserver; + __weak id notificationCenterDidFailObserver; // profile updates // avatar @@ -216,10 +216,10 @@ TableViewSectionsDelegate> GroupsDataSource *groupsDataSource; // Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar. - id kAppDelegateDidTapStatusBarNotificationObserver; + __weak id kAppDelegateDidTapStatusBarNotificationObserver; // Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change. - id kThemeServiceDidChangeThemeNotificationObserver; + __weak id kThemeServiceDidChangeThemeNotificationObserver; // Postpone destroy operation when saving, pwd reset or email binding is in progress BOOL isSavingInProgress; @@ -612,9 +612,13 @@ TableViewSectionsDelegate> self.tableView.sectionFooterHeight = UITableViewAutomaticDimension; self.tableView.estimatedSectionFooterHeight = 50; + MXWeakify(self); + // Add observer to handle removed accounts removedAccountObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountManagerDidRemoveAccountNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + if ([MXKAccountManager sharedManager].accounts.count) { // Refresh table to remove this account @@ -626,6 +630,8 @@ TableViewSectionsDelegate> // Add observer to handle accounts update accountUserInfoObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountUserInfoDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self stopActivityIndicator]; [self refreshSettings]; @@ -635,6 +641,8 @@ TableViewSectionsDelegate> // Add observer to push settings pushInfoUpdateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountAPNSActivityDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self stopActivityIndicator]; [self refreshSettings]; @@ -663,6 +671,8 @@ TableViewSectionsDelegate> // Observe user interface theme change. kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self userInterfaceThemeDidChange]; }]; @@ -777,10 +787,14 @@ TableViewSectionsDelegate> // Refresh linked emails and phone numbers in parallel [self loadAccount3PIDs]; + + MXWeakify(self); // Observe kAppDelegateDidTapStatusBarNotificationObserver. kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self.tableView setContentOffset:CGPointMake(-self.tableView.adjustedContentInset.left, -self.tableView.adjustedContentInset.top) animated:YES]; }]; From 4363e8203902a74ef6f811d637895dc3709d7e37 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 10:50:24 +0200 Subject: [PATCH 25/57] Update weak views usage. --- Riot/Modules/Common/Recents/RecentsViewController.h | 2 +- Riot/Modules/Room/RoomViewController.m | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Riot/Modules/Common/Recents/RecentsViewController.h b/Riot/Modules/Common/Recents/RecentsViewController.h index b0c993f1e..6a475073a 100644 --- a/Riot/Modules/Common/Recents/RecentsViewController.h +++ b/Riot/Modules/Common/Recents/RecentsViewController.h @@ -40,7 +40,7 @@ FOUNDATION_EXPORT NSString *const RecentsViewControllerDataReadyNotification; /** Current alert (if any). */ - UIAlertController *currentAlert; + __weak UIAlertController *currentAlert; /** The list of the section headers currently displayed in the recents table. diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 063f37ff7..56ab95084 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -2353,11 +2353,14 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; if (isVisible) { - previewHeader = [PreviewRoomTitleView roomTitleView]; + PreviewRoomTitleView *previewHeader = [PreviewRoomTitleView roomTitleView]; previewHeader.delegate = self; previewHeader.tapGestureDelegate = self; previewHeader.translatesAutoresizingMaskIntoConstraints = NO; [self.previewHeaderContainer addSubview:previewHeader]; + + self->previewHeader = previewHeader; + // Force preview header in full width NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:previewHeader attribute:NSLayoutAttributeLeading @@ -5398,7 +5401,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; // Remove potential existing subviews [self dismissTemporarySubViews]; - encryptionInfoView = [[EncryptionInfoView alloc] initWithEvent:event andMatrixSession:self.roomDataSource.mxSession]; + EncryptionInfoView *encryptionInfoView = [[EncryptionInfoView alloc] initWithEvent:event andMatrixSession:self.roomDataSource.mxSession]; // Add shadow on added view encryptionInfoView.layer.cornerRadius = 5; @@ -5408,6 +5411,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; // Add the view and define edge constraints [self.view addSubview:encryptionInfoView]; + self->encryptionInfoView = encryptionInfoView; + [self.view addConstraint:[NSLayoutConstraint constraintWithItem:encryptionInfoView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual From 3e9f16785429c7220073517d1c4b55b621ac1556 Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 28 Oct 2021 18:13:38 +0100 Subject: [PATCH 26/57] Send videos as 320p to encrypted rooms. --- Riot/Assets/en.lproj/Vector.strings | 3 + Riot/Generated/Strings.swift | 12 ++++ RiotShareExtension/Shared/ShareManager.m | 82 ++++++++++++++++++++---- 3 files changed, 84 insertions(+), 13 deletions(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 844626362..0ff5e437d 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -1016,6 +1016,9 @@ Tap the + to start adding people."; // Share extension "share_extension_auth_prompt" = "Login in the main app to share content"; "share_extension_failed_to_encrypt" = "Failed to send. Check in the main app the encryption settings for this room"; +"share_extension_low_quality_video_title" = "Video will be sent in low quality"; +"share_extension_low_quality_video_message" = "Send in %@ for better quality, or send in low quality below."; +"share_extension_send_now" = "Send now"; // Room key request dialog "e2e_room_key_request_title" = "Encryption key request"; diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index 54ca11b35..f3622c608 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -4775,6 +4775,18 @@ public class VectorL10n: NSObject { public static var shareExtensionFailedToEncrypt: String { return VectorL10n.tr("Vector", "share_extension_failed_to_encrypt") } + /// Send in %@ for better quality, or send in low quality below. + public static func shareExtensionLowQualityVideoMessage(_ p1: String) -> String { + return VectorL10n.tr("Vector", "share_extension_low_quality_video_message", p1) + } + /// Video will be sent in low quality + public static var shareExtensionLowQualityVideoTitle: String { + return VectorL10n.tr("Vector", "share_extension_low_quality_video_title") + } + /// Send now + public static var shareExtensionSendNow: String { + return VectorL10n.tr("Vector", "share_extension_send_now") + } /// Feedback public static var sideMenuActionFeedback: String { return VectorL10n.tr("Vector", "side_menu_action_feedback") diff --git a/RiotShareExtension/Shared/ShareManager.m b/RiotShareExtension/Shared/ShareManager.m index 6906f444b..fdec722ed 100644 --- a/RiotShareExtension/Shared/ShareManager.m +++ b/RiotShareExtension/Shared/ShareManager.m @@ -334,7 +334,9 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) { if ([self.shareItemProvider areAllItemsLoaded]) { + MXWeakify(self); void (^sendPendingImages)(void) = ^void() { + MXStrongifyAndReturnIfNil(self); [self sendImageDatas:self.pendingImages.copy toRooms:rooms success:requestSuccess failure:requestFailure]; }; @@ -423,6 +425,22 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) } } +- (BOOL)roomsContainEncryptedRoom:(NSArray *)rooms +{ + BOOL foundEncryptedRoom = NO; + + for (MXRoom *room in rooms) + { + if (room.summary.isEncrypted) + { + foundEncryptedRoom = YES; + break; + } + } + + return foundEncryptedRoom; +} + - (void)resetPendingData { [self.pendingImages removeAllObjects]; @@ -773,19 +791,9 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) MXWeakify(self); - // Ignore showMediaCompressionPrompt setting due to memory constraints when encrypting large videos. - UIAlertController *compressionPrompt = [MXKTools videoConversionPromptForVideoAsset:videoAsset withCompletion:^(NSString *presetName) { + void (^sendVideo)(void) = ^void() { MXStrongifyAndReturnIfNil(self); - // If the preset name is nil, the user cancelled. - if (!presetName) - { - return; - } - - // Set the chosen video conversion preset. - [MXSDKOptions sharedInstance].videoConversionPresetName = presetName; - [self didStartSending]; if (!videoLocalUrl) { @@ -823,9 +831,57 @@ typedef NS_ENUM(NSInteger, ImageCompressionMode) success(); } }); - }]; + }; - [self presentCompressionPrompt:compressionPrompt]; + BOOL allRoomsAreUnencrypted = ![self roomsContainEncryptedRoom:rooms]; + + // When rooms are unencrypted convert the video according to the user's normal preferences + if (allRoomsAreUnencrypted) + { + if (!RiotSettings.shared.showMediaCompressionPrompt) + { + [MXSDKOptions sharedInstance].videoConversionPresetName = AVCaptureSessionPreset1920x1080; + sendVideo(); + } + else + { + UIAlertController *compressionPrompt = [MXKTools videoConversionPromptForVideoAsset:videoAsset withCompletion:^(NSString *presetName) { + // If the preset name is nil, the user cancelled. + if (!presetName) + { + return; + } + + // Set the chosen video conversion preset. + [MXSDKOptions sharedInstance].videoConversionPresetName = presetName; + sendVideo(); + }]; + + [self presentCompressionPrompt:compressionPrompt]; + } + } + else + { + // When rooms are encrypted we quickly run out of memory encrypting the video + // Prompt the user if they're happy to send a low quality video (320p). + UIAlertController *lowQualityPrompt = [UIAlertController alertControllerWithTitle:VectorL10n.shareExtensionLowQualityVideoTitle + message:[VectorL10n shareExtensionLowQualityVideoMessage:AppInfo.current.displayName] + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:MatrixKitL10n.cancel style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { + // Do nothing + }]; + UIAlertAction *sendAction = [UIAlertAction actionWithTitle:VectorL10n.shareExtensionSendNow style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + [MXSDKOptions sharedInstance].videoConversionPresetName = AVAssetExportPresetMediumQuality; + sendVideo(); + }]; + + [lowQualityPrompt addAction:cancelAction]; + [lowQualityPrompt addAction:sendAction]; + [lowQualityPrompt setPreferredAction:sendAction]; + + [self presentCompressionPrompt:lowQualityPrompt]; + } } - (void)sendVoiceMessage:(NSURL *)fileUrl From db5a7f5bb2070ae6c7de93a6f589fb30f332f4c5 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 11:59:52 +0200 Subject: [PATCH 27/57] ContactsTableViewController: Prevent retain cycles. --- Riot/Modules/Contacts/ContactsTableViewController.h | 2 +- Riot/Modules/Contacts/ContactsTableViewController.m | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Riot/Modules/Contacts/ContactsTableViewController.h b/Riot/Modules/Contacts/ContactsTableViewController.h index 8b535495b..f1b3effaf 100644 --- a/Riot/Modules/Contacts/ContactsTableViewController.h +++ b/Riot/Modules/Contacts/ContactsTableViewController.h @@ -122,7 +122,7 @@ /** The delegate for the view controller. */ -@property (nonatomic) id contactsTableViewControllerDelegate; +@property (nonatomic, weak) id contactsTableViewControllerDelegate; @end diff --git a/Riot/Modules/Contacts/ContactsTableViewController.m b/Riot/Modules/Contacts/ContactsTableViewController.m index adbc1f9e9..f208f6f67 100644 --- a/Riot/Modules/Contacts/ContactsTableViewController.m +++ b/Riot/Modules/Contacts/ContactsTableViewController.m @@ -33,12 +33,12 @@ /** Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar. */ - id kAppDelegateDidTapStatusBarNotificationObserver; + __weak id kAppDelegateDidTapStatusBarNotificationObserver; /** Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change. */ - id kThemeServiceDidChangeThemeNotificationObserver; + __weak id kThemeServiceDidChangeThemeNotificationObserver; } @property (nonatomic, strong) FindYourContactsFooterView *findYourContactsFooterView; @@ -102,9 +102,13 @@ self.contactsTableView.tableFooterView = [[UIView alloc] init]; self.contactsAreFilteredWithSearch = NO; + MXWeakify(self); + // Observe user interface theme change. kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self userInterfaceThemeDidChange]; }]; @@ -158,10 +162,14 @@ // Screen tracking [[Analytics sharedInstance] trackScreen:_screenName]; + + MXWeakify(self); // Observe kAppDelegateDidTapStatusBarNotification. kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); + [self.contactsTableView setContentOffset:CGPointMake(-self.contactsTableView.adjustedContentInset.left, -self.contactsTableView.adjustedContentInset.top) animated:YES]; }]; From ab1f6a91cc5788d8d54f3adafcb94a0766984348 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 12:02:19 +0200 Subject: [PATCH 28/57] EnterNewRoomDetailsViewController: Prevent retain cycles. --- .../EnterNewRoomDetailsViewController.swift | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/Riot/Modules/CreateRoom/EnterNewRoomDetails/EnterNewRoomDetailsViewController.swift b/Riot/Modules/CreateRoom/EnterNewRoomDetails/EnterNewRoomDetailsViewController.swift index e68aedb51..d89e60635 100644 --- a/Riot/Modules/CreateRoom/EnterNewRoomDetails/EnterNewRoomDetailsViewController.swift +++ b/Riot/Modules/CreateRoom/EnterNewRoomDetails/EnterNewRoomDetailsViewController.swift @@ -105,8 +105,8 @@ final class EnterNewRoomDetailsViewController: UIViewController { var section3: Section? if RiotSettings.shared.roomCreationScreenAllowEncryptionConfiguration { - let row_3_0 = Row(type: .withSwitch(isOn: viewModel.roomCreationParameters.isEncrypted, onValueChanged: { (theSwitch) in - self.viewModel.roomCreationParameters.isEncrypted = theSwitch.isOn + let row_3_0 = Row(type: .withSwitch(isOn: viewModel.roomCreationParameters.isEncrypted, onValueChanged: { [weak self] (theSwitch) in + self?.viewModel.roomCreationParameters.isEncrypted = theSwitch.isOn }), text: VectorL10n.createRoomEnableEncryption, accessoryType: .none) { // no-op } @@ -117,11 +117,20 @@ final class EnterNewRoomDetailsViewController: UIViewController { var section4: Section? if RiotSettings.shared.roomCreationScreenAllowRoomTypeConfiguration { - let row_4_0 = Row(type: .default, text: VectorL10n.createRoomTypePrivate, accessoryType: viewModel.roomCreationParameters.isPublic ? .none : .checkmark) { + let row_4_0 = Row(type: .default, text: VectorL10n.createRoomTypePrivate, accessoryType: viewModel.roomCreationParameters.isPublic ? .none : .checkmark) { [weak self] in + guard let self = self else { + return + } + self.viewModel.roomCreationParameters.isPublic = false self.updateSections() } - let row_4_1 = Row(type: .default, text: VectorL10n.createRoomTypePublic, accessoryType: viewModel.roomCreationParameters.isPublic ? .checkmark : .none) { + let row_4_1 = Row(type: .default, text: VectorL10n.createRoomTypePublic, accessoryType: viewModel.roomCreationParameters.isPublic ? .checkmark : .none) { [weak self] in + + guard let self = self else { + return + } + self.viewModel.roomCreationParameters.isPublic = true self.updateSections() // scroll bottom to show user new fields @@ -149,8 +158,8 @@ final class EnterNewRoomDetailsViewController: UIViewController { } if viewModel.roomCreationParameters.isPublic { - let row_5_0 = Row(type: .withSwitch(isOn: viewModel.roomCreationParameters.showInDirectory, onValueChanged: { (theSwitch) in - self.viewModel.roomCreationParameters.showInDirectory = theSwitch.isOn + let row_5_0 = Row(type: .withSwitch(isOn: viewModel.roomCreationParameters.showInDirectory, onValueChanged: { [weak self] (theSwitch) in + self?.viewModel.roomCreationParameters.showInDirectory = theSwitch.isOn }), text: VectorL10n.createRoomShowInDirectory, accessoryType: .none) { // no-op } @@ -389,7 +398,10 @@ extension EnterNewRoomDetailsViewController: UITableViewDataSource { cell.mxkLabel.text = row.text cell.mxkSwitch.isOn = isOn cell.mxkSwitch.removeTarget(nil, action: nil, for: .valueChanged) - cell.mxkSwitch.vc_addAction(for: .valueChanged) { + cell.mxkSwitch.vc_addAction(for: .valueChanged) { [weak cell] in + guard let cell = cell else { + return + } onValueChanged?(cell.mxkSwitch) } cell.mxkLabelLeadingConstraint.constant = cell.vc_separatorInset.left From 03932238fc9957f8d3af7f7d17f87dc5190f3b1c Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 12:03:20 +0200 Subject: [PATCH 29/57] Update GroupDetailsCoordinator. --- .../Communities/TabDetail/GroupDetailsCoordinator.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Riot/Modules/Communities/TabDetail/GroupDetailsCoordinator.swift b/Riot/Modules/Communities/TabDetail/GroupDetailsCoordinator.swift index 27c3d7df0..976c188ef 100644 --- a/Riot/Modules/Communities/TabDetail/GroupDetailsCoordinator.swift +++ b/Riot/Modules/Communities/TabDetail/GroupDetailsCoordinator.swift @@ -43,6 +43,10 @@ final class GroupDetailsCoordinator: GroupDetailsCoordinatorProtocol { self.groupDetailsViewController = groupDetailsViewController } + deinit { + groupDetailsViewController.destroy() + } + // MARK: - Public func start() { From 8a1a8acc3f482fdc6dacac63f284c85f23c3ced9 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 12:14:20 +0200 Subject: [PATCH 30/57] Add changes --- changelog.d/5058.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5058.bugfix diff --git a/changelog.d/5058.bugfix b/changelog.d/5058.bugfix new file mode 100644 index 000000000..1e8112a36 --- /dev/null +++ b/changelog.d/5058.bugfix @@ -0,0 +1 @@ +Fix retain cycles that prevents deallocation in several classes. \ No newline at end of file From 1d3cacc5bbd36cabbefdfe887ff18d7b7ec41dfe Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 12:23:06 +0200 Subject: [PATCH 31/57] Weakify strong reference delegates. --- Riot/Managers/Analytics/DecryptionFailureTracker.h | 2 +- Riot/Modules/Integrations/Widgets/Jitsi/JitsiViewController.h | 2 +- Riot/Modules/Room/Members/Detail/Views/RoomMemberTitleView.h | 2 +- Riot/Modules/Room/Members/RoomParticipantsViewController.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Riot/Managers/Analytics/DecryptionFailureTracker.h b/Riot/Managers/Analytics/DecryptionFailureTracker.h index ffefe0d99..b2dbbfc77 100644 --- a/Riot/Managers/Analytics/DecryptionFailureTracker.h +++ b/Riot/Managers/Analytics/DecryptionFailureTracker.h @@ -32,7 +32,7 @@ /** The delegate object to receive analytics events. */ -@property (nonatomic) id delegate; +@property (nonatomic, weak) id delegate; /** Report an event unable to decrypt. diff --git a/Riot/Modules/Integrations/Widgets/Jitsi/JitsiViewController.h b/Riot/Modules/Integrations/Widgets/Jitsi/JitsiViewController.h index 653608c47..2fb2b368f 100644 --- a/Riot/Modules/Integrations/Widgets/Jitsi/JitsiViewController.h +++ b/Riot/Modules/Integrations/Widgets/Jitsi/JitsiViewController.h @@ -81,7 +81,7 @@ /** The delegate for the view controller. */ -@property (nonatomic) id delegate; +@property (nonatomic, weak) id delegate; @end diff --git a/Riot/Modules/Room/Members/Detail/Views/RoomMemberTitleView.h b/Riot/Modules/Room/Members/Detail/Views/RoomMemberTitleView.h index 009b77e22..6111b6939 100644 --- a/Riot/Modules/Room/Members/Detail/Views/RoomMemberTitleView.h +++ b/Riot/Modules/Room/Members/Detail/Views/RoomMemberTitleView.h @@ -54,6 +54,6 @@ /** The delegate. */ -@property (nonatomic) id delegate; +@property (nonatomic, weak) id delegate; @end diff --git a/Riot/Modules/Room/Members/RoomParticipantsViewController.h b/Riot/Modules/Room/Members/RoomParticipantsViewController.h index c0b8dc3f8..757bb2fca 100644 --- a/Riot/Modules/Room/Members/RoomParticipantsViewController.h +++ b/Riot/Modules/Room/Members/RoomParticipantsViewController.h @@ -90,7 +90,7 @@ /** The delegate for the view controller. */ -@property (nonatomic) id delegate; +@property (nonatomic, weak) id delegate; /** Returns the `UINib` object initialized for a `RoomParticipantsViewController`. From 584fc1ee8f28deef5a51b53d9b969553c477d81f Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 13:46:34 +0200 Subject: [PATCH 32/57] RoomInfoListViewController: Weakify self in a closure. --- .../RoomInfo/RoomInfoList/RoomInfoListViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift index daa9b2947..3590b5526 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift @@ -50,8 +50,8 @@ final class RoomInfoListViewController: UIViewController { private lazy var basicInfoView: RoomInfoBasicView = { let view = RoomInfoBasicView.loadFromNib() - view.onTopicSizeChange = { _ in - self.view.setNeedsLayout() + view.onTopicSizeChange = { [weak self] _ in + self?.view.setNeedsLayout() } return view }() From a46a18480c314cf545130cc7b6525ea23bfeee7d Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 13:47:16 +0200 Subject: [PATCH 33/57] RoomSearchViewController: Fix setup. --- Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift | 11 +++++------ Riot/Modules/Room/Search/RoomSearchViewController.h | 2 ++ Riot/Modules/Room/Search/RoomSearchViewController.m | 7 +++++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift index f65c06071..8f00a1d7d 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift @@ -152,12 +152,11 @@ final class RoomInfoCoordinator: NSObject, RoomInfoCoordinatorType { case .search: MXKRoomDataSourceManager.sharedManager(forMatrixSession: session)?.roomDataSource(forRoom: self.room.roomId, create: false, onComplete: { (roomDataSource) in guard let dataSource = roomDataSource else { return } - let storyboard = UIStoryboard(name: "Main", bundle: nil) - if let search = storyboard.instantiateViewController(withIdentifier: "RoomSearch") as? RoomSearchViewController { - search.roomDataSource = dataSource - self.navigationRouter.push(search, animated: animated, popCompletion: nil) - } - }) + let roomSearchViewController: RoomSearchViewController = RoomSearchViewController.instantiate() + roomSearchViewController.loadViewIfNeeded() + roomSearchViewController.roomDataSource = dataSource + self.navigationRouter.push(roomSearchViewController, animated: animated, popCompletion: nil) + }) case .notifications: let coordinator = createRoomNotificationSettingsCoordinator() coordinator.start() diff --git a/Riot/Modules/Room/Search/RoomSearchViewController.h b/Riot/Modules/Room/Search/RoomSearchViewController.h index b1168107b..14c1460b5 100644 --- a/Riot/Modules/Room/Search/RoomSearchViewController.h +++ b/Riot/Modules/Room/Search/RoomSearchViewController.h @@ -25,4 +25,6 @@ */ @property (nonatomic) MXKRoomDataSource *roomDataSource; ++ (instancetype)instantiate; + @end diff --git a/Riot/Modules/Room/Search/RoomSearchViewController.m b/Riot/Modules/Room/Search/RoomSearchViewController.m index b6a17df46..08374baea 100644 --- a/Riot/Modules/Room/Search/RoomSearchViewController.m +++ b/Riot/Modules/Room/Search/RoomSearchViewController.m @@ -37,6 +37,13 @@ @implementation RoomSearchViewController ++ (instancetype)instantiate +{ + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; + RoomSearchViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"RoomSearch"]; + return viewController; +} + - (void)finalizeInit { [super finalizeInit]; From d1c7c16980ffc5d0b1d386ef3f62c865870c2f9d Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 13:47:42 +0200 Subject: [PATCH 34/57] RoomViewController: Fix a crash on before iOS 14. --- Riot/Modules/Room/RoomViewController.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 56ab95084..6d989d669 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -2257,6 +2257,12 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; } UIViewController *suggestionsViewController = self.userSuggestionCoordinator.toPresentable; + + if (!suggestionsViewController) + { + return; + } + [suggestionsViewController.view setTranslatesAutoresizingMaskIntoConstraints:NO]; [self addChildViewController:suggestionsViewController]; From 5866dd755377ddd807bfa59210e9b224f420af67 Mon Sep 17 00:00:00 2001 From: Doug Date: Fri, 29 Oct 2021 11:47:06 +0100 Subject: [PATCH 35/57] Fix avatars and hide spaces in Share Extension. --- RiotShareExtension/Shared/ShareDataSource.m | 2 +- RiotShareExtension/Shared/View/RecentRoomTableViewCell.m | 2 +- changelog.d/5057.bugfix | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelog.d/5057.bugfix diff --git a/RiotShareExtension/Shared/ShareDataSource.m b/RiotShareExtension/Shared/ShareDataSource.m index a06a92e36..aa064c5a5 100644 --- a/RiotShareExtension/Shared/ShareDataSource.m +++ b/RiotShareExtension/Shared/ShareDataSource.m @@ -86,7 +86,7 @@ for (MXRoomSummary *roomSummary in roomsSummaries) { - if (!roomSummary.hiddenFromUser) + if (!roomSummary.hiddenFromUser && roomSummary.roomType == MXRoomTypeRoom) { [roomSummary setMatrixSession:session]; diff --git a/RiotShareExtension/Shared/View/RecentRoomTableViewCell.m b/RiotShareExtension/Shared/View/RecentRoomTableViewCell.m index b6fc0d27c..ed7eb32a8 100644 --- a/RiotShareExtension/Shared/View/RecentRoomTableViewCell.m +++ b/RiotShareExtension/Shared/View/RecentRoomTableViewCell.m @@ -86,7 +86,7 @@ [self.avatarImageView vc_setRoomAvatarImageWith:roomCellData.avatarUrl roomId:roomCellData.roomIdentifier displayName:roomCellData.roomDisplayname - mediaManager:roomCellData.mxSession.mediaManager]; + mediaManager:roomCellData.roomSummary.mxSession.mediaManager]; self.roomTitleLabel.text = roomCellData.roomDisplayname; if (!self.roomTitleLabel.text.length) diff --git a/changelog.d/5057.bugfix b/changelog.d/5057.bugfix new file mode 100644 index 000000000..b3f2b9744 --- /dev/null +++ b/changelog.d/5057.bugfix @@ -0,0 +1 @@ +Share Extension: Fix missing avatars and don't list spaces as rooms. \ No newline at end of file From 09923d6d05065285e595582ecaf8dd2c9ab602a6 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 14:48:42 +0200 Subject: [PATCH 36/57] TabBarCoordinator: Improve tab bar controllers management. Avoid to have twice HomeVC in memory. --- Riot/Modules/TabBar/TabBarCoordinator.swift | 44 +++++++++++++-------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/Riot/Modules/TabBar/TabBarCoordinator.swift b/Riot/Modules/TabBar/TabBarCoordinator.swift index 0f11fd17d..63bf354a2 100644 --- a/Riot/Modules/TabBar/TabBarCoordinator.swift +++ b/Riot/Modules/TabBar/TabBarCoordinator.swift @@ -41,7 +41,8 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType { private let masterNavigationController: UINavigationController private var currentSpaceId: String? - private var homeViewControllerWrapperViewController: HomeViewControllerWithBannerWrapperViewController? + + private weak var versionCheckCoordinator: VersionCheckCoordinator? private var currentMatrixSession: MXSession? { return parameters.userSessionsService.mainUserSession?.matrixSession @@ -97,14 +98,6 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType { self.registerUserSessionsServiceNotifications() self.registerSessionChange() - if let homeViewController = homeViewControllerWrapperViewController { - let versionCheckCoordinator = VersionCheckCoordinator(rootViewController: masterTabBarController, - bannerPresenter: homeViewController, - themeService: ThemeService.shared()) - versionCheckCoordinator.start() - add(childCoordinator: versionCheckCoordinator) - } - self.updateMasterTabBarController(with: spaceId, forceReload: true) } else { self.updateMasterTabBarController(with: spaceId) @@ -214,21 +207,25 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType { } searchBarButtonItem.accessibilityLabel = VectorL10n.searchDefaultPlaceholder - tabBarController.navigationItem.rightBarButtonItem = searchBarButtonItem - - self.updateTabControllers(for: tabBarController, showCommunities: true) + tabBarController.navigationItem.rightBarButtonItem = searchBarButtonItem return tabBarController } - private func createHomeViewController() -> UIViewController { + private func createVersionCheckCoordinator(withRootViewController rootViewController: UIViewController, bannerPresentrer: BannerPresentationProtocol) -> VersionCheckCoordinator { + let versionCheckCoordinator = VersionCheckCoordinator(rootViewController: rootViewController, + bannerPresenter: bannerPresentrer, + themeService: ThemeService.shared()) + return versionCheckCoordinator + } + + private func createHomeViewController() -> HomeViewControllerWithBannerWrapperViewController { let homeViewController: HomeViewController = HomeViewController.instantiate() homeViewController.tabBarItem.tag = Int(TABBAR_HOME_INDEX) homeViewController.tabBarItem.image = homeViewController.tabBarItem.image homeViewController.accessibilityLabel = VectorL10n.titleHome - let wrapperViewController = HomeViewControllerWithBannerWrapperViewController(viewController: homeViewController) - homeViewControllerWrapperViewController = wrapperViewController + let wrapperViewController = HomeViewControllerWithBannerWrapperViewController(viewController: homeViewController) return wrapperViewController } @@ -291,12 +288,27 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType { self.masterTabBarController.filterRooms(withParentId: spaceId, inMatrixSession: self.currentMatrixSession) } + // TODO: Avoid to reinstantiate controllers everytime private func updateTabControllers(for tabBarController: MasterTabBarController, showCommunities: Bool) { var viewControllers: [UIViewController] = [] - + let homeViewController = self.createHomeViewController() + viewControllers.append(homeViewController) + if let existingVersionCheckCoordinator = self.versionCheckCoordinator { + self.remove(childCoordinator: existingVersionCheckCoordinator) + } + + if let masterTabBarController = self.masterTabBarController { + + let versionCheckCoordinator = self.createVersionCheckCoordinator(withRootViewController: masterTabBarController, bannerPresentrer: homeViewController) + versionCheckCoordinator.start() + self.add(childCoordinator: versionCheckCoordinator) + + self.versionCheckCoordinator = versionCheckCoordinator + } + if RiotSettings.shared.homeScreenShowFavouritesTab { let favouritesViewController = self.createFavouritesViewController() viewControllers.append(favouritesViewController) From 087887d5f5244eda725de9f826e1e734bb9b42b0 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 29 Oct 2021 15:42:19 +0200 Subject: [PATCH 37/57] Update Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com> --- Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift index 8f00a1d7d..ccfe76a7e 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift @@ -156,7 +156,7 @@ final class RoomInfoCoordinator: NSObject, RoomInfoCoordinatorType { roomSearchViewController.loadViewIfNeeded() roomSearchViewController.roomDataSource = dataSource self.navigationRouter.push(roomSearchViewController, animated: animated, popCompletion: nil) - }) + }) case .notifications: let coordinator = createRoomNotificationSettingsCoordinator() coordinator.start() From a30915283583687d471443b99f358e5b4b0b629f Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Fri, 29 Oct 2021 16:34:51 +0300 Subject: [PATCH 38/57] Fixes vector-im/element-ios/issues/5063 - Fixed retain cycles between the user suggestion coordinator and the suggestion service, and in the suggestion service currentTextTrigger subject sink. --- .../UserSuggestionCoordinator.swift | 31 ++++++++++++------- .../Mock/MockUserSuggestionScreenState.swift | 2 +- .../Service/UserSuggestionService.swift | 10 +++--- changelog.d/5063.bugfix | 1 + 4 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 changelog.d/5063.bugfix diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinator.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinator.swift index bc50aae42..e7308710d 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinator.swift @@ -34,11 +34,10 @@ final class UserSuggestionCoordinator: Coordinator { private let parameters: UserSuggestionCoordinatorParameters - private var userSuggestionHostingController: UIViewController! - private var userSuggestionService: UserSuggestionServiceProtocol! - private var userSuggestionViewModel: UserSuggestionViewModelProtocol! - - private var roomMembers: [MXRoomMember] = [] + private var userSuggestionHostingController: UIViewController + private var userSuggestionService: UserSuggestionServiceProtocol + private var userSuggestionViewModel: UserSuggestionViewModelProtocol + private var roomMemberProvider: UserSuggestionCoordinatorRoomMemberProvider // MARK: Public @@ -54,9 +53,10 @@ final class UserSuggestionCoordinator: Coordinator { init(parameters: UserSuggestionCoordinatorParameters) { self.parameters = parameters - userSuggestionService = UserSuggestionService(roomMembersProvider: self) + roomMemberProvider = UserSuggestionCoordinatorRoomMemberProvider(room: parameters.room) + userSuggestionService = UserSuggestionService(roomMemberProvider: roomMemberProvider) userSuggestionViewModel = UserSuggestionViewModel.makeUserSuggestionViewModel(userSuggestionService: userSuggestionService) - + let view = UserSuggestionList(viewModel: userSuggestionViewModel.context) .addDependency(AvatarService.instantiate(mediaManager: parameters.mediaManager)) @@ -69,7 +69,7 @@ final class UserSuggestionCoordinator: Coordinator { switch result { case .selectedItemWithIdentifier(let identifier): - guard let member = self.roomMembers.filter({ $0.userId == identifier }).first else { + guard let member = self.roomMemberProvider.roomMembers.filter({ $0.userId == identifier }).first else { return } @@ -93,9 +93,18 @@ final class UserSuggestionCoordinator: Coordinator { } @available(iOS 14.0, *) -extension UserSuggestionCoordinator: RoomMembersProviderProtocol { +private class UserSuggestionCoordinatorRoomMemberProvider: RoomMembersProviderProtocol { + + private let room: MXRoom + + var roomMembers: [MXRoomMember] = [] + + init(room: MXRoom) { + self.room = room; + } + func fetchMembers(_ members: @escaping ([RoomMembersProviderMember]) -> Void) { - parameters.room.members({ [weak self] roomMembers in + room.members({ [weak self] roomMembers in guard let self = self, let joinedMembers = roomMembers?.joinedMembers else { return } @@ -108,7 +117,7 @@ extension UserSuggestionCoordinator: RoomMembersProviderProtocol { self.roomMembers = joinedMembers members(self.roomMembersToProviderMembers(joinedMembers)) }, failure: { error in - MXLog.error("[UserSuggestionCoordinator] Failed loading room with error: \(String(describing: error))") + MXLog.error("[UserSuggestionCoordinatorRoomMemberProvider] Failed loading room with error: \(String(describing: error))") }) } diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Service/Mock/MockUserSuggestionScreenState.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Service/Mock/MockUserSuggestionScreenState.swift index 7897c608d..7d4180201 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Service/Mock/MockUserSuggestionScreenState.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Service/Mock/MockUserSuggestionScreenState.swift @@ -30,7 +30,7 @@ enum MockUserSuggestionScreenState: MockScreenState, CaseIterable { } var screenView: ([Any], AnyView) { - let service = UserSuggestionService(roomMembersProvider: self) + let service = UserSuggestionService(roomMemberProvider: self) let listViewModel = UserSuggestionViewModel.makeUserSuggestionViewModel(userSuggestionService: service) let viewModel = UserSuggestionListWithInputViewModel(listViewModel: listViewModel) { textMessage in diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionService.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionService.swift index ad9de7e56..6e4fab347 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionService.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionService.swift @@ -45,7 +45,7 @@ class UserSuggestionService: UserSuggestionServiceProtocol { // MARK: Private - private let roomMembersProvider: RoomMembersProviderProtocol + private let roomMemberProvider: RoomMembersProviderProtocol private var suggestionItems: [UserSuggestionItemProtocol] = [] private let currentTextTriggerSubject = CurrentValueSubject(nil) @@ -61,13 +61,13 @@ class UserSuggestionService: UserSuggestionServiceProtocol { // MARK: - Setup - init(roomMembersProvider: RoomMembersProviderProtocol) { - self.roomMembersProvider = roomMembersProvider + init(roomMemberProvider: RoomMembersProviderProtocol) { + self.roomMemberProvider = roomMemberProvider currentTextTriggerSubject .debounce(for: 0.5, scheduler: RunLoop.main) .removeDuplicates() - .sink { self.fetchAndFilterMembersForTextTrigger($0) } + .sink { [weak self] in self?.fetchAndFilterMembersForTextTrigger($0) } .store(in: &cancellables) } @@ -96,7 +96,7 @@ class UserSuggestionService: UserSuggestionServiceProtocol { partialName.removeFirst() // remove the '@' prefix - roomMembersProvider.fetchMembers { [weak self] members in + roomMemberProvider.fetchMembers { [weak self] members in guard let self = self else { return } diff --git a/changelog.d/5063.bugfix b/changelog.d/5063.bugfix new file mode 100644 index 000000000..d1ee811c1 --- /dev/null +++ b/changelog.d/5063.bugfix @@ -0,0 +1 @@ +Fixed retain cycles between the user suggestion coordinator and the suggestion service, and in the suggestion service currentTextTrigger subject sink. \ No newline at end of file From 6ee8cc67ee13d9e02edb230ea7a5c7d570a8aa1c Mon Sep 17 00:00:00 2001 From: Doug Date: Mon, 1 Nov 2021 15:05:02 +0000 Subject: [PATCH 39/57] Present alerts before assigning to currentAlert. --- Riot/Modules/Room/RoomViewController.m | 355 +++++++++++++------------ 1 file changed, 182 insertions(+), 173 deletions(-) diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 6d989d669..b127e98fe 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -2062,20 +2062,22 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; [VectorL10n widgetStickerPickerNoStickerpacksAlert], [VectorL10n widgetStickerPickerNoStickerpacksAlertAddNow]]; - currentAlert = [UIAlertController alertControllerWithTitle:nil message:alertMessage preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *installPrompt = [UIAlertController alertControllerWithTitle:nil + message:alertMessage + preferredStyle:UIAlertControllerStyleAlert]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n no] - style:UIAlertActionStyleCancel - handler:^(UIAlertAction * action) + [installPrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n no] + style:UIAlertActionStyleCancel + handler:^(UIAlertAction * action) { MXStrongifyAndReturnIfNil(self); self->currentAlert = nil; }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n yes] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) + [installPrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n yes] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { MXStrongifyAndReturnIfNil(self); self->currentAlert = nil; @@ -2090,8 +2092,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; [self presentViewController:modularVC animated:NO completion:nil]; }]]; - [currentAlert mxk_setAccessibilityIdentifier:@"RoomVCStickerPickerAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [installPrompt mxk_setAccessibilityIdentifier:@"RoomVCStickerPickerAlert"]; + [self presentViewController:installPrompt animated:YES completion:nil]; + currentAlert = installPrompt; } } @@ -3145,14 +3148,14 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; } __weak __typeof(self) weakSelf = self; - currentAlert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; + UIAlertController *actionsMenu = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; // Add actions for a failed event if (selectedEvent.sentState == MXEventSentStateFailed) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n retry] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n retry] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3166,9 +3169,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionDelete] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionDelete] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3203,9 +3206,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; selectedEvent.sentState == MXEventSentStateEncrypting || selectedEvent.sentState == MXEventSentStateSending) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionCancelSend] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionCancelSend] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3223,9 +3226,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; } - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionForward] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionForward] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { self.shareManager = [[ShareManager alloc] initWithShareItemProvider:[[SimpleShareItemProvider alloc] initWithTextMessage:selectedComponent.textMessage] type:ShareManagerTypeForward]; @@ -3242,9 +3245,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; if (!isJitsiCallEvent) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionQuote] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionQuote] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3264,9 +3267,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; if (!isJitsiCallEvent && BuildSettings.messageDetailsAllowShare) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionShare] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionShare] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3298,9 +3301,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; attachment.type == MXKAttachmentTypeVideo || attachment.type == MXKAttachmentTypeVoiceMessage) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionForward] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionForward] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { self.shareManager = [[ShareManager alloc] initWithShareItemProvider:[[SimpleShareItemProvider alloc] initWithAttachment:attachment] type:ShareManagerTypeForward]; @@ -3320,9 +3323,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; { if (attachment.type == MXKAttachmentTypeImage || attachment.type == MXKAttachmentTypeVideo) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionSave] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionSave] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3365,9 +3368,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; NSString *uploadId = roomBubbleTableViewCell.bubbleData.attachment.contentURL; if ([MXMediaManager existingUploaderWithId:uploadId]) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionCancelSend] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionCancelSend] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { // Get again the loader MXMediaLoader *loader = [MXMediaManager existingUploaderWithId:uploadId]; @@ -3403,9 +3406,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; { if (BuildSettings.messageDetailsAllowShare) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionShare] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionShare] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3453,9 +3456,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; NSString *downloadId = roomBubbleTableViewCell.bubbleData.attachment.downloadId; if ([MXMediaManager existingDownloaderWithIdentifier:downloadId]) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionCancelDownload] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionCancelDownload] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3481,9 +3484,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; // because it breaks everything if (selectedEvent.eventType != MXEventTypeRoomEncryption) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionRedact] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionRedact] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3515,9 +3518,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; if (BuildSettings.messageDetailsAllowPermalink) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionPermalink] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionPermalink] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3544,9 +3547,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; // Add reaction history if event contains reactions if (roomBubbleTableViewCell.bubbleData.reactions[selectedEvent.eventId].aggregatedReactionsWithNonZeroCount) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionReactionHistory] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionReactionHistory] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { [self cancelEventSelection]; @@ -3557,9 +3560,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; if (BuildSettings.messageDetailsAllowViewSource) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionViewSource] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionViewSource] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3577,9 +3580,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; // Add "View Decrypted Source" for e2ee event we can decrypt if (selectedEvent.isEncrypted && selectedEvent.clearEvent) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionViewDecryptedSource] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionViewDecryptedSource] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3597,9 +3600,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; if (![selectedEvent.sender isEqualToString:self.mainSession.myUser.userId] && RiotSettings.shared.roomContextualMenuShowReportContentOption) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionReport] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionReport] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3608,15 +3611,15 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; [self cancelEventSelection]; // Prompt user to enter a description of the problem content. - self->currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionReportPromptReason] message:nil preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *reportReasonAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionReportPromptReason] message:nil preferredStyle:UIAlertControllerStyleAlert]; - [self->currentAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) { + [reportReasonAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) { textField.secureTextEntry = NO; textField.placeholder = nil; textField.keyboardType = UIKeyboardTypeDefault; }]; - [self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + [reportReasonAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3632,9 +3635,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; [self stopActivityIndicator]; // Prompt user to ignore content from this user - self->currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionReportPromptIgnoreUser] message:nil preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *ignoreUserAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionReportPromptIgnoreUser] + message:nil + preferredStyle:UIAlertControllerStyleAlert]; - [self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n yes] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + [ignoreUserAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n yes] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3663,7 +3668,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; - [self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n no] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + [ignoreUserAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n no] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3673,7 +3678,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; - [self presentViewController:self->currentAlert animated:YES completion:nil]; + [self presentViewController:ignoreUserAlert animated:YES completion:nil]; + self->currentAlert = ignoreUserAlert; } failure:^(NSError *error) { @@ -3689,7 +3695,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; - [self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) { + [reportReasonAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3699,7 +3705,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; - [self presentViewController:self->currentAlert animated:YES completion:nil]; + [self presentViewController:reportReasonAlert animated:YES completion:nil]; + self->currentAlert = reportReasonAlert; } }]]; @@ -3707,9 +3714,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; if (!isJitsiCallEvent && self.roomDataSource.room.summary.isEncrypted) { - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionViewEncryption] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionViewEncryption] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3724,9 +3731,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; } } - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n cancel] - style:UIAlertActionStyleCancel - handler:^(UIAlertAction * action) { + [actionsMenu addAction:[UIAlertAction actionWithTitle:[VectorL10n cancel] + style:UIAlertActionStyleCancel + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3737,20 +3744,17 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; // Do not display empty action sheet - if (currentAlert.actions.count > 1) + if (actionsMenu.actions.count > 1) { NSInteger bubbleComponentIndex = [roomBubbleTableViewCell.bubbleData bubbleComponentIndexForEventId:selectedEvent.eventId]; CGRect sourceRect = [roomBubbleTableViewCell componentFrameInContentViewForIndex:bubbleComponentIndex]; - [currentAlert mxk_setAccessibilityIdentifier:@"RoomVCEventMenuAlert"]; - [currentAlert popoverPresentationController].sourceView = roomBubbleTableViewCell; - [currentAlert popoverPresentationController].sourceRect = sourceRect; - [self presentViewController:currentAlert animated:animated completion:nil]; - } - else - { - currentAlert = nil; + [actionsMenu mxk_setAccessibilityIdentifier:@"RoomVCEventMenuAlert"]; + [actionsMenu popoverPresentationController].sourceView = roomBubbleTableViewCell; + [actionsMenu popoverPresentationController].sourceRect = sourceRect; + [self presentViewController:actionsMenu animated:animated completion:nil]; + currentAlert = actionsMenu; } } @@ -4123,14 +4127,14 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; - (void)showVoiceCallActionSheet { // Ask the user the kind of the call: voice or dialpad? - currentAlert = [UIAlertController alertControllerWithTitle:nil - message:nil - preferredStyle:UIAlertControllerStyleActionSheet]; + UIAlertController *callActionSheet = [UIAlertController alertControllerWithTitle:nil + message:nil + preferredStyle:UIAlertControllerStyleActionSheet]; __weak typeof(self) weakSelf = self; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomPlaceVoiceCall] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [callActionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n roomPlaceVoiceCall] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -4142,9 +4146,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomOpenDialpad] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [callActionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n roomOpenDialpad] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -4156,9 +4160,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] - style:UIAlertActionStyleCancel - handler:^(UIAlertAction * action) { + [callActionSheet addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] + style:UIAlertActionStyleCancel + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -4168,9 +4172,10 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; - [currentAlert popoverPresentationController].barButtonItem = self.navigationItem.rightBarButtonItems.firstObject; - [currentAlert popoverPresentationController].permittedArrowDirections = UIPopoverArrowDirectionUp; - [self presentViewController:currentAlert animated:YES completion:nil]; + [callActionSheet popoverPresentationController].barButtonItem = self.navigationItem.rightBarButtonItems.firstObject; + [callActionSheet popoverPresentationController].permittedArrowDirections = UIPopoverArrowDirectionUp; + [self presentViewController:callActionSheet animated:YES completion:nil]; + currentAlert = callActionSheet; } - (void)placeCallWithVideo2:(BOOL)video @@ -4222,20 +4227,21 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; MXWeakify(self); [currentAlert dismissViewControllerAnimated:NO completion:nil]; - currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomNoPrivilegesToCreateGroupCall] - message:nil - preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *unprivilegedAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomNoPrivilegesToCreateGroupCall] + message:nil + preferredStyle:UIAlertControllerStyleAlert]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) + [unprivilegedAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { MXStrongifyAndReturnIfNil(self); self->currentAlert = nil; }]]; - [currentAlert mxk_setAccessibilityIdentifier:@"RoomVCCallAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [unprivilegedAlert mxk_setAccessibilityIdentifier:@"RoomVCCallAlert"]; + [self presentViewController:unprivilegedAlert animated:YES completion:nil]; + currentAlert = unprivilegedAlert; } } } @@ -5163,6 +5169,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; [VectorL10n roomUnsentMessagesUnknownDevicesNotification] : [VectorL10n roomUnsentMessagesNotification]; + MXWeakify(self); RoomActivitiesView *roomActivitiesView = (RoomActivitiesView*) self.activitiesView; self.activitiesViewExpanded = YES; [roomActivitiesView displayUnsentMessagesNotification:notification withResendLink:^{ @@ -5174,57 +5181,53 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; [self cancelAllUnsentMessages]; } andIconTapGesture:^{ + MXStrongifyAndReturnIfNil(self); - if (currentAlert) + if (self->currentAlert) { - [currentAlert dismissViewControllerAnimated:NO completion:nil]; + [self->currentAlert dismissViewControllerAnimated:NO completion:nil]; } - __weak __typeof(self) weakSelf = self; - currentAlert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; + MXWeakify(self); + UIAlertController *resendAlert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomResendUnsentMessages] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [resendAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomResendUnsentMessages] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { - if (weakSelf) - { - typeof(self) self = weakSelf; - [self resendAllUnsentMessages]; - self->currentAlert = nil; - } + MXStrongifyAndReturnIfNil(self); + + [self resendAllUnsentMessages]; + self->currentAlert = nil; }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomDeleteUnsentMessages] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [resendAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomDeleteUnsentMessages] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { - if (weakSelf) - { - typeof(self) self = weakSelf; - [self cancelAllUnsentMessages]; - self->currentAlert = nil; - } + MXStrongifyAndReturnIfNil(self); + + [self cancelAllUnsentMessages]; + self->currentAlert = nil; }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n cancel] - style:UIAlertActionStyleCancel - handler:^(UIAlertAction * action) { + [resendAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n cancel] + style:UIAlertActionStyleCancel + handler:^(UIAlertAction * action) { - if (weakSelf) - { - typeof(self) self = weakSelf; - self->currentAlert = nil; - } + MXStrongifyAndReturnIfNil(self); + + self->currentAlert = nil; }]]; - [currentAlert mxk_setAccessibilityIdentifier:@"RoomVCUnsentMessagesMenuAlert"]; - [currentAlert popoverPresentationController].sourceView = roomActivitiesView; - [currentAlert popoverPresentationController].sourceRect = roomActivitiesView.bounds; - [self presentViewController:currentAlert animated:YES completion:nil]; + [resendAlert mxk_setAccessibilityIdentifier:@"RoomVCUnsentMessagesMenuAlert"]; + [resendAlert popoverPresentationController].sourceView = roomActivitiesView; + [resendAlert popoverPresentationController].sourceRect = roomActivitiesView.bounds; + [self presentViewController:resendAlert animated:YES completion:nil]; + self->currentAlert = resendAlert; }]; } @@ -5264,13 +5267,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; } } - currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n unknownDevicesAlertTitle] - message:[VectorL10n unknownDevicesAlert] - preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *unknownDevicesAlert = [UIAlertController alertControllerWithTitle:[VectorL10n unknownDevicesAlertTitle] + message:[VectorL10n unknownDevicesAlert] + preferredStyle:UIAlertControllerStyleAlert]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n unknownDevicesVerify] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [unknownDevicesAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n unknownDevicesVerify] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -5282,9 +5285,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n unknownDevicesSendAnyway] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [unknownDevicesAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n unknownDevicesSendAnyway] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -5305,8 +5308,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; - [currentAlert mxk_setAccessibilityIdentifier:@"RoomVCUnknownDevicesAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [unknownDevicesAlert mxk_setAccessibilityIdentifier:@"RoomVCUnknownDevicesAlert"]; + [self presentViewController:unknownDevicesAlert animated:YES completion:nil]; + currentAlert = unknownDevicesAlert; } } @@ -5368,15 +5372,17 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; - (void)cancelAllUnsentMessages { - currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomUnsentMessagesCancelTitle] message:[VectorL10n roomUnsentMessagesCancelMessage] preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *cancelAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomUnsentMessagesCancelTitle] + message:[VectorL10n roomUnsentMessagesCancelMessage] + preferredStyle:UIAlertControllerStyleAlert]; MXWeakify(self); - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) { + [cancelAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) { MXStrongifyAndReturnIfNil(self); self->currentAlert = nil; }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n delete] style:UIAlertActionStyleDestructive handler:^(UIAlertAction * action) { + [cancelAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n delete] style:UIAlertActionStyleDestructive handler:^(UIAlertAction * action) { MXStrongifyAndReturnIfNil(self); // Remove unsent event ids for (NSUInteger index = 0; index < self.roomDataSource.room.outgoingMessages.count;) @@ -5393,9 +5399,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; } [self refreshActivitiesViewDisplay]; + self->currentAlert = nil; }]]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [self presentViewController:cancelAlert animated:YES completion:nil]; + currentAlert = cancelAlert; } # pragma mark - Encryption Information view @@ -5624,11 +5632,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; // Invite ? NSString *promptMsg = [VectorL10n roomParticipantsInvitePromptMsg:contact.displayName]; - currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomParticipantsInvitePromptTitle] - message:promptMsg - preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *invitePrompt = [UIAlertController alertControllerWithTitle:[VectorL10n roomParticipantsInvitePromptTitle] + message:promptMsg + preferredStyle:UIAlertControllerStyleAlert]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] + [invitePrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) { @@ -5640,7 +5648,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n invite] + [invitePrompt addAction:[UIAlertAction actionWithTitle:[VectorL10n invite] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { @@ -5735,8 +5743,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; }]]; - [currentAlert mxk_setAccessibilityIdentifier:@"RoomVCInviteAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [invitePrompt mxk_setAccessibilityIdentifier:@"RoomVCInviteAlert"]; + [self presentViewController:invitePrompt animated:YES completion:nil]; + currentAlert = invitePrompt; } #pragma mark - Re-request encryption keys @@ -5780,8 +5789,6 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; alert = [UIAlertController alertControllerWithTitle:VectorL10n.rerequestKeysAlertTitle message:[VectorL10n e2eRoomKeyRequestMessage:AppInfo.current.displayName] preferredStyle:UIAlertControllerStyleAlert]; - currentAlert = alert; - [alert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] style:UIAlertActionStyleDefault @@ -5795,7 +5802,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; self->currentAlert = nil; }]]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [self presentViewController:alert animated:YES completion:nil]; + currentAlert = alert; } - (void)presentReviewUnverifiedSessionsAlert @@ -6069,18 +6077,19 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; [self hideContextualMenuAnimated:YES cancelEventSelection:YES completion:^{ MXStrongifyAndReturnIfNil(self); - self->currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionDeleteConfirmationTitle] - message:[VectorL10n roomEventActionDeleteConfirmationMessage] - preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *deleteConfirmation = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionDeleteConfirmationTitle] + message:[VectorL10n roomEventActionDeleteConfirmationMessage] + preferredStyle:UIAlertControllerStyleAlert]; - [self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + [deleteConfirmation addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { }]]; - [self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n delete] style:UIAlertActionStyleDestructive handler:^(UIAlertAction * action) { + [deleteConfirmation addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n delete] style:UIAlertActionStyleDestructive handler:^(UIAlertAction * action) { [self.roomDataSource removeEventWithEventId:event.eventId]; }]]; - [self presentViewController:self->currentAlert animated:YES completion:nil]; + [self presentViewController:deleteConfirmation animated:YES completion:nil]; + self->currentAlert = deleteConfirmation; }]; }; From 6c2b07b01a7200d7bfefd85021b0b3f5131ca5de Mon Sep 17 00:00:00 2001 From: Doug Date: Mon, 1 Nov 2021 17:26:51 +0000 Subject: [PATCH 40/57] Keep strong refs to weak views before display. --- .../Common/Recents/RecentsViewController.m | 76 ++++---- .../Modules/Settings/SettingsViewController.m | 177 ++++++++++-------- changelog.d/5071.bugfix | 1 + 3 files changed, 141 insertions(+), 113 deletions(-) create mode 100644 changelog.d/5071.bugfix diff --git a/Riot/Modules/Common/Recents/RecentsViewController.m b/Riot/Modules/Common/Recents/RecentsViewController.m index 585f79c5f..401a535e0 100644 --- a/Riot/Modules/Common/Recents/RecentsViewController.m +++ b/Riot/Modules/Common/Recents/RecentsViewController.m @@ -539,11 +539,13 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro [self->currentAlert dismissViewControllerAnimated:NO completion:nil]; - self->currentAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n roomErrorJoinFailedTitle] message:msg preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n roomErrorJoinFailedTitle] + message:msg + preferredStyle:UIAlertControllerStyleAlert]; - [self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { MXStrongifyAndReturnIfNil(self); self->currentAlert = nil; @@ -553,7 +555,8 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro } }]]; - [self presentViewController:self->currentAlert animated:YES completion:nil]; + [self presentViewController:errorAlert animated:YES completion:nil]; + currentAlert = errorAlert; } #pragma mark - Sticky Headers @@ -1202,13 +1205,13 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro } // confirm leave - currentAlert = [UIAlertController alertControllerWithTitle:title - message:message - preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *leavePrompt = [UIAlertController alertControllerWithTitle:title + message:message + preferredStyle:UIAlertControllerStyleAlert]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] - style:UIAlertActionStyleCancel - handler:^(UIAlertAction * action) { + [leavePrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] + style:UIAlertActionStyleCancel + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -1218,8 +1221,8 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n leave] - style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + [leavePrompt addAction:[UIAlertAction actionWithTitle:[VectorL10n leave] + style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { if (weakSelf) { @@ -1280,8 +1283,9 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro }]]; - [currentAlert mxk_setAccessibilityIdentifier:@"LeaveEditedRoomAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [leavePrompt mxk_setAccessibilityIdentifier:@"LeaveEditedRoomAlert"]; + [self presentViewController:leavePrompt animated:YES completion:nil]; + currentAlert = leavePrompt; } } @@ -1836,11 +1840,11 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro [currentAlert dismissViewControllerAnimated:NO completion:nil]; - currentAlert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; + UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomRecentsStartChatWith] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n roomRecentsStartChatWith] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -1852,9 +1856,9 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomRecentsCreateEmptyRoom] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n roomRecentsCreateEmptyRoom] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -1866,9 +1870,9 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomRecentsJoinRoom] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n roomRecentsJoinRoom] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -1882,10 +1886,9 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro if (self.mainSession.callManager.supportsPSTN) { - [currentAlert addAction:[UIAlertAction - actionWithTitle:[VectorL10n roomOpenDialpad] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [actionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n roomOpenDialpad] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -1898,9 +1901,9 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro }]]; } - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] - style:UIAlertActionStyleCancel - handler:^(UIAlertAction * action) { + [actionSheet addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] + style:UIAlertActionStyleCancel + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -1910,11 +1913,12 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro }]]; - [currentAlert popoverPresentationController].sourceView = plusButtonImageView; - [currentAlert popoverPresentationController].sourceRect = plusButtonImageView.bounds; + [actionSheet popoverPresentationController].sourceView = plusButtonImageView; + [actionSheet popoverPresentationController].sourceRect = plusButtonImageView.bounds; - [currentAlert mxk_setAccessibilityIdentifier:@"RecentsVCCreateRoomAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [actionSheet mxk_setAccessibilityIdentifier:@"RecentsVCCreateRoomAlert"]; + [self presentViewController:actionSheet animated:YES completion:nil]; + currentAlert = actionSheet; } - (void)openDialpad diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 7ecfcb533..cee976ad2 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -991,9 +991,11 @@ TableViewSectionsDelegate> { MXWeakify(self); [currentAlert dismissViewControllerAnimated:NO completion:nil]; - currentAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountEmailValidationTitle] message:message preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *validationAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountEmailValidationTitle] + message:message + preferredStyle:UIAlertControllerStyleAlert]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + [validationAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { MXStrongifyAndReturnIfNil(self); self->currentAlert = nil; [self stopActivityIndicator]; @@ -1002,14 +1004,15 @@ TableViewSectionsDelegate> self.newEmailEditingEnabled = NO; }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n continue] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + [validationAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n continue] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { MXStrongifyAndReturnIfNil(self); [self tryFinaliseAddEmailSession:threePidAddSession withAuthenticationParameters:authenticationParameters threePidAddManager:threePidAddManager]; }]]; - [currentAlert mxk_setAccessibilityIdentifier:@"SettingsVCEmailValidationAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [validationAlert mxk_setAccessibilityIdentifier:@"SettingsVCEmailValidationAlert"]; + [self presentViewController:validationAlert animated:YES completion:nil]; + currentAlert = validationAlert; } - (void)tryFinaliseAddEmailSession:(MX3PidAddSession*)threePidAddSession withAuthenticationParameters:(NSDictionary*)authParams threePidAddManager:(MX3PidAddManager*)threePidAddManager @@ -1049,11 +1052,13 @@ TableViewSectionsDelegate> MXLogDebug(@"[SettingsViewController] tryFinaliseAddEmailSession: Wrong credentials"); // Ask password again - self->currentAlert = [UIAlertController alertControllerWithTitle:nil - message:[VectorL10n settingsAdd3pidInvalidPasswordMessage] - preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *passwordPrompt = [UIAlertController alertControllerWithTitle:nil + message:[VectorL10n settingsAdd3pidInvalidPasswordMessage] + preferredStyle:UIAlertControllerStyleAlert]; - [self->currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n retry] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + MXWeakify(self); + [passwordPrompt addAction:[UIAlertAction actionWithTitle:[VectorL10n retry] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + MXStrongifyAndReturnIfNil(self); self->currentAlert = nil; [self showAuthenticationIfNeededForAdding:kMX3PIDMediumEmail withSession:self.mainSession completion:^(NSDictionary *authParams) { @@ -1061,7 +1066,8 @@ TableViewSectionsDelegate> }]; }]]; - [self presentViewController:self->currentAlert animated:YES completion:nil]; + [self presentViewController:passwordPrompt animated:YES completion:nil]; + self->currentAlert = passwordPrompt; return; } @@ -1102,9 +1108,11 @@ TableViewSectionsDelegate> MXWeakify(self); [currentAlert dismissViewControllerAnimated:NO completion:nil]; - currentAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountMsisdnValidationTitle] message:message preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *validationAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountMsisdnValidationTitle] + message:message + preferredStyle:UIAlertControllerStyleAlert]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + [validationAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { MXStrongifyAndReturnIfNil(self); self->currentAlert = nil; @@ -1115,13 +1123,13 @@ TableViewSectionsDelegate> self.newPhoneEditingEnabled = NO; }]]; - [currentAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) { + [validationAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) { textField.secureTextEntry = NO; textField.placeholder = nil; textField.keyboardType = UIKeyboardTypeDecimalPad; }]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n submit] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + [validationAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n submit] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { MXStrongifyAndReturnIfNil(self); @@ -1140,8 +1148,9 @@ TableViewSectionsDelegate> } }]]; - [currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCMsisdnValidationAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [validationAlert mxk_setAccessibilityIdentifier: @"SettingsVCMsisdnValidationAlert"]; + [self presentViewController:validationAlert animated:YES completion:nil]; + currentAlert = validationAlert; } - (void)finaliseAddPhoneNumberSession:(MX3PidAddSession*)threePidAddSession withToken:(NSString*)token andAuthenticationParameters:(NSDictionary*)authParams message:(NSString*)message threePidAddManager:(MX3PidAddManager*)threePidAddManager @@ -1180,11 +1189,13 @@ TableViewSectionsDelegate> MXLogDebug(@"[SettingsViewController] finaliseAddPhoneNumberSession: Wrong authentication credentials"); // Ask password again - self->currentAlert = [UIAlertController alertControllerWithTitle:nil - message:[VectorL10n settingsAdd3pidInvalidPasswordMessage] - preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *passwordPrompt = [UIAlertController alertControllerWithTitle:nil + message:[VectorL10n settingsAdd3pidInvalidPasswordMessage] + preferredStyle:UIAlertControllerStyleAlert]; - [self->currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n retry] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + MXWeakify(self); + [passwordPrompt addAction:[UIAlertAction actionWithTitle:[VectorL10n retry] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + MXStrongifyAndReturnIfNil(self); self->currentAlert = nil; [self showAuthenticationIfNeededForAdding:kMX3PIDMediumMSISDN withSession:self.mainSession completion:^(NSDictionary *authParams) { @@ -1192,7 +1203,8 @@ TableViewSectionsDelegate> }]; }]]; - [self presentViewController:self->currentAlert animated:YES completion:nil]; + [self presentViewController:passwordPrompt animated:YES completion:nil]; + self->currentAlert = passwordPrompt; return; } @@ -1232,17 +1244,20 @@ TableViewSectionsDelegate> } - self->currentAlert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert]; - [self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + MXWeakify(self); + [errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + MXStrongifyAndReturnIfNil(self); self->currentAlert = nil; // Ask again the sms token [self showValidationMsisdnDialogWithMessage:message for3PidAddSession:threePidAddSession threePidAddManager:threePidAddManager authenticationParameters:authParams]; }]]; - [self->currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCErrorAlert"]; - [self presentViewController:self->currentAlert animated:YES completion:nil]; + [errorAlert mxk_setAccessibilityIdentifier: @"SettingsVCErrorAlert"]; + [self presentViewController:errorAlert animated:YES completion:nil]; + self->currentAlert = errorAlert; } }]; } @@ -2606,11 +2621,11 @@ TableViewSectionsDelegate> __weak typeof(self) weakSelf = self; - currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n settingsUnignoreUser:ignoredUserId] message:nil preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *unignorePrompt = [UIAlertController alertControllerWithTitle:[VectorL10n settingsUnignoreUser:ignoredUserId] message:nil preferredStyle:UIAlertControllerStyleAlert]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n yes] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [unignorePrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n yes] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -2639,9 +2654,9 @@ TableViewSectionsDelegate> }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n no] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [unignorePrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n no] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -2651,8 +2666,9 @@ TableViewSectionsDelegate> }]]; - [currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCUnignoreAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [unignorePrompt mxk_setAccessibilityIdentifier: @"SettingsVCUnignoreAlert"]; + [self presentViewController:unignorePrompt animated:YES completion:nil]; + currentAlert = unignorePrompt; } } else if (section == SECTION_TAG_ABOUT) @@ -2838,9 +2854,9 @@ TableViewSectionsDelegate> } // Remove ? - currentAlert = [UIAlertController alertControllerWithTitle:[VectorL10n settingsRemovePromptTitle] message:promptMsg preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *removePrompt = [UIAlertController alertControllerWithTitle:[VectorL10n settingsRemovePromptTitle] message:promptMsg preferredStyle:UIAlertControllerStyleAlert]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] + [removePrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) { @@ -2852,7 +2868,7 @@ TableViewSectionsDelegate> }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n remove] + [removePrompt addAction:[UIAlertAction actionWithTitle:[VectorL10n remove] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { @@ -2892,8 +2908,9 @@ TableViewSectionsDelegate> }]]; - [currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCRemove3PIDAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [removePrompt mxk_setAccessibilityIdentifier: @"SettingsVCRemove3PIDAlert"]; + [self presentViewController:removePrompt animated:YES completion:nil]; + currentAlert = removePrompt; } } } @@ -2915,9 +2932,9 @@ TableViewSectionsDelegate> NSString *title = [VectorL10n settingsNotificationsDisabledAlertTitle]; NSString *message = [VectorL10n settingsNotificationsDisabledAlertMessage]; - currentAlert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *showSettingsPrompt = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] + [showSettingsPrompt addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) { @@ -2941,13 +2958,14 @@ TableViewSectionsDelegate> } }]; - [currentAlert addAction:settingsAction]; - currentAlert.preferredAction = settingsAction; + [showSettingsPrompt addAction:settingsAction]; + showSettingsPrompt.preferredAction = settingsAction; - [currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCPushNotificationsAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [showSettingsPrompt mxk_setAccessibilityIdentifier: @"SettingsVCPushNotificationsAlert"]; + [self presentViewController:showSettingsPrompt animated:YES completion:nil]; + currentAlert = showSettingsPrompt; - // Keep off the switch + // Keep the the switch off. sender.on = NO; } else if ([MXKAccountManager sharedManager].activeAccounts.count) @@ -3336,11 +3354,11 @@ TableViewSectionsDelegate> [currentAlert dismissViewControllerAnimated:NO completion:nil]; - currentAlert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n cancel] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3361,9 +3379,9 @@ TableViewSectionsDelegate> }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n retry] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n retry] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3377,8 +3395,9 @@ TableViewSectionsDelegate> }]]; - [currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCSaveChangesFailedAlert"]; - [rootViewController presentViewController:currentAlert animated:YES completion:nil]; + [errorAlert mxk_setAccessibilityIdentifier: @"SettingsVCSaveChangesFailedAlert"]; + [rootViewController presentViewController:errorAlert animated:YES completion:nil]; + currentAlert = errorAlert; } } @@ -3399,13 +3418,13 @@ TableViewSectionsDelegate> [currentAlert dismissViewControllerAnimated:NO completion:nil]; - currentAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountErrorEmailWrongTitle] - message:[MatrixKitL10n accountErrorEmailWrongDescription] - preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountErrorEmailWrongTitle] + message:[MatrixKitL10n accountErrorEmailWrongDescription] + preferredStyle:UIAlertControllerStyleAlert]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { + [errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { if (weakSelf) { @@ -3416,8 +3435,9 @@ TableViewSectionsDelegate> }]]; - [currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCAddEmailAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [errorAlert mxk_setAccessibilityIdentifier: @"SettingsVCAddEmailAlert"]; + [self presentViewController:errorAlert animated:YES completion:nil]; + currentAlert = errorAlert; return; } @@ -3509,11 +3529,11 @@ TableViewSectionsDelegate> [currentAlert dismissViewControllerAnimated:NO completion:nil]; __weak typeof(self) weakSelf = self; - currentAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountErrorMsisdnWrongTitle] - message:[MatrixKitL10n accountErrorMsisdnWrongDescription] - preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:[MatrixKitL10n accountErrorMsisdnWrongTitle] + message:[MatrixKitL10n accountErrorMsisdnWrongDescription] + preferredStyle:UIAlertControllerStyleAlert]; - [currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] + [errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { @@ -3525,8 +3545,9 @@ TableViewSectionsDelegate> }]]; - [currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCAddMsisdnAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + [errorAlert mxk_setAccessibilityIdentifier: @"SettingsVCAddMsisdnAlert"]; + [self presentViewController:errorAlert animated:YES completion:nil]; + currentAlert = errorAlert; return; } @@ -3882,9 +3903,9 @@ TableViewSectionsDelegate> { [self->currentAlert dismissViewControllerAnimated:NO completion:nil]; - self->currentAlert = [UIAlertController alertControllerWithTitle:nil message:[VectorL10n settingsPasswordUpdated] preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *successAlert = [UIAlertController alertControllerWithTitle:nil message:[VectorL10n settingsPasswordUpdated] preferredStyle:UIAlertControllerStyleAlert]; - [self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] + [successAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { @@ -3904,8 +3925,9 @@ TableViewSectionsDelegate> }]]; - [self->currentAlert mxk_setAccessibilityIdentifier:@"SettingsVCOnPasswordUpdatedAlert"]; - [self presentViewController:self->currentAlert animated:YES completion:nil]; + [successAlert mxk_setAccessibilityIdentifier:@"SettingsVCOnPasswordUpdatedAlert"]; + [self presentViewController:successAlert animated:YES completion:nil]; + self->currentAlert = successAlert; } else { @@ -3930,9 +3952,9 @@ TableViewSectionsDelegate> { [self->currentAlert dismissViewControllerAnimated:NO completion:nil]; - self->currentAlert = [UIAlertController alertControllerWithTitle:nil message:[VectorL10n settingsFailToUpdatePassword] preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:nil message:[VectorL10n settingsFailToUpdatePassword] preferredStyle:UIAlertControllerStyleAlert]; - [self->currentAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] + [errorAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { @@ -3953,8 +3975,9 @@ TableViewSectionsDelegate> }]]; - [self->currentAlert mxk_setAccessibilityIdentifier:@"SettingsVCPasswordChangeFailedAlert"]; - [rootViewController presentViewController:self->currentAlert animated:YES completion:nil]; + [errorAlert mxk_setAccessibilityIdentifier:@"SettingsVCPasswordChangeFailedAlert"]; + [rootViewController presentViewController:errorAlert animated:YES completion:nil]; + self->currentAlert = errorAlert; } } diff --git a/changelog.d/5071.bugfix b/changelog.d/5071.bugfix new file mode 100644 index 000000000..40e26a7da --- /dev/null +++ b/changelog.d/5071.bugfix @@ -0,0 +1 @@ +Ensure alerts with weak references are retained until they've been presented. \ No newline at end of file From 7540213a72a3dad3f8f75baa6c9c09c92f4e938e Mon Sep 17 00:00:00 2001 From: Gil Eluard Date: Tue, 2 Nov 2021 07:00:12 +0100 Subject: [PATCH 41/57] Set Show All Rooms to true by default #5076 --- Riot/Managers/Settings/RiotSettings.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Managers/Settings/RiotSettings.swift b/Riot/Managers/Settings/RiotSettings.swift index 9e1ccd05b..193e05ce6 100644 --- a/Riot/Managers/Settings/RiotSettings.swift +++ b/Riot/Managers/Settings/RiotSettings.swift @@ -143,7 +143,7 @@ final class RiotSettings: NSObject { @UserDefault(key: "roomsAllowToJoinPublicRooms", defaultValue: BuildSettings.roomsAllowToJoinPublicRooms, storage: defaults) var roomsAllowToJoinPublicRooms - @UserDefault(key: UserDefaultsKeys.showAllRoomsInHomeSpace, defaultValue: false, storage: defaults) + @UserDefault(key: UserDefaultsKeys.showAllRoomsInHomeSpace, defaultValue: true, storage: defaults) var showAllRoomsInHomeSpace // MARK: - Room Screen From cdb37935c3b6c60531b36b4d5099bd12062b4985 Mon Sep 17 00:00:00 2001 From: Doug Date: Wed, 3 Nov 2021 10:18:27 +0000 Subject: [PATCH 42/57] Ensure DisabledRoomInputToolbarView is used. Fix previewing rooms. Fix favourited DMs in Home. --- .../Common/Recents/RecentsViewController.m | 2 +- .../Service/MatrixSDK/RecentsListService.swift | 2 +- .../GlobalSearch/Rooms/DirectoryViewController.m | 2 +- Riot/Modules/Room/RoomCoordinator.swift | 11 ++++++++++- Riot/Modules/Room/RoomViewController.m | 15 ++++++--------- changelog.d/5079.bugfix | 1 + changelog.d/5081.bugfix | 1 + changelog.d/5083.bugfix | 1 + 8 files changed, 22 insertions(+), 13 deletions(-) create mode 100644 changelog.d/5079.bugfix create mode 100644 changelog.d/5081.bugfix create mode 100644 changelog.d/5083.bugfix diff --git a/Riot/Modules/Common/Recents/RecentsViewController.m b/Riot/Modules/Common/Recents/RecentsViewController.m index f47f08a9d..882cf6fe6 100644 --- a/Riot/Modules/Common/Recents/RecentsViewController.m +++ b/Riot/Modules/Common/Recents/RecentsViewController.m @@ -1996,7 +1996,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro } // Check whether the user has already joined the selected public room - if ([self.recentsDataSource.publicRoomsDirectoryDataSource.mxSession roomWithRoomId:publicRoom.roomId]) + if ([self.recentsDataSource.publicRoomsDirectoryDataSource.mxSession isJoinedOnRoom:publicRoom.roomId]) { // Open the public room [self showRoomWithRoomId:publicRoom.roomId diff --git a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift index cda8f716d..266a55360 100644 --- a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift +++ b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift @@ -427,7 +427,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { private func updateDirectFetcher(_ fetcher: MXRoomListDataFetcher, for mode: RecentsDataSourceMode) { switch mode { case .home: - fetcher.fetchOptions.filterOptions.notDataTypes = [.invited, .lowPriority] + fetcher.fetchOptions.filterOptions.notDataTypes = [.invited, .favorited, .lowPriority] case .people: fetcher.fetchOptions.filterOptions.notDataTypes = [.lowPriority] default: diff --git a/Riot/Modules/GlobalSearch/Rooms/DirectoryViewController.m b/Riot/Modules/GlobalSearch/Rooms/DirectoryViewController.m index 2f6e791d7..254831046 100644 --- a/Riot/Modules/GlobalSearch/Rooms/DirectoryViewController.m +++ b/Riot/Modules/GlobalSearch/Rooms/DirectoryViewController.m @@ -190,7 +190,7 @@ MXPublicRoom *publicRoom = [dataSource roomAtIndexPath:indexPath]; // Check whether the user has already joined the selected public room - if ([dataSource.mxSession roomWithRoomId:publicRoom.roomId]) + if ([dataSource.mxSession isJoinedOnRoom:publicRoom.roomId]) { // Open the public room. [self showRoomWithId:publicRoom.roomId inMatrixSession:dataSource.mxSession]; diff --git a/Riot/Modules/Room/RoomCoordinator.swift b/Riot/Modules/Room/RoomCoordinator.swift index dd3ca7d2f..5c8c0a46b 100644 --- a/Riot/Modules/Room/RoomCoordinator.swift +++ b/Riot/Modules/Room/RoomCoordinator.swift @@ -92,7 +92,9 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol { // Detect when view controller has been dismissed by gesture when presented modally (not in full screen). self.roomViewController.presentationController?.delegate = self - if let eventId = self.selectedEventId { + if let previewData = self.parameters.previewData { + self.loadRoomPreview(withData: previewData, completion: completion) + } else if let eventId = self.selectedEventId { self.loadRoom(withId: self.parameters.roomId, and: eventId, completion: completion) } else { self.loadRoom(withId: self.parameters.roomId, completion: completion) @@ -178,6 +180,13 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol { completion?() } } + + private func loadRoomPreview(withData previewData: RoomPreviewData, completion: (() -> Void)?) { + + self.roomViewController.displayRoomPreview(previewData) + + completion?() + } } // MARK: - RoomIdentifiable diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 5b4ad0c2b..072f4f81b 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -1084,16 +1084,12 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; if (self.roomDataSource) { - // Restore tool bar view and room activities view if none - if (!self.inputToolbarView) - { - [self updateRoomInputToolbarViewClassIfNeeded]; - - [self refreshRoomInputToolbar]; - - self.inputToolbarView.hidden = (self.roomDataSource.state != MXKDataSourceStateReady); - } + // Update the input toolbar class and update the layout + [self updateRoomInputToolbarViewClassIfNeeded]; + self.inputToolbarView.hidden = (self.roomDataSource.state != MXKDataSourceStateReady); + + // Restore room activities view if none if (!self.activitiesView) { // And the extra area @@ -1178,6 +1174,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; } [self updateInputToolBarViewHeight]; + [self refreshRoomInputToolbar]; } } diff --git a/changelog.d/5079.bugfix b/changelog.d/5079.bugfix new file mode 100644 index 000000000..0f6b2baf8 --- /dev/null +++ b/changelog.d/5079.bugfix @@ -0,0 +1 @@ +Message Composer: Ensure there is no text view when the user isn't allowed to send messages. \ No newline at end of file diff --git a/changelog.d/5081.bugfix b/changelog.d/5081.bugfix new file mode 100644 index 000000000..545779610 --- /dev/null +++ b/changelog.d/5081.bugfix @@ -0,0 +1 @@ +Home: Fix bug where favourited DM would be shown in both Favourites and People section. \ No newline at end of file diff --git a/changelog.d/5083.bugfix b/changelog.d/5083.bugfix new file mode 100644 index 000000000..12a915cc6 --- /dev/null +++ b/changelog.d/5083.bugfix @@ -0,0 +1 @@ +Room Previews: Fix room previews not loading. \ No newline at end of file From d50da2a60bdaf0fcd7e35a72939291e3e0a30a13 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 3 Nov 2021 11:41:11 +0100 Subject: [PATCH 43/57] SplitViewCoordinator: Fix detail screen reset behaviour. --- Riot/Modules/Application/AppCoordinator.swift | 2 +- .../SplitView/SplitViewCoordinator.swift | 23 ++++++++++++++----- .../SplitView/SplitViewCoordinatorType.swift | 6 +++-- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Riot/Modules/Application/AppCoordinator.swift b/Riot/Modules/Application/AppCoordinator.swift index 32121a0f6..d60faf924 100755 --- a/Riot/Modules/Application/AppCoordinator.swift +++ b/Riot/Modules/Application/AppCoordinator.swift @@ -228,7 +228,7 @@ extension AppCoordinator: LegacyAppDelegateDelegate { } func legacyAppDelegateRestoreEmptyDetailsViewController(_ legacyAppDelegate: LegacyAppDelegate!) { - self.splitViewCoordinator?.restorePlaceholderDetails() + self.splitViewCoordinator?.resetDetails(animated: false) } func legacyAppDelegate(_ legacyAppDelegate: LegacyAppDelegate!, didAddMatrixSession session: MXSession!) { diff --git a/Riot/Modules/SplitView/SplitViewCoordinator.swift b/Riot/Modules/SplitView/SplitViewCoordinator.swift index 479ebf702..ee1ad5af7 100644 --- a/Riot/Modules/SplitView/SplitViewCoordinator.swift +++ b/Riot/Modules/SplitView/SplitViewCoordinator.swift @@ -125,20 +125,20 @@ final class SplitViewCoordinator: NSObject, SplitViewCoordinatorType { } // TODO: Do not expose publicly this method - func restorePlaceholderDetails() { + func resetDetails(animated: Bool) { // Be sure that the primary is then visible too. if splitViewController.displayMode == .primaryHidden { splitViewController.preferredDisplayMode = .allVisible } - self.resetDetailNavigationControllerWithPlaceholder(animated: false) + self.resetDetailNavigationController(animated: animated) // Release the current selected item (room/contact/group...). self.tabBarCoordinator?.releaseSelectedItems() - } + } func popToHome(animated: Bool, completion: (() -> Void)?) { - self.resetDetailNavigationControllerWithPlaceholder(animated: animated) + self.resetDetails(animated: animated) // Force back to the main screen if this is not the one that is displayed self.tabBarCoordinator?.popToHome(animated: animated, completion: completion) @@ -172,6 +172,17 @@ final class SplitViewCoordinator: NSObject, SplitViewCoordinatorType { // Set placeholder screen as root controller of detail navigation controller let placeholderDetailsVC = self.createPlaceholderDetailsViewController() detailNavigationRouter.setRootModule(placeholderDetailsVC, hideNavigationBar: false, animated: animated, popCompletion: nil) + } + + private func resetDetailNavigationController(animated: Bool) { + + if self.splitViewController.isCollapsed { + if let topMostNavigationController = self.selectedNavigationRouter?.modules.last as? UINavigationController, topMostNavigationController == self.detailNavigationController { + self.selectedNavigationRouter?.popModule(animated: animated) + } + } else { + self.resetDetailNavigationControllerWithPlaceholder(animated: animated) + } } private func isPlaceholderShown(from secondaryViewController: UIViewController) -> Bool { @@ -270,7 +281,7 @@ extension SplitViewCoordinator: UISplitViewControllerDelegate { } // Restore detail navigation controller with placeholder as root - self.resetDetailNavigationControllerWithPlaceholder(animated: false) + self.resetDetailNavigationController(animated: false) // Return up to date detail navigation controller // In any cases `detailNavigationController` will be used as secondary view of the split view controller. @@ -353,6 +364,6 @@ extension SplitViewCoordinator: SplitViewMasterPresentableDelegate { } func splitViewMasterPresentableWantsToResetDetail(_ presentable: Presentable) { - self.resetDetailNavigationControllerWithPlaceholder(animated: false) + self.resetDetails(animated: false) } } diff --git a/Riot/Modules/SplitView/SplitViewCoordinatorType.swift b/Riot/Modules/SplitView/SplitViewCoordinatorType.swift index e49a54879..4fd2cfef6 100644 --- a/Riot/Modules/SplitView/SplitViewCoordinatorType.swift +++ b/Riot/Modules/SplitView/SplitViewCoordinatorType.swift @@ -30,8 +30,10 @@ protocol SplitViewCoordinatorType: Coordinator, Presentable { /// - Parameter spaceId: The id of the Space to use. func start(with spaceId: String?) + /// Restore navigation stack and show home screen func popToHome(animated: Bool, completion: (() -> Void)?) - + // TODO: Do not expose publicly this method - func restorePlaceholderDetails() + /// Remove detail screens and display placeholder if needed + func resetDetails(animated: Bool) } From 9d3238b64e86e69a223f56457714c1d21dae9360 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 3 Nov 2021 11:42:11 +0100 Subject: [PATCH 44/57] Update changes --- changelog.d/5084.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5084.bugfix diff --git a/changelog.d/5084.bugfix b/changelog.d/5084.bugfix new file mode 100644 index 000000000..c7826659d --- /dev/null +++ b/changelog.d/5084.bugfix @@ -0,0 +1 @@ +Do not make the placeholder appearing when leaving a room on iPhone. \ No newline at end of file From d1e907e474ed222bab88eae1b58c2d88e5ff1378 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 3 Nov 2021 18:59:35 +0100 Subject: [PATCH 45/57] SpaceList: Fix a crash when clearing cache or logout. --- .../Spaces/SpaceList/SpaceListViewModel.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Riot/Modules/Spaces/SpaceList/SpaceListViewModel.swift b/Riot/Modules/Spaces/SpaceList/SpaceListViewModel.swift index 3f9924531..62770e05e 100644 --- a/Riot/Modules/Spaces/SpaceList/SpaceListViewModel.swift +++ b/Riot/Modules/Spaces/SpaceList/SpaceListViewModel.swift @@ -131,6 +131,9 @@ final class SpaceListViewModel: SpaceListViewModelType { private func loadData() { guard let session = self.userSessionsService.mainUserSession?.matrixSession else { + // If there is no main session, reset current selection and give an empty section list + // It can happen when the user make a clear cache or logout + self.resetList() return } @@ -243,4 +246,15 @@ final class SpaceListViewModel: SpaceListViewModelType { return spaceViewData.spaceId } } + + private func resetList() { + self.sections = [] + + let selectedIndexPath = IndexPath(row: 0, section: 0) + + self.selectedIndexPath = selectedIndexPath + self.homeIndexPath = selectedIndexPath + + self.update(viewState: .loaded([])) + } } From 1a9661da5eebb21978c36a218a502a14fb60c5b9 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 3 Nov 2021 19:01:25 +0100 Subject: [PATCH 46/57] Add changes --- changelog.d/5082.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5082.bugfix diff --git a/changelog.d/5082.bugfix b/changelog.d/5082.bugfix new file mode 100644 index 000000000..d5563db47 --- /dev/null +++ b/changelog.d/5082.bugfix @@ -0,0 +1 @@ +FIx a crash when selected space is not home and a clear cache or logout is perfomed. \ No newline at end of file From 85c0ac5c181836a40da5ed49d8938d33577ee878 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 3 Nov 2021 19:03:37 +0100 Subject: [PATCH 47/57] Fix typo --- changelog.d/5082.bugfix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/5082.bugfix b/changelog.d/5082.bugfix index d5563db47..e7d60ca36 100644 --- a/changelog.d/5082.bugfix +++ b/changelog.d/5082.bugfix @@ -1 +1 @@ -FIx a crash when selected space is not home and a clear cache or logout is perfomed. \ No newline at end of file +Fix a crash when selected space is not home and a clear cache or logout is performed. \ No newline at end of file From 3107b1af3f110833730a5764e2d22e58e27915ed Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 4 Nov 2021 11:48:06 +0100 Subject: [PATCH 48/57] SettingsVC: Update about section footer text. --- .../Modules/Settings/SettingsViewController.m | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 7ecfcb533..e7b8be3b3 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -541,13 +541,8 @@ TableViewSectionsDelegate> sectionAbout.headerTitle = VectorL10n.settingsAbout; if (BuildSettings.settingsScreenShowAdvancedSettings) - { - sectionAbout.footerTitle = [NSString stringWithFormat:@"Element %@ (%@) / Olm %@\n%@\n%@", - AppInfo.current.appVersion.bundleShortVersion, - AppInfo.current.appVersion.bundleVersion, - [OLMKit versionString], - [MatrixKitL10n settingsConfigUserId:account.mxCredentials.userId], - [MatrixKitL10n settingsConfigHomeServer:account.mxCredentials.homeServer]]; + { + sectionAbout.footerTitle = [self buildAboutSectionFooterTitleWithAccount:account]; } [tmpSections addObject:sectionAbout]; @@ -1410,6 +1405,35 @@ TableViewSectionsDelegate> } } +- (NSString*)buildAboutSectionFooterTitleWithAccount:(MXKAccount*)account +{ + NSMutableString *footerText = [NSMutableString new]; + + AppInfo *appInfo = AppInfo.current; + + NSString *appName = appInfo.displayName; + NSString *appVersion = appInfo.appVersion.bundleShortVersion; + NSString *buildVersion = appInfo.appVersion.bundleVersion; + + NSString *appVersionInfo = [NSString stringWithFormat:@"%@ %@ (%@)", appName, appVersion, buildVersion]; + + NSString *loggedUserInfo = [MatrixKitL10n settingsConfigUserId:account.mxCredentials.userId]; + + NSString *homeserverInfo = [MatrixKitL10n settingsConfigHomeServer:account.mxCredentials.homeServer]; + + NSString *sdkVersionInfo = [NSString stringWithFormat:@"Matrix SDK %@", MatrixSDKVersion]; + + NSString *olmVersionInfo = [NSString stringWithFormat:@"OLM %@", [OLMKit versionString]]; + + [footerText appendFormat:@"%@\n", loggedUserInfo]; + [footerText appendFormat:@"%@\n", homeserverInfo]; + [footerText appendFormat:@"%@\n", appVersionInfo]; + [footerText appendFormat:@"%@\n", sdkVersionInfo]; + [footerText appendFormat:@"%@", olmVersionInfo]; + + return [footerText copy]; +} + #pragma mark - 3Pid Add - (void)showAuthenticationIfNeededForAdding:(MX3PIDMedium)medium withSession:(MXSession*)session completion:(void (^)(NSDictionary* authParams))completion From 9e0ed74f7929f859fb30db9403bdbe0570e90d54 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 4 Nov 2021 11:50:06 +0100 Subject: [PATCH 49/57] Add changes --- changelog.d/5090.change | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5090.change diff --git a/changelog.d/5090.change b/changelog.d/5090.change new file mode 100644 index 000000000..c4d0c6cd2 --- /dev/null +++ b/changelog.d/5090.change @@ -0,0 +1 @@ +Settings: Update about section footer text. \ No newline at end of file From e5fafb079fd9a0136df65ba484e33d7a5e15ac4c Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 10 Nov 2021 18:42:29 +0100 Subject: [PATCH 50/57] MXSession: Add logs to track if E2EE is enabled by default on the current HS. --- Riot/Categories/MXSession+Riot.m | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Categories/MXSession+Riot.m b/Riot/Categories/MXSession+Riot.m index 901c58406..05d5cd624 100644 --- a/Riot/Categories/MXSession+Riot.m +++ b/Riot/Categories/MXSession+Riot.m @@ -65,6 +65,7 @@ } else { + MXLogInfo(@"[MXSession] E2EE is disabled by default on this homeserver"); success(NO); return [MXHTTPOperation new]; } From afdad9dfe6a020333eab7ca1e6d455a4a321f2c7 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 10 Nov 2021 18:54:39 +0100 Subject: [PATCH 51/57] MXSession: Add logs to track if E2EE is enabled by default on the current HS. --- Riot/Categories/MXSession+Riot.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Categories/MXSession+Riot.m b/Riot/Categories/MXSession+Riot.m index 05d5cd624..f26fda0b1 100644 --- a/Riot/Categories/MXSession+Riot.m +++ b/Riot/Categories/MXSession+Riot.m @@ -65,7 +65,7 @@ } else { - MXLogInfo(@"[MXSession] E2EE is disabled by default on this homeserver"); + MXLogWarning(@"[MXSession] E2EE is disabled by default on this homeserver."); success(NO); return [MXHTTPOperation new]; } From e39dfc5c4dee12f21a4679a578485db1e71236c3 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 10 Nov 2021 18:58:34 +0100 Subject: [PATCH 52/57] MXSession: Add logs to track if E2EE is enabled by default on the current HS. --- Riot/Categories/MXSession+Riot.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Categories/MXSession+Riot.m b/Riot/Categories/MXSession+Riot.m index f26fda0b1..f89dc1f62 100644 --- a/Riot/Categories/MXSession+Riot.m +++ b/Riot/Categories/MXSession+Riot.m @@ -65,7 +65,7 @@ } else { - MXLogWarning(@"[MXSession] E2EE is disabled by default on this homeserver."); + MXLogWarning(@"[MXSession] E2EE is disabled by default on this homeserver.\nWellknown content: %@", self.homeserverWellknown.JSONDictionary); success(NO); return [MXHTTPOperation new]; } From 5a7d3c1f8a4232abad4f2e0e87b0e08e6b840fae Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 11 Nov 2021 09:28:12 +0000 Subject: [PATCH 53/57] Add changelog. Remove whitespace. --- Riot/Categories/MXSession+Riot.m | 2 +- changelog.d/5129.change | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/5129.change diff --git a/Riot/Categories/MXSession+Riot.m b/Riot/Categories/MXSession+Riot.m index f89dc1f62..069e13ca6 100644 --- a/Riot/Categories/MXSession+Riot.m +++ b/Riot/Categories/MXSession+Riot.m @@ -65,7 +65,7 @@ } else { - MXLogWarning(@"[MXSession] E2EE is disabled by default on this homeserver.\nWellknown content: %@", self.homeserverWellknown.JSONDictionary); + MXLogWarning(@"[MXSession] E2EE is disabled by default on this homeserver.\nWellknown content: %@", self.homeserverWellknown.JSONDictionary); success(NO); return [MXHTTPOperation new]; } diff --git a/changelog.d/5129.change b/changelog.d/5129.change new file mode 100644 index 000000000..86738a989 --- /dev/null +++ b/changelog.d/5129.change @@ -0,0 +1 @@ +MXSession: Add logs to track if E2EE is enabled by default on the current HS. \ No newline at end of file From 6a612f2aabc237c3dc65aef9faf5d57cbefcb2c2 Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 11 Nov 2021 15:43:43 +0000 Subject: [PATCH 54/57] Refresh RecentsListService when switching modes. --- .../Recents/Service/MatrixSDK/RecentsListService.swift | 7 ++++++- changelog.d/5105.bugfix | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 changelog.d/5105.bugfix diff --git a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift index 3261caa22..6651fddba 100644 --- a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift +++ b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift @@ -20,7 +20,12 @@ import Foundation public class RecentsListService: NSObject, RecentsListServiceProtocol { private weak var session: MXSession? - public private(set) var mode: RecentsDataSourceMode + public private(set) var mode: RecentsDataSourceMode { + didSet { + refresh() + } + } + public private(set) var query: String? public private(set) var space: MXSpace? diff --git a/changelog.d/5105.bugfix b/changelog.d/5105.bugfix new file mode 100644 index 000000000..4b833133a --- /dev/null +++ b/changelog.d/5105.bugfix @@ -0,0 +1 @@ +Fix room ordering when switching between Home and People/Rooms/Favourites. \ No newline at end of file From 143368ad461bd6751f72af2b19ac15a7c4dff42a Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Thu, 11 Nov 2021 19:52:21 +0300 Subject: [PATCH 55/57] Implement new summary properties --- .../Recents/Service/Mock/MockRoomSummary.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Riot/Modules/Common/Recents/Service/Mock/MockRoomSummary.swift b/Riot/Modules/Common/Recents/Service/Mock/MockRoomSummary.swift index 713932423..c211db025 100644 --- a/Riot/Modules/Common/Recents/Service/Mock/MockRoomSummary.swift +++ b/Riot/Modules/Common/Recents/Service/Mock/MockRoomSummary.swift @@ -60,6 +60,18 @@ public class MockRoomSummary: NSObject, MXRoomSummaryProtocol { public var highlightCount: UInt = 0 + public var hasAnyUnread: Bool { + return localUnreadEventCount > 0 + } + + public var hasAnyNotification: Bool { + return notificationCount > 0 + } + + public var hasAnyHighlight: Bool { + return highlightCount > 0 + } + public var isDirect: Bool { return isTyped(.direct) } From d99d798faffc4e3b736fc32be48b0d114dd0fa88 Mon Sep 17 00:00:00 2001 From: Doug Date: Wed, 17 Nov 2021 16:01:10 +0000 Subject: [PATCH 56/57] changelog.d: Upgrade MatrixKit version ([v0.16.10](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.16.10)). --- Config/AppVersion.xcconfig | 4 ++-- Podfile | 2 +- changelog.d/x-nolink-0.change | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 changelog.d/x-nolink-0.change diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index 5e6c9928e..4b18e27d3 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 1.6.7 -CURRENT_PROJECT_VERSION = 1.6.7 +MARKETING_VERSION = 1.6.8 +CURRENT_PROJECT_VERSION = 1.6.8 diff --git a/Podfile b/Podfile index f2fab251b..9c04e8912 100644 --- a/Podfile +++ b/Podfile @@ -13,7 +13,7 @@ use_frameworks! # - `{ {kit spec hash} => {sdk spec hash}` to depend on specific pod options (:git => …, :podspec => …) for each repo. Used by Fastfile during CI # # Warning: our internal tooling depends on the name of this variable name, so be sure not to change it -$matrixKitVersion = '= 0.16.9' +$matrixKitVersion = '= 0.16.10' # $matrixKitVersion = :local # $matrixKitVersion = {'develop' => 'develop'} diff --git a/changelog.d/x-nolink-0.change b/changelog.d/x-nolink-0.change new file mode 100644 index 000000000..2ae535db8 --- /dev/null +++ b/changelog.d/x-nolink-0.change @@ -0,0 +1 @@ +Upgrade MatrixKit version ([v0.16.10](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.16.10)). \ No newline at end of file From 7a114affbae7d892e6c304b1aafddfa4c7492f51 Mon Sep 17 00:00:00 2001 From: Doug Date: Wed, 17 Nov 2021 16:01:11 +0000 Subject: [PATCH 57/57] version++ --- CHANGES.md | 32 ++++++++++++++++++++++++++++++++ changelog.d/4384.change | 1 - changelog.d/4815.change | 1 - changelog.d/4976.change | 1 - changelog.d/4987.misc | 1 - changelog.d/5041.bugfix | 1 - changelog.d/5042.bugfix | 1 - changelog.d/5055.bugfix | 1 - changelog.d/5057.bugfix | 1 - changelog.d/5058.bugfix | 1 - changelog.d/5063.bugfix | 1 - changelog.d/5071.bugfix | 1 - changelog.d/5079.bugfix | 1 - changelog.d/5081.bugfix | 1 - changelog.d/5082.bugfix | 1 - changelog.d/5083.bugfix | 1 - changelog.d/5084.bugfix | 1 - changelog.d/5090.change | 1 - changelog.d/5105.bugfix | 1 - changelog.d/5129.change | 1 - changelog.d/x-nolink-0.change | 1 - 21 files changed, 32 insertions(+), 20 deletions(-) delete mode 100644 changelog.d/4384.change delete mode 100644 changelog.d/4815.change delete mode 100644 changelog.d/4976.change delete mode 100644 changelog.d/4987.misc delete mode 100644 changelog.d/5041.bugfix delete mode 100644 changelog.d/5042.bugfix delete mode 100644 changelog.d/5055.bugfix delete mode 100644 changelog.d/5057.bugfix delete mode 100644 changelog.d/5058.bugfix delete mode 100644 changelog.d/5063.bugfix delete mode 100644 changelog.d/5071.bugfix delete mode 100644 changelog.d/5079.bugfix delete mode 100644 changelog.d/5081.bugfix delete mode 100644 changelog.d/5082.bugfix delete mode 100644 changelog.d/5083.bugfix delete mode 100644 changelog.d/5084.bugfix delete mode 100644 changelog.d/5090.change delete mode 100644 changelog.d/5105.bugfix delete mode 100644 changelog.d/5129.change delete mode 100644 changelog.d/x-nolink-0.change diff --git a/CHANGES.md b/CHANGES.md index 966ee4efa..53518bf12 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,35 @@ +## Changes in 1.6.8 (2021-11-17) + +🙌 Improvements + +- Upgrade MatrixKit version ([v0.16.10](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.16.10)). +- Using mutable room list fetch sort options after chaning them to be a structure. ([#4384](https://github.com/vector-im/element-ios/issues/4384)) +- Share Extension: Remove the image compression prompt when the showMediaSizeSelection setting is disabled. ([#4815](https://github.com/vector-im/element-ios/issues/4815)) +- Replaced GrowingTextView with simpler, custom implementation. Cleaned up the RoomInputToolbar header. ([#4976](https://github.com/vector-im/element-ios/issues/4976)) +- Settings: Update about section footer text. ([#5090](https://github.com/vector-im/element-ios/issues/5090)) +- MXSession: Add logs to track if E2EE is enabled by default on the current HS. ([#5129](https://github.com/vector-im/element-ios/issues/5129)) + +🐛 Bugfixes + +- Fixed share extension and message forwarding room list accessory view icon. ([#5041](https://github.com/vector-im/element-ios/issues/5041)) +- Fixed message composer not following keyboard when swiping to dismiss. ([#5042](https://github.com/vector-im/element-ios/issues/5042)) +- RoomVC: Fix retain cycles that prevents `RoomViewController` to be deallocated. ([#5055](https://github.com/vector-im/element-ios/issues/5055)) +- Share Extension: Fix missing avatars and don't list spaces as rooms. ([#5057](https://github.com/vector-im/element-ios/issues/5057)) +- Fix retain cycles that prevents deallocation in several classes. ([#5058](https://github.com/vector-im/element-ios/issues/5058)) +- Fixed retain cycles between the user suggestion coordinator and the suggestion service, and in the suggestion service currentTextTrigger subject sink. ([#5063](https://github.com/vector-im/element-ios/issues/5063)) +- Ensure alerts with weak references are retained until they've been presented. ([#5071](https://github.com/vector-im/element-ios/issues/5071)) +- Message Composer: Ensure there is no text view when the user isn't allowed to send messages. ([#5079](https://github.com/vector-im/element-ios/issues/5079)) +- Home: Fix bug where favourited DM would be shown in both Favourites and People section. ([#5081](https://github.com/vector-im/element-ios/issues/5081)) +- Fix a crash when selected space is not home and a clear cache or logout is performed. ([#5082](https://github.com/vector-im/element-ios/issues/5082)) +- Room Previews: Fix room previews not loading. ([#5083](https://github.com/vector-im/element-ios/issues/5083)) +- Do not make the placeholder appearing when leaving a room on iPhone. ([#5084](https://github.com/vector-im/element-ios/issues/5084)) +- Fix room ordering when switching between Home and People/Rooms/Favourites. ([#5105](https://github.com/vector-im/element-ios/issues/5105)) + +Others + +- Improve wording around rageshakes in the defect issue template. ([#4987](https://github.com/vector-im/element-ios/issues/4987)) + + ## Changes in 1.6.6 (2021-10-21) ✨ Features diff --git a/changelog.d/4384.change b/changelog.d/4384.change deleted file mode 100644 index 9103529a3..000000000 --- a/changelog.d/4384.change +++ /dev/null @@ -1 +0,0 @@ -Using mutable room list fetch sort options after chaning them to be a structure. \ No newline at end of file diff --git a/changelog.d/4815.change b/changelog.d/4815.change deleted file mode 100644 index 757ff6d22..000000000 --- a/changelog.d/4815.change +++ /dev/null @@ -1 +0,0 @@ -Share Extension: Remove the image compression prompt when the showMediaSizeSelection setting is disabled. \ No newline at end of file diff --git a/changelog.d/4976.change b/changelog.d/4976.change deleted file mode 100644 index 7c52865d3..000000000 --- a/changelog.d/4976.change +++ /dev/null @@ -1 +0,0 @@ -Replaced GrowingTextView with simpler, custom implementation. Cleaned up the RoomInputToolbar header. \ No newline at end of file diff --git a/changelog.d/4987.misc b/changelog.d/4987.misc deleted file mode 100644 index ac7a294f3..000000000 --- a/changelog.d/4987.misc +++ /dev/null @@ -1 +0,0 @@ -Improve wording around rageshakes in the defect issue template. diff --git a/changelog.d/5041.bugfix b/changelog.d/5041.bugfix deleted file mode 100644 index 07882c073..000000000 --- a/changelog.d/5041.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixed share extension and message forwarding room list accessory view icon. \ No newline at end of file diff --git a/changelog.d/5042.bugfix b/changelog.d/5042.bugfix deleted file mode 100644 index 481c4c053..000000000 --- a/changelog.d/5042.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixed message composer not following keyboard when swiping to dismiss. \ No newline at end of file diff --git a/changelog.d/5055.bugfix b/changelog.d/5055.bugfix deleted file mode 100644 index a969f4fef..000000000 --- a/changelog.d/5055.bugfix +++ /dev/null @@ -1 +0,0 @@ -RoomVC: Fix retain cycles that prevents `RoomViewController` to be deallocated. \ No newline at end of file diff --git a/changelog.d/5057.bugfix b/changelog.d/5057.bugfix deleted file mode 100644 index b3f2b9744..000000000 --- a/changelog.d/5057.bugfix +++ /dev/null @@ -1 +0,0 @@ -Share Extension: Fix missing avatars and don't list spaces as rooms. \ No newline at end of file diff --git a/changelog.d/5058.bugfix b/changelog.d/5058.bugfix deleted file mode 100644 index 1e8112a36..000000000 --- a/changelog.d/5058.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix retain cycles that prevents deallocation in several classes. \ No newline at end of file diff --git a/changelog.d/5063.bugfix b/changelog.d/5063.bugfix deleted file mode 100644 index d1ee811c1..000000000 --- a/changelog.d/5063.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixed retain cycles between the user suggestion coordinator and the suggestion service, and in the suggestion service currentTextTrigger subject sink. \ No newline at end of file diff --git a/changelog.d/5071.bugfix b/changelog.d/5071.bugfix deleted file mode 100644 index 40e26a7da..000000000 --- a/changelog.d/5071.bugfix +++ /dev/null @@ -1 +0,0 @@ -Ensure alerts with weak references are retained until they've been presented. \ No newline at end of file diff --git a/changelog.d/5079.bugfix b/changelog.d/5079.bugfix deleted file mode 100644 index 0f6b2baf8..000000000 --- a/changelog.d/5079.bugfix +++ /dev/null @@ -1 +0,0 @@ -Message Composer: Ensure there is no text view when the user isn't allowed to send messages. \ No newline at end of file diff --git a/changelog.d/5081.bugfix b/changelog.d/5081.bugfix deleted file mode 100644 index 545779610..000000000 --- a/changelog.d/5081.bugfix +++ /dev/null @@ -1 +0,0 @@ -Home: Fix bug where favourited DM would be shown in both Favourites and People section. \ No newline at end of file diff --git a/changelog.d/5082.bugfix b/changelog.d/5082.bugfix deleted file mode 100644 index e7d60ca36..000000000 --- a/changelog.d/5082.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix a crash when selected space is not home and a clear cache or logout is performed. \ No newline at end of file diff --git a/changelog.d/5083.bugfix b/changelog.d/5083.bugfix deleted file mode 100644 index 12a915cc6..000000000 --- a/changelog.d/5083.bugfix +++ /dev/null @@ -1 +0,0 @@ -Room Previews: Fix room previews not loading. \ No newline at end of file diff --git a/changelog.d/5084.bugfix b/changelog.d/5084.bugfix deleted file mode 100644 index c7826659d..000000000 --- a/changelog.d/5084.bugfix +++ /dev/null @@ -1 +0,0 @@ -Do not make the placeholder appearing when leaving a room on iPhone. \ No newline at end of file diff --git a/changelog.d/5090.change b/changelog.d/5090.change deleted file mode 100644 index c4d0c6cd2..000000000 --- a/changelog.d/5090.change +++ /dev/null @@ -1 +0,0 @@ -Settings: Update about section footer text. \ No newline at end of file diff --git a/changelog.d/5105.bugfix b/changelog.d/5105.bugfix deleted file mode 100644 index 4b833133a..000000000 --- a/changelog.d/5105.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix room ordering when switching between Home and People/Rooms/Favourites. \ No newline at end of file diff --git a/changelog.d/5129.change b/changelog.d/5129.change deleted file mode 100644 index 86738a989..000000000 --- a/changelog.d/5129.change +++ /dev/null @@ -1 +0,0 @@ -MXSession: Add logs to track if E2EE is enabled by default on the current HS. \ No newline at end of file diff --git a/changelog.d/x-nolink-0.change b/changelog.d/x-nolink-0.change deleted file mode 100644 index 2ae535db8..000000000 --- a/changelog.d/x-nolink-0.change +++ /dev/null @@ -1 +0,0 @@ -Upgrade MatrixKit version ([v0.16.10](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.16.10)). \ No newline at end of file