Skip to content

Commit

Permalink
Merge branch 'release/0.22.5/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Anderas committed Mar 8, 2022
2 parents 9f5477e + e012260 commit 8568c45
Show file tree
Hide file tree
Showing 16 changed files with 161 additions and 36 deletions.
15 changes: 15 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## Changes in 0.22.5 (2022-03-08)

🙌 Improvements

- Room data filters: strict matches support ([#1379](https://github.com/matrix-org/matrix-ios-sdk/pull/1379))
- Analytics: Add event composition tracking and isSpace for joined room events. ([#5365](https://github.com/vector-im/element-ios/issues/5365))
- MXEvent+Extensions: Do not highlight any event that the current user sent. ([#5552](https://github.com/vector-im/element-ios/issues/5552))

🐛 Bugfixes

- Room: fix crash on members count not being always properly set ([#4949](https://github.com/vector-im/element-ios/issues/4949))
- MXSuggestedRoomListDataFetcher: hide suggested rooms that a user is already part of ([#5276](https://github.com/vector-im/element-ios/issues/5276))
- MXFileStore: Do not reuse room files if the room is marked for deletion ([#5717](https://github.com/vector-im/element-ios/issues/5717))


## Changes in 0.22.4 (2022-02-25)

🙌 Improvements
Expand Down
2 changes: 1 addition & 1 deletion MatrixSDK.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "MatrixSDK"
s.version = "0.22.4"
s.version = "0.22.5"
s.summary = "The iOS SDK to build apps compatible with Matrix (https://www.matrix.org)"

s.description = <<-DESC
Expand Down
2 changes: 1 addition & 1 deletion MatrixSDK.xcodeproj/xcshareddata/IDETemplateMacros.plist
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<dict>
<key>FILEHEADER</key>
<string>
// Copyright 2021 The Matrix.org Foundation C.I.C
// Copyright ___YEAR___ The Matrix.org Foundation C.I.C
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down
5 changes: 5 additions & 0 deletions MatrixSDK/Categories/MXEvent+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public extension MXEvent {
/// - Parameter session: session instance to read notification rules from
/// - Returns: true if clients should highlight the receiver event
func shouldBeHighlighted(inSession session: MXSession) -> Bool {
if sender == session.myUserId {
// do not highlight any event that the current user sent
return false
}

let displayNameChecker = MXPushRuleDisplayNameCondtionChecker(matrixSession: session,
currentUserDisplayName: nil)

Expand Down
71 changes: 50 additions & 21 deletions MatrixSDK/Data/MXRoom.m
Original file line number Diff line number Diff line change
Expand Up @@ -782,37 +782,66 @@ - (MXHTTPOperation*)_sendEventOfType:(MXEventTypeString)eventTypeString
failure:(void (^)(NSError *error))failure
{
NSDictionary *newContent = content;
if (threadId && MXSDKOptions.sharedInstance.enableThreads)
BOOL inThread = NO;
BOOL startsThread = NO;
BOOL isReply = content[kMXEventRelationRelatesToKey][@"m.in_reply_to"][@"event_id"] != nil;
BOOL isEditing = [content[kMXEventRelationRelatesToKey][@"rel_type"] isEqualToString:MXEventRelationTypeReplace];
if (MXSDKOptions.sharedInstance.enableThreads)
{
NSMutableDictionary *mutableContent = [newContent mutableDeepCopy];
BOOL isRealReply = content[kMXEventRelationRelatesToKey][@"m.in_reply_to"][@"event_id"] != nil;
if (isRealReply)
if (threadId)
{
mutableContent[kMXEventRelationRelatesToKey][@"m.in_reply_to"][@"m.render_in"] = @[MXEventRelationTypeThread];
}
else
{
NSString *lastEventId = [mxSession.threadingService threadWithId:threadId].lastMessage.eventId;
NSString *replyToEventId = lastEventId ?: threadId;

if (mutableContent[kMXEventRelationRelatesToKey])
inThread = YES;
NSMutableDictionary *mutableContent = [newContent mutableDeepCopy];
if (isReply)
{
mutableContent[kMXEventRelationRelatesToKey][@"m.in_reply_to"] = @{
@"event_id": replyToEventId
};
// this will be a real in-thread reply
mutableContent[kMXEventRelationRelatesToKey][@"m.in_reply_to"][@"m.render_in"] = @[MXEventRelationTypeThread];
}
else
{
mutableContent[kMXEventRelationRelatesToKey] = @{
@"m.in_reply_to": @{
// this will look like a reply, but only an in-thread event
NSString *lastEventId = [mxSession.threadingService threadWithId:threadId].lastMessage.eventId;
startsThread = lastEventId == nil;
NSString *replyToEventId = lastEventId ?: threadId;

if (mutableContent[kMXEventRelationRelatesToKey])
{
mutableContent[kMXEventRelationRelatesToKey][@"m.in_reply_to"] = @{
@"event_id": replyToEventId
};
}
else
{
mutableContent[kMXEventRelationRelatesToKey] = @{
@"m.in_reply_to": @{
@"event_id": replyToEventId
}
};
}
};
}
}
newContent = mutableContent;
}
else if (isEditing)
{
// detect in-thread edits
NSString *editedEventId = content[kMXEventRelationRelatesToKey][@"event_id"];
MXEvent *editedEvent = [self.mxSession.store eventWithEventId:editedEventId inRoom:self.roomId];
inThread = editedEvent.isInThread;
}
newContent = mutableContent;
}
return [mxSession.matrixRestClient sendEventToRoom:self.roomId threadId:threadId eventType:eventTypeString content:newContent txnId:txnId success:success failure:failure];
return [mxSession.matrixRestClient sendEventToRoom:self.roomId threadId:threadId eventType:eventTypeString content:newContent txnId:txnId success:^(NSString *eventId) {

// track event composed
[MXSDKOptions.sharedInstance.analyticsDelegate trackComposerEventInThread:inThread
isEditing:isEditing
isReply:isReply
startsThread:startsThread];

if (success)
{
success(eventId);
}
} failure:failure];
}

- (MXHTTPOperation*)sendStateEventOfType:(MXEventTypeString)eventTypeString
Expand Down
4 changes: 3 additions & 1 deletion MatrixSDK/Data/MXRoomState.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ - (id)initWithRoomId:(NSString*)roomId

stateEvents = [NSMutableDictionary dictionary];
_members = [[MXRoomMembers alloc] initWithRoomState:self andMatrixSession:mxSession];
_membersCount = [MXRoomMembersCount new];
_membersCount = [[MXRoomMembersCount alloc] initWithMembers:_members.members.count
joined:_members.joinedMembers.count
invited:[_members membersWithMembership:MXMembershipInvite].count];
roomAliases = [NSMutableDictionary dictionary];
thirdPartyInvites = [NSMutableDictionary dictionary];
membersWithThirdPartyInviteTokenCache = [NSMutableDictionary dictionary];
Expand Down
13 changes: 11 additions & 2 deletions MatrixSDK/Data/RoomList/Common/MXRoomListDataFilterable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,20 @@ extension MXRoomListDataFilterable {
MXMembership.unknown.rawValue)
predicates.append(memberPredicate)
}

if !filterOptions.dataTypes.isEmpty {
let predicate = NSPredicate(format: "(%K & %d) != 0",
let predicate: NSPredicate
if filterOptions.strictMatches {
predicate = NSPredicate(format: "(%K & %d) == %d",
#keyPath(MXRoomSummaryProtocol.dataTypes),
filterOptions.dataTypes.rawValue,
filterOptions.dataTypes.rawValue)

} else {
predicate = NSPredicate(format: "(%K & %d) != 0",
#keyPath(MXRoomSummaryProtocol.dataTypes),
filterOptions.dataTypes.rawValue)
}
predicates.append(predicate)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ import Foundation
internal class MXSuggestedRoomListDataFetcher: NSObject, MXRoomListDataFetcher {

internal let fetchOptions: MXRoomListDataFetchOptions
private weak var session: MXSession?
private let spaceService: MXSpaceService
private let cache: MXSuggestedRoomListDataCache

private var allRoomSummaries: [MXRoomSummaryProtocol] = []

private let multicastDelegate: MXMulticastDelegate<MXRoomListDataFetcherDelegate> = MXMulticastDelegate()
private var space: MXSpace? {
didSet {
Expand All @@ -34,6 +37,7 @@ internal class MXSuggestedRoomListDataFetcher: NSObject, MXRoomListDataFetcher {
}
private var spaceEventsListener: Any?
private var currentHttpOperation: MXHTTPOperation?
private var sessionDidSyncObserver: Any?

internal private(set) var data: MXRoomListData? {
didSet {
Expand All @@ -48,9 +52,11 @@ internal class MXSuggestedRoomListDataFetcher: NSObject, MXRoomListDataFetcher {
}

internal init(fetchOptions: MXRoomListDataFetchOptions,
session: MXSession,
spaceService: MXSpaceService,
cache: MXSuggestedRoomListDataCache = .shared) {
self.fetchOptions = fetchOptions
self.session = session
self.spaceService = spaceService
self.cache = cache
self.space = fetchOptions.filterOptions.space
Expand Down Expand Up @@ -88,10 +94,16 @@ internal class MXSuggestedRoomListDataFetcher: NSObject, MXRoomListDataFetcher {
}
self.refresh()
})
sessionDidSyncObserver = NotificationCenter.default.addObserver(forName: .mxSessionDidSync, object: nil, queue: OperationQueue.main) { [weak self] notification in
self?.updateData()
}
}

private func removeDataObservers(for space: MXSpace?) {
space?.room?.removeListener(spaceEventsListener)
if let observer = sessionDidSyncObserver {
NotificationCenter.default.removeObserver(observer)
}
}

internal func paginate() {
Expand Down Expand Up @@ -201,12 +213,24 @@ internal class MXSuggestedRoomListDataFetcher: NSObject, MXRoomListDataFetcher {

private func computeData(from childInfos: [MXSpaceChildInfo]) {
// create room summary objects
var rooms: [MXRoomSummaryProtocol] = childInfos.map({ MXRoomSummary(spaceChildInfo: $0) })
var rooms: [MXRoomSummaryProtocol] = childInfos.compactMap({ MXRoomSummary(spaceChildInfo: $0) })
rooms = filterRooms(rooms)
rooms = sortRooms(rooms)
allRoomSummaries = rooms
updateData()
}

private func updateData() {
let summaries = allRoomSummaries.filter { summary in
guard let room = self.session?.room(withRoomId: summary.roomId), let localsummary = room.summary else {
return true
}
return localsummary.membership != .join && localsummary.membership != .invite && localsummary.membership != .ban
}

// we don't know total rooms count, passing as current number of rooms
self.data = MXRoomListData(rooms: rooms,
counts: MXStoreRoomListDataCounts(withRooms: rooms,
self.data = MXRoomListData(rooms: summaries,
counts: MXStoreRoomListDataCounts(withRooms: summaries,
total: nil),
paginationOptions: fetchOptions.paginationOptions)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,18 @@ extension MXCoreDataRoomListDataFetcher: MXRoomListDataFilterable {

// data types
if !filterOptions.dataTypes.isEmpty {
let predicate = NSPredicate(format: "(%K & %d) != 0",
let predicate: NSPredicate
if filterOptions.strictMatches {
predicate = NSPredicate(format: "(%K & %d) == %d",
#keyPath(MXRoomSummaryMO.s_dataTypesInt),
filterOptions.dataTypes.rawValue,
filterOptions.dataTypes.rawValue)

} else {
predicate = NSPredicate(format: "(%K & %d) != 0",
#keyPath(MXRoomSummaryMO.s_dataTypesInt),
filterOptions.dataTypes.rawValue)
}
predicates.append(predicate)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ public class MXCoreDataRoomListDataManager: NSObject, MXRoomListDataManager {
assert(options.async, "[MXCoreDataRoomListDataManager] cannot work with sync fetch options")

if options.filterOptions.onlySuggested {
guard let spaceService = session?.spaceService else {
guard let session = session, let spaceService = session.spaceService else {
fatalError("[MXCoreDataRoomListDataManager] Session has no spaceService")
}
return MXSuggestedRoomListDataFetcher(fetchOptions: options,
session: session,
spaceService: spaceService)
}
guard let session = session, let store = session.store else {
Expand Down
9 changes: 8 additions & 1 deletion MatrixSDK/Data/RoomList/MXRoomListDataFilterOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public struct MXRoomListDataFilterOptions: Equatable {
/// Flag to hide any rooms where the user's membership is unknown. This has no effect when `onlySuggested` is `true`.
/// When set to `false`, rooms that have been cached during peeking may be included in the filtered results.
public let hideUnknownMembershipRooms: Bool

/// Flag to show only rooms that matches all the provided `dataTypes`. This has no effect when `onlySuggested` is `true`
public let strictMatches: Bool

/// Initializer
/// - Parameters:
Expand All @@ -52,19 +55,23 @@ public struct MXRoomListDataFilterOptions: Equatable {
/// - query: search query
/// - space: active space
/// - showAllRoomsInHomeSpace: flag to show all rooms in home space (when `space` is not provided)
/// - hideUnknownMembershipRooms: flag to hide any rooms where the user's membership is unknown
/// - strictMatches: flag to show only rooms that matches all the provided data types
public init(dataTypes: MXRoomSummaryDataTypes = MXRoomListDataFilterOptions.emptyDataTypes,
notDataTypes: MXRoomSummaryDataTypes = [.hidden, .conferenceUser, .space],
onlySuggested: Bool = false,
query: String? = nil,
space: MXSpace? = nil,
showAllRoomsInHomeSpace: Bool,
hideUnknownMembershipRooms: Bool = true) {
hideUnknownMembershipRooms: Bool = true,
strictMatches: Bool = false) {
self.dataTypes = dataTypes
self.notDataTypes = notDataTypes
self.onlySuggested = onlySuggested
self.query = query
self.space = space
self.showAllRoomsInHomeSpace = showAllRoomsInHomeSpace
self.hideUnknownMembershipRooms = hideUnknownMembershipRooms
self.strictMatches = strictMatches
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ public class MXStoreRoomListDataManager: NSObject, MXRoomListDataManager {

public func fetcher(withOptions options: MXRoomListDataFetchOptions) -> MXRoomListDataFetcher {
if options.filterOptions.onlySuggested {
guard let spaceService = session?.spaceService else {
guard let session = session, let spaceService = session.spaceService else {
fatalError("[MXStoreRoomListDataManager] Session has no spaceService")
}
return MXSuggestedRoomListDataFetcher(fetchOptions: options,
session: session,
spaceService: spaceService)
}
guard let store = session?.store else {
Expand Down
3 changes: 2 additions & 1 deletion MatrixSDK/Data/Store/MXFileStore/MXFileStore.m
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,8 @@ - (MXMemoryRoomStore*)getOrCreateRoomStore:(NSString*)roomId
// A per-room lock might be better.
@synchronized (roomStores) {
NSString *roomFile = [self messagesFileForRoom:roomId forBackup:NO];
if ([[NSFileManager defaultManager] fileExistsAtPath:roomFile])
BOOL isMarkedForDeletion = [roomsToCommitForDeletion containsObject:roomId];
if (!isMarkedForDeletion && [[NSFileManager defaultManager] fileExistsAtPath:roomFile])
{
@try
{
Expand Down
4 changes: 4 additions & 0 deletions MatrixSDK/MXSession.m
Original file line number Diff line number Diff line change
Expand Up @@ -2302,7 +2302,9 @@ - (void)onJoinedRoom:(NSString*)roomId success:(void (^)(MXRoom *room))success
// The /sync corresponding to this join may have happened before the
// homeserver answer to the joinRoom request.
success(room);
BOOL isSpace = room.summary.roomType == MXRoomTypeSpace;
[MXSDKOptions.sharedInstance.analyticsDelegate trackJoinedRoomAsDM:room.summary.isDirect
isSpace:isSpace
memberCount:room.summary.membersCount.joined];
}
else
Expand All @@ -2317,7 +2319,9 @@ - (void)onJoinedRoom:(NSString*)roomId success:(void (^)(MXRoom *room))success
{
success(room);
[[NSNotificationCenter defaultCenter] removeObserver:initialSyncObserver];
BOOL isSpace = room.summary.roomType == MXRoomTypeSpace;
[MXSDKOptions.sharedInstance.analyticsDelegate trackJoinedRoomAsDM:room.summary.isDirect
isSpace:isSpace
memberCount:room.summary.membersCount.joined];
}
}];
Expand Down
2 changes: 1 addition & 1 deletion MatrixSDK/MatrixSDKVersion.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@

#import <Foundation/Foundation.h>

NSString *const MatrixSDKVersion = @"0.22.4";
NSString *const MatrixSDKVersion = @"0.22.5";
Loading

0 comments on commit 8568c45

Please sign in to comment.