Periphery cleanup (#5893)

This commit is contained in:
Mauro
2026-07-20 11:16:11 +02:00
committed by GitHub
parent 175aca596e
commit 9093631f8b
275 changed files with 381 additions and 2268 deletions
@@ -9,7 +9,7 @@ import Foundation
import MatrixRustSDK
/// The rule used for users wishing to join a room.
public nonisolated enum JoinRule: Equatable, Hashable, Sendable {
nonisolated enum JoinRule: Equatable, Hashable, Sendable {
/// Anyone can join the room without any prior action.
case `public`
/// A user who wishes to join the room must first receive an invite.
@@ -52,7 +52,7 @@ public nonisolated enum JoinRule: Equatable, Hashable, Sendable {
}
/// An allow rule which defines a condition that allows joining a room.
public nonisolated enum AllowRule: Equatable, Hashable, Sendable {
nonisolated enum AllowRule: Equatable, Hashable, Sendable {
/// Only a member of the `room_id` Room can join the one this rule is used in.
case roomMembership(roomID: String)
/// A custom allow rule implementation, containing its JSON representation as a `String`.
@@ -18,7 +18,6 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol {
private let analyticsService: AnalyticsServiceProtocol
private let eventStringBuilder: RoomEventStringBuilder
// periphery:ignore - required for instance retention in the rust codebase
private var roomInfoObservationToken: TaskHandle?
// periphery:ignore - required for instance retention in the rust codebase
private var typingNotificationObservationToken: TaskHandle?
@@ -43,12 +42,6 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol {
/// The predecessor is set on room creation and never changes, so we lazily store it.
lazy var predecessorRoom = room.predecessorRoom()
/// The successor may change over time, so we access it dynamically.
/// It's suggested to observe it through the `infoPublisher`
var successorRoom: SuccessorRoom? {
room.successorRoom()
}
let timeline: TimelineProxyProtocol
private let infoSubject: CurrentValueSubject<RoomInfoProxyProtocol, Never>
@@ -301,16 +294,6 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol {
}
}
func redact(_ eventID: String) async -> Result<Void, RoomProxyError> {
do {
try await room.redact(eventId: eventID, reason: nil)
return .success(())
} catch {
MXLog.error("Failed redacting eventID: \(eventID) with error: \(error)")
return .failure(.sdkError(error))
}
}
func reportContent(_ eventID: String, reason: String?) async -> Result<Void, RoomProxyError> {
do {
try await room.reportContent(eventId: eventID, reason: reason)
@@ -442,16 +425,6 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol {
}
}
func edit(eventID: String, newContent: RoomMessageEventContentWithoutRelation) async -> Result<Void, RoomProxyError> {
do {
try await room.edit(eventId: eventID, newContent: newContent)
return .success(())
} catch {
MXLog.error("Failed editing event id \(eventID), in room \(id) with error: \(error)")
return .failure(.sdkError(error))
}
}
func sendTypingNotification(isTyping: Bool) async -> Result<Void, RoomProxyError> {
do {
try await room.typingNotice(isTyping: isTyping)
@@ -581,15 +554,6 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol {
// MARK: - Power Levels
func powerLevels() async -> Result<RoomPowerLevelsProxyProtocol?, RoomProxyError> {
do {
return try await .success(RoomPowerLevelsProxy(room.getPowerLevels()))
} catch {
MXLog.error("Failed building the current power level settings: \(error)")
return .failure(.sdkError(error))
}
}
func applyPowerLevelChanges(_ changes: RoomPowerLevelChanges) async -> Result<Void, RoomProxyError> {
do {
return try await .success(room.applyPowerLevelChanges(changes: changes))
@@ -609,15 +573,6 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol {
}
}
func suggestedRole(for userID: String) async -> Result<RoomMemberRole, RoomProxyError> {
do {
return try await .success(room.suggestedRoleForUser(userId: userID))
} catch {
MXLog.error("Failed getting a user's role: \(error)")
return .failure(.sdkError(error))
}
}
func updatePowerLevelsForUsers(_ updates: [(userID: String, powerLevel: Int64)]) async -> Result<Void, RoomProxyError> {
do {
let updates = updates.map { UserPowerLevelUpdate(userId: $0.userID, powerLevel: $0.powerLevel) }
@@ -16,6 +16,8 @@ nonisolated struct RoomInfoProxy: RoomInfoProxyProtocol {
roomInfo.id
}
// periphery:ignore - might be useful to have
var creators: [String] {
roomInfo.creators ?? []
}
@@ -24,6 +26,8 @@ nonisolated struct RoomInfoProxy: RoomInfoProxyProtocol {
roomInfo.displayName
}
// periphery:ignore - might be useful to have
var rawName: String? {
roomInfo.rawName
}
@@ -78,6 +82,8 @@ nonisolated struct RoomInfoProxy: RoomInfoProxyProtocol {
roomInfo.membership
}
// periphery:ignore - might be useful to have
var inviter: RoomMemberProxyProtocol? {
roomInfo.inviter.map(RoomMemberProxy.init)
}
@@ -90,6 +96,8 @@ nonisolated struct RoomInfoProxy: RoomInfoProxyProtocol {
Int(roomInfo.activeMembersCount)
}
// periphery:ignore - might be useful to have
var invitedMembersCount: Int {
Int(roomInfo.invitedMembersCount)
}
@@ -98,14 +106,20 @@ nonisolated struct RoomInfoProxy: RoomInfoProxyProtocol {
Int(roomInfo.joinedMembersCount)
}
// periphery:ignore - might be useful to have
var highlightCount: Int {
Int(roomInfo.highlightCount)
}
// periphery:ignore - might be useful to have
var notificationCount: Int {
Int(roomInfo.notificationCount)
}
// periphery:ignore - might be useful to have
var cachedUserDefinedNotificationMode: RoomNotificationMode? {
roomInfo.cachedUserDefinedNotificationMode
}
@@ -129,18 +143,26 @@ nonisolated struct RoomInfoProxy: RoomInfoProxyProtocol {
roomInfo.activeRoomCallParticipants
}
// periphery:ignore - might be useful to have
var isMarkedUnread: Bool {
roomInfo.isMarkedUnread
}
// periphery:ignore - might be useful to have
var unreadMessagesCount: UInt {
UInt(roomInfo.numUnreadMessages)
}
// periphery:ignore - might be useful to have
var unreadNotificationsCount: UInt {
UInt(roomInfo.numUnreadNotifications)
}
// periphery:ignore - might be useful to have
var unreadMentionsCount: UInt {
UInt(roomInfo.numUnreadMentions)
}
@@ -27,8 +27,10 @@ nonisolated protocol BaseRoomInfoProxyProtocol: Sendable {
// sourcery: AutoMockable
nonisolated protocol RoomInfoProxyProtocol: BaseRoomInfoProxyProtocol {
var id: String { get }
// periphery:ignore - might be useful to have
var creators: [String] { get }
var displayName: String? { get }
// periphery:ignore - might be useful to have
var rawName: String? { get }
var topic: String? { get }
/// The room's avatar URL. Use this for editing and favour ``avatar`` for display.
@@ -43,20 +45,29 @@ nonisolated protocol RoomInfoProxyProtocol: BaseRoomInfoProxyProtocol {
var canonicalAlias: String? { get }
var alternativeAliases: [String] { get }
var membership: Membership { get }
// periphery:ignore - might be useful to have
var inviter: RoomMemberProxyProtocol? { get }
var activeMembersCount: Int { get }
// periphery:ignore - might be useful to have
var invitedMembersCount: Int { get }
var joinedMembersCount: Int { get }
// periphery:ignore - might be useful to have
var highlightCount: Int { get }
// periphery:ignore - might be useful to have
var notificationCount: Int { get }
// periphery:ignore - might be useful to have
var cachedUserDefinedNotificationMode: RoomNotificationMode? { get }
var hasRoomCall: Bool { get }
var activeRoomCallIntent: CallIntent? { get }
var activeRoomCallParticipants: [String] { get }
// periphery:ignore - might be useful to have
var isMarkedUnread: Bool { get }
// periphery:ignore - might be useful to have
var unreadMessagesCount: UInt { get }
// periphery:ignore - might be useful to have
var unreadNotificationsCount: UInt { get }
// periphery:ignore - might be useful to have
var unreadMentionsCount: UInt { get }
var fullyReadEventID: String? { get }
var pinnedEventIDs: Set<String> { get }
@@ -56,6 +56,7 @@ final nonisolated class RoomMemberProxy: RoomMemberProxyProtocol {
.init(rustPowerLevel: member.powerLevel)
}
// periphery:ignore - might be useful to have
var isServiceMember: Bool {
member.isServiceMember
}
@@ -26,6 +26,7 @@ nonisolated protocol RoomMemberProxyProtocol: AnyObject, Sendable {
var powerLevel: RoomPowerLevel { get }
// periphery:ignore - might be useful to have
var isServiceMember: Bool { get }
}
@@ -20,10 +20,6 @@ nonisolated enum RoomPowerLevel: Hashable, Comparable {
self = .value(value)
}
init(value: Int64) {
self = .value(Int(value))
}
var rustPowerLevel: PowerLevel {
switch self {
case .infinite: .infinite
@@ -24,17 +24,6 @@ protocol RoomPowerLevelsProxyProtocol: Sendable {
func canOwnUserPinOrUnpin() -> Bool
func canOwnUserJoinCall() -> Bool
func canOwnUserEditRolesAndPermissions() -> Bool
func canUser(userID: String, sendMessage messageType: MessageLikeEventType) -> Result<Bool, RoomProxyError>
func canUser(userID: String, sendStateEvent event: StateEventType) -> Result<Bool, RoomProxyError>
func canUserInvite(userID: String) -> Result<Bool, RoomProxyError>
func canUserRedactOther(userID: String) -> Result<Bool, RoomProxyError>
func canUserRedactOwn(userID: String) -> Result<Bool, RoomProxyError>
func canUserKick(userID: String) -> Result<Bool, RoomProxyError>
func canUserBan(userID: String) -> Result<Bool, RoomProxyError>
func canUserTriggerRoomNotification(userID: String) -> Result<Bool, RoomProxyError>
func canUserPinOrUnpin(userID: String) -> Result<Bool, RoomProxyError>
func canUserJoinCall(userID: String) -> Result<Bool, RoomProxyError>
}
// MARK: - Helpers
@@ -70,94 +70,4 @@ nonisolated struct RoomPowerLevelsProxy: RoomPowerLevelsProxyProtocol {
func canOwnUserEditRolesAndPermissions() -> Bool {
powerLevels.canOwnUserSendState(stateEvent: .roomPowerLevels)
}
func canUser(userID: String, sendMessage messageType: MessageLikeEventType) -> Result<Bool, RoomProxyError> {
do {
return try .success(powerLevels.canUserSendMessage(userId: userID, message: messageType))
} catch {
MXLog.error("Failed checking if the user can send message with error: \(error)")
return .failure(.sdkError(error))
}
}
func canUser(userID: String, sendStateEvent event: StateEventType) -> Result<Bool, RoomProxyError> {
do {
return try .success(powerLevels.canUserSendState(userId: userID, stateEvent: event))
} catch {
MXLog.error("Failed checking if the user can send \(event) with error: \(error)")
return .failure(.sdkError(error))
}
}
func canUserInvite(userID: String) -> Result<Bool, RoomProxyError> {
do {
return try .success(powerLevels.canUserInvite(userId: userID))
} catch {
MXLog.error("Failed checking if the user can invite with error: \(error)")
return .failure(.sdkError(error))
}
}
func canUserRedactOther(userID: String) -> Result<Bool, RoomProxyError> {
do {
return try .success(powerLevels.canUserRedactOther(userId: userID))
} catch {
MXLog.error("Failed checking if the user can redact others with error: \(error)")
return .failure(.sdkError(error))
}
}
func canUserRedactOwn(userID: String) -> Result<Bool, RoomProxyError> {
do {
return try .success(powerLevels.canUserRedactOwn(userId: userID))
} catch {
MXLog.error("Failed checking if the user can redact self with error: \(error)")
return .failure(.sdkError(error))
}
}
func canUserKick(userID: String) -> Result<Bool, RoomProxyError> {
do {
return try .success(powerLevels.canUserKick(userId: userID))
} catch {
MXLog.error("Failed checking if the user can kick with error: \(error)")
return .failure(.sdkError(error))
}
}
func canUserBan(userID: String) -> Result<Bool, RoomProxyError> {
do {
return try .success(powerLevels.canUserBan(userId: userID))
} catch {
MXLog.error("Failed checking if the user can ban with error: \(error)")
return .failure(.sdkError(error))
}
}
func canUserTriggerRoomNotification(userID: String) -> Result<Bool, RoomProxyError> {
do {
return try .success(powerLevels.canUserTriggerRoomNotification(userId: userID))
} catch {
MXLog.error("Failed checking if the user can trigger room notification with error: \(error)")
return .failure(.sdkError(error))
}
}
func canUserPinOrUnpin(userID: String) -> Result<Bool, RoomProxyError> {
do {
return try .success(powerLevels.canUserPinUnpin(userId: userID))
} catch {
MXLog.error("Failed checking if the user can pin or unnpin: \(error)")
return .failure(.sdkError(error))
}
}
func canUserJoinCall(userID: String) -> Result<Bool, RoomProxyError> {
do {
return try .success(powerLevels.canUserSendState(userId: userID, stateEvent: .callMember))
} catch {
MXLog.error("Failed checking if the user can trigger room notification with error: \(error)")
return .failure(.sdkError(error))
}
}
}
@@ -17,7 +17,6 @@ enum RoomProxyError: Error {
case invalidURL
case invalidMedia
case eventNotFound
case missingTransactionID
case failedCreatingPinnedTimeline
case timelineError(TimelineProxyError)
case liveLocationSessionIsNotActive
@@ -57,22 +56,11 @@ protocol BannedRoomProxyProtocol: RoomProxyProtocol {
func forgetRoom() async -> Result<Void, RoomProxyError>
}
enum JoinedRoomProxyAction: Equatable {
case roomInfoUpdate
}
enum KnockRequestsState {
case loading
case loaded([KnockRequestProxyProtocol])
}
struct RTCDeclinedEvent {
/// The sender of the decline event
let sender: String
/// The rtc.notification event that is beeing declined
let notificationEventID: String
}
// sourcery: AutoMockable
protocol JoinedRoomProxyProtocol: RoomProxyProtocol {
var infoPublisher: CurrentValuePublisher<RoomInfoProxyProtocol, Never> { get }
@@ -89,8 +77,6 @@ protocol JoinedRoomProxyProtocol: RoomProxyProtocol {
var predecessorRoom: PredecessorRoom? { get }
var successorRoom: SuccessorRoom? { get }
func subscribeForUpdates() async
func subscribeToRoomInfoUpdates()
@@ -111,8 +97,6 @@ protocol JoinedRoomProxyProtocol: RoomProxyProtocol {
func enableEncryption() async -> Result<Void, RoomProxyError>
func redact(_ eventID: String) async -> Result<Void, RoomProxyError>
func reportContent(_ eventID: String, reason: String?) async -> Result<Void, RoomProxyError>
func reportRoom(reason: String) async -> Result<Void, RoomProxyError>
@@ -135,8 +119,6 @@ protocol JoinedRoomProxyProtocol: RoomProxyProtocol {
func markAsRead(receiptType: ReceiptType) async -> Result<Void, RoomProxyError>
func edit(eventID: String, newContent: RoomMessageEventContentWithoutRelation) async -> Result<Void, RoomProxyError>
/// https://spec.matrix.org/v1.9/client-server-api/#typing-notifications
@discardableResult func sendTypingNotification(isTyping: Bool) async -> Result<Void, RoomProxyError>
@@ -167,10 +149,8 @@ protocol JoinedRoomProxyProtocol: RoomProxyProtocol {
// MARK: - Power Levels
func powerLevels() async -> Result<RoomPowerLevelsProxyProtocol?, RoomProxyError>
func applyPowerLevelChanges(_ changes: RoomPowerLevelChanges) async -> Result<Void, RoomProxyError>
func resetPowerLevels() async -> Result<Void, RoomProxyError>
func suggestedRole(for userID: String) async -> Result<RoomMemberRole, RoomProxyError>
func updatePowerLevelsForUsers(_ updates: [(userID: String, powerLevel: Int64)]) async -> Result<Void, RoomProxyError>
// MARK: - Moderation
@@ -106,6 +106,7 @@ nonisolated struct RoomEventStringBuilder {
shouldPrefixSenderName: false)
}
// periphery:ignore - might be useful to have
static func threadListEventStringBuilder(userID: String) -> Self {
RoomEventStringBuilder(stateEventStringBuilder: .init(userID: userID),
messageEventStringBuilder: .init(attributedStringBuilder: AttributedStringBuilder(cacheKey: "threadList", mentionBuilder: PlainMentionBuilder()),
@@ -21,13 +21,6 @@ nonisolated struct RoomSummary {
default: false
}
}
var isKnock: Bool {
switch self {
case .knock: true
default: false
}
}
}
enum LastMessageState { case sending, failed }
@@ -26,7 +26,6 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
private var roomList: RoomListProtocol?
private var cancellables = Set<AnyCancellable>()
private var roomListServiceStateCancellable: AnyCancellable?
private var listUpdatesSubscriptionResult: RoomListEntriesWithDynamicAdaptersResult?
private var stateUpdatesTaskHandle: TaskHandle?
@@ -13,19 +13,21 @@ class RoomThreadListProxy: RoomThreadListServiceProxyProtocol {
private let threadListService: ThreadListServiceProtocol
private let eventStringBuilder: RoomEventStringBuilder
// periphery:ignore - required for instance retention in the rust codebase
private var itemUpdatesHandle: TaskHandle?
private let itemsSubject = CurrentValueSubject<[RoomThreadListItem], Never>([])
var itemsPublisher: CurrentValuePublisher<[RoomThreadListItem], Never> {
itemsSubject.asCurrentValuePublisher()
}
// periphery:ignore - required for instance retention in the rust codebase
private var paginationStateHandle: TaskHandle?
private let paginationStateSubject: CurrentValueSubject<RoomThreadListPaginationState, Never>
var paginationStatePublisher: CurrentValuePublisher<RoomThreadListPaginationState, Never> {
paginationStateSubject.asCurrentValuePublisher()
}
init(threadListService: ThreadListServiceProtocol, eventStringBuilder: RoomEventStringBuilder, paginationToken: String? = nil) {
init(threadListService: ThreadListServiceProtocol, eventStringBuilder: RoomEventStringBuilder) {
self.threadListService = threadListService
self.eventStringBuilder = eventStringBuilder