diff --git a/CHANGES.md b/CHANGES.md
index 717770810..53b527969 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,16 @@
+## Changes in 1.8.6 (2022-03-14)
+
+🙌 Improvements
+
+- Upgrade MatrixSDK version ([v0.22.6](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.22.6)).
+- Room: Ignore the sender of a room invite without needing to join the room first ([#5807](https://github.com/vector-im/element-ios/issues/5807))
+
+🐛 Bugfixes
+
+- Activity Indicators: Do not show user indicators when the view controller is not visible ([#5801](https://github.com/vector-im/element-ios/issues/5801))
+- Authentication: Fix social login buttons visibility during registration flow and other minor navigation tweaks. ([#5879](https://github.com/vector-im/element-ios/issues/5879))
+
+
## Changes in 1.8.5 (2022-03-09)
🐛 Bugfixes
diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig
index 174e0bd5b..164b076c5 100644
--- a/Config/AppVersion.xcconfig
+++ b/Config/AppVersion.xcconfig
@@ -15,5 +15,5 @@
//
// Version
-MARKETING_VERSION = 1.8.6
-CURRENT_PROJECT_VERSION = 1.8.6
+MARKETING_VERSION = 1.8.7
+CURRENT_PROJECT_VERSION = 1.8.7
diff --git a/Podfile b/Podfile
index 67f463d93..07fe178d6 100644
--- a/Podfile
+++ b/Podfile
@@ -13,7 +13,7 @@ use_frameworks!
# - `{ :specHash => {sdk spec hash}` to depend on specific pod options (:git => …, :podspec => …) for MatrixSDK 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
-$matrixSDKVersion = '= 0.22.5'
+$matrixSDKVersion = '= 0.22.6'
# $matrixSDKVersion = :local
# $matrixSDKVersion = { :branch => 'develop'}
# $matrixSDKVersion = { :specHash => { git: 'https://git.io/fork123', branch: 'fix' } }
diff --git a/Podfile.lock b/Podfile.lock
index 06d7a51e9..1c3e87179 100644
--- a/Podfile.lock
+++ b/Podfile.lock
@@ -56,16 +56,16 @@ PODS:
- LoggerAPI (1.9.200):
- Logging (~> 1.1)
- Logging (1.4.0)
- - MatrixSDK (0.22.5):
- - MatrixSDK/Core (= 0.22.5)
- - MatrixSDK/Core (0.22.5):
+ - MatrixSDK (0.22.6):
+ - MatrixSDK/Core (= 0.22.6)
+ - MatrixSDK/Core (0.22.6):
- AFNetworking (~> 4.0.0)
- GZIP (~> 1.3.0)
- libbase58 (~> 0.1.4)
- OLMKit (~> 3.2.5)
- Realm (= 10.16.0)
- SwiftyBeaver (= 1.9.5)
- - MatrixSDK/JingleCallStack (0.22.5):
+ - MatrixSDK/JingleCallStack (0.22.6):
- JitsiMeetSDK (= 3.10.2)
- MatrixSDK/Core
- OLMKit (3.2.5):
@@ -115,8 +115,8 @@ DEPENDENCIES:
- KeychainAccess (~> 4.2.2)
- KTCenterFlowLayout (~> 1.3.1)
- libPhoneNumber-iOS (~> 0.9.13)
- - MatrixSDK (= 0.22.5)
- - MatrixSDK/JingleCallStack (= 0.22.5)
+ - MatrixSDK (= 0.22.6)
+ - MatrixSDK/JingleCallStack (= 0.22.6)
- OLMKit
- PostHog (~> 1.4.4)
- ReadMoreTextView (~> 3.0.1)
@@ -208,7 +208,7 @@ SPEC CHECKSUMS:
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d
Logging: beeb016c9c80cf77042d62e83495816847ef108b
- MatrixSDK: 9bbe59564b2352e54254119dd217a9d86e3f8b17
+ MatrixSDK: f61997c146a03dfbf2ec0442bcae362c50666284
OLMKit: 9fb4799c4a044dd2c06bda31ec31a12191ad30b5
PostHog: 4b6321b521569092d4ef3a02238d9435dbaeb99f
ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d
@@ -225,6 +225,6 @@ SPEC CHECKSUMS:
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
-PODFILE CHECKSUM: 4e66f96dc80b17bfb36906bf85f9be35071cdbee
+PODFILE CHECKSUM: 16aaf5e59ec902619fbfd799939f044728a92ab7
COCOAPODS: 1.11.2
diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings
index fb675d28e..af5aa32be 100644
--- a/Riot/Assets/en.lproj/Vector.strings
+++ b/Riot/Assets/en.lproj/Vector.strings
@@ -506,6 +506,7 @@ Tap the + to start adding people.";
"room_preview_unlinked_email_warning" = "This invitation was sent to %@, which is not associated with this account. You may wish to login with a different account, or add this email to your account.";
"room_preview_try_join_an_unknown_room" = "You are trying to access %@. Would you like to join in order to participate in the discussion?";
"room_preview_try_join_an_unknown_room_default" = "a room";
+"room_preview_decline_invitation_options" = "Do you want to decline the invitation or ignore this user?";
// Settings
"settings_title" = "Settings";
@@ -2168,6 +2169,7 @@ Tap the + to start adding people.";
"end_call" = "End Call";
"resume_call" = "Resume";
"ignore" = "Ignore";
+"ignore_user" = "Ignore User";
"unignore" = "Unignore";
// Events formatter
diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift
index f2ff7c539..ca1a6125a 100644
--- a/Riot/Generated/Strings.swift
+++ b/Riot/Generated/Strings.swift
@@ -2163,6 +2163,10 @@ public class VectorL10n: NSObject {
public static var ignore: String {
return VectorL10n.tr("Vector", "ignore")
}
+ /// Ignore User
+ public static var ignoreUser: String {
+ return VectorL10n.tr("Vector", "ignore_user")
+ }
/// Take photo
public static var imagePickerActionCamera: String {
return VectorL10n.tr("Vector", "image_picker_action_camera")
@@ -5467,6 +5471,10 @@ public class VectorL10n: NSObject {
public static var roomPredecessorLink: String {
return VectorL10n.tr("Vector", "room_predecessor_link")
}
+ /// Do you want to decline the invitation or ignore this user?
+ public static var roomPreviewDeclineInvitationOptions: String {
+ return VectorL10n.tr("Vector", "room_preview_decline_invitation_options")
+ }
/// You have been invited to join this room by %@
public static func roomPreviewInvitationFormat(_ p1: String) -> String {
return VectorL10n.tr("Vector", "room_preview_invitation_format", p1)
diff --git a/Riot/Modules/Authentication/AuthenticationCoordinator.swift b/Riot/Modules/Authentication/AuthenticationCoordinator.swift
index 708798844..3bcae3348 100644
--- a/Riot/Modules/Authentication/AuthenticationCoordinator.swift
+++ b/Riot/Modules/Authentication/AuthenticationCoordinator.swift
@@ -43,6 +43,13 @@ final class AuthenticationCoordinator: NSObject, AuthenticationCoordinatorProtoc
var childCoordinators: [Coordinator] = []
var completion: ((AuthenticationCoordinatorResult) -> Void)?
+ var customServerFieldsVisible = false {
+ didSet {
+ guard customServerFieldsVisible != oldValue else { return }
+ authenticationViewController.setCustomServerFieldsVisible(customServerFieldsVisible)
+ }
+ }
+
// MARK: - Setup
init(parameters: AuthenticationCoordinatorParameters) {
@@ -74,10 +81,6 @@ final class AuthenticationCoordinator: NSObject, AuthenticationCoordinatorProtoc
authenticationViewController.authType = authenticationType
}
- func showCustomServer() {
- authenticationViewController.setCustomServerFieldsVisible(true)
- }
-
func update(externalRegistrationParameters: [AnyHashable: Any]) {
authenticationViewController.externalRegistrationParameters = externalRegistrationParameters
}
diff --git a/Riot/Modules/Authentication/AuthenticationCoordinatorProtocol.swift b/Riot/Modules/Authentication/AuthenticationCoordinatorProtocol.swift
index f04676861..54696e503 100644
--- a/Riot/Modules/Authentication/AuthenticationCoordinatorProtocol.swift
+++ b/Riot/Modules/Authentication/AuthenticationCoordinatorProtocol.swift
@@ -36,12 +36,12 @@ enum AuthenticationCoordinatorResult {
protocol AuthenticationCoordinatorProtocol: Coordinator, Presentable {
var completion: ((AuthenticationCoordinatorResult) -> Void)? { get set }
+ /// Whether the custom homeserver checkbox is enabled for the user to enter a homeserver URL.
+ var customServerFieldsVisible: Bool { get set }
+
/// Update the screen to display registration or login.
func update(authenticationType: MXKAuthenticationType)
- /// Enable the custom server checkbox to allow the user to enter a homeserver URL.
- func showCustomServer()
-
/// Force a registration process based on a predefined set of parameters from a server provisioning link.
/// For more information see `AuthenticationViewController.externalRegistrationParameters`.
func update(externalRegistrationParameters: [AnyHashable: Any])
diff --git a/Riot/Modules/Authentication/AuthenticationViewController.m b/Riot/Modules/Authentication/AuthenticationViewController.m
index 449276f09..448d75b8b 100644
--- a/Riot/Modules/Authentication/AuthenticationViewController.m
+++ b/Riot/Modules/Authentication/AuthenticationViewController.m
@@ -504,6 +504,7 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
// Remove the potential back button.
self.navigationItem.leftBarButtonItem = nil;
+ [self.navigationItem setHidesBackButton:YES];
}
else
{
@@ -903,6 +904,12 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
authInputsview.thirdPartyIdentifiersHidden = YES;
[self updateRegistrationScreenWithThirdPartyIdentifiersHidden:YES];
+
+ // Show the social login buttons again if needed.
+ [self updateSocialLoginViewVisibility];
+
+ // Allow backward navigation in the flow again.
+ [self.navigationItem setHidesBackButton:NO];
}
}
else if (sender == self.submitButton)
@@ -947,7 +954,10 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
else
{
[self.authenticationActivityIndicator stopAnimating];
-
+
+ // Hide the social login buttons now that a different flow has started.
+ [self hideSocialLoginView];
+
// Show the supported 3rd party ids which may be added to the account
authInputsview.thirdPartyIdentifiersHidden = NO;
[self updateRegistrationScreenWithThirdPartyIdentifiersHidden:NO];
diff --git a/Riot/Modules/Common/ActivityIndicator/UserIndicatorPresenterWrapper.swift b/Riot/Modules/Common/ActivityIndicator/UserIndicatorPresenterWrapper.swift
index f7faa03f6..7d1bd9d3b 100644
--- a/Riot/Modules/Common/ActivityIndicator/UserIndicatorPresenterWrapper.swift
+++ b/Riot/Modules/Common/ActivityIndicator/UserIndicatorPresenterWrapper.swift
@@ -30,21 +30,23 @@ import CommonKit
self.presenter = presenter
}
- @objc func presentActivityIndicator() {
- presentActivityIndicator(label: VectorL10n.homeSyncing)
+ @objc func presentLoadingIndicator() {
+ presentLoadingIndicator(label: VectorL10n.homeSyncing)
}
- @objc func presentActivityIndicator(label: String) {
+ @objc func presentLoadingIndicator(label: String) {
guard loadingIndicator == nil else {
- // The app is very liberal with calling `presentActivityIndicator` (often not matched by corresponding `removeCurrentActivityIndicator`),
+ // The app is very liberal with calling `presentLoadingIndicator` (often not matched by corresponding `dismissLoadingIndicator`),
// so there is no reason to keep adding new indiciators if there is one already showing.
return
}
+ MXLog.debug("[UserIndicatorPresenterWrapper] Present loading indicator")
loadingIndicator = presenter.present(.loading(label: label, isInteractionBlocking: false))
}
- @objc func dismissActivityIndicator() {
+ @objc func dismissLoadingIndicator() {
+ MXLog.debug("[UserIndicatorPresenterWrapper] Dismiss loading indicator")
loadingIndicator = nil
}
diff --git a/Riot/Modules/Common/Recents/RecentsViewController.m b/Riot/Modules/Common/Recents/RecentsViewController.m
index 042c0becc..9d3518a80 100644
--- a/Riot/Modules/Common/Recents/RecentsViewController.m
+++ b/Riot/Modules/Common/Recents/RecentsViewController.m
@@ -64,6 +64,9 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
// when the user selects it.
UISearchBar *tableSearchBar;
+ // Flag indicating whether the view controller is (at least partially) visible and not dissapearing
+ BOOL isViewVisible;
+
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
__weak id kThemeServiceDidChangeThemeNotificationObserver;
}
@@ -264,6 +267,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
+ isViewVisible = YES;
[self.screenTracker trackScreen];
@@ -301,6 +305,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
+ isViewVisible = NO;
// Leave potential editing mode
[self cancelEditionMode:NO];
@@ -2419,16 +2424,16 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
}
- (void)startActivityIndicatorWithLabel:(NSString *)label {
- if (self.indicatorPresenter) {
- [self.indicatorPresenter presentActivityIndicatorWithLabel:label];
+ if (self.indicatorPresenter && isViewVisible) {
+ [self.indicatorPresenter presentLoadingIndicatorWithLabel:label];
} else {
[super startActivityIndicator];
}
}
- (void)startActivityIndicator {
- if (self.indicatorPresenter) {
- [self.indicatorPresenter presentActivityIndicator];
+ if (self.indicatorPresenter && isViewVisible) {
+ [self.indicatorPresenter presentLoadingIndicator];
} else {
[super startActivityIndicator];
}
@@ -2436,7 +2441,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
- (void)stopActivityIndicator {
if (self.indicatorPresenter) {
- [self.indicatorPresenter dismissActivityIndicator];
+ [self.indicatorPresenter dismissLoadingIndicator];
} else {
[super stopActivityIndicator];
}
diff --git a/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m b/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m
index 3ebb69a4b..61b2a12ce 100644
--- a/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m
+++ b/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m
@@ -1261,7 +1261,7 @@ static NSString *const kHTMLATagRegexPattern = @"([^<]*)";
isHTML =YES;
MXJSONModelSetString(body, event.content[@"formatted_body"]);
}
- else if (eventThreadId && !RiotSettings.shared.enableThreads)
+ else if (event.isReplyEvent || (eventThreadId && !RiotSettings.shared.enableThreads))
{
NSString *repliedEventId = event.relatesTo.inReplyTo.eventId ?: eventThreadId;
isHTML = YES;
@@ -2067,7 +2067,7 @@ static NSString *const kHTMLATagRegexPattern = @"([^<]*)";
textColor = _errorTextColor;
}
// Check whether the message is highlighted.
- else if (event.mxkIsHighlighted || (!RiotSettings.shared.enableThreads && event.isInThread && [event shouldBeHighlightedInSession:mxSession]))
+ else if (event.mxkIsHighlighted || (mxSession && [event shouldBeHighlightedInSession:mxSession]))
{
textColor = _bingTextColor;
}
@@ -2132,7 +2132,7 @@ static NSString *const kHTMLATagRegexPattern = @"([^<]*)";
{
font = _callNoticesTextFont;
}
- else if (event.mxkIsHighlighted || (!RiotSettings.shared.enableThreads && event.isInThread && [event shouldBeHighlightedInSession:mxSession]))
+ else if (event.mxkIsHighlighted || (mxSession && [event shouldBeHighlightedInSession:mxSession]))
{
font = _bingTextFont;
}
diff --git a/Riot/Modules/Onboarding/OnboardingCoordinator.swift b/Riot/Modules/Onboarding/OnboardingCoordinator.swift
index 94182fa56..dd2a379ba 100644
--- a/Riot/Modules/Onboarding/OnboardingCoordinator.swift
+++ b/Riot/Modules/Onboarding/OnboardingCoordinator.swift
@@ -215,9 +215,7 @@ final class OnboardingCoordinator: NSObject, OnboardingCoordinatorProtocol {
coordinator.update(externalRegistrationParameters: externalRegistrationParameters)
}
- if useCaseResult == .customServer {
- coordinator.showCustomServer()
- }
+ coordinator.customServerFieldsVisible = useCaseResult == .customServer
if let softLogoutCredentials = parameters.softLogoutCredentials {
coordinator.update(softLogoutCredentials: softLogoutCredentials)
diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m
index 65365e94c..c962e56d6 100644
--- a/Riot/Modules/Room/RoomViewController.m
+++ b/Riot/Modules/Room/RoomViewController.m
@@ -568,7 +568,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
isAppeared = NO;
[VoiceMessageMediaServiceProvider.sharedProvider pauseAllServices];
- [self stopActivityIndicator];
+
+ // Stop the loading indicator even if the session is still in progress
+ [self stopLoadingUserIndicator];
}
- (void)viewDidAppear:(BOOL)animated
@@ -938,10 +940,14 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
self.updateRoomReadMarker = NO;
}
+#pragma mark - Loading indicators
+
- (BOOL)providesCustomActivityIndicator {
return [self.delegate roomViewControllerCanDelegateUserIndicators:self];
}
+// Override of a legacy method to determine whether to use a newer implementation instead.
+// Will be removed in the future https://github.com/vector-im/element-ios/issues/5608
- (void)startActivityIndicator {
if ([self providesCustomActivityIndicator]) {
[self.delegate roomViewControllerDidStartLoading:self];
@@ -950,6 +956,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
}
}
+// Override of a legacy method to determine whether to use a newer implementation instead.
+// Will be removed in the future https://github.com/vector-im/element-ios/issues/5608
- (void)stopActivityIndicator
{
if (notificationTaskProfile)
@@ -959,14 +967,22 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
notificationTaskProfile = nil;
}
if ([self providesCustomActivityIndicator]) {
+ // The legacy super implementation of `stopActivityIndicator` contains a number of checks grouped under `canStopActivityIndicator`
+ // to determine whether the indicator can be stopped or not (and the method should thus rather be called `stopActivityIndicatorIfPossible`).
+ // Since the newer indicators are not calling super implementation, the check for `canStopActivityIndicator` has to be performed manually.
if ([self canStopActivityIndicator]) {
- [self.delegate roomViewControllerDidStopLoading:self];
+ [self stopLoadingUserIndicator];
}
} else {
[super stopActivityIndicator];
}
}
+- (void)stopLoadingUserIndicator
+{
+ [self.delegate roomViewControllerDidStopLoading:self];
+}
+
- (void)displayRoom:(MXKRoomDataSource *)dataSource
{
// Remove potential preview Data
@@ -1261,6 +1277,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
if (!bubbleTableViewDisplayInTransition && !self.bubblesTableView.isHidden)
{
[self refreshActivitiesViewDisplay];
+ [self refreshRoomTitle];
[self checkReadMarkerVisibility];
[self refreshJumpToLastUnreadBannerDisplay];
@@ -4963,10 +4980,32 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
}
else if (tappedView == previewHeader.leftButton)
{
- [self declineRoomInvitation];
+ [self presentDeclineOptionsFromView:tappedView];
}
}
+- (void)presentDeclineOptionsFromView:(UIView *)view
+{
+ UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:[VectorL10n roomPreviewDeclineInvitationOptions]
+ message:nil
+ preferredStyle:UIAlertControllerStyleActionSheet];
+ [actionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n decline]
+ style:UIAlertActionStyleDefault
+ handler:^(UIAlertAction * _Nonnull action) {
+ [self declineRoomInvitation];
+ }]];
+ [actionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n ignoreUser]
+ style:UIAlertActionStyleDestructive
+ handler:^(UIAlertAction * _Nonnull action) {
+ [self ignoreInviteSender];
+ }]];
+ [actionSheet addAction:[UIAlertAction actionWithTitle:[VectorL10n cancel]
+ style:UIAlertActionStyleCancel
+ handler:nil]];
+ actionSheet.popoverPresentationController.sourceView = view;
+ [self presentViewController:actionSheet animated:YES completion:nil];
+}
+
- (void)declineRoomInvitation
{
// 'Decline' button has been pressed
@@ -4977,16 +5016,15 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
else
{
[self startActivityIndicator];
-
+ MXWeakify(self);
[self.roomDataSource.room leave:^{
+ MXStrongifyAndReturnIfNil(self);
[self stopActivityIndicator];
-
- // We remove the current view controller.
- // Pop to homes view controller
- [[AppDelegate theDelegate] restoreInitialDisplay:^{}];
+ [self popToHomeViewController];
} failure:^(NSError *error) {
+ MXStrongifyAndReturnIfNil(self);
[self stopActivityIndicator];
MXLogDebug(@"[RoomVC] Failed to reject an invited room (%@) failed", self.roomDataSource.room.roomId);
@@ -4995,6 +5033,31 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
}
}
+- (void)ignoreInviteSender
+{
+ [self startActivityIndicator];
+ MXWeakify(self);
+ [self.roomDataSource.room ignoreInviteSender:^{
+ MXStrongifyAndReturnIfNil(self);
+
+ [self stopActivityIndicator];
+ [self popToHomeViewController];
+
+ } failure:^(NSError *error) {
+ MXStrongifyAndReturnIfNil(self);
+
+ [self stopActivityIndicator];
+ MXLogDebug(@"[RoomVC] Failed to ignore inviter in room (%@)", self.roomDataSource.room.roomId);
+ }];
+}
+
+- (void)popToHomeViewController
+{
+ // We remove the current view controller.
+ // Pop to homes view controller
+ [[AppDelegate theDelegate] restoreInitialDisplay:^{}];
+}
+
#pragma mark - Typing management
- (void)removeTypingNotificationsListener
diff --git a/changelog.d/5800.bugfix b/changelog.d/5800.bugfix
new file mode 100644
index 000000000..9bc811246
--- /dev/null
+++ b/changelog.d/5800.bugfix
@@ -0,0 +1 @@
+Room: Refresh header when call actions become available (member count changes)
diff --git a/changelog.d/5816.change b/changelog.d/5816.change
new file mode 100644
index 000000000..3e4652799
--- /dev/null
+++ b/changelog.d/5816.change
@@ -0,0 +1 @@
+MXKEventFormatter: Extend reply fallback for also non-thread events.