mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-21 00:52:43 +02:00
Merge commit '3d672a05b2a7117ade2e4e87bd2b5762063d7922' into feature/3977_merge_element_1_9_13
# Conflicts: # Config/AppVersion.xcconfig # Podfile.lock # Riot/Modules/Application/LegacyAppDelegate.m # Riot/Modules/Authentication/AuthenticationCoordinator.swift # Riot/Modules/Authentication/Legacy/LegacyAuthenticationCoordinator.swift # Riot/Modules/LaunchLoading/LaunchLoadingView.swift # Riot/Modules/LaunchLoading/LaunchLoadingView.xib # Riot/Modules/MatrixKit/Models/Account/MXKAccount.m # Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.m # Riot/Modules/Room/TimelineCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m # Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellProvider.m # Riot/Modules/TabBar/MasterTabBarController.m # fastlane/Fastfile
This commit is contained in:
@@ -374,11 +374,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
|
||||
- (void)resetDeviceId;
|
||||
|
||||
#pragma mark - Sync filter
|
||||
/**
|
||||
Check if the homeserver supports room members lazy loading.
|
||||
@param completion the check result.
|
||||
*/
|
||||
- (void)supportLazyLoadOfRoomMembers:(void (^)(BOOL supportLazyLoadOfRoomMembers))completion;
|
||||
|
||||
/**
|
||||
Call this method at an appropriate time to attempt dehydrating to a new backup device
|
||||
|
||||
@@ -897,6 +897,9 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->mxSession = nil;
|
||||
|
||||
NSString *myUserId = self.mxSession.myUser.userId;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error userInfo:myUserId ? @{kMXKErrorUserIdKey: myUserId} : nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self->sessionStateObserver];
|
||||
self->sessionStateObserver = nil;
|
||||
|
||||
@@ -1684,6 +1687,14 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
NSString *myUserId = self.mxSession.myUser.userId;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error userInfo:myUserId ? @{kMXKErrorUserIdKey: myUserId} : nil];
|
||||
}
|
||||
|
||||
// If we cannot resolve this error by retrying, exit early
|
||||
BOOL isRetryableError = [error.domain isEqualToString:NSURLErrorDomain] || [MXHTTPOperation urlResponseFromError:error] != nil;
|
||||
if (!isRetryableError)
|
||||
{
|
||||
MXLogDebug(@"[MXKAccount] Initial sync will not be retried");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if it is a network connectivity issue
|
||||
AFNetworkReachabilityManager *networkReachabilityManager = [AFNetworkReachabilityManager sharedManager];
|
||||
@@ -1691,7 +1702,6 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
|
||||
if (networkReachabilityManager.isReachable)
|
||||
{
|
||||
// The problem is not the network
|
||||
// If we have network, we retry immediately, otherwise the server may clear any cache it has computed thus far
|
||||
[self launchInitialServerSync];
|
||||
}
|
||||
@@ -2085,14 +2095,15 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
|
||||
#pragma mark - Sync filter
|
||||
|
||||
- (void)supportLazyLoadOfRoomMembers:(void (^)(BOOL supportLazyLoadOfRoomMembers))completion
|
||||
- (void)supportLazyLoadOfRoomMembersWithMatrixVersion:(MXMatrixVersions *)matrixVersions
|
||||
completion:(void (^)(BOOL supportLazyLoadOfRoomMembers))completion
|
||||
{
|
||||
void(^onUnsupportedLazyLoadOfRoomMembers)(NSError *) = ^(NSError *error) {
|
||||
completion(NO);
|
||||
};
|
||||
|
||||
// Check if the server supports LL sync filter
|
||||
MXFilterJSONModel *filter = [self syncFilterWithLazyLoadOfRoomMembers:YES];
|
||||
MXFilterJSONModel *filter = [self syncFilterWithLazyLoadOfRoomMembers:YES supportsNotificationsForThreads:NO];
|
||||
[mxSession.store filterIdForFilter:filter success:^(NSString * _Nullable filterId) {
|
||||
|
||||
if (filterId)
|
||||
@@ -2103,8 +2114,8 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
else
|
||||
{
|
||||
// Check the Matrix versions supported by the HS
|
||||
[self.mxSession supportedMatrixVersions:^(MXMatrixVersions *matrixVersions) {
|
||||
|
||||
if (matrixVersions)
|
||||
{
|
||||
if (matrixVersions.supportLazyLoadMembers)
|
||||
{
|
||||
// The HS supports LL
|
||||
@@ -2114,8 +2125,11 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
{
|
||||
onUnsupportedLazyLoadOfRoomMembers(nil);
|
||||
}
|
||||
|
||||
} failure:onUnsupportedLazyLoadOfRoomMembers];
|
||||
}
|
||||
else
|
||||
{
|
||||
completion(NO);
|
||||
}
|
||||
}
|
||||
} failure:onUnsupportedLazyLoadOfRoomMembers];
|
||||
}
|
||||
@@ -2130,28 +2144,42 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
// Check settings
|
||||
BOOL syncWithLazyLoadOfRoomMembersSetting = [MXKAppSettings standardAppSettings].syncWithLazyLoadOfRoomMembers;
|
||||
|
||||
if (syncWithLazyLoadOfRoomMembersSetting)
|
||||
{
|
||||
// Check if the server supports LL sync filter before enabling it
|
||||
[self supportLazyLoadOfRoomMembers:^(BOOL supportLazyLoadOfRoomMembers) {
|
||||
void(^buildSyncFilter)(MXMatrixVersions *) = ^(MXMatrixVersions *matrixVersions) {
|
||||
BOOL supportsNotificationsForThreads = matrixVersions ? matrixVersions.supportsNotificationsForThreads : NO;
|
||||
|
||||
if (syncWithLazyLoadOfRoomMembersSetting)
|
||||
{
|
||||
// Check if the server supports LL sync filter before enabling it
|
||||
[self supportLazyLoadOfRoomMembersWithMatrixVersion:matrixVersions completion:^(BOOL supportLazyLoadOfRoomMembers) {
|
||||
|
||||
|
||||
if (supportLazyLoadOfRoomMembers)
|
||||
{
|
||||
completion([self syncFilterWithLazyLoadOfRoomMembers:YES]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No support from the HS
|
||||
// Disable the setting. That will avoid to make a request at every startup
|
||||
[MXKAppSettings standardAppSettings].syncWithLazyLoadOfRoomMembers = NO;
|
||||
completion([self syncFilterWithLazyLoadOfRoomMembers:NO]);
|
||||
}
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
completion([self syncFilterWithLazyLoadOfRoomMembers:NO]);
|
||||
}
|
||||
if (supportLazyLoadOfRoomMembers)
|
||||
{
|
||||
completion([self syncFilterWithLazyLoadOfRoomMembers:YES
|
||||
supportsNotificationsForThreads:supportsNotificationsForThreads]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No support from the HS
|
||||
// Disable the setting. That will avoid to make a request at every startup
|
||||
[MXKAppSettings standardAppSettings].syncWithLazyLoadOfRoomMembers = NO;
|
||||
completion([self syncFilterWithLazyLoadOfRoomMembers:NO
|
||||
supportsNotificationsForThreads:supportsNotificationsForThreads]);
|
||||
}
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
completion([self syncFilterWithLazyLoadOfRoomMembers:NO supportsNotificationsForThreads:supportsNotificationsForThreads]);
|
||||
}
|
||||
};
|
||||
|
||||
[mxSession supportedMatrixVersions:^(MXMatrixVersions *matrixVersions) {
|
||||
buildSyncFilter(matrixVersions);
|
||||
} failure:^(NSError *error) {
|
||||
MXLogWarning(@"[MXAccount] buildSyncFilter: failed to get supported versions: %@", error);
|
||||
buildSyncFilter(nil);
|
||||
}];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2160,7 +2188,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
@param syncWithLazyLoadOfRoomMembers enable LL support.
|
||||
@return the sync filter to use.
|
||||
*/
|
||||
- (MXFilterJSONModel *)syncFilterWithLazyLoadOfRoomMembers:(BOOL)syncWithLazyLoadOfRoomMembers
|
||||
- (MXFilterJSONModel *)syncFilterWithLazyLoadOfRoomMembers:(BOOL)syncWithLazyLoadOfRoomMembers supportsNotificationsForThreads:(BOOL)supportsNotificationsForThreads
|
||||
{
|
||||
MXFilterJSONModel *syncFilter;
|
||||
NSUInteger limit = 10;
|
||||
@@ -2195,11 +2223,11 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
// Set that limit in the filter
|
||||
if (syncWithLazyLoadOfRoomMembers)
|
||||
{
|
||||
syncFilter = [MXFilterJSONModel syncFilterForLazyLoadingWithMessageLimit:limit];
|
||||
syncFilter = [MXFilterJSONModel syncFilterForLazyLoadingWithMessageLimit:limit unreadThreadNotifications:supportsNotificationsForThreads];
|
||||
}
|
||||
else
|
||||
{
|
||||
syncFilter = [MXFilterJSONModel syncFilterWithMessageLimit:limit];
|
||||
syncFilter = [MXFilterJSONModel syncFilterWithMessageLimit:limit unreadThreadNotifications:supportsNotificationsForThreads];
|
||||
}
|
||||
|
||||
// TODO: We could extend the filter to match other settings (self.showAllEventsInRoomHistory,
|
||||
|
||||
@@ -518,7 +518,6 @@
|
||||
|
||||
- (CGSize)textContentSize:(NSAttributedString*)attributedText removeVerticalInset:(BOOL)removeVerticalInset
|
||||
{
|
||||
|
||||
static UITextView* measurementTextView = nil;
|
||||
static UITextView* measurementTextViewWithoutInset = nil;
|
||||
|
||||
@@ -527,24 +526,23 @@
|
||||
if (!measurementTextView)
|
||||
{
|
||||
measurementTextView = [[UITextView alloc] init];
|
||||
|
||||
measurementTextViewWithoutInset = [[UITextView alloc] init];
|
||||
// Remove the container inset: this operation impacts only the vertical margin.
|
||||
// Note: consider textContainer.lineFragmentPadding to remove horizontal margin
|
||||
measurementTextViewWithoutInset.textContainerInset = UIEdgeInsetsZero;
|
||||
}
|
||||
|
||||
|
||||
// Select the right text view for measurement
|
||||
UITextView *selectedTextView = (removeVerticalInset ? measurementTextViewWithoutInset : measurementTextView);
|
||||
|
||||
|
||||
selectedTextView.frame = CGRectMake(0, 0, _maxTextViewWidth, 0);
|
||||
selectedTextView.attributedText = attributedText;
|
||||
|
||||
|
||||
// Force the layout manager to layout the text, fixes problems starting iOS 16
|
||||
[selectedTextView.layoutManager ensureLayoutForTextContainer:selectedTextView.textContainer];
|
||||
|
||||
|
||||
CGSize size = [selectedTextView sizeThatFits:selectedTextView.frame.size];
|
||||
|
||||
|
||||
// Manage the case where a string attribute has a single paragraph with a left indent
|
||||
// In this case, [UITextView sizeThatFits] ignores the indent and return the width
|
||||
// of the text only.
|
||||
@@ -557,8 +555,10 @@
|
||||
{
|
||||
size.width = size.width + paragraphStyle.headIndent;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
|
||||
@@ -985,8 +985,19 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
else if (nil == localEcho)
|
||||
{
|
||||
// Process here incoming events, and outgoing events sent from another device.
|
||||
[self queueEventForProcessing:event withRoomState:roomState direction:MXTimelineDirectionForwards];
|
||||
[self processQueuedEvents:nil];
|
||||
if (self.threadId == nil && event.isInThread)
|
||||
{
|
||||
NSInteger index = [self indexOfCellDataWithEventId:event.relatesTo.eventId];
|
||||
if (index != NSNotFound)
|
||||
{
|
||||
[self reloadNotifying:NO];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[self queueEventForProcessing:event withRoomState:roomState direction:MXTimelineDirectionForwards];
|
||||
[self processQueuedEvents:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
}];
|
||||
@@ -1373,6 +1384,11 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
// ignore the event
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Ignore voice message related to an actual voice broadcast.
|
||||
if (event.content[VoiceBroadcastSettings.voiceBroadcastContentKeyChunkType] != nil) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for undecryptable messages that were sent while the user was not in the room and hide them
|
||||
@@ -2358,15 +2374,61 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
|
||||
// Update cell data we have received a read receipt for
|
||||
NSArray *readEventIds = receiptEvent.readReceiptEventIds;
|
||||
for (NSString* eventId in readEventIds)
|
||||
if (RiotSettings.shared.enableThreads)
|
||||
{
|
||||
MXKRoomBubbleCellData *cellData = [self cellDataOfEventWithEventId:eventId];
|
||||
if (cellData)
|
||||
NSArray *readThreadIds = receiptEvent.readReceiptThreadIds;
|
||||
for (int i = 0 ; i < readEventIds.count ; i++)
|
||||
{
|
||||
NSString *eventId = readEventIds[i];
|
||||
MXKRoomBubbleCellData *cellData = [self cellDataOfEventWithEventId:eventId];
|
||||
if (cellData)
|
||||
{
|
||||
if ([readThreadIds[i] isEqualToString:kMXEventUnthreaded])
|
||||
{
|
||||
// Unthreaded RR must be propagated through all threads.
|
||||
[self.mxSession.threadingService allThreadsInRoomWithId:self.roomId onlyParticipated:NO completion:^(NSArray<id<MXThreadProtocol>> *threads) {
|
||||
NSMutableArray *threadIds = [NSMutableArray arrayWithObject:kMXEventTimelineMain];
|
||||
for (id<MXThreadProtocol> thread in threads)
|
||||
{
|
||||
[threadIds addObject:thread.id];
|
||||
}
|
||||
|
||||
for (NSString *threadId in threadIds)
|
||||
{
|
||||
@synchronized(self->bubbles)
|
||||
{
|
||||
dispatch_group_enter(dispatchGroup);
|
||||
[self addReadReceiptsForEvent:eventId threadId:threadId inCellDatas:self->bubbles startingAtCellData:cellData completion:^{
|
||||
dispatch_group_leave(dispatchGroup);
|
||||
}];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString *threadId = readThreadIds[i];
|
||||
@synchronized(self->bubbles)
|
||||
{
|
||||
dispatch_group_enter(dispatchGroup);
|
||||
[self addReadReceiptsForEvent:eventId threadId:threadId inCellDatas:self->bubbles startingAtCellData:cellData completion:^{
|
||||
dispatch_group_leave(dispatchGroup);
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If
|
||||
for (NSString *eventId in readEventIds)
|
||||
{
|
||||
MXKRoomBubbleCellData *cellData = [self cellDataOfEventWithEventId:eventId];
|
||||
@synchronized(self->bubbles)
|
||||
{
|
||||
dispatch_group_enter(dispatchGroup);
|
||||
[self addReadReceiptsForEvent:eventId inCellDatas:self->bubbles startingAtCellData:cellData completion:^{
|
||||
[self addReadReceiptsForEvent:eventId threadId:kMXEventTimelineMain inCellDatas:self->bubbles startingAtCellData:cellData completion:^{
|
||||
dispatch_group_leave(dispatchGroup);
|
||||
}];
|
||||
}
|
||||
@@ -3512,7 +3574,10 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
@autoreleasepool
|
||||
{
|
||||
dispatch_group_enter(dispatchGroup);
|
||||
[self addReadReceiptsForEvent:queuedEvent.event.eventId inCellDatas:self->bubblesSnapshot startingAtCellData:self->eventIdToBubbleMap[queuedEvent.event.eventId] completion:^{
|
||||
[self addReadReceiptsForEvent:queuedEvent.event.eventId
|
||||
threadId:queuedEvent.event.threadId
|
||||
inCellDatas:self->bubblesSnapshot
|
||||
startingAtCellData:self->eventIdToBubbleMap[queuedEvent.event.eventId] completion:^{
|
||||
dispatch_group_leave(dispatchGroup);
|
||||
}];
|
||||
}
|
||||
@@ -3667,16 +3732,22 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
If the event is not displayed, read receipts will be added to a previous displayed message.
|
||||
|
||||
@param eventId the id of the event.
|
||||
@param threadId the Id of the thread related of the event.
|
||||
@param cellDatas the working array of cell datas.
|
||||
@param cellData the original cell data the event belongs to.
|
||||
@param completion completion block
|
||||
*/
|
||||
- (void)addReadReceiptsForEvent:(NSString*)eventId inCellDatas:(NSArray<id<MXKRoomBubbleCellDataStoring>>*)cellDatas startingAtCellData:(id<MXKRoomBubbleCellDataStoring>)cellData completion:(void (^)(void))completion
|
||||
- (void)addReadReceiptsForEvent:(NSString*)eventId
|
||||
threadId:(NSString *)threadId
|
||||
inCellDatas:(NSArray<id<MXKRoomBubbleCellDataStoring>>*)cellDatas
|
||||
startingAtCellData:(id<MXKRoomBubbleCellDataStoring>)cellData
|
||||
completion:(void (^)(void))completion
|
||||
{
|
||||
if (self.showBubbleReceipts)
|
||||
{
|
||||
if (self.room)
|
||||
{
|
||||
[self.room getEventReceipts:eventId sorted:YES completion:^(NSArray<MXReceiptData *> * _Nonnull readReceipts) {
|
||||
[self.room getEventReceipts:eventId threadId:threadId sorted:YES completion:^(NSArray<MXReceiptData *> * _Nonnull readReceipts) {
|
||||
if (readReceipts.count)
|
||||
{
|
||||
NSInteger cellDataIndex = [cellDatas indexOfObject:cellData];
|
||||
@@ -3686,6 +3757,14 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!RiotSettings.shared.enableThreads)
|
||||
{
|
||||
// If threads are disabled, we may have several threaded RR with same userId
|
||||
// but different threadId within the same timeline.
|
||||
// We just need to keep the latest one.
|
||||
[self clearDuplicatedReadReceiptsInCellDatas:cellDatas];
|
||||
}
|
||||
|
||||
if (completion)
|
||||
{
|
||||
completion();
|
||||
@@ -3771,6 +3850,45 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Clear all potential duplicated RR with same user ID within a given list of cell data.
|
||||
|
||||
This is needed for client with threads disabled in order to clean threaded RRs.
|
||||
|
||||
@param cellDatas the working array of cell datas.
|
||||
*/
|
||||
- (void)clearDuplicatedReadReceiptsInCellDatas:(NSArray<id<MXKRoomBubbleCellDataStoring>>*)cellDatas
|
||||
{
|
||||
NSMutableSet<NSString *> *seenUserIds = [NSMutableSet set];
|
||||
for (id<MXKRoomBubbleCellDataStoring> cellData in cellDatas.reverseObjectEnumerator)
|
||||
{
|
||||
if ([cellData isKindOfClass:MXKRoomBubbleCellData.class])
|
||||
{
|
||||
MXKRoomBubbleCellData *roomBubbleCellData = (MXKRoomBubbleCellData*)cellData;
|
||||
|
||||
for (MXKRoomBubbleComponent *component in roomBubbleCellData.bubbleComponents)
|
||||
{
|
||||
if (component.attributedTextMessage)
|
||||
{
|
||||
if (roomBubbleCellData.readReceipts[component.event.eventId])
|
||||
{
|
||||
NSArray<MXReceiptData*> *currentReadReceipts = roomBubbleCellData.readReceipts[component.event.eventId];
|
||||
NSMutableArray<MXReceiptData*> *newReadReceipts = [NSMutableArray array];
|
||||
for (MXReceiptData *readReceipt in currentReadReceipts)
|
||||
{
|
||||
if (![seenUserIds containsObject:readReceipt.userId])
|
||||
{
|
||||
[newReadReceipts addObject:readReceipt];
|
||||
[seenUserIds addObject:readReceipt.userId];
|
||||
}
|
||||
}
|
||||
[self updateCellData:roomBubbleCellData withReadReceipts:newReadReceipts forEventId:component.event.eventId];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
|
||||
Reference in New Issue
Block a user