mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-06 04:18:31 +00:00
updated SDK and improved report flow
the report flow is now based on the matrix version and the new one will only be used if the SDK checks if the server supports it.
This commit is contained in:
@@ -8659,7 +8659,7 @@
|
|||||||
repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift";
|
repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift";
|
||||||
requirement = {
|
requirement = {
|
||||||
kind = exactVersion;
|
kind = exactVersion;
|
||||||
version = 25.04.16;
|
version = 25.04.29;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {
|
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {
|
||||||
|
|||||||
@@ -158,8 +158,8 @@
|
|||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/element-hq/matrix-rust-components-swift",
|
"location" : "https://github.com/element-hq/matrix-rust-components-swift",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "895ba54c171859cace965e77b6fe2f64919ecb27",
|
"revision" : "cd4509acd56641c4d110b29f692ecafe5438698f",
|
||||||
"version" : "25.4.16"
|
"version" : "25.4.29"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,8 +57,6 @@ final class AppSettings {
|
|||||||
case fuzzyRoomListSearchEnabled
|
case fuzzyRoomListSearchEnabled
|
||||||
case enableOnlySignedDeviceIsolationMode
|
case enableOnlySignedDeviceIsolationMode
|
||||||
case knockingEnabled
|
case knockingEnabled
|
||||||
case reportRoomEnabled
|
|
||||||
case reportInviteEnabled
|
|
||||||
case threadsEnabled
|
case threadsEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,11 +325,6 @@ final class AppSettings {
|
|||||||
@UserPreference(key: UserDefaultsKeys.knockingEnabled, defaultValue: false, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.knockingEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||||
var knockingEnabled
|
var knockingEnabled
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.reportRoomEnabled, defaultValue: false, storageType: .userDefaults(store)) var reportRoomEnabled
|
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.reportInviteEnabled, defaultValue: false, storageType: .userDefaults(store))
|
|
||||||
var reportInviteEnabled
|
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.threadsEnabled, defaultValue: false, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.threadsEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||||
var threadsEnabled
|
var threadsEnabled
|
||||||
|
|
||||||
|
|||||||
@@ -92,5 +92,7 @@ extension ClientProxyMock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
userIdentityForReturnValue = .success(UserIdentityProxyMock(configuration: .init()))
|
userIdentityForReturnValue = .success(UserIdentityProxyMock(configuration: .init()))
|
||||||
|
|
||||||
|
underlyingIsReportRoomSupported = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2303,6 +2303,23 @@ class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable {
|
|||||||
}
|
}
|
||||||
var underlyingSecureBackupController: SecureBackupControllerProtocol!
|
var underlyingSecureBackupController: SecureBackupControllerProtocol!
|
||||||
var sessionVerificationController: SessionVerificationControllerProxyProtocol?
|
var sessionVerificationController: SessionVerificationControllerProxyProtocol?
|
||||||
|
var isReportRoomSupportedCallsCount = 0
|
||||||
|
var isReportRoomSupportedCalled: Bool {
|
||||||
|
return isReportRoomSupportedCallsCount > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var isReportRoomSupported: Bool {
|
||||||
|
get async {
|
||||||
|
isReportRoomSupportedCallsCount += 1
|
||||||
|
if let isReportRoomSupportedClosure = isReportRoomSupportedClosure {
|
||||||
|
return await isReportRoomSupportedClosure()
|
||||||
|
} else {
|
||||||
|
return underlyingIsReportRoomSupported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var underlyingIsReportRoomSupported: Bool!
|
||||||
|
var isReportRoomSupportedClosure: (() async -> Bool)?
|
||||||
|
|
||||||
//MARK: - isOnlyDeviceLeft
|
//MARK: - isOnlyDeviceLeft
|
||||||
|
|
||||||
|
|||||||
@@ -108,9 +108,9 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
.weakAssign(to: \.state.hideInviteAvatars, on: self)
|
.weakAssign(to: \.state.hideInviteAvatars, on: self)
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
appSettings.$reportRoomEnabled
|
Task {
|
||||||
.weakAssign(to: \.state.reportRoomEnabled, on: self)
|
state.reportRoomEnabled = await userSession.clientProxy.isReportRoomSupported
|
||||||
.store(in: &cancellables)
|
}
|
||||||
|
|
||||||
let isSearchFieldFocused = context.$viewState.map(\.bindings.isSearchFieldFocused)
|
let isSearchFieldFocused = context.$viewState.map(\.bindings.isSearchFieldFocused)
|
||||||
let searchQuery = context.$viewState.map(\.bindings.searchQuery)
|
let searchQuery = context.$viewState.map(\.bindings.searchQuery)
|
||||||
@@ -208,7 +208,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
await acceptInvite(roomID: roomIdentifier)
|
await acceptInvite(roomID: roomIdentifier)
|
||||||
}
|
}
|
||||||
case .declineInvite(let roomIdentifier):
|
case .declineInvite(let roomIdentifier):
|
||||||
showDeclineInviteConfirmationAlert(roomID: roomIdentifier)
|
Task { await showDeclineInviteConfirmationAlert(roomID: roomIdentifier) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,7 +419,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func showDeclineInviteConfirmationAlert(roomID: String) {
|
private func showDeclineInviteConfirmationAlert(roomID: String) async {
|
||||||
guard let room = state.rooms.first(where: { $0.id == roomID }) else {
|
guard let room = state.rooms.first(where: { $0.id == roomID }) else {
|
||||||
displayError()
|
displayError()
|
||||||
return
|
return
|
||||||
@@ -429,7 +429,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
let title = room.isDirect ? L10n.screenInvitesDeclineDirectChatTitle : L10n.screenInvitesDeclineChatTitle
|
let title = room.isDirect ? L10n.screenInvitesDeclineDirectChatTitle : L10n.screenInvitesDeclineChatTitle
|
||||||
let message = room.isDirect ? L10n.screenInvitesDeclineDirectChatMessage(roomPlaceholder) : L10n.screenInvitesDeclineChatMessage(roomPlaceholder)
|
let message = room.isDirect ? L10n.screenInvitesDeclineDirectChatMessage(roomPlaceholder) : L10n.screenInvitesDeclineChatMessage(roomPlaceholder)
|
||||||
|
|
||||||
if appSettings.reportInviteEnabled, let userID = room.inviter?.id {
|
if await userSession.clientProxy.isReportRoomSupported, let userID = room.inviter?.id {
|
||||||
state.bindings.alertInfo = .init(id: UUID(),
|
state.bindings.alertInfo = .init(id: UUID(),
|
||||||
title: title,
|
title: title,
|
||||||
message: message,
|
message: message,
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
|||||||
case .dismiss:
|
case .dismiss:
|
||||||
actionsSubject.send(.dismiss)
|
actionsSubject.send(.dismiss)
|
||||||
case .declineInviteAndBlock(let userID):
|
case .declineInviteAndBlock(let userID):
|
||||||
showDeclineAndBlockConfirmationAlert(userID: userID)
|
Task { await showDeclineAndBlockConfirmationAlert(userID: userID) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,8 +322,8 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
|||||||
secondaryButton: .init(title: L10n.screenJoinRoomCancelKnockAlertConfirmation, role: .destructive) { Task { await self.cancelKnock() } })
|
secondaryButton: .init(title: L10n.screenJoinRoomCancelKnockAlertConfirmation, role: .destructive) { Task { await self.cancelKnock() } })
|
||||||
}
|
}
|
||||||
|
|
||||||
private func showDeclineAndBlockConfirmationAlert(userID: String) {
|
private func showDeclineAndBlockConfirmationAlert(userID: String) async {
|
||||||
if appSettings.reportInviteEnabled {
|
if await clientProxy.isReportRoomSupported {
|
||||||
actionsSubject.send(.presentDeclineAndBlock(userID: userID))
|
actionsSubject.send(.presentDeclineAndBlock(userID: userID))
|
||||||
} else {
|
} else {
|
||||||
state.bindings.alertInfo = .init(id: .declineInviteAndBlock,
|
state.bindings.alertInfo = .init(id: .declineInviteAndBlock,
|
||||||
|
|||||||
@@ -78,9 +78,9 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
.weakAssign(to: \.state.knockingEnabled, on: self)
|
.weakAssign(to: \.state.knockingEnabled, on: self)
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
appSettings.$reportRoomEnabled
|
Task {
|
||||||
.weakAssign(to: \.state.reportRoomEnabled, on: self)
|
state.reportRoomEnabled = await clientProxy.isReportRoomSupported
|
||||||
.store(in: &cancellables)
|
}
|
||||||
|
|
||||||
appMediator.networkMonitor.reachabilityPublisher
|
appMediator.networkMonitor.reachabilityPublisher
|
||||||
.filter { $0 == .reachable }
|
.filter { $0 == .reachable }
|
||||||
|
|||||||
-2
@@ -44,8 +44,6 @@ protocol DeveloperOptionsProtocol: AnyObject {
|
|||||||
var enableOnlySignedDeviceIsolationMode: Bool { get set }
|
var enableOnlySignedDeviceIsolationMode: Bool { get set }
|
||||||
var elementCallBaseURLOverride: URL? { get set }
|
var elementCallBaseURLOverride: URL? { get set }
|
||||||
var knockingEnabled: Bool { get set }
|
var knockingEnabled: Bool { get set }
|
||||||
var reportRoomEnabled: Bool { get set }
|
|
||||||
var reportInviteEnabled: Bool { get set }
|
|
||||||
var threadsEnabled: Bool { get set }
|
var threadsEnabled: Bool { get set }
|
||||||
var isNewBloomEnabled: Bool { get set }
|
var isNewBloomEnabled: Bool { get set }
|
||||||
}
|
}
|
||||||
|
|||||||
-11
@@ -73,17 +73,6 @@ struct DeveloperOptionsScreen: View {
|
|||||||
} footer: {
|
} footer: {
|
||||||
Text("This setting controls how end-to-end encryption (E2EE) keys are exchanged. Enabling it will prevent the inclusion of devices that have not been explicitly verified by their owners.")
|
Text("This setting controls how end-to-end encryption (E2EE) keys are exchanged. Enabling it will prevent the inclusion of devices that have not been explicitly verified by their owners.")
|
||||||
}
|
}
|
||||||
|
|
||||||
Section("Reporting") {
|
|
||||||
Toggle(isOn: $context.reportRoomEnabled) {
|
|
||||||
Text("Report rooms")
|
|
||||||
Text("Report API might not work properly")
|
|
||||||
}
|
|
||||||
Toggle(isOn: $context.reportInviteEnabled) {
|
|
||||||
Text("Report invites")
|
|
||||||
Text("Report API might not work properly")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
TextField("Leave empty to use EC locally", text: $elementCallURLOverrideString)
|
TextField("Leave empty to use EC locally", text: $elementCallURLOverrideString)
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ extension OIDCConfigurationProxy {
|
|||||||
logoUri: logoURI.absoluteString,
|
logoUri: logoURI.absoluteString,
|
||||||
tosUri: tosURI.absoluteString,
|
tosUri: tosURI.absoluteString,
|
||||||
policyUri: policyURI.absoluteString,
|
policyUri: policyURI.absoluteString,
|
||||||
contacts: nil,
|
|
||||||
staticRegistrations: staticRegistrations)
|
staticRegistrations: staticRegistrations)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
syncServiceStateUpdateTaskHandle = createSyncServiceStateObserver(syncService)
|
syncServiceStateUpdateTaskHandle = createSyncServiceStateObserver(syncService)
|
||||||
roomListStateUpdateTaskHandle = createRoomListServiceObserver(roomListService)
|
roomListStateUpdateTaskHandle = createRoomListServiceObserver(roomListService)
|
||||||
roomListStateLoadingStateUpdateTaskHandle = createRoomListLoadingStateUpdateObserver(roomListService)
|
roomListStateLoadingStateUpdateTaskHandle = createRoomListLoadingStateUpdateObserver(roomListService)
|
||||||
|
|
||||||
delegateHandle = client.setDelegate(delegate: ClientDelegateWrapper { [weak self] isSoftLogout in
|
delegateHandle = client.setDelegate(delegate: ClientDelegateWrapper { [weak self] isSoftLogout in
|
||||||
self?.hasEncounteredAuthError = true
|
self?.hasEncounteredAuthError = true
|
||||||
self?.actionsSubject.send(.receivedAuthError(isSoftLogout: isSoftLogout))
|
self?.actionsSubject.send(.receivedAuthError(isSoftLogout: isSoftLogout))
|
||||||
@@ -269,6 +269,17 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isReportRoomSupported: Bool {
|
||||||
|
get async {
|
||||||
|
do {
|
||||||
|
return try await client.isReportRoomApiSupported()
|
||||||
|
} catch {
|
||||||
|
MXLog.error("Failed checking report room support with error: \(error)")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private(set) lazy var pusherNotificationClientIdentifier: String? = {
|
private(set) lazy var pusherNotificationClientIdentifier: String? = {
|
||||||
// NOTE: The result is stored as part of the restoration token. Any changes
|
// NOTE: The result is stored as part of the restoration token. Any changes
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
|||||||
|
|
||||||
var sessionVerificationController: SessionVerificationControllerProxyProtocol? { get }
|
var sessionVerificationController: SessionVerificationControllerProxyProtocol? { get }
|
||||||
|
|
||||||
|
var isReportRoomSupported: Bool { get async }
|
||||||
|
|
||||||
func isOnlyDeviceLeft() async -> Result<Bool, ClientProxyError>
|
func isOnlyDeviceLeft() async -> Result<Bool, ClientProxyError>
|
||||||
|
|
||||||
func startSync()
|
func startSync()
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
MXLog.info("Sending audio")
|
MXLog.info("Sending audio")
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let handle = try timeline.sendAudio(params: .init(filename: url.path(percentEncoded: false),
|
let handle = try timeline.sendAudio(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||||
caption: caption,
|
caption: caption,
|
||||||
formattedCaption: nil, // Rust will build this from the caption's markdown.
|
formattedCaption: nil, // Rust will build this from the caption's markdown.
|
||||||
mentions: nil,
|
mentions: nil,
|
||||||
@@ -261,7 +261,7 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
MXLog.info("Sending file")
|
MXLog.info("Sending file")
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let handle = try timeline.sendFile(params: .init(filename: url.path(percentEncoded: false),
|
let handle = try timeline.sendFile(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||||
caption: caption,
|
caption: caption,
|
||||||
formattedCaption: nil, // Rust will build this from the caption's markdown.
|
formattedCaption: nil, // Rust will build this from the caption's markdown.
|
||||||
mentions: nil,
|
mentions: nil,
|
||||||
@@ -290,7 +290,7 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
MXLog.info("Sending image")
|
MXLog.info("Sending image")
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let handle = try timeline.sendImage(params: .init(filename: url.path(percentEncoded: false),
|
let handle = try timeline.sendImage(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||||
caption: caption,
|
caption: caption,
|
||||||
formattedCaption: nil, // Rust will build this from the caption's markdown.
|
formattedCaption: nil, // Rust will build this from the caption's markdown.
|
||||||
mentions: nil,
|
mentions: nil,
|
||||||
@@ -338,7 +338,7 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
MXLog.info("Sending video")
|
MXLog.info("Sending video")
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let handle = try timeline.sendVideo(params: .init(filename: url.path(percentEncoded: false),
|
let handle = try timeline.sendVideo(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||||
caption: caption,
|
caption: caption,
|
||||||
formattedCaption: nil,
|
formattedCaption: nil,
|
||||||
mentions: nil,
|
mentions: nil,
|
||||||
@@ -367,7 +367,7 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
MXLog.info("Sending voice message")
|
MXLog.info("Sending voice message")
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let handle = try timeline.sendVoiceMessage(params: .init(filename: url.path(percentEncoded: false),
|
let handle = try timeline.sendVoiceMessage(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||||
caption: nil,
|
caption: nil,
|
||||||
formattedCaption: nil,
|
formattedCaption: nil,
|
||||||
mentions: nil,
|
mentions: nil,
|
||||||
|
|||||||
@@ -304,7 +304,6 @@ class HomeScreenViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
func testDeclineInvite() async throws {
|
func testDeclineInvite() async throws {
|
||||||
setupViewModel(withInvites: true)
|
setupViewModel(withInvites: true)
|
||||||
|
|
||||||
let invitedRoomIDs = context.viewState.rooms.invites.compactMap(\.roomID)
|
let invitedRoomIDs = context.viewState.rooms.invites.compactMap(\.roomID)
|
||||||
appSettings.seenInvites = Set(invitedRoomIDs)
|
appSettings.seenInvites = Set(invitedRoomIDs)
|
||||||
XCTAssertEqual(invitedRoomIDs.count, 2)
|
XCTAssertEqual(invitedRoomIDs.count, 2)
|
||||||
@@ -323,7 +322,7 @@ class HomeScreenViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
return .invited(roomProxy)
|
return .invited(roomProxy)
|
||||||
}
|
}
|
||||||
context.viewState.bindings.alertInfo?.secondaryButton?.action?()
|
context.viewState.bindings.alertInfo?.verticalButtons?[0].action?()
|
||||||
await fulfillment(of: [rejectExpectation], timeout: 1.0)
|
await fulfillment(of: [rejectExpectation], timeout: 1.0)
|
||||||
|
|
||||||
XCTAssertEqual(appSettings.seenInvites, [invitedRoomIDs[1]])
|
XCTAssertEqual(appSettings.seenInvites, [invitedRoomIDs[1]])
|
||||||
@@ -331,6 +330,21 @@ class HomeScreenViewModelTests: XCTestCase {
|
|||||||
XCTAssertEqual(notificationManager.removeDeliveredMessageNotificationsForReceivedInvocations, [invitedRoomIDs[0]])
|
XCTAssertEqual(notificationManager.removeDeliveredMessageNotificationsForReceivedInvocations, [invitedRoomIDs[0]])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testDeclineAndBlockInvite() async throws {
|
||||||
|
setupViewModel(withInvites: true)
|
||||||
|
let invitedRoomIDs = context.viewState.rooms.invites.compactMap(\.roomID)
|
||||||
|
appSettings.seenInvites = Set(invitedRoomIDs)
|
||||||
|
XCTAssertEqual(invitedRoomIDs.count, 2)
|
||||||
|
|
||||||
|
let deferred = deferFulfillment(context.$viewState) { $0.bindings.alertInfo != nil }
|
||||||
|
context.send(viewAction: .declineInvite(roomIdentifier: invitedRoomIDs[0]))
|
||||||
|
try await deferred.fulfill()
|
||||||
|
|
||||||
|
let deferredAction = deferFulfillment(viewModel.actions) { $0 == .presentDeclineAndBlock(userID: RoomMemberProxyMock.mockCharlie.userID, roomID: invitedRoomIDs[0]) }
|
||||||
|
context.viewState.bindings.alertInfo?.secondaryButton?.action?()
|
||||||
|
try await deferredAction.fulfill()
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Helpers
|
// MARK: - Helpers
|
||||||
|
|
||||||
private func setupViewModel(securityStatePublisher: CurrentValuePublisher<SessionSecurityState, Never>? = nil, withInvites: Bool = false) {
|
private func setupViewModel(securityStatePublisher: CurrentValuePublisher<SessionSecurityState, Never>? = nil, withInvites: Bool = false) {
|
||||||
|
|||||||
@@ -111,8 +111,9 @@ class JoinRoomScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDeclineAndBlockInviteInteraction() async throws {
|
func testDeclineAndBlockInviteLegacyInteraction() async throws {
|
||||||
setupViewModel(mode: .invited)
|
setupViewModel(mode: .invited)
|
||||||
|
clientProxy.underlyingIsReportRoomSupported = false
|
||||||
let expectation = expectation(description: "Wait for the user to be ignored")
|
let expectation = expectation(description: "Wait for the user to be ignored")
|
||||||
clientProxy.ignoreUserClosure = { userID in
|
clientProxy.ignoreUserClosure = { userID in
|
||||||
defer { expectation.fulfill() }
|
defer { expectation.fulfill() }
|
||||||
@@ -124,15 +125,23 @@ class JoinRoomScreenViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
context.send(viewAction: .declineInviteAndBlock(userID: "@test:matrix.org"))
|
context.send(viewAction: .declineInviteAndBlock(userID: "@test:matrix.org"))
|
||||||
|
|
||||||
|
try await deferFulfillment(viewModel.context.$viewState) { $0.bindings.alertInfo != nil }.fulfill()
|
||||||
XCTAssertEqual(viewModel.context.alertInfo?.id, .declineInviteAndBlock)
|
XCTAssertEqual(viewModel.context.alertInfo?.id, .declineInviteAndBlock)
|
||||||
|
|
||||||
let deferred = deferFulfillment(viewModel.actionsPublisher) { action in
|
let deferred = deferFulfillment(viewModel.actionsPublisher) { action in
|
||||||
action == .dismiss
|
action == .dismiss
|
||||||
}
|
}
|
||||||
context.alertInfo?.secondaryButton?.action?()
|
context.alertInfo?.secondaryButton?.action?()
|
||||||
try await deferred.fulfill()
|
|
||||||
|
|
||||||
await fulfillment(of: [expectation], timeout: 10)
|
await fulfillment(of: [expectation], timeout: 10)
|
||||||
|
try await deferred.fulfill()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDeclineAndBlockInviteInteraction() async throws {
|
||||||
|
setupViewModel(mode: .invited)
|
||||||
|
try await deferFulfillment(viewModel.context.$viewState) { $0.roomDetails != nil }.fulfill()
|
||||||
|
let deferredAction = deferFulfillment(viewModel.actionsPublisher) { $0 == .presentDeclineAndBlock(userID: "@test:matrix.org") }
|
||||||
|
context.send(viewAction: .declineInviteAndBlock(userID: "@test:matrix.org"))
|
||||||
|
try await deferredAction.fulfill()
|
||||||
}
|
}
|
||||||
|
|
||||||
func testForgetRoom() async throws {
|
func testForgetRoom() async throws {
|
||||||
|
|||||||
+1
-1
@@ -59,7 +59,7 @@ packages:
|
|||||||
# Element/Matrix dependencies
|
# Element/Matrix dependencies
|
||||||
MatrixRustSDK:
|
MatrixRustSDK:
|
||||||
url: https://github.com/element-hq/matrix-rust-components-swift
|
url: https://github.com/element-hq/matrix-rust-components-swift
|
||||||
exactVersion: 25.04.16
|
exactVersion: 25.04.29
|
||||||
# path: ../matrix-rust-sdk
|
# path: ../matrix-rust-sdk
|
||||||
Compound:
|
Compound:
|
||||||
url: https://github.com/element-hq/compound-ios
|
url: https://github.com/element-hq/compound-ios
|
||||||
|
|||||||
Reference in New Issue
Block a user