Add a workaround to include some via parameters for room v12 tombstone links. (#4413)

Without them, following the link fails as previously the server could use the server name from the room ID (which in and of itself seems somewhat error prone).
This commit is contained in:
Doug
2025-08-14 13:02:07 +01:00
committed by GitHub
parent 3dc6d73899
commit de626186bd
7 changed files with 23 additions and 11 deletions
@@ -627,9 +627,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
stateMachine.tryEvent(.presentKnockRequestsListScreen)
case .presentThread(let itemID):
stateMachine.tryEvent(.presentThread(itemID: itemID))
case .presentRoom(roomID: let roomID):
case .presentRoom(let roomID, let via):
stateMachine.tryEvent(.startChildFlow(roomID: roomID,
via: [],
via: via,
entryPoint: .room))
}
}
@@ -46,7 +46,7 @@ enum RoomScreenCoordinatorAction {
case presentResolveSendFailure(failure: TimelineItemSendFailure.VerifiedUser, sendHandle: SendHandleProxy)
case presentKnockRequestsList
case presentThread(itemID: TimelineItemIdentifier)
case presentRoom(roomID: String)
case presentRoom(roomID: String, via: [String])
}
final class RoomScreenCoordinator: CoordinatorProtocol {
@@ -148,8 +148,8 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
composerViewModel.process(timelineAction: action)
case .hasScrolled(direction: let direction):
roomViewModel.timelineHasScrolled(direction: direction)
case .displayRoom(let roomID):
actionsSubject.send(.presentRoom(roomID: roomID))
case .displayRoom(let roomID, let via):
actionsSubject.send(.presentRoom(roomID: roomID, via: via))
case .viewInRoomTimeline:
fatalError("The action: \(action) should not be sent to this coordinator")
}
@@ -181,8 +181,8 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
composerViewModel.process(timelineAction: .removeFocus)
case .displayKnockRequests:
actionsSubject.send(.presentKnockRequestsList)
case .displayRoom(let roomID):
actionsSubject.send(.presentRoom(roomID: roomID))
case .displayRoom(let roomID, let via):
actionsSubject.send(.presentRoom(roomID: roomID, via: via))
}
}
.store(in: &cancellables)
@@ -15,7 +15,7 @@ enum RoomScreenViewModelAction: Equatable {
case displayCall
case removeComposerFocus
case displayKnockRequests
case displayRoom(roomID: String)
case displayRoom(roomID: String, via: [String])
}
enum RoomScreenViewAction {
@@ -5,6 +5,7 @@
// Please see LICENSE files in the repository root for full details.
//
import Algorithms
import Combine
import Foundation
import MatrixRustSDK
@@ -117,7 +118,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
actionsSubject.send(.displayKnockRequests)
case .displaySuccessorRoom:
guard let successorID = roomProxy.infoPublisher.value.successor?.roomId else { return }
actionsSubject.send(.displayRoom(roomID: successorID))
let serverNames = roomProxy.knownServerNames(maxCount: 50) // Limit to the same number used by ClientProxy.resolveRoomAlias(_:)
actionsSubject.send(.displayRoom(roomID: successorID, via: Array(serverNames)))
}
}
@@ -28,7 +28,7 @@ enum TimelineViewModelAction {
case composer(action: TimelineComposerAction)
case hasScrolled(direction: ScrollDirection)
case viewInRoomTimeline(eventID: String)
case displayRoom(roomID: String)
case displayRoom(roomID: String, via: [String])
}
enum TimelineViewPollAction {
@@ -214,7 +214,8 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
guard let predecessorID = roomProxy.predecessorRoom?.roomId else {
fatalError("Predecessor room should exist if this action is triggered.")
}
actionsSubject.send(.displayRoom(roomID: predecessorID))
let serverNames = roomProxy.knownServerNames(maxCount: 50) // Limit to the same number used by ClientProxy.resolveRoomAlias(_:)
actionsSubject.send(.displayRoom(roomID: predecessorID, via: Array(serverNames)))
}
}
@@ -200,4 +200,13 @@ extension JoinedRoomProxyProtocol {
await updateMembers()
return membersPublisher.value
}
// This is a horrible workaround for not having any server names available when using tombstone links with v12 room IDs.
func knownServerNames(maxCount: Int) -> any Sequence<String> {
membersPublisher.value
.prefix(1000) // No need to go crazy here…
.compactMap { $0.userID.split(separator: ":").last.map(String.init) }
.uniqued()
.prefix(maxCount)
}
}