mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
- automatically retry failed requests as soon as the network is availble again - remove manual retry options
This commit is contained in:
committed by
Stefan Ceriu
parent
53fc5df55b
commit
6c1647b851
@@ -7335,7 +7335,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 = 1.0.8;
|
version = 1.0.9;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {
|
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {
|
||||||
|
|||||||
@@ -139,8 +139,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" : "464227df09ff5ab4d00e432df131f779ba2f7ced",
|
"revision" : "4f46a00c5a0ab3053f49f449b769237645f00b18",
|
||||||
"version" : "1.0.8"
|
"version" : "1.0.9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -666,10 +666,12 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
|||||||
ServiceLocator.shared.networkMonitor
|
ServiceLocator.shared.networkMonitor
|
||||||
.reachabilityPublisher
|
.reachabilityPublisher
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
.sink { reachability in
|
.sink { [weak self] reachability in
|
||||||
MXLog.info("Reachability changed to \(reachability)")
|
MXLog.info("Reachability changed to \(reachability)")
|
||||||
|
|
||||||
if reachability == .reachable {
|
if reachability == .reachable {
|
||||||
|
self?.userSession?.clientProxy.setSendingQueueEnabled(true)
|
||||||
|
|
||||||
ServiceLocator.shared.userIndicatorController.retractIndicatorWithId(reachabilityNotificationIdentifier)
|
ServiceLocator.shared.userIndicatorController.retractIndicatorWithId(reachabilityNotificationIdentifier)
|
||||||
} else {
|
} else {
|
||||||
ServiceLocator.shared.userIndicatorController.submitIndicator(.init(id: reachabilityNotificationIdentifier,
|
ServiceLocator.shared.userIndicatorController.submitIndicator(.init(id: reachabilityNotificationIdentifier,
|
||||||
|
|||||||
@@ -3496,6 +3496,45 @@ class ClientProxyMock: ClientProxyProtocol {
|
|||||||
return resolveRoomAliasReturnValue
|
return resolveRoomAliasReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//MARK: - setSendingQueueEnabled
|
||||||
|
|
||||||
|
var setSendingQueueEnabledUnderlyingCallsCount = 0
|
||||||
|
var setSendingQueueEnabledCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return setSendingQueueEnabledUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = setSendingQueueEnabledUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
setSendingQueueEnabledUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
setSendingQueueEnabledUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var setSendingQueueEnabledCalled: Bool {
|
||||||
|
return setSendingQueueEnabledCallsCount > 0
|
||||||
|
}
|
||||||
|
var setSendingQueueEnabledReceivedEnabled: Bool?
|
||||||
|
var setSendingQueueEnabledReceivedInvocations: [Bool] = []
|
||||||
|
var setSendingQueueEnabledClosure: ((Bool) -> Void)?
|
||||||
|
|
||||||
|
func setSendingQueueEnabled(_ enabled: Bool) {
|
||||||
|
setSendingQueueEnabledCallsCount += 1
|
||||||
|
setSendingQueueEnabledReceivedEnabled = enabled
|
||||||
|
setSendingQueueEnabledReceivedInvocations.append(enabled)
|
||||||
|
setSendingQueueEnabledClosure?(enabled)
|
||||||
|
}
|
||||||
//MARK: - ignoreUser
|
//MARK: - ignoreUser
|
||||||
|
|
||||||
var ignoreUserUnderlyingCallsCount = 0
|
var ignoreUserUnderlyingCallsCount = 0
|
||||||
@@ -11057,11 +11096,6 @@ class SessionVerificationControllerProxyMock: SessionVerificationControllerProxy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
class TimelineProxyMock: TimelineProxyProtocol {
|
class TimelineProxyMock: TimelineProxyProtocol {
|
||||||
var actions: AnyPublisher<TimelineProxyAction, Never> {
|
|
||||||
get { return underlyingActions }
|
|
||||||
set(value) { underlyingActions = value }
|
|
||||||
}
|
|
||||||
var underlyingActions: AnyPublisher<TimelineProxyAction, Never>!
|
|
||||||
var isLive: Bool {
|
var isLive: Bool {
|
||||||
get { return underlyingIsLive }
|
get { return underlyingIsLive }
|
||||||
set(value) { underlyingIsLive = value }
|
set(value) { underlyingIsLive = value }
|
||||||
@@ -11108,113 +11142,6 @@ class TimelineProxyMock: TimelineProxyProtocol {
|
|||||||
subscribeForUpdatesCallsCount += 1
|
subscribeForUpdatesCallsCount += 1
|
||||||
await subscribeForUpdatesClosure?()
|
await subscribeForUpdatesClosure?()
|
||||||
}
|
}
|
||||||
//MARK: - cancelSend
|
|
||||||
|
|
||||||
var cancelSendTransactionIDUnderlyingCallsCount = 0
|
|
||||||
var cancelSendTransactionIDCallsCount: Int {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return cancelSendTransactionIDUnderlyingCallsCount
|
|
||||||
} else {
|
|
||||||
var returnValue: Int? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = cancelSendTransactionIDUnderlyingCallsCount
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
cancelSendTransactionIDUnderlyingCallsCount = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
cancelSendTransactionIDUnderlyingCallsCount = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var cancelSendTransactionIDCalled: Bool {
|
|
||||||
return cancelSendTransactionIDCallsCount > 0
|
|
||||||
}
|
|
||||||
var cancelSendTransactionIDReceivedTransactionID: String?
|
|
||||||
var cancelSendTransactionIDReceivedInvocations: [String] = []
|
|
||||||
var cancelSendTransactionIDClosure: ((String) async -> Void)?
|
|
||||||
|
|
||||||
func cancelSend(transactionID: String) async {
|
|
||||||
cancelSendTransactionIDCallsCount += 1
|
|
||||||
cancelSendTransactionIDReceivedTransactionID = transactionID
|
|
||||||
cancelSendTransactionIDReceivedInvocations.append(transactionID)
|
|
||||||
await cancelSendTransactionIDClosure?(transactionID)
|
|
||||||
}
|
|
||||||
//MARK: - editMessage
|
|
||||||
|
|
||||||
var editMessageHtmlOriginalIntentionalMentionsUnderlyingCallsCount = 0
|
|
||||||
var editMessageHtmlOriginalIntentionalMentionsCallsCount: Int {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return editMessageHtmlOriginalIntentionalMentionsUnderlyingCallsCount
|
|
||||||
} else {
|
|
||||||
var returnValue: Int? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = editMessageHtmlOriginalIntentionalMentionsUnderlyingCallsCount
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
editMessageHtmlOriginalIntentionalMentionsUnderlyingCallsCount = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
editMessageHtmlOriginalIntentionalMentionsUnderlyingCallsCount = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var editMessageHtmlOriginalIntentionalMentionsCalled: Bool {
|
|
||||||
return editMessageHtmlOriginalIntentionalMentionsCallsCount > 0
|
|
||||||
}
|
|
||||||
var editMessageHtmlOriginalIntentionalMentionsReceivedArguments: (message: String, html: String?, eventID: String, intentionalMentions: IntentionalMentions)?
|
|
||||||
var editMessageHtmlOriginalIntentionalMentionsReceivedInvocations: [(message: String, html: String?, eventID: String, intentionalMentions: IntentionalMentions)] = []
|
|
||||||
|
|
||||||
var editMessageHtmlOriginalIntentionalMentionsUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
|
||||||
var editMessageHtmlOriginalIntentionalMentionsReturnValue: Result<Void, TimelineProxyError>! {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return editMessageHtmlOriginalIntentionalMentionsUnderlyingReturnValue
|
|
||||||
} else {
|
|
||||||
var returnValue: Result<Void, TimelineProxyError>? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = editMessageHtmlOriginalIntentionalMentionsUnderlyingReturnValue
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
editMessageHtmlOriginalIntentionalMentionsUnderlyingReturnValue = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
editMessageHtmlOriginalIntentionalMentionsUnderlyingReturnValue = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var editMessageHtmlOriginalIntentionalMentionsClosure: ((String, String?, String, IntentionalMentions) async -> Result<Void, TimelineProxyError>)?
|
|
||||||
|
|
||||||
func editMessage(_ message: String, html: String?, original eventID: String, intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
|
|
||||||
editMessageHtmlOriginalIntentionalMentionsCallsCount += 1
|
|
||||||
editMessageHtmlOriginalIntentionalMentionsReceivedArguments = (message: message, html: html, eventID: eventID, intentionalMentions: intentionalMentions)
|
|
||||||
editMessageHtmlOriginalIntentionalMentionsReceivedInvocations.append((message: message, html: html, eventID: eventID, intentionalMentions: intentionalMentions))
|
|
||||||
if let editMessageHtmlOriginalIntentionalMentionsClosure = editMessageHtmlOriginalIntentionalMentionsClosure {
|
|
||||||
return await editMessageHtmlOriginalIntentionalMentionsClosure(message, html, eventID, intentionalMentions)
|
|
||||||
} else {
|
|
||||||
return editMessageHtmlOriginalIntentionalMentionsReturnValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//MARK: - fetchDetails
|
//MARK: - fetchDetails
|
||||||
|
|
||||||
var fetchDetailsForUnderlyingCallsCount = 0
|
var fetchDetailsForUnderlyingCallsCount = 0
|
||||||
@@ -11283,8 +11210,8 @@ class TimelineProxyMock: TimelineProxyProtocol {
|
|||||||
var messageEventContentForCalled: Bool {
|
var messageEventContentForCalled: Bool {
|
||||||
return messageEventContentForCallsCount > 0
|
return messageEventContentForCallsCount > 0
|
||||||
}
|
}
|
||||||
var messageEventContentForReceivedEventID: String?
|
var messageEventContentForReceivedTimelineItemID: TimelineItemIdentifier?
|
||||||
var messageEventContentForReceivedInvocations: [String] = []
|
var messageEventContentForReceivedInvocations: [TimelineItemIdentifier] = []
|
||||||
|
|
||||||
var messageEventContentForUnderlyingReturnValue: RoomMessageEventContentWithoutRelation?
|
var messageEventContentForUnderlyingReturnValue: RoomMessageEventContentWithoutRelation?
|
||||||
var messageEventContentForReturnValue: RoomMessageEventContentWithoutRelation? {
|
var messageEventContentForReturnValue: RoomMessageEventContentWithoutRelation? {
|
||||||
@@ -11310,14 +11237,14 @@ class TimelineProxyMock: TimelineProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var messageEventContentForClosure: ((String) async -> RoomMessageEventContentWithoutRelation?)?
|
var messageEventContentForClosure: ((TimelineItemIdentifier) async -> RoomMessageEventContentWithoutRelation?)?
|
||||||
|
|
||||||
func messageEventContent(for eventID: String) async -> RoomMessageEventContentWithoutRelation? {
|
func messageEventContent(for timelineItemID: TimelineItemIdentifier) async -> RoomMessageEventContentWithoutRelation? {
|
||||||
messageEventContentForCallsCount += 1
|
messageEventContentForCallsCount += 1
|
||||||
messageEventContentForReceivedEventID = eventID
|
messageEventContentForReceivedTimelineItemID = timelineItemID
|
||||||
messageEventContentForReceivedInvocations.append(eventID)
|
messageEventContentForReceivedInvocations.append(timelineItemID)
|
||||||
if let messageEventContentForClosure = messageEventContentForClosure {
|
if let messageEventContentForClosure = messageEventContentForClosure {
|
||||||
return await messageEventContentForClosure(eventID)
|
return await messageEventContentForClosure(timelineItemID)
|
||||||
} else {
|
} else {
|
||||||
return messageEventContentForReturnValue
|
return messageEventContentForReturnValue
|
||||||
}
|
}
|
||||||
@@ -11361,45 +11288,6 @@ class TimelineProxyMock: TimelineProxyProtocol {
|
|||||||
retryDecryptionForReceivedInvocations.append(sessionID)
|
retryDecryptionForReceivedInvocations.append(sessionID)
|
||||||
await retryDecryptionForClosure?(sessionID)
|
await retryDecryptionForClosure?(sessionID)
|
||||||
}
|
}
|
||||||
//MARK: - retrySend
|
|
||||||
|
|
||||||
var retrySendTransactionIDUnderlyingCallsCount = 0
|
|
||||||
var retrySendTransactionIDCallsCount: Int {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return retrySendTransactionIDUnderlyingCallsCount
|
|
||||||
} else {
|
|
||||||
var returnValue: Int? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = retrySendTransactionIDUnderlyingCallsCount
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
retrySendTransactionIDUnderlyingCallsCount = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
retrySendTransactionIDUnderlyingCallsCount = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var retrySendTransactionIDCalled: Bool {
|
|
||||||
return retrySendTransactionIDCallsCount > 0
|
|
||||||
}
|
|
||||||
var retrySendTransactionIDReceivedTransactionID: String?
|
|
||||||
var retrySendTransactionIDReceivedInvocations: [String] = []
|
|
||||||
var retrySendTransactionIDClosure: ((String) async -> Void)?
|
|
||||||
|
|
||||||
func retrySend(transactionID: String) async {
|
|
||||||
retrySendTransactionIDCallsCount += 1
|
|
||||||
retrySendTransactionIDReceivedTransactionID = transactionID
|
|
||||||
retrySendTransactionIDReceivedInvocations.append(transactionID)
|
|
||||||
await retrySendTransactionIDClosure?(transactionID)
|
|
||||||
}
|
|
||||||
//MARK: - paginateBackwards
|
//MARK: - paginateBackwards
|
||||||
|
|
||||||
var paginateBackwardsRequestSizeUnderlyingCallsCount = 0
|
var paginateBackwardsRequestSizeUnderlyingCallsCount = 0
|
||||||
@@ -11536,6 +11424,142 @@ class TimelineProxyMock: TimelineProxyProtocol {
|
|||||||
return paginateForwardsRequestSizeReturnValue
|
return paginateForwardsRequestSizeReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//MARK: - edit
|
||||||
|
|
||||||
|
var editMessageHtmlIntentionalMentionsUnderlyingCallsCount = 0
|
||||||
|
var editMessageHtmlIntentionalMentionsCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return editMessageHtmlIntentionalMentionsUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = editMessageHtmlIntentionalMentionsUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
editMessageHtmlIntentionalMentionsUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
editMessageHtmlIntentionalMentionsUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var editMessageHtmlIntentionalMentionsCalled: Bool {
|
||||||
|
return editMessageHtmlIntentionalMentionsCallsCount > 0
|
||||||
|
}
|
||||||
|
var editMessageHtmlIntentionalMentionsReceivedArguments: (timelineItemID: TimelineItemIdentifier, message: String, html: String?, intentionalMentions: IntentionalMentions)?
|
||||||
|
var editMessageHtmlIntentionalMentionsReceivedInvocations: [(timelineItemID: TimelineItemIdentifier, message: String, html: String?, intentionalMentions: IntentionalMentions)] = []
|
||||||
|
|
||||||
|
var editMessageHtmlIntentionalMentionsUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||||
|
var editMessageHtmlIntentionalMentionsReturnValue: Result<Void, TimelineProxyError>! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return editMessageHtmlIntentionalMentionsUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: Result<Void, TimelineProxyError>? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = editMessageHtmlIntentionalMentionsUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
editMessageHtmlIntentionalMentionsUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
editMessageHtmlIntentionalMentionsUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var editMessageHtmlIntentionalMentionsClosure: ((TimelineItemIdentifier, String, String?, IntentionalMentions) async -> Result<Void, TimelineProxyError>)?
|
||||||
|
|
||||||
|
func edit(_ timelineItemID: TimelineItemIdentifier, message: String, html: String?, intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
|
||||||
|
editMessageHtmlIntentionalMentionsCallsCount += 1
|
||||||
|
editMessageHtmlIntentionalMentionsReceivedArguments = (timelineItemID: timelineItemID, message: message, html: html, intentionalMentions: intentionalMentions)
|
||||||
|
editMessageHtmlIntentionalMentionsReceivedInvocations.append((timelineItemID: timelineItemID, message: message, html: html, intentionalMentions: intentionalMentions))
|
||||||
|
if let editMessageHtmlIntentionalMentionsClosure = editMessageHtmlIntentionalMentionsClosure {
|
||||||
|
return await editMessageHtmlIntentionalMentionsClosure(timelineItemID, message, html, intentionalMentions)
|
||||||
|
} else {
|
||||||
|
return editMessageHtmlIntentionalMentionsReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//MARK: - redact
|
||||||
|
|
||||||
|
var redactReasonUnderlyingCallsCount = 0
|
||||||
|
var redactReasonCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return redactReasonUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = redactReasonUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
redactReasonUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
redactReasonUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var redactReasonCalled: Bool {
|
||||||
|
return redactReasonCallsCount > 0
|
||||||
|
}
|
||||||
|
var redactReasonReceivedArguments: (timelineItemID: TimelineItemIdentifier, reason: String?)?
|
||||||
|
var redactReasonReceivedInvocations: [(timelineItemID: TimelineItemIdentifier, reason: String?)] = []
|
||||||
|
|
||||||
|
var redactReasonUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||||
|
var redactReasonReturnValue: Result<Void, TimelineProxyError>! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return redactReasonUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: Result<Void, TimelineProxyError>? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = redactReasonUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
redactReasonUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
redactReasonUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var redactReasonClosure: ((TimelineItemIdentifier, String?) async -> Result<Void, TimelineProxyError>)?
|
||||||
|
|
||||||
|
func redact(_ timelineItemID: TimelineItemIdentifier, reason: String?) async -> Result<Void, TimelineProxyError> {
|
||||||
|
redactReasonCallsCount += 1
|
||||||
|
redactReasonReceivedArguments = (timelineItemID: timelineItemID, reason: reason)
|
||||||
|
redactReasonReceivedInvocations.append((timelineItemID: timelineItemID, reason: reason))
|
||||||
|
if let redactReasonClosure = redactReasonClosure {
|
||||||
|
return await redactReasonClosure(timelineItemID, reason)
|
||||||
|
} else {
|
||||||
|
return redactReasonReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
//MARK: - sendAudio
|
//MARK: - sendAudio
|
||||||
|
|
||||||
var sendAudioUrlAudioInfoProgressSubjectRequestHandleUnderlyingCallsCount = 0
|
var sendAudioUrlAudioInfoProgressSubjectRequestHandleUnderlyingCallsCount = 0
|
||||||
|
|||||||
@@ -4,6 +4,82 @@
|
|||||||
// swiftlint:disable all
|
// swiftlint:disable all
|
||||||
import Foundation
|
import Foundation
|
||||||
import MatrixRustSDK
|
import MatrixRustSDK
|
||||||
|
open class AbortSendHandleSDKMock: MatrixRustSDK.AbortSendHandle {
|
||||||
|
init() {
|
||||||
|
super.init(noPointer: .init())
|
||||||
|
}
|
||||||
|
|
||||||
|
public required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
|
||||||
|
fatalError("init(unsafeFromRawPointer:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate var pointer: UnsafeMutableRawPointer!
|
||||||
|
|
||||||
|
//MARK: - abort
|
||||||
|
|
||||||
|
var abortUnderlyingCallsCount = 0
|
||||||
|
open var abortCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return abortUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = abortUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
abortUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
abortUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var abortCalled: Bool {
|
||||||
|
return abortCallsCount > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var abortUnderlyingReturnValue: Bool!
|
||||||
|
open var abortReturnValue: Bool! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return abortUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: Bool? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = abortUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
abortUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
abortUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var abortClosure: (() async -> Bool)?
|
||||||
|
|
||||||
|
open override func abort() async -> Bool {
|
||||||
|
abortCallsCount += 1
|
||||||
|
if let abortClosure = abortClosure {
|
||||||
|
return await abortClosure()
|
||||||
|
} else {
|
||||||
|
return abortReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
open class AuthenticationServiceSDKMock: MatrixRustSDK.AuthenticationService {
|
open class AuthenticationServiceSDKMock: MatrixRustSDK.AuthenticationService {
|
||||||
init() {
|
init() {
|
||||||
super.init(noPointer: .init())
|
super.init(noPointer: .init())
|
||||||
@@ -889,6 +965,46 @@ open class ClientSDKMock: MatrixRustSDK.Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//MARK: - enableSendingQueue
|
||||||
|
|
||||||
|
var enableSendingQueueEnableUnderlyingCallsCount = 0
|
||||||
|
open var enableSendingQueueEnableCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return enableSendingQueueEnableUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = enableSendingQueueEnableUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
enableSendingQueueEnableUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
enableSendingQueueEnableUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var enableSendingQueueEnableCalled: Bool {
|
||||||
|
return enableSendingQueueEnableCallsCount > 0
|
||||||
|
}
|
||||||
|
open var enableSendingQueueEnableReceivedEnable: Bool?
|
||||||
|
open var enableSendingQueueEnableReceivedInvocations: [Bool] = []
|
||||||
|
open var enableSendingQueueEnableClosure: ((Bool) -> Void)?
|
||||||
|
|
||||||
|
open override func enableSendingQueue(enable: Bool) {
|
||||||
|
enableSendingQueueEnableCallsCount += 1
|
||||||
|
enableSendingQueueEnableReceivedEnable = enable
|
||||||
|
enableSendingQueueEnableReceivedInvocations.append(enable)
|
||||||
|
enableSendingQueueEnableClosure?(enable)
|
||||||
|
}
|
||||||
|
|
||||||
//MARK: - encryption
|
//MARK: - encryption
|
||||||
|
|
||||||
var encryptionUnderlyingCallsCount = 0
|
var encryptionUnderlyingCallsCount = 0
|
||||||
@@ -2593,15 +2709,15 @@ open class ClientSDKMock: MatrixRustSDK.Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
open var sessionClosure: (() async throws -> Session)?
|
open var sessionClosure: (() throws -> Session)?
|
||||||
|
|
||||||
open override func session() async throws -> Session {
|
open override func session() throws -> Session {
|
||||||
if let error = sessionThrowableError {
|
if let error = sessionThrowableError {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
sessionCallsCount += 1
|
sessionCallsCount += 1
|
||||||
if let sessionClosure = sessionClosure {
|
if let sessionClosure = sessionClosure {
|
||||||
return try await sessionClosure()
|
return try sessionClosure()
|
||||||
} else {
|
} else {
|
||||||
return sessionReturnValue
|
return sessionReturnValue
|
||||||
}
|
}
|
||||||
@@ -2877,6 +2993,75 @@ open class ClientSDKMock: MatrixRustSDK.Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//MARK: - subscribeToSendingQueueStatus
|
||||||
|
|
||||||
|
var subscribeToSendingQueueStatusListenerUnderlyingCallsCount = 0
|
||||||
|
open var subscribeToSendingQueueStatusListenerCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return subscribeToSendingQueueStatusListenerUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = subscribeToSendingQueueStatusListenerUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
subscribeToSendingQueueStatusListenerUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
subscribeToSendingQueueStatusListenerUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var subscribeToSendingQueueStatusListenerCalled: Bool {
|
||||||
|
return subscribeToSendingQueueStatusListenerCallsCount > 0
|
||||||
|
}
|
||||||
|
open var subscribeToSendingQueueStatusListenerReceivedListener: SendingQueueStatusListener?
|
||||||
|
open var subscribeToSendingQueueStatusListenerReceivedInvocations: [SendingQueueStatusListener] = []
|
||||||
|
|
||||||
|
var subscribeToSendingQueueStatusListenerUnderlyingReturnValue: TaskHandle!
|
||||||
|
open var subscribeToSendingQueueStatusListenerReturnValue: TaskHandle! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return subscribeToSendingQueueStatusListenerUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: TaskHandle? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = subscribeToSendingQueueStatusListenerUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
subscribeToSendingQueueStatusListenerUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
subscribeToSendingQueueStatusListenerUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var subscribeToSendingQueueStatusListenerClosure: ((SendingQueueStatusListener) -> TaskHandle)?
|
||||||
|
|
||||||
|
open override func subscribeToSendingQueueStatus(listener: SendingQueueStatusListener) -> TaskHandle {
|
||||||
|
subscribeToSendingQueueStatusListenerCallsCount += 1
|
||||||
|
subscribeToSendingQueueStatusListenerReceivedListener = listener
|
||||||
|
subscribeToSendingQueueStatusListenerReceivedInvocations.append(listener)
|
||||||
|
if let subscribeToSendingQueueStatusListenerClosure = subscribeToSendingQueueStatusListenerClosure {
|
||||||
|
return subscribeToSendingQueueStatusListenerClosure(listener)
|
||||||
|
} else {
|
||||||
|
return subscribeToSendingQueueStatusListenerReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//MARK: - syncService
|
//MARK: - syncService
|
||||||
|
|
||||||
var syncServiceUnderlyingCallsCount = 0
|
var syncServiceUnderlyingCallsCount = 0
|
||||||
@@ -7398,6 +7583,71 @@ open class MessageSDKMock: MatrixRustSDK.Message {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//MARK: - content
|
||||||
|
|
||||||
|
var contentUnderlyingCallsCount = 0
|
||||||
|
open var contentCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return contentUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = contentUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
contentUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
contentUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var contentCalled: Bool {
|
||||||
|
return contentCallsCount > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var contentUnderlyingReturnValue: RoomMessageEventContentWithoutRelation!
|
||||||
|
open var contentReturnValue: RoomMessageEventContentWithoutRelation! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return contentUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: RoomMessageEventContentWithoutRelation? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = contentUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
contentUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
contentUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var contentClosure: (() -> RoomMessageEventContentWithoutRelation)?
|
||||||
|
|
||||||
|
open override func content() -> RoomMessageEventContentWithoutRelation {
|
||||||
|
contentCallsCount += 1
|
||||||
|
if let contentClosure = contentClosure {
|
||||||
|
return contentClosure()
|
||||||
|
} else {
|
||||||
|
return contentReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//MARK: - inReplyTo
|
//MARK: - inReplyTo
|
||||||
|
|
||||||
var inReplyToUnderlyingCallsCount = 0
|
var inReplyToUnderlyingCallsCount = 0
|
||||||
@@ -13954,15 +14204,15 @@ open class RoomListItemSDKMock: MatrixRustSDK.RoomListItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
open var fullRoomClosure: (() async throws -> Room)?
|
open var fullRoomClosure: (() throws -> Room)?
|
||||||
|
|
||||||
open override func fullRoom() async throws -> Room {
|
open override func fullRoom() throws -> Room {
|
||||||
if let error = fullRoomThrowableError {
|
if let error = fullRoomThrowableError {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
fullRoomCallsCount += 1
|
fullRoomCallsCount += 1
|
||||||
if let fullRoomClosure = fullRoomClosure {
|
if let fullRoomClosure = fullRoomClosure {
|
||||||
return try await fullRoomClosure()
|
return try fullRoomClosure()
|
||||||
} else {
|
} else {
|
||||||
return fullRoomReturnValue
|
return fullRoomReturnValue
|
||||||
}
|
}
|
||||||
@@ -16307,46 +16557,6 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - cancelSend
|
|
||||||
|
|
||||||
var cancelSendTxnIdUnderlyingCallsCount = 0
|
|
||||||
open var cancelSendTxnIdCallsCount: Int {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return cancelSendTxnIdUnderlyingCallsCount
|
|
||||||
} else {
|
|
||||||
var returnValue: Int? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = cancelSendTxnIdUnderlyingCallsCount
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
cancelSendTxnIdUnderlyingCallsCount = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
cancelSendTxnIdUnderlyingCallsCount = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
open var cancelSendTxnIdCalled: Bool {
|
|
||||||
return cancelSendTxnIdCallsCount > 0
|
|
||||||
}
|
|
||||||
open var cancelSendTxnIdReceivedTxnId: String?
|
|
||||||
open var cancelSendTxnIdReceivedInvocations: [String] = []
|
|
||||||
open var cancelSendTxnIdClosure: ((String) -> Void)?
|
|
||||||
|
|
||||||
open override func cancelSend(txnId: String) {
|
|
||||||
cancelSendTxnIdCallsCount += 1
|
|
||||||
cancelSendTxnIdReceivedTxnId = txnId
|
|
||||||
cancelSendTxnIdReceivedInvocations.append(txnId)
|
|
||||||
cancelSendTxnIdClosure?(txnId)
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: - createPoll
|
//MARK: - createPoll
|
||||||
|
|
||||||
open var createPollQuestionAnswersMaxSelectionsPollKindThrowableError: Error?
|
open var createPollQuestionAnswersMaxSelectionsPollKindThrowableError: Error?
|
||||||
@@ -16379,16 +16589,16 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline {
|
|||||||
}
|
}
|
||||||
open var createPollQuestionAnswersMaxSelectionsPollKindReceivedArguments: (question: String, answers: [String], maxSelections: UInt8, pollKind: PollKind)?
|
open var createPollQuestionAnswersMaxSelectionsPollKindReceivedArguments: (question: String, answers: [String], maxSelections: UInt8, pollKind: PollKind)?
|
||||||
open var createPollQuestionAnswersMaxSelectionsPollKindReceivedInvocations: [(question: String, answers: [String], maxSelections: UInt8, pollKind: PollKind)] = []
|
open var createPollQuestionAnswersMaxSelectionsPollKindReceivedInvocations: [(question: String, answers: [String], maxSelections: UInt8, pollKind: PollKind)] = []
|
||||||
open var createPollQuestionAnswersMaxSelectionsPollKindClosure: ((String, [String], UInt8, PollKind) throws -> Void)?
|
open var createPollQuestionAnswersMaxSelectionsPollKindClosure: ((String, [String], UInt8, PollKind) async throws -> Void)?
|
||||||
|
|
||||||
open override func createPoll(question: String, answers: [String], maxSelections: UInt8, pollKind: PollKind) throws {
|
open override func createPoll(question: String, answers: [String], maxSelections: UInt8, pollKind: PollKind) async throws {
|
||||||
if let error = createPollQuestionAnswersMaxSelectionsPollKindThrowableError {
|
if let error = createPollQuestionAnswersMaxSelectionsPollKindThrowableError {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
createPollQuestionAnswersMaxSelectionsPollKindCallsCount += 1
|
createPollQuestionAnswersMaxSelectionsPollKindCallsCount += 1
|
||||||
createPollQuestionAnswersMaxSelectionsPollKindReceivedArguments = (question: question, answers: answers, maxSelections: maxSelections, pollKind: pollKind)
|
createPollQuestionAnswersMaxSelectionsPollKindReceivedArguments = (question: question, answers: answers, maxSelections: maxSelections, pollKind: pollKind)
|
||||||
createPollQuestionAnswersMaxSelectionsPollKindReceivedInvocations.append((question: question, answers: answers, maxSelections: maxSelections, pollKind: pollKind))
|
createPollQuestionAnswersMaxSelectionsPollKindReceivedInvocations.append((question: question, answers: answers, maxSelections: maxSelections, pollKind: pollKind))
|
||||||
try createPollQuestionAnswersMaxSelectionsPollKindClosure?(question, answers, maxSelections, pollKind)
|
try await createPollQuestionAnswersMaxSelectionsPollKindClosure?(question, answers, maxSelections, pollKind)
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - edit
|
//MARK: - edit
|
||||||
@@ -16749,18 +16959,18 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - getTimelineEventContentByEventId
|
//MARK: - getEventTimelineItemByTransactionId
|
||||||
|
|
||||||
open var getTimelineEventContentByEventIdEventIdThrowableError: Error?
|
open var getEventTimelineItemByTransactionIdTransactionIdThrowableError: Error?
|
||||||
var getTimelineEventContentByEventIdEventIdUnderlyingCallsCount = 0
|
var getEventTimelineItemByTransactionIdTransactionIdUnderlyingCallsCount = 0
|
||||||
open var getTimelineEventContentByEventIdEventIdCallsCount: Int {
|
open var getEventTimelineItemByTransactionIdTransactionIdCallsCount: Int {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return getTimelineEventContentByEventIdEventIdUnderlyingCallsCount
|
return getEventTimelineItemByTransactionIdTransactionIdUnderlyingCallsCount
|
||||||
} else {
|
} else {
|
||||||
var returnValue: Int? = nil
|
var returnValue: Int? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = getTimelineEventContentByEventIdEventIdUnderlyingCallsCount
|
returnValue = getEventTimelineItemByTransactionIdTransactionIdUnderlyingCallsCount
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue!
|
return returnValue!
|
||||||
@@ -16768,29 +16978,29 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline {
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
getTimelineEventContentByEventIdEventIdUnderlyingCallsCount = newValue
|
getEventTimelineItemByTransactionIdTransactionIdUnderlyingCallsCount = newValue
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
getTimelineEventContentByEventIdEventIdUnderlyingCallsCount = newValue
|
getEventTimelineItemByTransactionIdTransactionIdUnderlyingCallsCount = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
open var getTimelineEventContentByEventIdEventIdCalled: Bool {
|
open var getEventTimelineItemByTransactionIdTransactionIdCalled: Bool {
|
||||||
return getTimelineEventContentByEventIdEventIdCallsCount > 0
|
return getEventTimelineItemByTransactionIdTransactionIdCallsCount > 0
|
||||||
}
|
}
|
||||||
open var getTimelineEventContentByEventIdEventIdReceivedEventId: String?
|
open var getEventTimelineItemByTransactionIdTransactionIdReceivedTransactionId: String?
|
||||||
open var getTimelineEventContentByEventIdEventIdReceivedInvocations: [String] = []
|
open var getEventTimelineItemByTransactionIdTransactionIdReceivedInvocations: [String] = []
|
||||||
|
|
||||||
var getTimelineEventContentByEventIdEventIdUnderlyingReturnValue: RoomMessageEventContentWithoutRelation!
|
var getEventTimelineItemByTransactionIdTransactionIdUnderlyingReturnValue: EventTimelineItem!
|
||||||
open var getTimelineEventContentByEventIdEventIdReturnValue: RoomMessageEventContentWithoutRelation! {
|
open var getEventTimelineItemByTransactionIdTransactionIdReturnValue: EventTimelineItem! {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return getTimelineEventContentByEventIdEventIdUnderlyingReturnValue
|
return getEventTimelineItemByTransactionIdTransactionIdUnderlyingReturnValue
|
||||||
} else {
|
} else {
|
||||||
var returnValue: RoomMessageEventContentWithoutRelation? = nil
|
var returnValue: EventTimelineItem? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = getTimelineEventContentByEventIdEventIdUnderlyingReturnValue
|
returnValue = getEventTimelineItemByTransactionIdTransactionIdUnderlyingReturnValue
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue!
|
return returnValue!
|
||||||
@@ -16798,27 +17008,27 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline {
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
getTimelineEventContentByEventIdEventIdUnderlyingReturnValue = newValue
|
getEventTimelineItemByTransactionIdTransactionIdUnderlyingReturnValue = newValue
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
getTimelineEventContentByEventIdEventIdUnderlyingReturnValue = newValue
|
getEventTimelineItemByTransactionIdTransactionIdUnderlyingReturnValue = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
open var getTimelineEventContentByEventIdEventIdClosure: ((String) async throws -> RoomMessageEventContentWithoutRelation)?
|
open var getEventTimelineItemByTransactionIdTransactionIdClosure: ((String) async throws -> EventTimelineItem)?
|
||||||
|
|
||||||
open override func getTimelineEventContentByEventId(eventId: String) async throws -> RoomMessageEventContentWithoutRelation {
|
open override func getEventTimelineItemByTransactionId(transactionId: String) async throws -> EventTimelineItem {
|
||||||
if let error = getTimelineEventContentByEventIdEventIdThrowableError {
|
if let error = getEventTimelineItemByTransactionIdTransactionIdThrowableError {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
getTimelineEventContentByEventIdEventIdCallsCount += 1
|
getEventTimelineItemByTransactionIdTransactionIdCallsCount += 1
|
||||||
getTimelineEventContentByEventIdEventIdReceivedEventId = eventId
|
getEventTimelineItemByTransactionIdTransactionIdReceivedTransactionId = transactionId
|
||||||
getTimelineEventContentByEventIdEventIdReceivedInvocations.append(eventId)
|
getEventTimelineItemByTransactionIdTransactionIdReceivedInvocations.append(transactionId)
|
||||||
if let getTimelineEventContentByEventIdEventIdClosure = getTimelineEventContentByEventIdEventIdClosure {
|
if let getEventTimelineItemByTransactionIdTransactionIdClosure = getEventTimelineItemByTransactionIdTransactionIdClosure {
|
||||||
return try await getTimelineEventContentByEventIdEventIdClosure(eventId)
|
return try await getEventTimelineItemByTransactionIdTransactionIdClosure(transactionId)
|
||||||
} else {
|
} else {
|
||||||
return getTimelineEventContentByEventIdEventIdReturnValue
|
return getEventTimelineItemByTransactionIdTransactionIdReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17004,6 +17214,79 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//MARK: - redactEvent
|
||||||
|
|
||||||
|
open var redactEventItemReasonThrowableError: Error?
|
||||||
|
var redactEventItemReasonUnderlyingCallsCount = 0
|
||||||
|
open var redactEventItemReasonCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return redactEventItemReasonUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = redactEventItemReasonUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
redactEventItemReasonUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
redactEventItemReasonUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var redactEventItemReasonCalled: Bool {
|
||||||
|
return redactEventItemReasonCallsCount > 0
|
||||||
|
}
|
||||||
|
open var redactEventItemReasonReceivedArguments: (item: EventTimelineItem, reason: String?)?
|
||||||
|
open var redactEventItemReasonReceivedInvocations: [(item: EventTimelineItem, reason: String?)] = []
|
||||||
|
|
||||||
|
var redactEventItemReasonUnderlyingReturnValue: Bool!
|
||||||
|
open var redactEventItemReasonReturnValue: Bool! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return redactEventItemReasonUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: Bool? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = redactEventItemReasonUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
redactEventItemReasonUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
redactEventItemReasonUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var redactEventItemReasonClosure: ((EventTimelineItem, String?) async throws -> Bool)?
|
||||||
|
|
||||||
|
open override func redactEvent(item: EventTimelineItem, reason: String?) async throws -> Bool {
|
||||||
|
if let error = redactEventItemReasonThrowableError {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
redactEventItemReasonCallsCount += 1
|
||||||
|
redactEventItemReasonReceivedArguments = (item: item, reason: reason)
|
||||||
|
redactEventItemReasonReceivedInvocations.append((item: item, reason: reason))
|
||||||
|
if let redactEventItemReasonClosure = redactEventItemReasonClosure {
|
||||||
|
return try await redactEventItemReasonClosure(item, reason)
|
||||||
|
} else {
|
||||||
|
return redactEventItemReasonReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//MARK: - retryDecryption
|
//MARK: - retryDecryption
|
||||||
|
|
||||||
var retryDecryptionSessionIdsUnderlyingCallsCount = 0
|
var retryDecryptionSessionIdsUnderlyingCallsCount = 0
|
||||||
@@ -17044,48 +17327,9 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline {
|
|||||||
retryDecryptionSessionIdsClosure?(sessionIds)
|
retryDecryptionSessionIdsClosure?(sessionIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - retrySend
|
|
||||||
|
|
||||||
var retrySendTxnIdUnderlyingCallsCount = 0
|
|
||||||
open var retrySendTxnIdCallsCount: Int {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return retrySendTxnIdUnderlyingCallsCount
|
|
||||||
} else {
|
|
||||||
var returnValue: Int? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = retrySendTxnIdUnderlyingCallsCount
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
retrySendTxnIdUnderlyingCallsCount = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
retrySendTxnIdUnderlyingCallsCount = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
open var retrySendTxnIdCalled: Bool {
|
|
||||||
return retrySendTxnIdCallsCount > 0
|
|
||||||
}
|
|
||||||
open var retrySendTxnIdReceivedTxnId: String?
|
|
||||||
open var retrySendTxnIdReceivedInvocations: [String] = []
|
|
||||||
open var retrySendTxnIdClosure: ((String) -> Void)?
|
|
||||||
|
|
||||||
open override func retrySend(txnId: String) {
|
|
||||||
retrySendTxnIdCallsCount += 1
|
|
||||||
retrySendTxnIdReceivedTxnId = txnId
|
|
||||||
retrySendTxnIdReceivedInvocations.append(txnId)
|
|
||||||
retrySendTxnIdClosure?(txnId)
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: - send
|
//MARK: - send
|
||||||
|
|
||||||
|
open var sendMsgThrowableError: Error?
|
||||||
var sendMsgUnderlyingCallsCount = 0
|
var sendMsgUnderlyingCallsCount = 0
|
||||||
open var sendMsgCallsCount: Int {
|
open var sendMsgCallsCount: Int {
|
||||||
get {
|
get {
|
||||||
@@ -17115,13 +17359,45 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline {
|
|||||||
}
|
}
|
||||||
open var sendMsgReceivedMsg: RoomMessageEventContentWithoutRelation?
|
open var sendMsgReceivedMsg: RoomMessageEventContentWithoutRelation?
|
||||||
open var sendMsgReceivedInvocations: [RoomMessageEventContentWithoutRelation] = []
|
open var sendMsgReceivedInvocations: [RoomMessageEventContentWithoutRelation] = []
|
||||||
open var sendMsgClosure: ((RoomMessageEventContentWithoutRelation) -> Void)?
|
|
||||||
|
|
||||||
open override func send(msg: RoomMessageEventContentWithoutRelation) {
|
var sendMsgUnderlyingReturnValue: AbortSendHandle!
|
||||||
|
open var sendMsgReturnValue: AbortSendHandle! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return sendMsgUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: AbortSendHandle? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = sendMsgUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
sendMsgUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
sendMsgUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open var sendMsgClosure: ((RoomMessageEventContentWithoutRelation) async throws -> AbortSendHandle)?
|
||||||
|
|
||||||
|
open override func send(msg: RoomMessageEventContentWithoutRelation) async throws -> AbortSendHandle {
|
||||||
|
if let error = sendMsgThrowableError {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
sendMsgCallsCount += 1
|
sendMsgCallsCount += 1
|
||||||
sendMsgReceivedMsg = msg
|
sendMsgReceivedMsg = msg
|
||||||
sendMsgReceivedInvocations.append(msg)
|
sendMsgReceivedInvocations.append(msg)
|
||||||
sendMsgClosure?(msg)
|
if let sendMsgClosure = sendMsgClosure {
|
||||||
|
return try await sendMsgClosure(msg)
|
||||||
|
} else {
|
||||||
|
return sendMsgReturnValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - sendAudio
|
//MARK: - sendAudio
|
||||||
@@ -17362,13 +17638,13 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline {
|
|||||||
}
|
}
|
||||||
open var sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeReceivedArguments: (body: String, geoUri: String, description: String?, zoomLevel: UInt8?, assetType: AssetType?)?
|
open var sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeReceivedArguments: (body: String, geoUri: String, description: String?, zoomLevel: UInt8?, assetType: AssetType?)?
|
||||||
open var sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeReceivedInvocations: [(body: String, geoUri: String, description: String?, zoomLevel: UInt8?, assetType: AssetType?)] = []
|
open var sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeReceivedInvocations: [(body: String, geoUri: String, description: String?, zoomLevel: UInt8?, assetType: AssetType?)] = []
|
||||||
open var sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeClosure: ((String, String, String?, UInt8?, AssetType?) -> Void)?
|
open var sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeClosure: ((String, String, String?, UInt8?, AssetType?) async -> Void)?
|
||||||
|
|
||||||
open override func sendLocation(body: String, geoUri: String, description: String?, zoomLevel: UInt8?, assetType: AssetType?) {
|
open override func sendLocation(body: String, geoUri: String, description: String?, zoomLevel: UInt8?, assetType: AssetType?) async {
|
||||||
sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeCallsCount += 1
|
sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeCallsCount += 1
|
||||||
sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeReceivedArguments = (body: body, geoUri: geoUri, description: description, zoomLevel: zoomLevel, assetType: assetType)
|
sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeReceivedArguments = (body: body, geoUri: geoUri, description: description, zoomLevel: zoomLevel, assetType: assetType)
|
||||||
sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeReceivedInvocations.append((body: body, geoUri: geoUri, description: description, zoomLevel: zoomLevel, assetType: assetType))
|
sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeReceivedInvocations.append((body: body, geoUri: geoUri, description: description, zoomLevel: zoomLevel, assetType: assetType))
|
||||||
sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeClosure?(body, geoUri, description, zoomLevel, assetType)
|
await sendLocationBodyGeoUriDescriptionZoomLevelAssetTypeClosure?(body, geoUri, description, zoomLevel, assetType)
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - sendPollResponse
|
//MARK: - sendPollResponse
|
||||||
@@ -17403,16 +17679,16 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline {
|
|||||||
}
|
}
|
||||||
open var sendPollResponsePollStartIdAnswersReceivedArguments: (pollStartId: String, answers: [String])?
|
open var sendPollResponsePollStartIdAnswersReceivedArguments: (pollStartId: String, answers: [String])?
|
||||||
open var sendPollResponsePollStartIdAnswersReceivedInvocations: [(pollStartId: String, answers: [String])] = []
|
open var sendPollResponsePollStartIdAnswersReceivedInvocations: [(pollStartId: String, answers: [String])] = []
|
||||||
open var sendPollResponsePollStartIdAnswersClosure: ((String, [String]) throws -> Void)?
|
open var sendPollResponsePollStartIdAnswersClosure: ((String, [String]) async throws -> Void)?
|
||||||
|
|
||||||
open override func sendPollResponse(pollStartId: String, answers: [String]) throws {
|
open override func sendPollResponse(pollStartId: String, answers: [String]) async throws {
|
||||||
if let error = sendPollResponsePollStartIdAnswersThrowableError {
|
if let error = sendPollResponsePollStartIdAnswersThrowableError {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
sendPollResponsePollStartIdAnswersCallsCount += 1
|
sendPollResponsePollStartIdAnswersCallsCount += 1
|
||||||
sendPollResponsePollStartIdAnswersReceivedArguments = (pollStartId: pollStartId, answers: answers)
|
sendPollResponsePollStartIdAnswersReceivedArguments = (pollStartId: pollStartId, answers: answers)
|
||||||
sendPollResponsePollStartIdAnswersReceivedInvocations.append((pollStartId: pollStartId, answers: answers))
|
sendPollResponsePollStartIdAnswersReceivedInvocations.append((pollStartId: pollStartId, answers: answers))
|
||||||
try sendPollResponsePollStartIdAnswersClosure?(pollStartId, answers)
|
try await sendPollResponsePollStartIdAnswersClosure?(pollStartId, answers)
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - sendReadReceipt
|
//MARK: - sendReadReceipt
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ struct RoomProxyMockConfiguration {
|
|||||||
|
|
||||||
func makeTimeline() -> TimelineProxyMock {
|
func makeTimeline() -> TimelineProxyMock {
|
||||||
let timeline = TimelineProxyMock()
|
let timeline = TimelineProxyMock()
|
||||||
timeline.underlyingActions = Empty(completeImmediately: false).eraseToAnyPublisher()
|
|
||||||
timeline.sendMessageEventContentReturnValue = .success(())
|
timeline.sendMessageEventContentReturnValue = .success(())
|
||||||
|
|
||||||
let timelineProvider = RoomTimelineProviderMock()
|
let timelineProvider = RoomTimelineProviderMock()
|
||||||
|
|||||||
@@ -157,7 +157,9 @@ class RoomScreenInteractionHandler {
|
|||||||
actions.append(.copy)
|
actions.append(.copy)
|
||||||
}
|
}
|
||||||
|
|
||||||
actions.append(.copyPermalink)
|
if item.isRemoteMessage {
|
||||||
|
actions.append(.copyPermalink)
|
||||||
|
}
|
||||||
|
|
||||||
if canRedactItem(item), let poll = item.pollIfAvailable, !poll.hasEnded, let eventID = itemID.eventID {
|
if canRedactItem(item), let poll = item.pollIfAvailable, !poll.hasEnded, let eventID = itemID.eventID {
|
||||||
actions.append(.endPoll(pollStartID: eventID))
|
actions.append(.endPoll(pollStartID: eventID))
|
||||||
@@ -224,11 +226,7 @@ class RoomScreenInteractionHandler {
|
|||||||
}
|
}
|
||||||
case .redact:
|
case .redact:
|
||||||
Task {
|
Task {
|
||||||
if eventTimelineItem.hasFailedToSend {
|
await timelineController.redact(itemID)
|
||||||
await timelineController.cancelSending(itemID: itemID)
|
|
||||||
} else {
|
|
||||||
await timelineController.redact(itemID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case .reply:
|
case .reply:
|
||||||
guard let eventID = eventTimelineItem.id.eventID else {
|
guard let eventID = eventTimelineItem.id.eventID else {
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ enum RoomScreenViewAction {
|
|||||||
case displayRoomMemberDetails(userID: String)
|
case displayRoomMemberDetails(userID: String)
|
||||||
case displayReactionSummary(itemID: TimelineItemIdentifier, key: String)
|
case displayReactionSummary(itemID: TimelineItemIdentifier, key: String)
|
||||||
case displayEmojiPicker(itemID: TimelineItemIdentifier)
|
case displayEmojiPicker(itemID: TimelineItemIdentifier)
|
||||||
case displayMessageSendingFailureAlert(itemID: TimelineItemIdentifier)
|
|
||||||
case displayReadReceipts(itemID: TimelineItemIdentifier)
|
case displayReadReceipts(itemID: TimelineItemIdentifier)
|
||||||
case displayCall
|
case displayCall
|
||||||
|
|
||||||
@@ -175,10 +174,6 @@ struct TimelineItemActionMenuInfo: Equatable, Identifiable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MessageSendingFailureInfo: Hashable {
|
|
||||||
let itemID: TimelineItemIdentifier
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ReactionSummaryInfo: Identifiable {
|
struct ReactionSummaryInfo: Identifiable {
|
||||||
let reactions: [AggregatedReaction]
|
let reactions: [AggregatedReaction]
|
||||||
let selectedKey: String
|
let selectedKey: String
|
||||||
@@ -196,7 +191,6 @@ struct ReadReceiptSummaryInfo: Identifiable {
|
|||||||
enum RoomScreenAlertInfoType: Hashable {
|
enum RoomScreenAlertInfoType: Hashable {
|
||||||
case audioRecodingPermissionError
|
case audioRecodingPermissionError
|
||||||
case pollEndConfirmation(String)
|
case pollEndConfirmation(String)
|
||||||
case messageSendingFailure(TimelineItemIdentifier)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RoomMemberState {
|
struct RoomMemberState {
|
||||||
|
|||||||
@@ -174,8 +174,6 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
roomScreenInteractionHandler.displayEmojiPicker(for: itemID)
|
roomScreenInteractionHandler.displayEmojiPicker(for: itemID)
|
||||||
case .displayReactionSummary(let itemID, let key):
|
case .displayReactionSummary(let itemID, let key):
|
||||||
displayReactionSummary(for: itemID, selectedKey: key)
|
displayReactionSummary(for: itemID, selectedKey: key)
|
||||||
case .displayMessageSendingFailureAlert(let itemID):
|
|
||||||
displayAlert(.messageSendingFailure(itemID))
|
|
||||||
case .displayReadReceipts(itemID: let itemID):
|
case .displayReadReceipts(itemID: let itemID):
|
||||||
displayReadReceipts(for: itemID)
|
displayReadReceipts(for: itemID)
|
||||||
case .displayCall:
|
case .displayCall:
|
||||||
@@ -387,14 +385,6 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
roomProxy.timeline.actions
|
|
||||||
.filter { $0 == .sentMessage }
|
|
||||||
.receive(on: DispatchQueue.main)
|
|
||||||
.sink { [weak self] _ in
|
|
||||||
self?.scrollToBottom()
|
|
||||||
}
|
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
appSettings.$timelineStyle
|
appSettings.$timelineStyle
|
||||||
.weakAssign(to: \.state.timelineStyle, on: self)
|
.weakAssign(to: \.state.timelineStyle, on: self)
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
@@ -558,10 +548,10 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
inReplyTo: itemId,
|
inReplyTo: itemId,
|
||||||
intentionalMentions: intentionalMentions)
|
intentionalMentions: intentionalMentions)
|
||||||
case .edit(let originalItemId):
|
case .edit(let originalItemId):
|
||||||
await timelineController.editMessage(message,
|
await timelineController.edit(originalItemId,
|
||||||
html: html,
|
message: message,
|
||||||
original: originalItemId,
|
html: html,
|
||||||
intentionalMentions: intentionalMentions)
|
intentionalMentions: intentionalMentions)
|
||||||
case .default:
|
case .default:
|
||||||
await timelineController.sendMessage(message,
|
await timelineController.sendMessage(message,
|
||||||
html: html,
|
html: html,
|
||||||
@@ -569,6 +559,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
case .recordVoiceMessage, .previewVoiceMessage:
|
case .recordVoiceMessage, .previewVoiceMessage:
|
||||||
fatalError("invalid composer mode.")
|
fatalError("invalid composer mode.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scrollToBottom()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func trackComposerMode(_ mode: RoomScreenComposerMode) {
|
private func trackComposerMode(_ mode: RoomScreenComposerMode) {
|
||||||
@@ -770,15 +762,6 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
message: L10n.commonPollEndConfirmation,
|
message: L10n.commonPollEndConfirmation,
|
||||||
primaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil),
|
primaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil),
|
||||||
secondaryButton: .init(title: L10n.actionOk, action: { self.roomScreenInteractionHandler.endPoll(pollStartID: pollStartID) }))
|
secondaryButton: .init(title: L10n.actionOk, action: { self.roomScreenInteractionHandler.endPoll(pollStartID: pollStartID) }))
|
||||||
case .messageSendingFailure(let itemID):
|
|
||||||
state.bindings.alertInfo = .init(id: type,
|
|
||||||
title: L10n.screenRoomRetrySendMenuTitle,
|
|
||||||
primaryButton: .init(title: L10n.screenRoomRetrySendMenuSendAgainAction) {
|
|
||||||
Task { await self.timelineController.retrySending(itemID: itemID) }
|
|
||||||
},
|
|
||||||
secondaryButton: .init(title: L10n.actionRemove, role: .destructive) {
|
|
||||||
Task { await self.timelineController.cancelSending(itemID: itemID) }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,9 +110,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
|
|||||||
VStack(alignment: alignment, spacing: -3) {
|
VStack(alignment: alignment, spacing: -3) {
|
||||||
messageBubble
|
messageBubble
|
||||||
.timelineItemAccessibility(timelineItem) {
|
.timelineItemAccessibility(timelineItem) {
|
||||||
if adjustedDeliveryStatus == .sendingFailed {
|
if adjustedDeliveryStatus != .sendingFailed {
|
||||||
context.send(viewAction: .displayMessageSendingFailureAlert(itemID: timelineItem.id))
|
|
||||||
} else {
|
|
||||||
context.send(viewAction: .displayTimelineItemMenu(itemID: timelineItem.id))
|
context.send(viewAction: .displayTimelineItemMenu(itemID: timelineItem.id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,22 +169,10 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
|
|||||||
timelineItem.bubbleSendInfoLayoutType
|
timelineItem.bubbleSendInfoLayoutType
|
||||||
.layout {
|
.layout {
|
||||||
contentWithReply
|
contentWithReply
|
||||||
interactiveLocalizedSendInfo
|
layoutedLocalizedSendInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
var interactiveLocalizedSendInfo: some View {
|
|
||||||
if adjustedDeliveryStatus == .sendingFailed {
|
|
||||||
layoutedLocalizedSendInfo
|
|
||||||
.onTapGesture {
|
|
||||||
context.send(viewAction: .displayMessageSendingFailureAlert(itemID: timelineItem.id))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
layoutedLocalizedSendInfo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
var layoutedLocalizedSendInfo: some View {
|
var layoutedLocalizedSendInfo: some View {
|
||||||
switch timelineItem.bubbleSendInfoLayoutType {
|
switch timelineItem.bubbleSendInfoLayoutType {
|
||||||
|
|||||||
@@ -55,9 +55,6 @@ struct TimelineItemStatusView: View {
|
|||||||
if style == .plain {
|
if style == .plain {
|
||||||
CompoundIcon(\.error, size: .xSmall, relativeTo: .compound.bodyMD)
|
CompoundIcon(\.error, size: .xSmall, relativeTo: .compound.bodyMD)
|
||||||
.foregroundColor(.compound.iconCriticalPrimary)
|
.foregroundColor(.compound.iconCriticalPrimary)
|
||||||
.onTapGesture {
|
|
||||||
context.send(viewAction: .displayMessageSendingFailureAlert(itemID: timelineItem.id))
|
|
||||||
}
|
|
||||||
.accessibilityLabel(L10n.commonSendingFailed)
|
.accessibilityLabel(L10n.commonSendingFailed)
|
||||||
.accessibilityHint(L10n.actionTapForOptions)
|
.accessibilityHint(L10n.actionTapForOptions)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
|
|||||||
initialDeviceName: initialDeviceName,
|
initialDeviceName: initialDeviceName,
|
||||||
deviceId: deviceID)
|
deviceId: deviceID)
|
||||||
|
|
||||||
let refreshToken = try? await client.session().refreshToken
|
let refreshToken = try? client.session().refreshToken
|
||||||
|
|
||||||
if refreshToken != nil {
|
if refreshToken != nil {
|
||||||
MXLog.warning("Refresh token found for a non oidc session, can't restore session, logging out")
|
MXLog.warning("Refresh token found for a non oidc session, can't restore session, logging out")
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
// periphery:ignore - required for instance retention in the rust codebase
|
// periphery:ignore - required for instance retention in the rust codebase
|
||||||
private var verificationStateListenerTaskHandle: TaskHandle?
|
private var verificationStateListenerTaskHandle: TaskHandle?
|
||||||
|
|
||||||
|
// periphery:ignore - required for instance retention in the rust codebase
|
||||||
|
private var sendingQueueListenerTaskHandle: TaskHandle?
|
||||||
|
|
||||||
private var delegateHandle: TaskHandle?
|
private var delegateHandle: TaskHandle?
|
||||||
|
|
||||||
// These following summary providers both operate on the same allRooms() list but
|
// These following summary providers both operate on the same allRooms() list but
|
||||||
@@ -161,6 +164,17 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
verificationStateListenerTaskHandle = client.encryption().verificationStateListener(listener: VerificationStateListenerProxy { [weak self] verificationState in
|
verificationStateListenerTaskHandle = client.encryption().verificationStateListener(listener: VerificationStateListenerProxy { [weak self] verificationState in
|
||||||
self?.updateVerificationState(verificationState)
|
self?.updateVerificationState(verificationState)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
sendingQueueListenerTaskHandle = client.subscribeToSendingQueueStatus(listener: SendingQueueStatusListenerProxy { [weak self] enabled in
|
||||||
|
guard let self else { return }
|
||||||
|
|
||||||
|
MXLog.error("Sending queue status changed to enabled: \(enabled)")
|
||||||
|
|
||||||
|
if enabled == false,
|
||||||
|
networkMonitor.reachabilityPublisher.value == .reachable {
|
||||||
|
setSendingQueueEnabled(true)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateVerificationState(_ verificationState: VerificationState) {
|
private func updateVerificationState(_ verificationState: VerificationState) {
|
||||||
@@ -578,6 +592,11 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setSendingQueueEnabled(_ enabled: Bool) {
|
||||||
|
MXLog.info("Setting sending queue to enabled: \(enabled)")
|
||||||
|
client.enableSendingQueue(enable: enabled)
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Ignored users
|
// MARK: Ignored users
|
||||||
|
|
||||||
func ignoreUser(_ userID: String) async -> Result<Void, ClientProxyError> {
|
func ignoreUser(_ userID: String) async -> Result<Void, ClientProxyError> {
|
||||||
@@ -784,7 +803,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
if roomListItem?.isTimelineInitialized() == false {
|
if roomListItem?.isTimelineInitialized() == false {
|
||||||
try await roomListItem?.initTimeline(eventTypeFilter: eventFilters, internalIdPrefix: nil)
|
try await roomListItem?.initTimeline(eventTypeFilter: eventFilters, internalIdPrefix: nil)
|
||||||
}
|
}
|
||||||
let fullRoom = try await roomListItem?.fullRoom()
|
let fullRoom = try roomListItem?.fullRoom()
|
||||||
|
|
||||||
return (roomListItem, fullRoom)
|
return (roomListItem, fullRoom)
|
||||||
} catch {
|
} catch {
|
||||||
@@ -920,6 +939,18 @@ private class IgnoredUsersListenerProxy: IgnoredUsersListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class SendingQueueStatusListenerProxy: SendingQueueStatusListener {
|
||||||
|
private let onUpdateClosure: (Bool) -> Void
|
||||||
|
|
||||||
|
init(onUpdateClosure: @escaping (Bool) -> Void) {
|
||||||
|
self.onUpdateClosure = onUpdateClosure
|
||||||
|
}
|
||||||
|
|
||||||
|
func onUpdate(newValue: Bool) {
|
||||||
|
onUpdateClosure(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private extension RoomPreviewDetails {
|
private extension RoomPreviewDetails {
|
||||||
init(_ roomPreview: RoomPreview) {
|
init(_ roomPreview: RoomPreview) {
|
||||||
self = RoomPreviewDetails(roomID: roomPreview.roomId,
|
self = RoomPreviewDetails(roomID: roomPreview.roomId,
|
||||||
|
|||||||
@@ -160,6 +160,8 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
|||||||
func roomDirectorySearchProxy() -> RoomDirectorySearchProxyProtocol
|
func roomDirectorySearchProxy() -> RoomDirectorySearchProxyProtocol
|
||||||
|
|
||||||
func resolveRoomAlias(_ alias: String) async -> Result<ResolvedRoomAlias, ClientProxyError>
|
func resolveRoomAlias(_ alias: String) async -> Result<ResolvedRoomAlias, ClientProxyError>
|
||||||
|
|
||||||
|
func setSendingQueueEnabled(_ enabled: Bool)
|
||||||
|
|
||||||
// MARK: - Ignored users
|
// MARK: - Ignored users
|
||||||
|
|
||||||
|
|||||||
+5
-21
@@ -92,11 +92,11 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
intentionalMentions: IntentionalMentions) async { }
|
intentionalMentions: IntentionalMentions) async { }
|
||||||
|
|
||||||
func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async { }
|
func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async { }
|
||||||
|
|
||||||
func editMessage(_ newMessage: String,
|
func edit(_ timelineItemID: TimelineItemIdentifier,
|
||||||
html: String?,
|
message: String,
|
||||||
original itemID: TimelineItemIdentifier,
|
html: String?,
|
||||||
intentionalMentions: IntentionalMentions) async { }
|
intentionalMentions: IntentionalMentions) async { }
|
||||||
|
|
||||||
func redact(_ itemID: TimelineItemIdentifier) async { }
|
func redact(_ itemID: TimelineItemIdentifier) async { }
|
||||||
|
|
||||||
@@ -109,23 +109,7 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func retryDecryption(for sessionID: String) async { }
|
func retryDecryption(for sessionID: String) async { }
|
||||||
|
|
||||||
func retrySending(itemID: TimelineItemIdentifier) async {
|
|
||||||
guard let transactionID = itemID.transactionID else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
await roomProxy?.timeline.retrySend(transactionID: transactionID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func cancelSending(itemID: TimelineItemIdentifier) async {
|
|
||||||
guard let transactionID = itemID.transactionID else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
await roomProxy?.timeline.cancelSend(transactionID: transactionID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func eventTimestamp(for itemID: TimelineItemIdentifier) -> Date? {
|
func eventTimestamp(for itemID: TimelineItemIdentifier) -> Date? {
|
||||||
timelineItemsTimestamp[itemID] ?? .now
|
timelineItemsTimestamp[itemID] ?? .now
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-58
@@ -131,7 +131,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = await roomProxy.timeline.sendReadReceipt(for: eventID, type: receiptType)
|
_ = await activeTimeline.sendReadReceipt(for: eventID, type: receiptType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,10 +162,10 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch await roomProxy.timeline.sendMessage(message,
|
switch await activeTimeline.sendMessage(message,
|
||||||
html: html,
|
html: html,
|
||||||
inReplyTo: inReplyTo,
|
inReplyTo: inReplyTo,
|
||||||
intentionalMentions: intentionalMentions) {
|
intentionalMentions: intentionalMentions) {
|
||||||
case .success:
|
case .success:
|
||||||
MXLog.info("Finished sending message")
|
MXLog.info("Finished sending message")
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
@@ -188,38 +188,27 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func editMessage(_ newMessage: String,
|
func edit(_ timelineItemID: TimelineItemIdentifier,
|
||||||
html: String?,
|
message: String,
|
||||||
original itemID: TimelineItemIdentifier,
|
html: String?,
|
||||||
intentionalMentions: IntentionalMentions) async {
|
intentionalMentions: IntentionalMentions) async {
|
||||||
MXLog.info("Edit message in \(roomID)")
|
MXLog.info("Edit message in \(roomID)")
|
||||||
if let timelineItem = timelineItems.firstUsingStableID(itemID),
|
|
||||||
let item = timelineItem as? EventBasedTimelineItemProtocol,
|
switch await activeTimeline.edit(timelineItemID,
|
||||||
item.hasFailedToSend {
|
message: message,
|
||||||
MXLog.info("Editing a failed echo, will cancel and resend it as a new message")
|
html: html,
|
||||||
await cancelSending(itemID: itemID)
|
intentionalMentions: intentionalMentions) {
|
||||||
await sendMessage(newMessage, html: html, intentionalMentions: intentionalMentions)
|
case .success:
|
||||||
} else if let eventID = itemID.eventID {
|
MXLog.info("Finished editing message")
|
||||||
switch await activeTimeline.editMessage(newMessage,
|
case .failure(let error):
|
||||||
html: html,
|
MXLog.error("Failed editing message with error: \(error)")
|
||||||
original: eventID,
|
|
||||||
intentionalMentions: intentionalMentions) {
|
|
||||||
case .success:
|
|
||||||
MXLog.info("Finished editing message")
|
|
||||||
case .failure(let error):
|
|
||||||
MXLog.error("Failed editing message with error: \(error)")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
MXLog.error("Editing failed: missing identifiers")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func redact(_ itemID: TimelineItemIdentifier) async {
|
func redact(_ timelineItemID: TimelineItemIdentifier) async {
|
||||||
MXLog.info("Send redaction in \(roomID)")
|
MXLog.info("Send redaction in \(roomID)")
|
||||||
guard let eventID = itemID.eventID else {
|
|
||||||
return
|
switch await activeTimeline.redact(timelineItemID, reason: nil) {
|
||||||
}
|
|
||||||
switch await roomProxy.redact(eventID) {
|
|
||||||
case .success:
|
case .success:
|
||||||
MXLog.info("Finished redacting message")
|
MXLog.info("Finished redacting message")
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
@@ -227,12 +216,8 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func messageEventContent(for itemID: TimelineItemIdentifier) async -> RoomMessageEventContentWithoutRelation? {
|
func messageEventContent(for timelineItemID: TimelineItemIdentifier) async -> RoomMessageEventContentWithoutRelation? {
|
||||||
guard let eventID = itemID.eventID else {
|
await activeTimeline.messageEventContent(for: timelineItemID)
|
||||||
MXLog.warning("The item doesn't have an event ID.")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return await activeTimeline.messageEventContent(for: eventID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle this parallel to the timeline items so we're not forced
|
// Handle this parallel to the timeline items so we're not forced
|
||||||
@@ -256,26 +241,6 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
await activeTimeline.retryDecryption(for: sessionID)
|
await activeTimeline.retryDecryption(for: sessionID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func retrySending(itemID: TimelineItemIdentifier) async {
|
|
||||||
guard let transactionID = itemID.transactionID else {
|
|
||||||
MXLog.error("Failed Retry Send: missing transaction ID")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
MXLog.info("Retry sending in \(roomID)")
|
|
||||||
await roomProxy.timeline.retrySend(transactionID: transactionID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func cancelSending(itemID: TimelineItemIdentifier) async {
|
|
||||||
guard let transactionID = itemID.transactionID else {
|
|
||||||
MXLog.error("Failed Cancel Send: missing transaction ID")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
MXLog.info("Cancelling send in \(roomID)")
|
|
||||||
await roomProxy.timeline.cancelSend(transactionID: transactionID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
/// The cancellable used to update the timeline items.
|
/// The cancellable used to update the timeline items.
|
||||||
|
|||||||
+4
-8
@@ -59,10 +59,10 @@ protocol RoomTimelineControllerProtocol {
|
|||||||
inReplyTo itemID: TimelineItemIdentifier?,
|
inReplyTo itemID: TimelineItemIdentifier?,
|
||||||
intentionalMentions: IntentionalMentions) async
|
intentionalMentions: IntentionalMentions) async
|
||||||
|
|
||||||
func editMessage(_ newMessage: String,
|
func edit(_ timelineItemID: TimelineItemIdentifier,
|
||||||
html: String?,
|
message: String,
|
||||||
original itemID: TimelineItemIdentifier,
|
html: String?,
|
||||||
intentionalMentions: IntentionalMentions) async
|
intentionalMentions: IntentionalMentions) async
|
||||||
|
|
||||||
func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async
|
func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async
|
||||||
|
|
||||||
@@ -74,10 +74,6 @@ protocol RoomTimelineControllerProtocol {
|
|||||||
|
|
||||||
func retryDecryption(for sessionID: String) async
|
func retryDecryption(for sessionID: String) async
|
||||||
|
|
||||||
func retrySending(itemID: TimelineItemIdentifier) async
|
|
||||||
|
|
||||||
func cancelSending(itemID: TimelineItemIdentifier) async
|
|
||||||
|
|
||||||
func eventTimestamp(for itemID: TimelineItemIdentifier) -> Date?
|
func eventTimestamp(for itemID: TimelineItemIdentifier) -> Date?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,11 +78,8 @@ class EventTimelineItemProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch localSendState {
|
switch localSendState {
|
||||||
case .notSentYet:
|
case .notSentYet, .sendingFailed:
|
||||||
return .sending
|
return .sending
|
||||||
// cancelled is exactly like sendingFailed but does not contain an error
|
|
||||||
case .sendingFailed, .cancelled:
|
|
||||||
return .sendingFailed
|
|
||||||
case .sent:
|
case .sent:
|
||||||
return .sent
|
return .sent
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
|
|||||||
return buildEncryptedTimelineItem(eventItemProxy, encryptedMessage, isOutgoing)
|
return buildEncryptedTimelineItem(eventItemProxy, encryptedMessage, isOutgoing)
|
||||||
case .redactedMessage:
|
case .redactedMessage:
|
||||||
return buildRedactedTimelineItem(eventItemProxy, isOutgoing)
|
return buildRedactedTimelineItem(eventItemProxy, isOutgoing)
|
||||||
case .sticker(let body, let imageInfo, let urlString):
|
case .sticker(let body, let imageInfo, let mediaSource):
|
||||||
guard let url = URL(string: urlString) else {
|
guard let url = URL(string: mediaSource.url()) else {
|
||||||
MXLog.error("Invalid sticker url string: \(urlString)")
|
MXLog.error("Invalid sticker url string: \(mediaSource.url())")
|
||||||
return buildUnsupportedTimelineItem(eventItemProxy, "m.sticker", "Invalid Sticker URL", isOutgoing)
|
return buildUnsupportedTimelineItem(eventItemProxy, "m.sticker", "Invalid Sticker URL", isOutgoing)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,11 +33,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
private let forwardPaginationStatusSubject = CurrentValueSubject<PaginationStatus, Never>(.timelineEndReached)
|
private let forwardPaginationStatusSubject = CurrentValueSubject<PaginationStatus, Never>(.timelineEndReached)
|
||||||
private let timelineUpdatesSubject = PassthroughSubject<[TimelineDiff], Never>()
|
private let timelineUpdatesSubject = PassthroughSubject<[TimelineDiff], Never>()
|
||||||
|
|
||||||
private let actionsSubject = PassthroughSubject<TimelineProxyAction, Never>()
|
|
||||||
var actions: AnyPublisher<TimelineProxyAction, Never> {
|
|
||||||
actionsSubject.eraseToAnyPublisher()
|
|
||||||
}
|
|
||||||
|
|
||||||
let isLive: Bool
|
let isLive: Bool
|
||||||
|
|
||||||
private var innerTimelineProvider: RoomTimelineProviderProtocol!
|
private var innerTimelineProvider: RoomTimelineProviderProtocol!
|
||||||
@@ -83,38 +78,6 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
paginationStatePublisher: paginationStatePublisher)
|
paginationStatePublisher: paginationStatePublisher)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cancelSend(transactionID: String) async {
|
|
||||||
MXLog.info("Cancelling sending for transaction ID: \(transactionID)")
|
|
||||||
|
|
||||||
return await Task.dispatch(on: messageSendingDispatchQueue) {
|
|
||||||
self.timeline.cancelSend(txnId: transactionID)
|
|
||||||
MXLog.info("Finished cancelling sending for transaction ID: \(transactionID)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func editMessage(_ message: String,
|
|
||||||
html: String?,
|
|
||||||
original eventID: String,
|
|
||||||
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
|
|
||||||
MXLog.info("Editing message with original event ID: \(eventID)")
|
|
||||||
|
|
||||||
let messageContent = buildMessageContentFor(message,
|
|
||||||
html: html,
|
|
||||||
intentionalMentions: intentionalMentions.toRustMentions())
|
|
||||||
|
|
||||||
do {
|
|
||||||
let originalEvent = try await timeline.getEventTimelineItemByEventId(eventId: eventID)
|
|
||||||
try await timeline.edit(newContent: messageContent, editItem: originalEvent)
|
|
||||||
|
|
||||||
MXLog.info("Finished editing message with original event ID: \(eventID)")
|
|
||||||
|
|
||||||
return .success(())
|
|
||||||
} catch {
|
|
||||||
MXLog.error("Failed editing message with original event ID: \(eventID) with error: \(error)")
|
|
||||||
return .failure(.failedEditingMessage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func fetchDetails(for eventID: String) {
|
func fetchDetails(for eventID: String) {
|
||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
@@ -127,17 +90,8 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func messageEventContent(for eventID: String) async -> RoomMessageEventContentWithoutRelation? {
|
func messageEventContent(for timelineItemID: TimelineItemIdentifier) async -> RoomMessageEventContentWithoutRelation? {
|
||||||
MXLog.info("Fetching event content for \(eventID)")
|
await timelineProvider.itemProxies.firstEventTimelineItemUsingID(timelineItemID)?.content().asMessage()?.content()
|
||||||
|
|
||||||
do {
|
|
||||||
let result = try await timeline.getTimelineEventContentByEventId(eventId: eventID)
|
|
||||||
MXLog.info("Finished fetching event content for eventID: \(eventID)")
|
|
||||||
return result
|
|
||||||
} catch {
|
|
||||||
MXLog.error("Failed fetching event content for eventID: \(eventID) with error: \(error)")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func paginateBackwards(requestSize: UInt16) async -> Result<Void, TimelineProxyError> {
|
func paginateBackwards(requestSize: UInt16) async -> Result<Void, TimelineProxyError> {
|
||||||
@@ -150,7 +104,7 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed paginating backwards with error: \(error)")
|
MXLog.error("Failed paginating backwards with error: \(error)")
|
||||||
return .failure(.failedPaginatingBackwards)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +113,7 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
// We need it to make sure we send a valid status after a failure.
|
// We need it to make sure we send a valid status after a failure.
|
||||||
guard forwardPaginationStatusSubject.value == .idle else {
|
guard forwardPaginationStatusSubject.value == .idle else {
|
||||||
MXLog.error("Attempting to paginate forwards when already at the end.")
|
MXLog.error("Attempting to paginate forwards when already at the end.")
|
||||||
return .failure(.failedPaginatingBackwards)
|
return .failure(.failedPaginatingEndReached)
|
||||||
}
|
}
|
||||||
|
|
||||||
MXLog.info("Paginating forwards")
|
MXLog.info("Paginating forwards")
|
||||||
@@ -174,7 +128,7 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed paginating forwards with error: \(error)")
|
MXLog.error("Failed paginating forwards with error: \(error)")
|
||||||
forwardPaginationStatusSubject.send(.idle)
|
forwardPaginationStatusSubject.send(.idle)
|
||||||
return .failure(.failedPaginatingBackwards)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,15 +141,59 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func retrySend(transactionID: String) async {
|
func edit(_ timelineItemID: TimelineItemIdentifier,
|
||||||
MXLog.info("Retrying sending for transactionID: \(transactionID)")
|
message: String, html: String?,
|
||||||
|
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError> {
|
||||||
|
MXLog.info("Editing timeline item: \(timelineItemID)")
|
||||||
|
|
||||||
return await Task.dispatch(on: messageSendingDispatchQueue) {
|
guard let eventTimelineItem = await timelineProvider.itemProxies.firstEventTimelineItemUsingID(timelineItemID) else {
|
||||||
self.timeline.retrySend(txnId: transactionID)
|
MXLog.error("Unknown timeline item: \(timelineItemID)")
|
||||||
MXLog.info("Finished retrying sending for transactionID: \(transactionID)")
|
return .failure(.failedEditing)
|
||||||
|
}
|
||||||
|
|
||||||
|
let messageContent = buildMessageContentFor(message,
|
||||||
|
html: html,
|
||||||
|
intentionalMentions: intentionalMentions.toRustMentions())
|
||||||
|
|
||||||
|
do {
|
||||||
|
try await timeline.edit(newContent: messageContent, editItem: eventTimelineItem)
|
||||||
|
|
||||||
|
MXLog.info("Finished editing timeline item: \(timelineItemID)")
|
||||||
|
|
||||||
|
return .success(())
|
||||||
|
} catch {
|
||||||
|
MXLog.error("Failed editing timeline item: \(timelineItemID) with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func redact(_ timelineItemID: TimelineItemIdentifier, reason: String?) async -> Result<Void, TimelineProxyError> {
|
||||||
|
MXLog.info("Redacting timeline item: \(timelineItemID)")
|
||||||
|
|
||||||
|
guard let eventTimelineItem = await timelineProvider.itemProxies.firstEventTimelineItemUsingID(timelineItemID) else {
|
||||||
|
MXLog.error("Unknown timeline item: \(timelineItemID)")
|
||||||
|
return .failure(.failedRedacting)
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
let success = try await timeline.redactEvent(item: eventTimelineItem, reason: reason)
|
||||||
|
|
||||||
|
guard success else {
|
||||||
|
MXLog.error("Failed redacting timeline item: \(timelineItemID)")
|
||||||
|
return .failure(.failedRedacting)
|
||||||
|
}
|
||||||
|
|
||||||
|
MXLog.info("Redacted timeline item: \(timelineItemID)")
|
||||||
|
|
||||||
|
return .success(())
|
||||||
|
} catch {
|
||||||
|
MXLog.error("Failed redacting timeline item: \(timelineItemID) with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Sending
|
||||||
|
|
||||||
func sendAudio(url: URL,
|
func sendAudio(url: URL,
|
||||||
audioInfo: AudioInfo,
|
audioInfo: AudioInfo,
|
||||||
progressSubject: CurrentValueSubject<Double, Never>?,
|
progressSubject: CurrentValueSubject<Double, Never>?,
|
||||||
@@ -213,11 +211,9 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
MXLog.info("Finished sending audio")
|
MXLog.info("Finished sending audio")
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed sending audio with error: \(error)")
|
MXLog.error("Failed sending audio with error: \(error)")
|
||||||
return .failure(.failedSendingMedia)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
actionsSubject.send(.sentMessage)
|
|
||||||
|
|
||||||
return .success(())
|
return .success(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,11 +234,9 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
MXLog.info("Finished sending file")
|
MXLog.info("Finished sending file")
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed sending file with error: \(error)")
|
MXLog.error("Failed sending file with error: \(error)")
|
||||||
return .failure(.failedSendingMedia)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
actionsSubject.send(.sentMessage)
|
|
||||||
|
|
||||||
return .success(())
|
return .success(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,11 +258,9 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
MXLog.info("Finished sending image")
|
MXLog.info("Finished sending image")
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed sending image with error: \(error)")
|
MXLog.error("Failed sending image with error: \(error)")
|
||||||
return .failure(.failedSendingMedia)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
actionsSubject.send(.sentMessage)
|
|
||||||
|
|
||||||
return .success(())
|
return .success(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,19 +271,15 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
assetType: AssetType?) async -> Result<Void, TimelineProxyError> {
|
assetType: AssetType?) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Sending location")
|
MXLog.info("Sending location")
|
||||||
|
|
||||||
return await Task.dispatch(on: messageSendingDispatchQueue) {
|
await timeline.sendLocation(body: body,
|
||||||
self.timeline.sendLocation(body: body,
|
geoUri: geoURI.string,
|
||||||
geoUri: geoURI.string,
|
description: description,
|
||||||
description: description,
|
zoomLevel: zoomLevel,
|
||||||
zoomLevel: zoomLevel,
|
assetType: assetType)
|
||||||
assetType: assetType)
|
|
||||||
|
MXLog.info("Finished sending location")
|
||||||
self.actionsSubject.send(.sentMessage)
|
|
||||||
|
return .success(())
|
||||||
MXLog.info("Finished sending location")
|
|
||||||
|
|
||||||
return .success(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendVideo(url: URL,
|
func sendVideo(url: URL,
|
||||||
@@ -312,11 +300,9 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
MXLog.info("Finished sending video")
|
MXLog.info("Finished sending video")
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed sending video with error: \(error)")
|
MXLog.error("Failed sending video with error: \(error)")
|
||||||
return .failure(.failedSendingMedia)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
actionsSubject.send(.sentMessage)
|
|
||||||
|
|
||||||
return .success(())
|
return .success(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,11 +324,9 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
MXLog.info("Finished sending voice message")
|
MXLog.info("Finished sending voice message")
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed sending vocie message with error: \(error)")
|
MXLog.error("Failed sending vocie message with error: \(error)")
|
||||||
return .failure(.failedSendingMedia)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
actionsSubject.send(.sentMessage)
|
|
||||||
|
|
||||||
return .success(())
|
return .success(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,36 +350,34 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
try await timeline.sendReply(msg: messageContent, replyItem: replyItem)
|
try await timeline.sendReply(msg: messageContent, replyItem: replyItem)
|
||||||
MXLog.info("Finished sending reply to eventID: \(eventID)")
|
MXLog.info("Finished sending reply to eventID: \(eventID)")
|
||||||
} else {
|
} else {
|
||||||
timeline.send(msg: messageContent)
|
_ = try await timeline.send(msg: messageContent)
|
||||||
MXLog.info("Finished sending message")
|
MXLog.info("Finished sending message")
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
if let eventID {
|
if let eventID {
|
||||||
MXLog.error("Failed sending reply to eventID: \(eventID)")
|
MXLog.error("Failed sending reply to eventID: \(eventID) with error: \(error)")
|
||||||
} else {
|
} else {
|
||||||
MXLog.error("Failed sending message")
|
MXLog.error("Failed sending message with error: \(error)")
|
||||||
}
|
}
|
||||||
|
|
||||||
return .failure(.failedSendingMessage)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
actionsSubject.send(.sentMessage)
|
|
||||||
|
|
||||||
return .success(())
|
return .success(())
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendMessageEventContent(_ messageContent: RoomMessageEventContentWithoutRelation) async -> Result<Void, TimelineProxyError> {
|
func sendMessageEventContent(_ messageContent: RoomMessageEventContentWithoutRelation) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Sending message content")
|
MXLog.info("Sending message content")
|
||||||
|
|
||||||
return await Task.dispatch(on: messageSendingDispatchQueue) {
|
do {
|
||||||
self.timeline.send(msg: messageContent)
|
_ = try await timeline.send(msg: messageContent)
|
||||||
|
} catch {
|
||||||
self.actionsSubject.send(.sentMessage)
|
MXLog.error("Failed sending message with error: \(error)")
|
||||||
|
|
||||||
MXLog.info("Finished sending message content")
|
|
||||||
|
|
||||||
return .success(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MXLog.info("Finished sending message content")
|
||||||
|
|
||||||
|
return .success(())
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendReadReceipt(for eventID: String, type: ReceiptType) async -> Result<Void, TimelineProxyError> {
|
func sendReadReceipt(for eventID: String, type: ReceiptType) async -> Result<Void, TimelineProxyError> {
|
||||||
@@ -407,7 +389,7 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed sending read receipt for eventID: \(eventID) with error: \(error)")
|
MXLog.error("Failed sending read receipt for eventID: \(eventID) with error: \(error)")
|
||||||
return .failure(.failedSendingReadReceipt)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,7 +402,7 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed toggling reaction for eventID: \(eventID)")
|
MXLog.error("Failed toggling reaction for eventID: \(eventID)")
|
||||||
return .failure(.failedSendingReaction)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,19 +411,15 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
func createPoll(question: String, answers: [String], pollKind: Poll.Kind) async -> Result<Void, TimelineProxyError> {
|
func createPoll(question: String, answers: [String], pollKind: Poll.Kind) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Creating poll")
|
MXLog.info("Creating poll")
|
||||||
|
|
||||||
return await Task.dispatch(on: .global()) {
|
do {
|
||||||
do {
|
try await timeline.createPoll(question: question, answers: answers, maxSelections: 1, pollKind: .init(pollKind: pollKind))
|
||||||
try self.timeline.createPoll(question: question, answers: answers, maxSelections: 1, pollKind: .init(pollKind: pollKind))
|
|
||||||
|
MXLog.info("Finished creating poll")
|
||||||
self.actionsSubject.send(.sentMessage)
|
|
||||||
|
return .success(())
|
||||||
MXLog.info("Finished creating poll")
|
} catch {
|
||||||
|
MXLog.error("Failed creating poll with error: \(error)")
|
||||||
return .success(())
|
return .failure(.sdkError(error))
|
||||||
} catch {
|
|
||||||
MXLog.error("Failed creating poll with error: \(error)")
|
|
||||||
return .failure(.failedCreatingPoll)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,7 +439,7 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed editing poll with eventID: \(eventID) with error: \(error)")
|
MXLog.error("Failed editing poll with eventID: \(eventID) with error: \(error)")
|
||||||
return .failure(.failedEditingPoll)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,7 +455,7 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed ending poll with eventID: \(pollStartID) with error: \(error)")
|
MXLog.error("Failed ending poll with eventID: \(pollStartID) with error: \(error)")
|
||||||
return .failure(.failedEndingPoll)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -485,17 +463,15 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
func sendPollResponse(pollStartID: String, answers: [String]) async -> Result<Void, TimelineProxyError> {
|
func sendPollResponse(pollStartID: String, answers: [String]) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Sending response for poll with eventID: \(pollStartID)")
|
MXLog.info("Sending response for poll with eventID: \(pollStartID)")
|
||||||
|
|
||||||
return await Task.dispatch(on: .global()) {
|
do {
|
||||||
do {
|
try await timeline.sendPollResponse(pollStartId: pollStartID, answers: answers)
|
||||||
try self.timeline.sendPollResponse(pollStartId: pollStartID, answers: answers)
|
|
||||||
|
MXLog.info("Finished sending response for poll with eventID: \(pollStartID)")
|
||||||
MXLog.info("Finished sending response for poll with eventID: \(pollStartID)")
|
|
||||||
|
return .success(())
|
||||||
return .success(())
|
} catch {
|
||||||
} catch {
|
MXLog.error("Failed sending response for poll with eventID: \(pollStartID) with error: \(error)")
|
||||||
MXLog.error("Failed sending response for poll with eventID: \(pollStartID) with error: \(error)")
|
return .failure(.sdkError(error))
|
||||||
return .failure(.failedSendingPollResponse)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -607,3 +583,20 @@ private extension MatrixRustSDK.PollKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Array where Element == TimelineItemProxy {
|
||||||
|
func firstEventTimelineItemUsingID(_ id: TimelineItemIdentifier) -> EventTimelineItem? {
|
||||||
|
var eventTimelineItemProxy: EventTimelineItemProxy?
|
||||||
|
|
||||||
|
for item in self {
|
||||||
|
if case let .event(eventTimelineItem) = item {
|
||||||
|
if eventTimelineItem.id == id {
|
||||||
|
eventTimelineItemProxy = eventTimelineItem
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return eventTimelineItemProxy?.item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,55 +18,41 @@ import Combine
|
|||||||
import Foundation
|
import Foundation
|
||||||
import MatrixRustSDK
|
import MatrixRustSDK
|
||||||
|
|
||||||
enum TimelineProxyError: Error, Equatable {
|
enum TimelineProxyError: Error {
|
||||||
case failedEditingMessage
|
case sdkError(Error)
|
||||||
case failedPaginatingBackwards
|
|
||||||
case failedSendingMessage
|
|
||||||
case failedSendingReaction
|
|
||||||
case failedSendingReadReceipt
|
|
||||||
case failedSendingMedia
|
|
||||||
|
|
||||||
// Polls
|
case failedEditing
|
||||||
case failedCreatingPoll
|
case failedRedacting
|
||||||
case failedEditingPoll
|
case failedPaginatingEndReached
|
||||||
case failedEndingPoll
|
|
||||||
case failedSendingPollResponse
|
|
||||||
}
|
|
||||||
|
|
||||||
enum TimelineProxyAction {
|
|
||||||
case sentMessage
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sourcery: AutoMockable
|
// sourcery: AutoMockable
|
||||||
protocol TimelineProxyProtocol {
|
protocol TimelineProxyProtocol {
|
||||||
var actions: AnyPublisher<TimelineProxyAction, Never> { get }
|
|
||||||
|
|
||||||
var isLive: Bool { get }
|
var isLive: Bool { get }
|
||||||
|
|
||||||
var timelineProvider: RoomTimelineProviderProtocol { get }
|
var timelineProvider: RoomTimelineProviderProtocol { get }
|
||||||
|
|
||||||
func subscribeForUpdates() async
|
func subscribeForUpdates() async
|
||||||
|
|
||||||
/// Cancels a failed message given its transaction ID from the timeline
|
|
||||||
func cancelSend(transactionID: String) async
|
|
||||||
|
|
||||||
func editMessage(_ message: String,
|
|
||||||
html: String?,
|
|
||||||
original eventID: String,
|
|
||||||
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError>
|
|
||||||
|
|
||||||
func fetchDetails(for eventID: String)
|
func fetchDetails(for eventID: String)
|
||||||
|
|
||||||
func messageEventContent(for eventID: String) async -> RoomMessageEventContentWithoutRelation?
|
func messageEventContent(for timelineItemID: TimelineItemIdentifier) async -> RoomMessageEventContentWithoutRelation?
|
||||||
|
|
||||||
func retryDecryption(for sessionID: String) async
|
func retryDecryption(for sessionID: String) async
|
||||||
|
|
||||||
/// Retries sending a failed message given its transaction ID
|
|
||||||
func retrySend(transactionID: String) async
|
|
||||||
|
|
||||||
func paginateBackwards(requestSize: UInt16) async -> Result<Void, TimelineProxyError>
|
func paginateBackwards(requestSize: UInt16) async -> Result<Void, TimelineProxyError>
|
||||||
func paginateForwards(requestSize: UInt16) async -> Result<Void, TimelineProxyError>
|
func paginateForwards(requestSize: UInt16) async -> Result<Void, TimelineProxyError>
|
||||||
|
|
||||||
|
func edit(_ timelineItemID: TimelineItemIdentifier,
|
||||||
|
message: String,
|
||||||
|
html: String?,
|
||||||
|
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError>
|
||||||
|
|
||||||
|
func redact(_ timelineItemID: TimelineItemIdentifier,
|
||||||
|
reason: String?) async -> Result<Void, TimelineProxyError>
|
||||||
|
|
||||||
|
// MARK: - Sending
|
||||||
|
|
||||||
func sendAudio(url: URL,
|
func sendAudio(url: URL,
|
||||||
audioInfo: AudioInfo,
|
audioInfo: AudioInfo,
|
||||||
progressSubject: CurrentValueSubject<Double, Never>?,
|
progressSubject: CurrentValueSubject<Double, Never>?,
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class UserSessionStore: UserSessionStoreProtocol {
|
|||||||
|
|
||||||
func userSession(for client: Client, passphrase: String?) async -> Result<UserSessionProtocol, UserSessionStoreError> {
|
func userSession(for client: Client, passphrase: String?) async -> Result<UserSessionProtocol, UserSessionStoreError> {
|
||||||
do {
|
do {
|
||||||
let session = try await client.session()
|
let session = try client.session()
|
||||||
let userID = try client.userId()
|
let userID = try client.userId()
|
||||||
let clientProxy = await setupProxyForClient(client)
|
let clientProxy = await setupProxyForClient(client)
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -5,8 +5,8 @@
|
|||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/apple/swift-argument-parser",
|
"location" : "https://github.com/apple/swift-argument-parser",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "46989693916f56d1186bd59ac15124caef896560",
|
"revision" : "0fbc8848e389af3bb55c182bc19ca9d5dc2f255b",
|
||||||
"version" : "1.3.1"
|
"version" : "1.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ class RoomPollsHistoryScreenViewModelTests: XCTestCase {
|
|||||||
value.bindings.alertInfo != nil
|
value.bindings.alertInfo != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
interactionHandler.endPollPollStartIDReturnValue = .failure(TimelineProxyError.failedEndingPoll)
|
interactionHandler.endPollPollStartIDReturnValue = .failure(SDKError.generic)
|
||||||
viewModel.context.send(viewAction: .end(pollStartID: "somePollID"))
|
viewModel.context.send(viewAction: .end(pollStartID: "somePollID"))
|
||||||
|
|
||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
@@ -155,7 +155,7 @@ class RoomPollsHistoryScreenViewModelTests: XCTestCase {
|
|||||||
value.bindings.alertInfo != nil
|
value.bindings.alertInfo != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
interactionHandler.sendPollResponsePollStartIDOptionIDReturnValue = .failure(TimelineProxyError.failedSendingPollResponse)
|
interactionHandler.sendPollResponsePollStartIDOptionIDReturnValue = .failure(SDKError.generic)
|
||||||
viewModel.context.send(viewAction: .sendPollResponse(pollStartID: "somePollID", optionID: "someOptionID"))
|
viewModel.context.send(viewAction: .sendPollResponse(pollStartID: "somePollID", optionID: "someOptionID"))
|
||||||
|
|
||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
@@ -180,3 +180,7 @@ class RoomPollsHistoryScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum SDKError: Error {
|
||||||
|
case generic
|
||||||
|
}
|
||||||
|
|||||||
@@ -336,7 +336,6 @@ class RoomScreenViewModelTests: XCTestCase {
|
|||||||
let roomProxy = RoomProxyMock(.init(name: ""))
|
let roomProxy = RoomProxyMock(.init(name: ""))
|
||||||
|
|
||||||
let timelineProxy = TimelineProxyMock()
|
let timelineProxy = TimelineProxyMock()
|
||||||
timelineProxy.underlyingActions = Empty(completeImmediately: false).eraseToAnyPublisher()
|
|
||||||
|
|
||||||
roomProxy.timeline = timelineProxy
|
roomProxy.timeline = timelineProxy
|
||||||
let timelineController = MockRoomTimelineController()
|
let timelineController = MockRoomTimelineController()
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ class VoiceMessageRecorderTests: XCTestCase {
|
|||||||
let timelineProxy = TimelineProxyMock()
|
let timelineProxy = TimelineProxyMock()
|
||||||
let roomProxy = RoomProxyMock()
|
let roomProxy = RoomProxyMock()
|
||||||
roomProxy.timeline = timelineProxy
|
roomProxy.timeline = timelineProxy
|
||||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformProgressSubjectRequestHandleReturnValue = .failure(.failedSendingMedia)
|
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformProgressSubjectRequestHandleReturnValue = .failure(.sdkError(SDKError.generic))
|
||||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: audioConverter) else {
|
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: audioConverter) else {
|
||||||
XCTFail("An error is expected")
|
XCTFail("An error is expected")
|
||||||
return
|
return
|
||||||
@@ -260,7 +260,7 @@ class VoiceMessageRecorderTests: XCTestCase {
|
|||||||
let timelineProxy = TimelineProxyMock()
|
let timelineProxy = TimelineProxyMock()
|
||||||
let roomProxy = RoomProxyMock()
|
let roomProxy = RoomProxyMock()
|
||||||
roomProxy.timeline = timelineProxy
|
roomProxy.timeline = timelineProxy
|
||||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformProgressSubjectRequestHandleReturnValue = .failure(.failedSendingMedia)
|
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformProgressSubjectRequestHandleReturnValue = .failure(.sdkError(SDKError.generic))
|
||||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: audioConverter) else {
|
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: audioConverter) else {
|
||||||
XCTFail("An error is expected")
|
XCTFail("An error is expected")
|
||||||
return
|
return
|
||||||
@@ -283,7 +283,7 @@ class VoiceMessageRecorderTests: XCTestCase {
|
|||||||
let timelineProxy = TimelineProxyMock()
|
let timelineProxy = TimelineProxyMock()
|
||||||
let roomProxy = RoomProxyMock()
|
let roomProxy = RoomProxyMock()
|
||||||
roomProxy.timeline = timelineProxy
|
roomProxy.timeline = timelineProxy
|
||||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformProgressSubjectRequestHandleReturnValue = .failure(.failedSendingMedia)
|
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformProgressSubjectRequestHandleReturnValue = .failure(.sdkError(SDKError.generic))
|
||||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: audioConverter) else {
|
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: audioConverter) else {
|
||||||
XCTFail("An error is expected")
|
XCTFail("An error is expected")
|
||||||
return
|
return
|
||||||
@@ -389,3 +389,7 @@ class VoiceMessageRecorderTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum SDKError: Error {
|
||||||
|
case generic
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
Adopt new automatically retrying message sending queue
|
||||||
+1
-1
@@ -49,7 +49,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: 1.0.8
|
exactVersion: 1.0.9
|
||||||
# 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